Skip to content

Commit

Permalink
prepare transactions for approval properly
Browse files Browse the repository at this point in the history
  • Loading branch information
talentlessguy committed Oct 23, 2024
1 parent 5136ca9 commit f0677dd
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 38 deletions.
2 changes: 2 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
"commitName": "Start timer",
"registerName": "Register name",
"approveNameWrapper": "Approve NameWrapper",
"approveEthRegistrar": "Approve ETH Registrar",
"clearRecords": "Clear records",
"updateRecords": "Update records",
"updateRecord": "Update record",
Expand Down Expand Up @@ -247,6 +248,7 @@
"burnFuses": "Burn the chosen permissions until name expiry",
"commitName": "Start timer to register name",
"approveNameWrapper": "Approve the NameWrapper to manage your names",
"approveEthRegistrar": "Approve ETH Registrar to migrate your unwrapped names",
"fuses": {
"revoke": "Revoke",
"grant": "Grant",
Expand Down
43 changes: 16 additions & 27 deletions src/components/pages/migrate/MigrationNamesList.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { useState } from 'react'
import { TFunction, useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { Address } from 'viem'
import { useEnsAvatar } from 'wagmi'

import { GetNamesForAddressParameters, NameWithRelation } from '@ensdomains/ensjs/subgraph'
import { NameWithRelation } from '@ensdomains/ensjs/subgraph'
import { CheckCircleSVG, Colors, DisabledSVG, PlusCircleSVG } from '@ensdomains/thorin'

import { useNamesForAddress } from '@app/hooks/ensjs/subgraph/useNamesForAddress'
import { calculateDatesDiff } from '@app/utils/date'
import { ensAvatarConfig } from '@app/utils/query/ipfsGateway'
import { formatDurationOfDates } from '@app/utils/utils'

const tabs = ['eligible', 'ineligible', 'approved'] as const

type Tab = (typeof tabs)[number]

const icons: Record<Tab, any> = {
eligible: <PlusCircleSVG />,
ineligible: <DisabledSVG />,
Expand All @@ -38,8 +36,6 @@ const colors: Record<Tab, { fg: Colors; bg: Colors; hover: Colors }> = {
},
}

type Tab = (typeof tabs)[number]

const Container = styled.div(
({ theme }) => css`
display: flex;
Expand Down Expand Up @@ -121,6 +117,10 @@ const NameCard = styled.div(
`,
)

const nameListTabs = ['eligible', 'ineligible', 'approved'] as const

export type NameListTab = (typeof nameListTabs)[number]

const MigrationName = ({ name, t }: { name: NameWithRelation; t: TFunction }) => {
const now = new Date()
const { data: avatar } = useEnsAvatar({ ...ensAvatarConfig, name: name.name! })
Expand All @@ -140,28 +140,17 @@ const MigrationName = ({ name, t }: { name: NameWithRelation; t: TFunction }) =>
)
}

const filter: Record<Tab, GetNamesForAddressParameters['filter']> = {
eligible: { owner: false, wrappedOwner: true, registrant: true, resolvedAddress: false },
ineligible: { owner: true, wrappedOwner: false, registrant: false, resolvedAddress: false },
}

export const MigrationNamesList = ({ address }: { address?: Address }) => {
const [activeTab, setTab] = useState<Tab>('eligible')

export const MigrationNamesList = ({
activeTab,
setTab,
names,
}: {
activeTab: NameListTab
names: NameWithRelation[]
setTab: (tab: NameListTab) => void
}) => {
const { t } = useTranslation('migrate')

const { infiniteData, isLoading } = useNamesForAddress({
address,
pageSize: 20,
filter: filter[activeTab],
})

const names = infiniteData.filter(
(name) =>
name.parentName === 'eth' &&
(activeTab === 'ineligible' ? name.registrant !== name.owner : true),
)

return (
<Container>
<TabsContainer>
Expand Down
64 changes: 53 additions & 11 deletions src/pages/migrate.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* eslint-disable @next/next/no-img-element */
import { useConnectModal } from '@rainbow-me/rainbowkit'
import Head from 'next/head'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { match } from 'ts-pattern'
import { useAccount } from 'wagmi'

import { GetNamesForAddressParameters } from '@ensdomains/ensjs/subgraph'
import {
Banner,
Button,
Expand All @@ -23,10 +25,11 @@ import {
} from '@ensdomains/thorin'

import { Carousel } from '@app/components/pages/migrate/Carousel'
import { MigrationNamesList } from '@app/components/pages/migrate/MigrationNamesList'
import { MigrationNamesList, NameListTab } from '@app/components/pages/migrate/MigrationNamesList'
import { useNamesForAddress } from '@app/hooks/ensjs/subgraph/useNamesForAddress'
import { useQueryParameterState } from '@app/hooks/useQueryParameterState'
import { makeIntroItem } from '@app/transaction-flow/intro'
import { createTransactionItem } from '@app/transaction-flow/transaction'
import { createTransactionItem, TransactionData } from '@app/transaction-flow/transaction'
import { useTransactionFlow } from '@app/transaction-flow/TransactionFlowProvider'

import DAOSVG from '../assets/DAO.svg'
Expand Down Expand Up @@ -236,6 +239,12 @@ const TabManager = styled.div(

const tabs = ['ensv2', 'migrations', 'extension'] as const

const filter: Record<NameListTab, GetNamesForAddressParameters['filter']> = {
eligible: { owner: false, wrappedOwner: true, registrant: true, resolvedAddress: false },
ineligible: { owner: true, wrappedOwner: false, registrant: false, resolvedAddress: false },
approved: {},
}

type Tab = (typeof tabs)[number]

export default function Page() {
Expand All @@ -249,6 +258,20 @@ export default function Page() {

const { createTransactionFlow } = useTransactionFlow()

const [activeNameListTab, setNameListTab] = useState<NameListTab>('eligible')

const { infiniteData } = useNamesForAddress({
address,
pageSize: 20,
filter: filter[activeNameListTab],
})

const names = infiniteData.filter(
(name) =>
name.parentName === 'eth' &&
(activeNameListTab === 'ineligible' ? name.registrant !== name.owner : true),
)

return (
<>
<Main>
Expand Down Expand Up @@ -318,6 +341,26 @@ export default function Page() {
<Button
onClick={() => {
if (isConnected) {
const transactions: {
name: 'approveNameWrapper' | 'approveEthRegistrar'
data: TransactionData<'approveNameWrapper' | 'approveEthRegistrar'>
}[] = []

if (names.find((name) => name.wrappedOwner)) {
transactions.push(
createTransactionItem('approveNameWrapper', {
address: address!,
}),
)
}
if (names.find((name) => name.relation.registrant)) {
transactions.push(
createTransactionItem('approveEthRegistrar', {
address: address!,
}),
)
}

createTransactionFlow('migrate-names', {
resumable: true,
intro: {
Expand All @@ -326,14 +369,7 @@ export default function Page() {
description: t('details.approve.description'),
}),
},
transactions: [
createTransactionItem('approveNameWrapper', {
address: address!,
}),
createTransactionItem('approveNameWrapper', {
address: address!,
}),
],
transactions,
})
} else {
openConnectModal?.()
Expand Down Expand Up @@ -429,7 +465,13 @@ export default function Page() {
))
.with('migrations', () => (
<>
{isConnected ? <MigrationNamesList address={address} /> : null}
{isConnected ? (
<MigrationNamesList
{...{ names }}
activeTab={activeNameListTab}
setTab={setNameListTab}
/>
) : null}
<Section>
<Typography asProp="h3" fontVariant="headingThree">
{t('approval-benefits.title')}
Expand Down
53 changes: 53 additions & 0 deletions src/transaction-flow/transaction/approveEthRegistrar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { TFunction } from 'react-i18next'
import { Address } from 'viem/accounts'
import { encodeFunctionData } from 'viem/utils'

import {
getChainContractAddress,
registrySetApprovalForAllSnippet,
} from '@ensdomains/ensjs/contracts'

import type { Transaction, TransactionDisplayItem, TransactionFunctionParameters } from '@app/types'

type Data = { address: Address }

const displayItems = (
{ address }: Data,
t: TFunction<'translation', undefined>,
): TransactionDisplayItem[] => [
{
label: 'address',
value: address,
type: 'address',
},
{
label: 'action',
value: t('transaction.description.approveEthRegistrar'),
},
{
label: 'info',
value: t('transaction.info.approveEthRegistrar'),
},
]

const transaction = async ({ client }: TransactionFunctionParameters<Data>) => {
return {
to: getChainContractAddress({
client,
contract: 'ensBaseRegistrarImplementation',
}),
data: encodeFunctionData({
abi: registrySetApprovalForAllSnippet,
functionName: 'setApprovalForAll',
args: [
getChainContractAddress({
client,
contract: 'ensBaseRegistrarImplementation',
}),
true,
],
}),
}
}

export default { displayItems, transaction } satisfies Transaction<Data>
2 changes: 2 additions & 0 deletions src/transaction-flow/transaction/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import approveDnsRegistrar from './approveDnsRegistrar'
import approveEthRegistrar from './approveEthRegistrar'
import approveNameWrapper from './approveNameWrapper'
import burnFuses from './burnFuses'
import changePermissions from './changePermissions'
Expand Down Expand Up @@ -31,6 +32,7 @@ import wrapName from './wrapName'

export const transactions = {
approveDnsRegistrar,
approveEthRegistrar,
approveNameWrapper,
burnFuses,
changePermissions,
Expand Down

0 comments on commit f0677dd

Please sign in to comment.