diff --git a/.github/workflows/pages-deployment.yaml b/.github/workflows/pages-deployment.yaml index 6aea45954..f92265db5 100644 --- a/.github/workflows/pages-deployment.yaml +++ b/.github/workflows/pages-deployment.yaml @@ -3,6 +3,7 @@ name: Cloudflare Pages env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} NEXT_PUBLIC_INTERCOM_ID: re9q5yti + NEXT_PUBLIC_DRPC_KEY: ${{ github.ref == 'refs/heads/main' && AnmpasF2C0JBqeAEzxVO8aTteiMlrW4R75hpDonbV6cR || '' }} on: [push] jobs: diff --git a/e2e/specs/stateful/address.spec.ts b/e2e/specs/stateful/address.spec.ts index 3997ab815..4fce98112 100644 --- a/e2e/specs/stateful/address.spec.ts +++ b/e2e/specs/stateful/address.spec.ts @@ -18,7 +18,6 @@ test('should go to the address page', async ({ page, login }) => { await page.goto('/') await login.connect() - await page.pause() await page .getByPlaceholder('Search for a name') .fill('0xFc5958B4B6F9a06D21E06429c8833f865577acf0') diff --git a/e2e/specs/stateless/_importName.spec.ts b/e2e/specs/stateless/_importName.spec.ts index 55e9d7172..1c9c9de6f 100644 --- a/e2e/specs/stateless/_importName.spec.ts +++ b/e2e/specs/stateless/_importName.spec.ts @@ -2,8 +2,33 @@ import { expect } from '@playwright/test' import { test } from '../../../playwright' -test('should allow claim (owned by user)', async ({ page, login, accounts, makePageObject }) => { +// When testing locally, reducers will be run twice because of strict mode +const strictModeEventCount = process.env.CI ? 1 : 2 + +test('should allow claim (owned by user)', async ({ + page, + login, + accounts, + makePageObject, + consoleListener, +}) => { + console.log(strictModeEventCount) const name = 'swagabc.xyz' + await consoleListener.initialize({ + regex: new RegExp( + `Event triggered on local development.*?(${[ + 'search_selected_dns', + 'dns_selected_import_type', + 'dns_sec_enabled', + 'dns_verified_ownership', + 'dns_claim_started', + 'dns_claimed', + 'dns_approve_registrar_wallet_opened', + 'dns_import_wallet_opened', + 'dns_claim_wallet_opened', + ].join('|')})`, + ), + }) const homePage = makePageObject('HomePage') const importPage = makePageObject('ImportPage') @@ -14,7 +39,17 @@ test('should allow claim (owned by user)', async ({ page, login, accounts, makeP // should redirect to registration page await homePage.searchInput.fill(name) + await page.locator(`[data-testid="search-result-name"]`, { hasText: name }).waitFor() + await page.locator(`[data-testid="search-result-name"]`, { hasText: 'Not Imported' }).waitFor() await homePage.searchInput.press('Enter') + + await test.step('should fire DNS import tracking event: search_selected_dns', async () => { + await expect(consoleListener.getMessages()).toHaveLength(1) + + await expect(consoleListener.getMessages().toString()).toContain('search_selected_dns') + consoleListener.clearMessages() + }) + await expect(importPage.heading).toHaveText(`Claim ${name}`) // no type should be checked yet @@ -31,6 +66,15 @@ test('should allow claim (owned by user)', async ({ page, login, accounts, makeP // should jump straight to transaction step await expect(importPage.heading).toHaveText('Claim your domain') + await test.step('should fire DNS import tracking event: dns_selected_import_type', async () => { + await expect(consoleListener.getMessages()).toHaveLength(strictModeEventCount) + + await expect(consoleListener.getMessages().toString()).toMatch( + new RegExp(`dns_selected_import_type.*?${name}`), + ) + consoleListener.clearMessages() + }) + // should show cost value above 0 await expect(importPage.getCost()).resolves.toBeGreaterThan(0) @@ -39,10 +83,26 @@ test('should allow claim (owned by user)', async ({ page, login, accounts, makeP await importPage.nextButton.click() + await test.step('should fire DNS import tracking event: dns_claim_started', async () => { + await expect(consoleListener.getMessages()).toHaveLength(1) + + await expect(consoleListener.getMessages().toString()).toContain('dns_claim_started') + consoleListener.clearMessages() + }) + // should be two steps: approve and claim await expect(transactionModal.getStepCount()).resolves.toEqual(2) await transactionModal.confirm() + + await test.step('should fire DNS import tracking event: dns_approve_registrar_wallet_opened', async () => { + await expect(consoleListener.getMessages()).toHaveLength(1) + await expect(consoleListener.getMessages().toString()).toContain( + 'dns_approve_registrar_wallet_opened', + ) + consoleListener.clearMessages() + }) + await transactionModal.complete() // should save transaction status on refresh @@ -59,6 +119,12 @@ test('should allow claim (owned by user)', async ({ page, login, accounts, makeP await expect(page.getByText('Open Wallet')).toBeVisible() await transactionModal.confirm() + await test.step('should fire DNS import tracking event: dns_claim_wallet_opened', async () => { + await expect(consoleListener.getMessages()).toHaveLength(1) + await expect(consoleListener.getMessages().toString()).toContain('dns_claim_wallet_opened') + consoleListener.clearMessages() + }) + // should show complete step await expect(page.getByText('Congratulations!')).toBeVisible() await expect(page.getByText(`You are now the owner of ${name}`)).toBeVisible() @@ -69,9 +135,24 @@ test('should allow claim (owned by user)', async ({ page, login, accounts, makeP ) }) -test('should allow import (not owned by user)', async ({ page, login, makePageObject }) => { +test('should allow import (not owned by user)', async ({ + page, + login, + makePageObject, + consoleListener, +}) => { const name = 'taytems.xyz' + await consoleListener.initialize({ + regex: new RegExp( + `Event triggered on local development.*?(${[ + 'search_selected_dns', + 'dns_selected_import_type', + 'dns_verified_ownership', + ].join('|')})`, + ), + }) + const homePage = makePageObject('HomePage') const importPage = makePageObject('ImportPage') const transactionModal = makePageObject('TransactionModal') @@ -81,7 +162,19 @@ test('should allow import (not owned by user)', async ({ page, login, makePageOb // should redirect to registration page await homePage.searchInput.fill(name) + await page.locator(`[data-testid="search-result-name"]`, { hasText: name }).waitFor() + await page.locator(`[data-testid="search-result-name"]`, { hasText: 'Not Imported' }).waitFor() await homePage.searchInput.press('Enter') + + await test.step('should fire DNS import tracking event: search_selected_dns', async () => { + await expect(consoleListener.getMessages()).toHaveLength(1) + + await expect(consoleListener.getMessages().toString()).toMatch( + new RegExp(`search_selected_dns.*?${name}`), + ) + consoleListener.clearMessages() + }) + await expect(importPage.heading).toHaveText(`Claim ${name}`) // no type should be checked yet @@ -95,6 +188,15 @@ test('should allow import (not owned by user)', async ({ page, login, makePageOb await expect(importPage.nextButton).toBeEnabled({ timeout: 15000 }) await importPage.nextButton.click() + await test.step('should fire DNS import tracking event: dns_selected_import_type', async () => { + await expect(consoleListener.getMessages()).toHaveLength(strictModeEventCount) + + await expect(consoleListener.getMessages().toString()).toMatch( + new RegExp(`dns_selected_import_type.*?${name}`), + ) + consoleListener.clearMessages() + }) + // should show verify ownership step with error message await expect(importPage.heading).toHaveText('Verify Ownership') await expect( @@ -107,6 +209,13 @@ test('should allow import (not owned by user)', async ({ page, login, makePageOb await importPage.nextButton.click() + await test.step('should fire DNS import tracking event: dns_verified_ownership', async () => { + await expect(consoleListener.getMessages()).toHaveLength(strictModeEventCount) + + await expect(consoleListener.getMessages().toString()).toContain('dns_verified_ownership') + consoleListener.clearMessages() + }) + // should go to transaction step await expect(importPage.heading).toHaveText('Import this domain') diff --git a/e2e/specs/stateless/advancedEditor.spec.ts b/e2e/specs/stateless/advancedEditor.spec.ts index 1f4e770d1..ec83ed3a3 100644 --- a/e2e/specs/stateless/advancedEditor.spec.ts +++ b/e2e/specs/stateless/advancedEditor.spec.ts @@ -152,7 +152,6 @@ test('should maintain state and when returning from transaction modal when addin await recordsPage.goto(name) await login.connect() - await page.pause() // Validate records await expect(recordsPage.getRecordValue('text', 'name')).toHaveText('Bob') @@ -257,7 +256,7 @@ test('should maintain state and when returning from transaction modal when addin await transactionModal.autoComplete() // Validate change in records - await page.pause() + await expect(recordsPage.getRecordValue('text', 'name')).toHaveText('Nick') await expect(recordsPage.getRecordValue('text', 'another text')).toHaveText('another record') await expect(recordsPage.getRecordValue('address', 'bnb')).toHaveText( @@ -266,7 +265,7 @@ test('should maintain state and when returning from transaction modal when addin await expect(recordsPage.getRecordValue('address', 'eth')).toHaveText( '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', ) - await page.pause() + await expect(recordsPage.getRecordValue('contentHash')).toHaveText( 'bzz://e40101fa011b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162'.toLowerCase(), ) diff --git a/e2e/specs/stateless/deleteSubname.spec.ts b/e2e/specs/stateless/deleteSubname.spec.ts index 094c294ed..25b4b61a8 100644 --- a/e2e/specs/stateless/deleteSubname.spec.ts +++ b/e2e/specs/stateless/deleteSubname.spec.ts @@ -26,7 +26,6 @@ test.describe('unwrapped', () => { await profilePage.goto(subname) await login.connect() - await page.pause() // Manager button should exist await expect(page.getByTestId('owner-profile-button-name.manager')).toBeVisible() diff --git a/e2e/specs/stateless/extendNames.spec.ts b/e2e/specs/stateless/extendNames.spec.ts index b13b390ee..5cf031d5e 100644 --- a/e2e/specs/stateless/extendNames.spec.ts +++ b/e2e/specs/stateless/extendNames.spec.ts @@ -196,7 +196,6 @@ test('should be able to extend a single unwrapped name in grace period from prof const timestamp = await profilePage.getExpiryTimestamp() - await page.pause() await profilePage.getExtendButton.click() const extendNamesModal = makePageObject('ExtendNamesModal') @@ -343,7 +342,6 @@ test('should be able to extend a name by a month', async ({ await profilePage.goto(name) await login.connect() - await page.pause() const timestamp = await profilePage.getExpiryTimestamp() await profilePage.getExtendButton.click() @@ -408,7 +406,6 @@ test('should be able to extend a name by a day', async ({ await profilePage.goto(name) await login.connect() - await page.pause() const timestamp = await profilePage.getExpiryTimestamp() await profilePage.getExtendButton.click() @@ -475,7 +472,6 @@ test('should be able to extend a name in grace period by a month', async ({ const timestamp = await profilePage.getExpiryTimestamp() - await page.pause() await profilePage.getExtendButton.click() const extendNamesModal = makePageObject('ExtendNamesModal') @@ -552,7 +548,6 @@ test('should be able to extend a name in grace period by 1 day', async ({ const timestamp = await profilePage.getExpiryTimestamp() - await page.pause() await profilePage.getExtendButton.click() const extendNamesModal = makePageObject('ExtendNamesModal') diff --git a/e2e/specs/stateless/myNames.spec.ts b/e2e/specs/stateless/myNames.spec.ts index 0c3ae97c5..ac85f255e 100644 --- a/e2e/specs/stateless/myNames.spec.ts +++ b/e2e/specs/stateless/myNames.spec.ts @@ -1,5 +1,12 @@ import { expect } from '@playwright/test' -import { testClient } from '@root/playwright/fixtures/contracts/utils/addTestContracts' +import { createAccounts } from '@root/playwright/fixtures/accounts' +import { + testClient, + walletClient, +} from '@root/playwright/fixtures/contracts/utils/addTestContracts' +import { Address, labelhash } from 'viem' + +import { deleteSubname } from '@ensdomains/ensjs/wallet' import { test } from '../../../playwright' import { Name } from '../../../playwright/fixtures/makeName' @@ -18,7 +25,6 @@ test('myNames', async ({ page, login, makeName }) => { await page.goto('/') await login.connect('user2') - await page.pause() await page.goto('/my/names') @@ -32,6 +38,229 @@ test('myNames', async ({ page, login, makeName }) => { ) expect(timestamps.every((timestamp) => timestamp === timestamps[0])).toBe(true) +}) + +test.describe.serial('myNames', () => { + test.beforeAll(async ({ subgraph }) => { + // Move time to the future to force previous names to expire + await testClient.increaseTime({ seconds: 2 * 365 * 24 * 60 * 60 }) + await testClient.mine({ blocks: 1 }) + await subgraph.sync() + }) + + let subnamesToDelete: string[] = [] + let allNames: string[] = [] + + test.afterAll(async () => { + console.log('cleaning up subnames') + const account = createAccounts().getAddress('user4') as Address + for (const subname of subnamesToDelete) { + const contract = subname.includes('wrapped') ? 'nameWrapper' : 'registry' + console.log('deleting subname:', subname, 'on', contract) + // eslint-disable-next-line no-await-in-loop + await deleteSubname(walletClient, { + name: subname, + account, + contract, + }) + } + }) + + const makeSubnamesConfig = (type: 'legacy' | 'wrapped') => + Array.from( + { length: 10 }, + (_, i) => + ({ + label: `sub${i}`, + owner: 'user4', + type, + ...(type === 'wrapped' + ? { + fuses: { + parent: { + named: ['PARENT_CANNOT_CONTROL'], + }, + }, + } + : {}), + }) as any, + ) + + test('should display all names for expiry date ASC', async ({ page, login, makeName }) => { + const earlierName = await makeName({ + label: 'earlier-wrapped', + type: 'wrapped', + owner: 'user4', + fuses: { + named: ['CANNOT_UNWRAP'], + }, + subnames: makeSubnamesConfig('wrapped'), + }) + const concurrentNames = await makeName([ + { + label: `concurrent-legacy`, + type: 'legacy', + owner: 'user4', + subnames: makeSubnamesConfig('legacy'), + } as Name, + { + label: `concurrent-wrapped`, + type: 'wrapped', + owner: 'user4', + fuses: { + named: ['CANNOT_UNWRAP'], + }, + subnames: makeSubnamesConfig('wrapped'), + }, + ]) + const laterName = await makeName({ + label: 'later-legacy-name', + type: 'legacy', + owner: 'user4', + subnames: makeSubnamesConfig('legacy'), + }) + + subnamesToDelete = [earlierName, ...concurrentNames, laterName].flatMap((name) => + Array.from({ length: 10 }, (_, i) => `sub${i}.${name}`), + ) + allNames = [earlierName, ...concurrentNames, laterName, ...subnamesToDelete] + + await page.goto('/') + await login.connect('user4') + await page.goto('/my/names') + + await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 }) + + await page.evaluate(async () => { + let previousScrollHeight = 0 + let { scrollHeight } = document.body + do { + window.scrollTo(0, scrollHeight) + // eslint-disable-next-line no-await-in-loop + await new Promise((resolve) => { + setTimeout(resolve, 1000) + }) + previousScrollHeight = scrollHeight + scrollHeight = document.body.scrollHeight + } while (previousScrollHeight !== scrollHeight) + }) + + for (const name of allNames) { + const decryptedLocator = page.getByTestId(`name-item-${name}`) + const nameParts = name.split('.') + const label = nameParts.shift()! + const labelHash = `[${labelhash(label).replace('0x', '')}]` + const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`) + // eslint-disable-next-line no-await-in-loop + await expect(decryptedLocator.or(encryptedLocator)).toBeVisible() + } + }) + + test('should display all names for expiry date DESC', async ({ page, login }) => { + await page.goto('/') + await login.connect('user4') + await page.goto('/my/names') + + await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 }) + + await page.getByTestId('sort-desc').click() + await page.waitForTimeout(1000) + + await page.evaluate(async () => { + let previousScrollHeight = 0 + let { scrollHeight } = document.body + do { + window.scrollTo(0, scrollHeight) + // eslint-disable-next-line no-await-in-loop + await new Promise((resolve) => { + setTimeout(resolve, 1000) + }) + previousScrollHeight = scrollHeight + scrollHeight = document.body.scrollHeight + } while (previousScrollHeight !== scrollHeight) + }) + + for (const name of allNames) { + const decryptedLocator = page.getByTestId(`name-item-${name}`) + const nameParts = name.split('.') + const label = nameParts.shift()! + const labelHash = `[${labelhash(label).replace('0x', '')}]` + const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`) + // eslint-disable-next-line no-await-in-loop + await expect(decryptedLocator.or(encryptedLocator)).toBeVisible() + } + }) + + test('should display all names for createdAt ASC', async ({ page, login }) => { + await page.goto('/') + await login.connect('user4') + await page.goto('/my/names') + + await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 }) + + await page.getByTestId('select-container').getByRole('button').click() + await page.getByTestId('select-option-createdAt').click() + await page.waitForTimeout(1000) + + await page.evaluate(async () => { + let previousScrollHeight = 0 + let { scrollHeight } = document.body + do { + window.scrollTo(0, scrollHeight) + // eslint-disable-next-line no-await-in-loop + await new Promise((resolve) => { + setTimeout(resolve, 1000) + }) + previousScrollHeight = scrollHeight + scrollHeight = document.body.scrollHeight + } while (previousScrollHeight !== scrollHeight) + }) + + for (const name of allNames) { + const decryptedLocator = page.getByTestId(`name-item-${name}`) + const nameParts = name.split('.') + const label = nameParts.shift()! + const labelHash = `[${labelhash(label).replace('0x', '')}]` + const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`) + // eslint-disable-next-line no-await-in-loop + await expect(decryptedLocator.or(encryptedLocator)).toBeVisible() + } + }) + + test('should display all names for createdAt DESC', async ({ page, login }) => { + await page.goto('/') + await login.connect('user4') + await page.goto('/my/names') + + await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 }) + + await page.getByTestId('select-container').getByRole('button').click() + await page.getByTestId('select-option-createdAt').click() + await page.getByTestId('sort-desc').click() + await page.waitForTimeout(1000) + + await page.evaluate(async () => { + let previousScrollHeight = 0 + let { scrollHeight } = document.body + do { + window.scrollTo(0, scrollHeight) + // eslint-disable-next-line no-await-in-loop + await new Promise((resolve) => { + setTimeout(resolve, 1000) + }) + previousScrollHeight = scrollHeight + scrollHeight = document.body.scrollHeight + } while (previousScrollHeight !== scrollHeight) + }) - await page.pause() + for (const name of allNames) { + const decryptedLocator = page.getByTestId(`name-item-${name}`) + const nameParts = name.split('.') + const label = nameParts.shift()! + const labelHash = `[${labelhash(label).replace('0x', '')}]` + const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`) + // eslint-disable-next-line no-await-in-loop + await expect(decryptedLocator.or(encryptedLocator)).toBeVisible() + } + }) }) diff --git a/e2e/specs/stateless/ownership.2LD.spec.ts b/e2e/specs/stateless/ownership.2LD.spec.ts index f4aa055c4..3910a0738 100644 --- a/e2e/specs/stateless/ownership.2LD.spec.ts +++ b/e2e/specs/stateless/ownership.2LD.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { test } from '../../../playwright' test.describe('Unwrapped 2LD - Owner and Manager', () => { - test('Send feature', async ({ page, login, accounts, makeName, makePageObject }) => { + test('Send feature', async ({ login, accounts, makeName, makePageObject }) => { const name = await makeName({ label: 'owner-manager', type: 'legacy', @@ -48,7 +48,6 @@ test.describe('Unwrapped 2LD - Owner and Manager', () => { await transactionModal.autoComplete() - await page.pause() await expect(ownershipPage.roleRow(accounts.getAddress('user3'))).toContainText('owner', { timeout: 15000, }) @@ -368,7 +367,6 @@ test.describe('Unwrapped 2LD - Manager Only', () => { await ownershipPage.goto(name) await login.connect() - await page.pause() expect(await ownershipPage.getExpiryTimestamp()).toBeGreaterThan(0) await expect(ownershipPage.expiryPanelRegistrationDate).toHaveCount(1) await expect(ownershipPage.expiryPanelGracePeriod).toHaveCount(1) @@ -518,7 +516,7 @@ test.describe('Wrapped and Emancipated 2LD - Owner', () => { }) test.describe('Grace Period Unwrapped 2LD', () => { - test('Send feature', async ({ page, login, makeName, makePageObject }) => { + test('Send feature', async ({ login, makeName, makePageObject }) => { const name = await makeName({ label: 'grace-period-unwrapped', type: 'legacy', @@ -538,7 +536,6 @@ test.describe('Grace Period Unwrapped 2LD', () => { await ownershipPage.goto(name) await login.connect() - await page.pause() await expect(ownershipPage.sendNameButton).toHaveCount(0) }) @@ -567,7 +564,7 @@ test.describe('Grace Period Unwrapped 2LD', () => { await expect(ownershipPage.syncManagerButton).toHaveCount(0) }) - test('Edit Roles', async ({ page, login, accounts, makeName, makePageObject }) => { + test('Edit Roles', async ({ login, accounts, makeName, makePageObject }) => { const name = await makeName({ label: 'grace-period-unwrapped', type: 'legacy', @@ -580,7 +577,7 @@ test.describe('Grace Period Unwrapped 2LD', () => { await ownershipPage.goto(name) await login.connect() - await page.pause() + await ownershipPage.editRolesButton.click() await expect(editRolesModal.roleCardChangeButton('owner')).toHaveCount(0) @@ -630,7 +627,7 @@ test.describe('Grace Period Unwrapped 2LD', () => { }) test.describe('Grace Period Wrapped 2LD', () => { - test('Send feature', async ({ page, login, makeName, makePageObject }) => { + test('Send feature', async ({ login, makeName, makePageObject }) => { const name = await makeName({ label: 'grace-period-wrapped', type: 'wrapped', @@ -650,7 +647,6 @@ test.describe('Grace Period Wrapped 2LD', () => { await ownershipPage.goto(name) await login.connect() - await page.pause() await expect(ownershipPage.sendNameButton).toHaveCount(0) }) @@ -678,7 +674,7 @@ test.describe('Grace Period Wrapped 2LD', () => { await expect(ownershipPage.syncManagerButton).toHaveCount(0) }) - test('Edit Roles', async ({ page, login, accounts, makeName, makePageObject }) => { + test('Edit Roles', async ({ login, accounts, makeName, makePageObject }) => { const name = await makeName({ label: 'grace-period-wrapped', type: 'wrapped', @@ -691,7 +687,7 @@ test.describe('Grace Period Wrapped 2LD', () => { await ownershipPage.goto(name) await login.connect() - await page.pause() + await ownershipPage.editRolesButton.click() await expect(editRolesModal.roleCardChangeButton('owner')).toHaveCount(0) diff --git a/e2e/specs/stateless/ownership.3LD.spec.ts b/e2e/specs/stateless/ownership.3LD.spec.ts index 000cbef68..0d574db81 100644 --- a/e2e/specs/stateless/ownership.3LD.spec.ts +++ b/e2e/specs/stateless/ownership.3LD.spec.ts @@ -4,7 +4,7 @@ import { test } from '../../../playwright' import { testClient } from '../../../playwright/fixtures/contracts/utils/addTestContracts' test.describe('Unwrapped 3LD, Unwrapped 2LD - Parent Owner and Manager', () => { - test('Send feature', async ({ page, login, accounts, makeName, makePageObject }) => { + test('Send feature', async ({ login, accounts, makeName, makePageObject }) => { const name = await makeName({ label: 'unwrapped', type: 'legacy', @@ -34,7 +34,6 @@ test.describe('Unwrapped 3LD, Unwrapped 2LD - Parent Owner and Manager', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await ownershipPage.sendNameButton.click() await sendNameModal.searchInput.fill(accounts.getAddress('user3')) await sendNameModal.searchResult(accounts.getAddress('user3')).click() @@ -1161,7 +1160,7 @@ test.describe('Wrapped 3LD - Wrapped 2LD - Parent Owner only', () => { }) test.describe('Wrapped 3LD, Unwrapped 2LD - Manager only', () => { - test('Send feature', async ({ page, login, accounts, makeName, makePageObject }) => { + test('Send feature', async ({ login, accounts, makeName, makePageObject }) => { const name = await makeName({ label: 'unwrapped', type: 'legacy', @@ -1193,7 +1192,6 @@ test.describe('Wrapped 3LD, Unwrapped 2LD - Manager only', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await ownershipPage.sendNameButton.click() await sendNameModal.searchInput.fill(accounts.getAddress('user3')) await sendNameModal.searchResult(accounts.getAddress('user3')).click() @@ -1390,7 +1388,6 @@ test.describe('Wrapped 3LD, Unwrapped 2LD - Parent only', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await page.waitForTimeout(2000) await expect(ownershipPage.sendNameButton).toHaveCount(0) await expect(ownershipPage.editRolesButton).toHaveCount(0) diff --git a/e2e/specs/stateless/ownership.4LD.spec.ts b/e2e/specs/stateless/ownership.4LD.spec.ts index 19ffef7c6..702de55a2 100644 --- a/e2e/specs/stateless/ownership.4LD.spec.ts +++ b/e2e/specs/stateless/ownership.4LD.spec.ts @@ -386,12 +386,7 @@ test.describe('Unwrapped 4LD, Unwrapped 3LD,2LD - Manager Only', () => { }) }) - test('Expiry Section, Extend & Set Reminder', async ({ - login, - makeName, - makePageObject, - page, - }) => { + test('Expiry Section, Extend & Set Reminder', async ({ login, makeName, makePageObject }) => { const name = await makeName({ label: 'unwrapped', type: 'legacy', @@ -424,7 +419,6 @@ test.describe('Unwrapped 4LD, Unwrapped 3LD,2LD - Manager Only', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await expect(ownershipPage.expiryPanelExpiry).toHaveCount(0) await expect(ownershipPage.expiryPanelGracePeriod).toHaveCount(0) @@ -683,7 +677,6 @@ test.describe('Unwrapped 4LD - Wrapped 3LD,2LD - Parent Owner only', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await page.waitForTimeout(2000) await expect(ownershipPage.sendNameButton).toHaveCount(0) await expect(ownershipPage.editRolesButton).toHaveCount(0) @@ -738,7 +731,7 @@ test.describe('Unwrapped 4LD - Wrapped 3LD,2LD - Parent Owner only', () => { }) test.describe('Unwrapped 4LD, Wrapped 3LD,2LD - Manager Only', () => { - test('Send feature', async ({ page, login, accounts, makeName, makePageObject }) => { + test('Send feature', async ({ login, accounts, makeName, makePageObject }) => { const name = await makeName({ label: 'unwrapped', type: 'wrapped', @@ -776,7 +769,6 @@ test.describe('Unwrapped 4LD, Wrapped 3LD,2LD - Manager Only', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await ownershipPage.sendNameButton.click() await sendNameModal.searchInput.fill(accounts.getAddress('user3')) await sendNameModal.searchResult(accounts.getAddress('user3')).click() diff --git a/e2e/specs/stateless/ownership.spec.ts b/e2e/specs/stateless/ownership.spec.ts index 332de2f35..50aa0cd55 100644 --- a/e2e/specs/stateless/ownership.spec.ts +++ b/e2e/specs/stateless/ownership.spec.ts @@ -328,7 +328,6 @@ test.describe('Send name', () => { }) test('should be able to send manager and eth-record if user is manager and not parent owner of unwrapped subname', async ({ - page, login, accounts, makeName, @@ -389,7 +388,7 @@ test.describe('Send name', () => { await expect(ownershipPage.roleRow(accounts.getAddress('user3'))).toContainText('manager', { timeout: 15000, }) - await page.pause() + await expect(ownershipPage.roleRow(accounts.getAddress('user2'))).toContainText('Parent owner') await expect(ownershipPage.roleRow(accounts.getAddress('user3'))).toContainText('ETH record') }) @@ -436,7 +435,6 @@ test.describe('Send name', () => { await profilePage.goto(subname) await login.connect() await expect(profilePage.record('text', 'nickname')).toContainText('test') - await page.pause() await ownershipPage.goto(subname) await ownershipPage.sendNameButton.click() @@ -460,7 +458,7 @@ test.describe('Send name', () => { await expect(ownershipPage.roleRow(accounts.getAddress('user3'))).toContainText('manager', { timeout: 15000, }) - await page.pause() + await expect(ownershipPage.roleRow(accounts.getAddress('user'))).toContainText('Parent owner') await expect(ownershipPage.roleRow('0x42D63ae25990889E35F215bC95884039Ba354115')).toContainText( 'ETH record', @@ -535,7 +533,7 @@ test.describe('Send name', () => { await expect(ownershipPage.roleRow(accounts.getAddress('user3'))).toContainText('manager', { timeout: 15000, }) - await page.pause() + await expect(ownershipPage.roleRow(accounts.getAddress('user2'))).toContainText('Parent owner') await expect(ownershipPage.roleRow(accounts.getAddress('user3'))).toContainText('ETH record') @@ -601,7 +599,6 @@ test.describe('Send name', () => { await sendNameModal.searchResult(accounts.getAddress('user3')).click() await sendNameModal.resetProfileSwitch.check() - await page.pause() // Should not be able to set owner because name is unwrapped // Should not be able to set eth record because user is not the manager // Should not be able to reset profile since old resolver does not support VersionableResolver @@ -657,7 +654,6 @@ test.describe('Edit roles: Happy ', () => { }) test('Should allow manager to change manager when they are not the owner', async ({ - page, login, accounts, makeName, @@ -682,7 +678,7 @@ test.describe('Edit roles: Happy ', () => { // Should not allow the manager to change the owner await expect(editRolesModal.roleCard('owner')).toHaveCount(0) await editRolesModal.roleCardChangeButton('manager').click() - await page.pause() + await editRolesModal.searchInput.fill(accounts.getAddress('user3')) await editRolesModal.searchResult(accounts.getAddress('user3')).click() await editRolesModal.saveButton.click() @@ -889,7 +885,6 @@ test.describe('Edit roles: Unwrapped subnames', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await page.waitForTimeout(2000) await expect(ownershipPage.sendNameButton).toHaveCount(0) @@ -932,7 +927,6 @@ test.describe('Edit roles: Unwrapped name', () => { test.describe('Edit roles: Wrapped subnames', () => { test('should allow namewrapper subname owner to send name', async ({ - page, login, accounts, makeName, @@ -959,7 +953,6 @@ test.describe('Edit roles: Wrapped subnames', () => { await ownershipPage.goto(subname) await login.connect() - await page.pause() await ownershipPage.editRolesButton.click() await editRolesModal.roleCardChangeButton('manager').click() @@ -1143,7 +1136,6 @@ test.describe('Extend name', () => { await ownershipPage.goto(name) await login.connect() - await page.pause() const timestamp = await ownershipPage.getExpiryTimestamp() diff --git a/e2e/specs/stateless/profileEditor.spec.ts b/e2e/specs/stateless/profileEditor.spec.ts index 77839e758..823c9cdb6 100644 --- a/e2e/specs/stateless/profileEditor.spec.ts +++ b/e2e/specs/stateless/profileEditor.spec.ts @@ -84,7 +84,7 @@ const makeRecords = async (overwrites: RecordOptions = {}): Promise { - test('should display profile records', async ({ page, login, makeName, makePageObject }) => { + test('should display profile records', async ({ login, makeName, makePageObject }) => { const name = await makeName({ label: 'profile', type: 'legacy', @@ -96,7 +96,6 @@ test.describe('profile', () => { await profilePage.goto(name) await login.connect() - await page.pause() await expect(profilePage.record('text', 'description')).toHaveText('Hello2') await expect(profilePage.record('text', 'url')).toHaveText('twitter.com') await expect(profilePage.record('address', 'btc')).toHaveText('bc1qj...pwa6n') @@ -126,7 +125,6 @@ test.describe('profile', () => { await expect(page).toHaveURL(`/${name}`) - await page.pause() await expect(profilePage.record('text', 'description')).toHaveText('Hello2') await expect(profilePage.record('text', 'url')).toHaveText('twitter.com') await expect(profilePage.record('address', 'btc')).toHaveText('bc1qj...pwa6n') @@ -196,7 +194,6 @@ test.describe('migrations', () => { }) test('should force a name with an unauthorised resolver to update their resolver', async ({ - page, login, makeName, makePageObject, @@ -215,7 +212,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect('user2') - await page.pause() await expect(morePage.resolver.getByText(ownedResolverAddress)).toBeVisible() @@ -231,7 +227,6 @@ test.describe('migrations', () => { }) test('should force a name with an invalid resolver to update their resolver', async ({ - page, login, makeName, makePageObject, @@ -250,7 +245,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(invalidResolverAddress)).toBeVisible() @@ -266,7 +260,6 @@ test.describe('migrations', () => { }) test('should force a wrapped name with a resolver that is not name wrapper aware to migrate update their resolver', async ({ - page, login, makeName, makePageObject, @@ -283,7 +276,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver).toHaveText(oldResolver) @@ -329,7 +321,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -350,7 +341,7 @@ test.describe('migrations', () => { await expect(morePage.resolver.getByText(newResolver)).toBeVisible() await recordsPage.goto(name) - await page.pause() + await expect(recordsPage.getRecordValue('text', 'email')).toHaveText('fakeemail@fake.com') await expect(recordsPage.getRecordValue('text', 'description')).toHaveText('Hello2') await expect(recordsPage.getRecordValue('text', 'url')).toHaveText('https://twitter.com') @@ -399,7 +390,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -424,7 +414,7 @@ test.describe('migrations', () => { await expect(morePage.resolver.getByText(newResolver)).toBeVisible() await recordsPage.goto(name) - await page.pause() + await expect(page.getByTestId('text-amount')).toHaveText('0 Records') await expect(page.getByTestId('address-amount')).toHaveText('0 Records') await expect(page.getByText('No Content Hash')).toBeVisible() @@ -466,7 +456,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -484,7 +473,7 @@ test.describe('migrations', () => { await expect(morePage.resolver.getByText(newResolver)).toBeVisible() await recordsPage.goto(name) - await page.pause() + await expect(recordsPage.getRecordValue('text', 'email')).toHaveText('fakeemail@fake.com') await expect(recordsPage.getRecordValue('text', 'description')).toHaveText('New profile') await expect(recordsPage.getRecordValue('text', 'url')).toHaveText('https://twitter.com') @@ -538,7 +527,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -547,7 +535,6 @@ test.describe('migrations', () => { await expect(page.getByText('Resolver out of sync')).toBeVisible() await profilePage.profileEditor.getByTestId('warning-overlay-next-button').click() - await page.pause() await page.getByTestId('migrate-profile-selector-current').check() await expect(page.getByTestId('migrate-profile-selector-current')).toBeChecked() await profilePage.profileEditor.getByTestId('warning-overlay-next-button').click() @@ -561,7 +548,7 @@ test.describe('migrations', () => { await expect(morePage.resolver.getByText(newResolver)).toBeVisible() await recordsPage.goto(name) - await page.pause() + await expect(page.getByTestId('text-amount')).toHaveText('3 Records') await expect(recordsPage.getRecordValue('text', 'email')).toHaveText('fakeemail@fake.com') await expect(recordsPage.getRecordValue('text', 'description')).toHaveText('Hello2') @@ -615,7 +602,6 @@ test.describe('migrations', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -624,13 +610,10 @@ test.describe('migrations', () => { await expect(page.getByText('Resolver out of sync')).toBeVisible() await profilePage.profileEditor.getByTestId('warning-overlay-next-button').click() - await page.pause() await page.getByTestId('migrate-profile-selector-reset').check() await expect(page.getByTestId('migrate-profile-selector-reset')).toBeChecked() await profilePage.profileEditor.getByTestId('warning-overlay-next-button').click() - await page.pause() - await expect(page.getByText('Reset profile')).toBeVisible() await profilePage.profileEditor.getByTestId('warning-overlay-next-button').click() @@ -640,7 +623,7 @@ test.describe('migrations', () => { await expect(morePage.resolver.getByText(newResolver)).toBeVisible() await recordsPage.goto(name) - await page.pause() + await expect(page.getByTestId('text-amount')).toHaveText('0 Records') await expect(page.getByTestId('address-amount')).toHaveText('0 Records') await expect(page.getByText('No Content Hash')).toBeVisible() @@ -650,7 +633,6 @@ test.describe('migrations', () => { test.describe('unwrapped', () => { test('should be able to add/update profile records without migration', async ({ - page, login, makeName, makePageObject, @@ -670,7 +652,6 @@ test.describe('unwrapped', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -702,7 +683,6 @@ test.describe('unwrapped', () => { await morePage.goto(name) await expect(morePage.resolver).toHaveText(oldResolver) - await page.pause() await recordsPage.goto(name) await expect(recordsPage.getRecordValue('text', 'location')).toHaveText('L1 chain') await expect(recordsPage.getRecordValue('text', 'description')).toHaveText('new name') @@ -737,7 +717,6 @@ test.describe('unwrapped', () => { await morePage.goto(name) await login.connect() - await page.pause() await expect(morePage.resolver.getByText(oldResolver)).toBeVisible() @@ -785,7 +764,6 @@ test.describe('unwrapped', () => { await morePage.goto(name) await expect(morePage.resolver).toHaveText(oldResolver) - await page.pause() await recordsPage.goto(name) await expect(page.getByTestId('text-amount')).toHaveText('0 Records') await expect(page.getByTestId('address-amount')).toHaveText('0 Records') @@ -796,7 +774,6 @@ test.describe('unwrapped', () => { test.describe('wrapped', () => { test('should be able to add/update profile records without migration', async ({ - page, login, makeName, makePageObject, @@ -814,7 +791,6 @@ test.describe('wrapped', () => { await profilePage.goto(name) await login.connect() - await page.pause() await expect(profilePage.record('text', 'description')).toHaveText('Hello2') await expect(profilePage.record('text', 'url')).toHaveText('twitter.com') @@ -838,7 +814,6 @@ test.describe('wrapped', () => { await transactionModal.autoComplete() - await page.pause() await recordsPage.goto(name) await expect(recordsPage.getRecordValue('text', 'location')).toHaveText('L1 chain') await expect(recordsPage.getRecordValue('text', 'description')).toHaveText('new name') @@ -871,7 +846,6 @@ test.describe('wrapped', () => { await profilePage.goto(name) await login.connect() - await page.pause() await expect(profilePage.record('text', 'description')).toHaveText('Hello2') await expect(profilePage.record('text', 'url')).toHaveText('twitter.com') @@ -911,7 +885,6 @@ test.describe('wrapped', () => { await transactionModal.autoComplete() - await page.pause() await recordsPage.goto(name) await expect(page.getByTestId('text-amount')).toHaveText('0 Records') await expect(page.getByTestId('address-amount')).toHaveText('0 Records') diff --git a/e2e/specs/stateless/registerName.spec.ts b/e2e/specs/stateless/registerName.spec.ts index 1b2209a93..d4ccb4326 100644 --- a/e2e/specs/stateless/registerName.spec.ts +++ b/e2e/specs/stateless/registerName.spec.ts @@ -388,7 +388,6 @@ test('should allow registering a name and resuming from the commit toast', async await page.goto(`/${name}/register`) await login.connect() - await page.pause() await page.getByTestId('payment-choice-ethereum').click() await page.getByTestId('primary-name-toggle').uncheck() await page.getByTestId('next-button').click() @@ -449,7 +448,6 @@ test('should allow registering with a specific date', async ({ page, login, make await calendar.fill(dateToDateInput(twoYearsAndHalfLater)) - await page.pause() await expect(page.getByTestId('calendar-date')).toHaveValue( dateToDateInput(twoYearsAndHalfLater), ) diff --git a/e2e/specs/stateless/setPrimary.spec.ts b/e2e/specs/stateless/setPrimary.spec.ts index df0bf6040..8237984eb 100644 --- a/e2e/specs/stateless/setPrimary.spec.ts +++ b/e2e/specs/stateless/setPrimary.spec.ts @@ -186,7 +186,7 @@ test.describe('profile', () => { await morePage.goto(subname) await login.connect() - await page.pause() + await expect(morePage.resolver).toContainText(UNAUTHORISED_RESOLVER) await profilePage.goto(subname) @@ -317,7 +317,7 @@ test.describe('profile', () => { await profilePage.goto(subname) await login.connect() - await page.pause() + // Assert state await expect(page.getByTestId('profile-title')).not.toContainText(subname) @@ -426,8 +426,6 @@ test.describe('profile', () => { await profilePage.goto(subname) await login.connect() - await page.pause() - // Assert state await expect(page.getByTestId('owner-profile-button-name.manager')).toContainText( accounts.getAddress('user', 5), @@ -482,8 +480,6 @@ test.describe('profile', () => { await profilePage.goto(name) await login.connect() - await page.pause() - await expect(page.getByTestId('profile-action-Set as primary name')).toHaveCount(0) // Assert state diff --git a/e2e/specs/stateless/verifications.spec.ts b/e2e/specs/stateless/verifications.spec.ts index f96b06b33..77e75b660 100644 --- a/e2e/specs/stateless/verifications.spec.ts +++ b/e2e/specs/stateless/verifications.spec.ts @@ -272,8 +272,6 @@ test.describe('Verified records', () => { await page.goto(`/${name}`) - await page.pause() - await expect(page.getByTestId('profile-section-verifications')).toBeVisible() await profilePage.isRecordVerified('text', 'com.twitter', false) @@ -347,8 +345,6 @@ test.describe('Verified records', () => { await page.goto(`/${name}`) - await page.pause() - await expect(page.getByTestId('profile-section-verifications')).toBeVisible() await profilePage.isRecordVerified('text', 'com.twitter', false) diff --git a/e2e/specs/stateless/wrapName.spec.ts b/e2e/specs/stateless/wrapName.spec.ts index a1d104e0d..607839564 100644 --- a/e2e/specs/stateless/wrapName.spec.ts +++ b/e2e/specs/stateless/wrapName.spec.ts @@ -131,7 +131,7 @@ test('should wrap name', async ({ makeName, login, makePageObject }) => { await expect(morePage.wrapButton).toHaveCount(0) }) -test('should allow wrapping a subdomain', async ({ page, makeName, login, makePageObject }) => { +test('should allow wrapping a subdomain', async ({ makeName, login, makePageObject }) => { const name = await makeName({ label: 'unwrapped-with-wrapped-subnames', type: 'legacy', @@ -158,8 +158,6 @@ test('should allow wrapping a subdomain', async ({ page, makeName, login, makePa await morePage.goto(subname) await login.connect() - await page.pause() - // should approve name wrapper for address await morePage.wrapButton.click() @@ -198,7 +196,6 @@ test('should allow wrapping a name with an unknown label', async ({ await morePage.goto(subname) await login.connect() - await page.pause() await morePage.wrapButton.click() const input = page.getByTestId(`unknown-label-input-${unknownLabelhash}`) diff --git a/knip.config.ts b/knip.config.ts index edc38490a..ece2f9479 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -24,6 +24,8 @@ const config: KnipConfig = { 'src/utils/query/match/matchExactOrNullParamItem.test-d.ts', 'src/utils/query/match/matchQueryKeyMeta.test-d.ts', 'src/utils/query/match/queryKeyToInternalParams.test-d.ts', + // Will need later + 'src/components/pages/migrate/Carousel.tsx', ], } diff --git a/package.json b/package.json index 4558ec1e7..328e491e8 100644 --- a/package.json +++ b/package.json @@ -51,16 +51,18 @@ "knip:fix": "knip --fix --allow-remove-files" }, "dependencies": { + "@adraffy/ens-normalize": "1.10.1", "@ensdomains/address-encoder": "1.1.1", "@ensdomains/content-hash": "^3.0.0-beta.5", "@ensdomains/ens-contracts": "1.2.0-beta.0", - "@ensdomains/ensjs": "4.0.0", + "@ensdomains/ensjs": "4.0.2", "@ensdomains/thorin": "0.6.50", "@metamask/post-message-stream": "^6.1.2", "@metamask/providers": "^14.0.2", "@noble/hashes": "^1.3.2", "@rainbow-me/rainbowkit": "2.1.2", "@sentry/nextjs": "7.43.x", + "@splidejs/react-splide": "^0.7.12", "@svgr/webpack": "^8.1.0", "@tanstack/query-persist-client-core": "5.22.2", "@tanstack/query-sync-storage-persister": "5.22.2", diff --git a/playwright/fixtures/accounts.ts b/playwright/fixtures/accounts.ts index ff1ea21ea..5aa446225 100644 --- a/playwright/fixtures/accounts.ts +++ b/playwright/fixtures/accounts.ts @@ -17,13 +17,12 @@ const shortenAddress = (address = '', maxLength = 10, leftSlice = 5, rightSlice export type Accounts = ReturnType -export type User = 'user' | 'user2' | 'user3' +const users = ['user', 'user2', 'user3', 'user4'] as const +export type User = typeof users[number] export const createAccounts = (stateful = false) => { const mnemonic = stateful ? process.env.SECRET_WORDS || DEFAULT_MNEMONIC : DEFAULT_MNEMONIC - const users: User[] = ['user', 'user2', 'user3'] - const { accounts, privateKeys } = users.reduce<{ accounts: Account[]; privateKeys: Hash[] }>( (acc, _, index) => { const { getHdKey } = mnemonicToAccount(mnemonic, { addressIndex: index }) diff --git a/playwright/fixtures/makeName/generators/legacyNameGenerator.ts b/playwright/fixtures/makeName/generators/legacyNameGenerator.ts index 9aaa527b8..4d8c65172 100644 --- a/playwright/fixtures/makeName/generators/legacyNameGenerator.ts +++ b/playwright/fixtures/makeName/generators/legacyNameGenerator.ts @@ -101,16 +101,15 @@ export const makeLegacyNameGenerator = ({ accounts }: Dependencies) => ({ configure: async (nameConfig: LegacyName) => { const { label, owner, manager, subnames = [], secret } = nameWithDefaults(nameConfig) const name = `${label}.eth` + // Create subnames - await Promise.all( - subnames.map((subname) => { - return generateLegacySubname({ accounts })({ - ...subname, - name: `${label}.eth`, - nameOwner: owner, - }) - }), - ) + for (const subname of subnames) { + await generateLegacySubname({ accounts })({ + ...subname, + name: `${label}.eth`, + nameOwner: owner, + }) + } if (!!manager && manager !== owner) { console.log('setting manager:', name, manager) diff --git a/playwright/fixtures/makeName/generators/legacyWithConfigNameGenerator.ts b/playwright/fixtures/makeName/generators/legacyWithConfigNameGenerator.ts index 0d58f8c49..65158fd2e 100644 --- a/playwright/fixtures/makeName/generators/legacyWithConfigNameGenerator.ts +++ b/playwright/fixtures/makeName/generators/legacyWithConfigNameGenerator.ts @@ -130,16 +130,14 @@ export const makeLegacyWithConfigNameGenerator = ({ accounts }: Dependencies) => await generateRecords({ accounts })({ name: `${label}.eth`, owner, resolver, records }) // Create subnames - await Promise.all( - subnames.map((subname) => - generateLegacySubname({ accounts })({ - ...subname, - name, - nameOwner: owner, - resolver: subname.resolver ?? _resolver, - }), - ), - ) + for (const subname of subnames) { + await generateLegacySubname({ accounts })({ + ...subname, + name, + nameOwner: owner, + resolver: subname.resolver ?? _resolver, + }) + } // Set resolver if not valid if (!hasValidResolver && resolver) { diff --git a/playwright/fixtures/makeName/generators/wrappedNameGenerator.ts b/playwright/fixtures/makeName/generators/wrappedNameGenerator.ts index 0d3dbd865..0d9ff76ab 100644 --- a/playwright/fixtures/makeName/generators/wrappedNameGenerator.ts +++ b/playwright/fixtures/makeName/generators/wrappedNameGenerator.ts @@ -159,16 +159,14 @@ export const makeWrappedNameGenerator = ({ accounts }: Dependencies) => ({ }) } - await Promise.all( - subnames.map((subname) => - generateWrappedSubname({ accounts })({ + for (const subname of subnames) { + await generateWrappedSubname({ accounts })({ ...subname, name: `${label}.eth`, nameOwner: owner, resolver: subname.resolver ?? _resolver, - }), - ), - ) + }) + } if (!hasValidResolver && resolver) { console.log('setting resolver: ', name, resolver) diff --git a/playwright/fixtures/makeName/index.ts b/playwright/fixtures/makeName/index.ts index 3bcd6dbcd..9e3030b75 100644 --- a/playwright/fixtures/makeName/index.ts +++ b/playwright/fixtures/makeName/index.ts @@ -91,18 +91,21 @@ export function createMakeNames({ accounts, time, subgraph }: Dependencies) { await testClient.setAutomine(true) - // Finish setting up names - await Promise.all( - adjustedNames.map((name) => { + // Make sure that registration and subnames are on different block or it might cause the subgraph to crash due to + // RegisterName and TransferName event having the same event ids. + await testClient.mine({ blocks: 1 }) + + // Finish setting up names + for (const name of adjustedNames) { if (isWrappendName(name)) { - return wrappedNameGenerator.configure(name) + await wrappedNameGenerator.configure(name) } else if (isLegacyName(name)) { - return legacyRegisterNameGenerator.configure(name) + console.log('registering legacy name:', name) + await legacyRegisterNameGenerator.configure(name) } else { - return legacyNameGenerator.configure(name) + await legacyNameGenerator.configure(name) } - }), - ) + } if (offset > 0) { console.warn('You are increasing the block timestamp. Do not run this test in parallel mode.') diff --git a/playwright/fixtures/subgraph.ts b/playwright/fixtures/subgraph.ts index 0fda0a1ff..78867ab69 100644 --- a/playwright/fixtures/subgraph.ts +++ b/playwright/fixtures/subgraph.ts @@ -23,17 +23,20 @@ const query = gql` export const waitForSubgraph = () => async () => { const blockNumber = await getBlockNumber(publicClient) - - let wait = true - let count = 0 + const anvilBlockNumbers: number[] = [] do { await new Promise((resolve) => setTimeout(resolve, 500)) const client = new GraphQLClient('http://localhost:8000/subgraphs/name/graphprotocol/ens') const res = await client.request(query) - wait = blockNumber > res._meta.block.number - count += 1 - console.log(`subgraph: ${res._meta.block.number} -> ${blockNumber} ${!wait ? '[IN SYNC]' : ''}`) - } while (wait && count < 10) + + anvilBlockNumbers.push(res._meta.block.number) + if (anvilBlockNumbers.length > 10) anvilBlockNumbers.shift() + + const finished = res._meta.block.number >= blockNumber + console.log(`subgraph: ${res._meta.block.number} -> ${blockNumber} ${finished ? '[IN SYNC]' : ''}`) + + if (anvilBlockNumbers.length >= 10 && anvilBlockNumbers.every((blockNumb) => blockNumb === anvilBlockNumbers[0])) throw new Error('Subgraph not in sync') + } while (anvilBlockNumbers[anvilBlockNumbers.length - 1] < blockNumber) } export const createSubgraph = () => ({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4485e22a9..318e9d40a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,6 +108,9 @@ importers: .: dependencies: + '@adraffy/ens-normalize': + specifier: 1.10.1 + version: 1.10.1 '@ensdomains/address-encoder': specifier: 1.1.1 version: 1.1.1 @@ -118,8 +121,8 @@ importers: specifier: 1.2.0-beta.0 version: 1.2.0-beta.0 '@ensdomains/ensjs': - specifier: 4.0.0 - version: 4.0.0(encoding@0.1.13)(typescript@5.4.5)(viem@2.19.4(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + specifier: 4.0.2 + version: 4.0.2(encoding@0.1.13)(typescript@5.4.5)(viem@2.19.4(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) '@ensdomains/thorin': specifier: 0.6.50 version: 0.6.50(react-dom@18.3.1(react@18.3.1))(react-transition-state@1.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(styled-components@5.3.11(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)) @@ -138,6 +141,9 @@ importers: '@sentry/nextjs': specifier: 7.43.x version: 7.43.0(encoding@0.1.13)(next@13.5.6(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.91.0(esbuild@0.17.19)) + '@splidejs/react-splide': + specifier: ^0.7.12 + version: 0.7.12 '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.4.5) @@ -1620,8 +1626,8 @@ packages: '@ensdomains/ensjs@2.1.0': resolution: {integrity: sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==} - '@ensdomains/ensjs@4.0.0': - resolution: {integrity: sha512-iI6ieuP0TeSK46JCP21EGxyup5rPE5rMmDMTrpRs+u3iwk42Bx3e4oG5sEtTRmxnXFO9uaSqk+WSXEMcHyPKxQ==} + '@ensdomains/ensjs@4.0.2': + resolution: {integrity: sha512-4vDIZEFAa1doNA3H9MppUHxflSDYYPVNyaDbdHLksTa4taq3y4dGpletX67Xea8nxI+cMfjEi4nOzLJmPzRE/g==} peerDependencies: viem: ^2.9.2 @@ -3023,8 +3029,8 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - '@socketregistry/aggregate-error@1.0.6': - resolution: {integrity: sha512-QsK9ig68OfwbISp+P9y8SxbC3I7LGyHuig5/p6qDhIdAyqeyZhWKaqo7Ik8wUx607HaftfWKvcRIBHrM4Svd3A==} + '@socketregistry/aggregate-error@1.0.8': + resolution: {integrity: sha512-KQsneipbEPCO0kobysdinnuNWEfn8WT8Aw3Qk/0rSpQBCZrO7j4utXRBrtsxL0LcxR7at8Pdoo4vJDwAZVCHig==} engines: {node: '>=18.20.4'} '@socketregistry/array-buffer-byte-length@1.0.5': @@ -3123,8 +3129,8 @@ packages: resolution: {integrity: sha512-xknlSx99HYF6t4cRLVMg9iW1eR8kKG92m/Yz7Bo9pntIpvLlKs3Rm+eCwEzTjp+NZacGTxG0T2IP/vGwGD2d8Q==} engines: {node: '>=18.20.4'} - '@socketregistry/indent-string@1.0.5': - resolution: {integrity: sha512-r4hX/Z7qhKBu0H1XJdOHEa2c51qnIN2AyEcmvyfa3qFk0GLZhzYUdAXXw6w+GtlU4U08wnf7WQGf+btlKmRAcg==} + '@socketregistry/indent-string@1.0.6': + resolution: {integrity: sha512-WdAA0PW4h/sIIciGPby09LHaq+a9c7S+wZIn/YvhWdqC0GJGvzfiVSqQFSLuk1+NDvnhSVd64w/6MXjjuRs+mg==} engines: {node: '>=18.20.4'} '@socketregistry/internal-slot@1.0.5': @@ -3307,6 +3313,12 @@ packages: resolution: {integrity: sha512-ErJqzcM65dVIo9O1d3PcMXc4Vk+5PfdbmF2dfr1GdcULepv0+g2wcLcQ0CF3eNqAf7tGyOPgkYrQifBG7qhseQ==} engines: {node: '>=18.20.4'} + '@splidejs/react-splide@0.7.12': + resolution: {integrity: sha512-UfXH+j47jsMc4x5HA/aOwuuHPqn6y9+ZTNYPWDRD8iLKvIVMZlzq2unjUEvyDAU+TTVPZOXkG2Ojeoz0P4AkZw==} + + '@splidejs/splide@4.1.4': + resolution: {integrity: sha512-5I30evTJcAJQXt6vJ26g2xEkG+l1nXcpEw4xpKh0/FWQ8ozmAeTbtniVtVmz2sH1Es3vgfC4SS8B2X4o5JMptA==} + '@stablelib/aead@1.0.1': resolution: {integrity: sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==} @@ -9224,6 +9236,9 @@ packages: ts-pattern@4.3.0: resolution: {integrity: sha512-pefrkcd4lmIVR0LA49Imjf9DYLK8vtWhqBPA3Ya1ir8xCW0O2yjL9dsCVvI7pCodLC5q7smNpEtDR2yVulQxOg==} + ts-pattern@5.5.0: + resolution: {integrity: sha512-jqbIpTsa/KKTJYWgPNsFNbLVpwCgzXfFJ1ukNn4I8hMwyQzHMJnk/BqWzggB0xpkILuKzaO/aMYhS0SkaJyKXg==} + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -10317,7 +10332,7 @@ snapshots: '@babel/traverse': 7.24.6(supports-color@5.5.0) '@babel/types': 7.24.6 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -10411,7 +10426,7 @@ snapshots: '@babel/core': 7.24.6 '@babel/helper-compilation-targets': 7.24.6 '@babel/helper-plugin-utils': 7.24.8 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -11485,7 +11500,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.6 '@babel/parser': 7.24.6 '@babel/types': 7.24.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -11497,7 +11512,7 @@ snapshots: '@babel/parser': 7.25.3 '@babel/template': 7.25.0 '@babel/types': 7.25.2 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -11602,9 +11617,9 @@ snapshots: '@ensdomains/address-encoder@1.0.0-rc.3': dependencies: - '@noble/curves': 1.4.0 - '@noble/hashes': 1.4.0 - '@scure/base': 1.1.6 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 '@ensdomains/address-encoder@1.1.1': dependencies: @@ -11622,12 +11637,12 @@ snapshots: '@ensdomains/content-hash@3.1.0-rc.1': dependencies: '@ensdomains/address-encoder': 1.0.0-rc.3 - '@noble/curves': 1.4.0 - '@scure/base': 1.1.6 + '@noble/curves': 1.6.0 + '@scure/base': 1.1.9 '@ensdomains/dnsprovejs@0.5.1': dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.5.0 dns-packet: 5.6.1 typescript-logging: 1.0.1 @@ -11677,17 +11692,18 @@ snapshots: - bufferutil - utf-8-validate - '@ensdomains/ensjs@4.0.0(encoding@0.1.13)(typescript@5.4.5)(viem@2.19.4(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)': + '@ensdomains/ensjs@4.0.2(encoding@0.1.13)(typescript@5.4.5)(viem@2.19.4(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)': dependencies: '@adraffy/ens-normalize': 1.10.1 '@ensdomains/address-encoder': 1.1.1 '@ensdomains/content-hash': 3.1.0-rc.1 '@ensdomains/dnsprovejs': 0.5.1 - abitype: 1.0.5(typescript@5.4.5)(zod@3.23.8) + abitype: 1.0.6(typescript@5.4.5)(zod@3.23.8) dns-packet: 5.6.1 graphql: 16.8.1 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.8.1) pako: 2.1.0 + ts-pattern: 5.5.0 viem: 2.19.4(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) transitivePeerDependencies: - encoding @@ -11874,7 +11890,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -12197,7 +12213,7 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -12449,7 +12465,7 @@ snapshots: bufferutil: 4.0.8 cross-fetch: 4.0.0(encoding@0.1.13) date-fns: 2.30.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) eciesjs: 0.3.18 eventemitter2: 6.4.9 readable-stream: 3.6.2 @@ -12477,7 +12493,7 @@ snapshots: '@types/dom-screen-wake-lock': 1.0.3 bowser: 2.11.0 cross-fetch: 4.0.0(encoding@0.1.13) - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) eciesjs: 0.3.18 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 @@ -12509,7 +12525,7 @@ snapshots: dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) semver: 7.6.2 superstruct: 1.0.4 transitivePeerDependencies: @@ -12521,7 +12537,7 @@ snapshots: '@noble/hashes': 1.4.0 '@scure/base': 1.1.6 '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) pony-cause: 2.1.11 semver: 7.6.2 superstruct: 1.0.4 @@ -12536,7 +12552,7 @@ snapshots: '@noble/hashes': 1.4.0 '@scure/base': 1.1.6 '@types/debug': 4.1.12 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) pony-cause: 2.1.11 semver: 7.6.3 uuid: 9.0.1 @@ -12598,7 +12614,7 @@ snapshots: '@open-draft/until': 1.0.3 '@types/debug': 4.1.12 '@xmldom/xmldom': 0.8.10 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) headers-polyfill: 3.2.5 outvariant: 1.4.2 strict-event-emitter: 0.2.8 @@ -13509,7 +13525,7 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} - '@socketregistry/aggregate-error@1.0.6': {} + '@socketregistry/aggregate-error@1.0.8': {} '@socketregistry/array-buffer-byte-length@1.0.5': {} @@ -13561,7 +13577,7 @@ snapshots: '@socketregistry/hasown@1.0.5': {} - '@socketregistry/indent-string@1.0.5': {} + '@socketregistry/indent-string@1.0.6': {} '@socketregistry/internal-slot@1.0.5': {} @@ -13653,6 +13669,12 @@ snapshots: '@socketregistry/which-typed-array@1.0.5': {} + '@splidejs/react-splide@0.7.12': + dependencies: + '@splidejs/splide': 4.1.4 + + '@splidejs/splide@4.1.4': {} + '@stablelib/aead@1.0.1': {} '@stablelib/binary@1.0.1': @@ -13929,7 +13951,7 @@ snapshots: big.js: 6.2.1 bn.js: 5.2.1 cbor: 5.2.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) lodash: 4.17.21 semver: 7.6.2 utf8: 3.0.0 @@ -13945,7 +13967,7 @@ snapshots: '@truffle/contract-schema@3.4.16': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -13958,7 +13980,7 @@ snapshots: '@truffle/error': 0.2.2 '@truffle/interface-adapter': 0.5.37(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bignumber.js: 7.2.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) ethers: 4.0.49 web3: 1.10.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) web3-core-helpers: 1.10.0 @@ -13977,7 +13999,7 @@ snapshots: '@trufflesuite/chromafi': 3.0.0 bn.js: 5.2.1 chalk: 2.4.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) highlightjs-solidity: 2.0.6 transitivePeerDependencies: - supports-color @@ -14211,7 +14233,7 @@ snapshots: '@typescript-eslint/type-utils': 6.21.0(eslint@8.50.0)(typescript@5.4.5) '@typescript-eslint/utils': 6.21.0(eslint@8.50.0)(typescript@5.4.5) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.50.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -14229,7 +14251,7 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.50.0 optionalDependencies: typescript: 5.4.5 @@ -14255,7 +14277,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) '@typescript-eslint/utils': 6.21.0(eslint@8.50.0)(typescript@5.4.5) - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) eslint: 8.50.0 ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: @@ -14273,7 +14295,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -14287,7 +14309,7 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -14302,7 +14324,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.10.0 '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 @@ -14407,7 +14429,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -14966,13 +14988,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) transitivePeerDependencies: - supports-color agent-base@7.1.1: dependencies: - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -15440,7 +15462,7 @@ snapshots: capnp-ts@0.7.0: dependencies: - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) tslib: 2.6.2 transitivePeerDependencies: - supports-color @@ -15995,21 +16017,17 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.4(supports-color@5.5.0): - dependencies: - ms: 2.1.2 - optionalDependencies: - supports-color: 5.5.0 - debug@4.3.4(supports-color@8.1.1): dependencies: ms: 2.1.2 optionalDependencies: supports-color: 8.1.1 - debug@4.3.6: + debug@4.3.6(supports-color@5.5.0): dependencies: ms: 2.1.2 + optionalDependencies: + supports-color: 5.5.0 decamelize-keys@1.1.1: dependencies: @@ -16248,7 +16266,7 @@ snapshots: engine.io-client@6.5.3(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) engine.io-parser: 5.2.2 ws: 8.11.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) xmlhttprequest-ssl: 2.0.0 @@ -16517,7 +16535,7 @@ snapshots: eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.50.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.50.0): dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.6(supports-color@5.5.0) enhanced-resolve: 5.16.1 eslint: 8.50.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.50.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.50.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.50.0))(eslint@8.50.0) @@ -16669,7 +16687,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -17166,7 +17184,7 @@ snapshots: follow-redirects@1.15.6(debug@4.3.4): optionalDependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) foreground-child@3.3.0: dependencies: @@ -17504,7 +17522,7 @@ snapshots: axios: 0.21.4(debug@4.3.4) chalk: 4.1.2 chokidar: 3.6.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) enquirer: 2.4.1 ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) form-data: 4.0.0 @@ -17531,13 +17549,13 @@ snapshots: '@types/bn.js': 5.1.5 '@types/lru-cache': 5.1.1 adm-zip: 0.4.16 - aggregate-error: '@socketregistry/aggregate-error@1.0.6' + aggregate-error: '@socketregistry/aggregate-error@1.0.8' ansi-escapes: 4.3.2 boxen: 5.1.2 chalk: 2.4.2 chokidar: 3.6.0 ci-info: 2.0.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) enquirer: 2.4.1 env-paths: 2.2.1 ethereum-cryptography: 1.2.0 @@ -17677,7 +17695,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -17702,14 +17720,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -17973,7 +17991,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -18788,7 +18806,7 @@ snapshots: stoppable: 1.1.0 undici: 5.28.4 workerd: 1.20240512.0 - ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) youch: 3.3.3 zod: 3.23.8 transitivePeerDependencies: @@ -19328,7 +19346,7 @@ snapshots: p-map@4.0.0: dependencies: - aggregate-error: '@socketregistry/aggregate-error@1.0.6' + aggregate-error: '@socketregistry/aggregate-error@1.0.8' p-try@1.0.0: {} @@ -19955,7 +19973,7 @@ snapshots: redent@3.0.0: dependencies: - indent-string: '@socketregistry/indent-string@1.0.5' + indent-string: '@socketregistry/indent-string@1.0.6' strip-indent: 3.0.0 regenerate-unicode-properties@10.1.1: @@ -20361,7 +20379,7 @@ snapshots: socket.io-client@4.7.5(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) engine.io-client: 6.5.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) socket.io-parser: 4.2.4 transitivePeerDependencies: @@ -20372,7 +20390,7 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -20695,7 +20713,7 @@ snapshots: colord: 2.9.3 cosmiconfig: 7.1.0 css-functions-list: 3.2.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 6.0.1 @@ -20983,6 +21001,8 @@ snapshots: ts-pattern@4.3.0: {} + ts-pattern@5.5.0: {} + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -21279,7 +21299,7 @@ snapshots: vite-node@2.0.5(@types/node@18.19.33)(terser@5.31.5): dependencies: cac: 6.7.14 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) pathe: 1.1.2 tinyrainbow: 1.2.0 vite: 5.2.11(@types/node@18.19.33)(terser@5.31.5) @@ -21325,7 +21345,7 @@ snapshots: '@vitest/spy': 2.0.5 '@vitest/utils': 2.0.5 chai: 5.1.1 - debug: 4.3.6 + debug: 4.3.6(supports-color@5.5.0) execa: 8.0.1 magic-string: 0.30.10 pathe: 1.1.2 diff --git a/public/locales/en/ensv2.json b/public/locales/en/ensv2.json new file mode 100644 index 000000000..6064ec0a5 --- /dev/null +++ b/public/locales/en/ensv2.json @@ -0,0 +1,61 @@ +{ + "title": "Namechain is a Layer 2 designed for onchain identity", + "caption": "Built for everyone tired of addresses, numbers, and complexity. Namechain lets users and developers create onchain identities through the power of names, not numbers.", + "accessible": { + "title": "Making ENS accessible to more people", + "caption": "We're taking our knowledge from the last 7 years at the frontier of web3 naming to re-envision the architecture from the ground up on L2 By utilizing L2s, we're excited to make ENS more accessible to a wider range of users.", + "link": "ENSv2 Project Plan", + "gas": { + "title": "Lower Gas Costs", + "text": "Layer 2 reduces gas fees, making .eth registrations and renewals cheaper and faster." + }, + "control": { + "title": "Enhanced Control", + "text": "ENSv2 gives each .eth name its own registry, offering more flexibility and control." + }, + "multichain": { + "title": "Improved Multi-Chain", + "text": "Layer 2 enables seamless .eth name use across blockchains with trustless connections." + } + }, + "learn-more": { + "title": "Want to learn more?", + "caption": "If you’re interested in learning more and building on Namechain, join the ENS Developer Telegram.", + "button": "Developer Telegram" + }, + "announcement": { + "title": "Announcements", + "l2": { + "title": "L2 partner announcement", + "caption": "We’re announced that we’re partnering with _____! Watch Nick’s ___ presentation to see the full announcement." + }, + "ensv2": { + "title": "ENSv2: An Update on our Progress", + "caption": "This update aims to be informative and slightly technical, allowing you, the ENS community, to stay connected with our progress." + }, + "nextgen": { + "title": "ENSv2: The Next Generation of ENS", + "caption": "Our vision for the next iterations of the ENS protocol, on L2." + } + }, + "footer": { + "title": "Got questions?", + "learn": { + "title": "Learn", + "faq": "ENSv2 FAQs", + "plan": "ENSv2 Project Plan", + "base": "Knowledge base" + }, + "support": { + "title": "Support", + "ticket": "Open a ticket", + "twitter": "X (Twitter)", + "dao": "DAO forums" + } + }, + "banner": { + "title": "Namechain is coming!", + "caption": "Keep up with ENSv2 development", + "cta": "ENSv2 hub" + } +} \ No newline at end of file diff --git a/public/migrate/confetti.png b/public/migrate/confetti.png new file mode 100644 index 000000000..eab8f092f Binary files /dev/null and b/public/migrate/confetti.png differ diff --git a/public/migrate/preview.svg b/public/migrate/preview.svg new file mode 100644 index 000000000..5c5546d10 --- /dev/null +++ b/public/migrate/preview.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/DAO.svg b/src/assets/DAO.svg new file mode 100644 index 000000000..2d33444de --- /dev/null +++ b/src/assets/DAO.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/social/SocialX.svg b/src/assets/social/SocialX.svg index 6a7b7dfe7..134d9024f 100644 --- a/src/assets/social/SocialX.svg +++ b/src/assets/social/SocialX.svg @@ -1,3 +1,3 @@ - + diff --git a/src/components/@molecules/NameTableHeader/NameTableHeader.tsx b/src/components/@molecules/NameTableHeader/NameTableHeader.tsx index 1c4479a40..141416219 100644 --- a/src/components/@molecules/NameTableHeader/NameTableHeader.tsx +++ b/src/components/@molecules/NameTableHeader/NameTableHeader.tsx @@ -189,12 +189,14 @@ export const NameTableHeader = ({ /> onSortDirectionChange?.('asc')} > onSortDirectionChange?.('desc')} > diff --git a/src/components/@molecules/SearchInput/SearchInput.tsx b/src/components/@molecules/SearchInput/SearchInput.tsx index 770dd55d1..0d091ee4c 100644 --- a/src/components/@molecules/SearchInput/SearchInput.tsx +++ b/src/components/@molecules/SearchInput/SearchInput.tsx @@ -13,6 +13,7 @@ import { import { TFunction, useTranslation } from 'react-i18next' import useTransition, { TransitionState } from 'react-transition-state' import styled, { css } from 'styled-components' +import { match } from 'ts-pattern' import { Address, isAddress } from 'viem' import { useAccount, useChainId } from 'wagmi' @@ -343,17 +344,12 @@ const createSearchHandler = const path = getRouteForSearchItem({ address, chainId, queryClient, selectedItem }) - if (path === `/register/${text}`) { - trackEvent({ - eventName: 'search_selected_eth', - customProperties: { name: text }, - }) - } else if (path === `/dotbox/${text}`) { - trackEvent({ - eventName: 'search_selected_box', - customProperties: { name: text }, - }) - } + const eventName = match(path) + .with(`/register/${text}`, () => 'search_selected_eth' as const) + .with(`/dotbox/${text}`, () => 'search_selected_box' as const) + .with(`/import/${text}`, () => 'search_selected_dns' as const) + .otherwise(() => undefined) + if (eventName) trackEvent({ eventName, customProperties: { name: text } }) setInputVal('') searchInputRef.current?.blur() diff --git a/src/components/@molecules/TransactionDialogManager/stage/TransactionStageModal.tsx b/src/components/@molecules/TransactionDialogManager/stage/TransactionStageModal.tsx index 6620b1281..435f3b759 100644 --- a/src/components/@molecules/TransactionDialogManager/stage/TransactionStageModal.tsx +++ b/src/components/@molecules/TransactionDialogManager/stage/TransactionStageModal.tsx @@ -469,6 +469,15 @@ export const TransactionStageModal = ({ }, [helper]) const ActionButton = useMemo(() => { + const handleCompleteTransaction = () => { + dispatch({ name: 'incrementTransaction' }) + + if (actionName === 'approveDnsRegistrar') { + trackEvent({ + eventName: 'register_started_dns', + }) + } + } if (stage === 'complete') { const final = currentStep + 1 === stepCount @@ -486,7 +495,7 @@ export const TransactionStageModal = ({ return ( @@ -542,12 +551,14 @@ export const TransactionStageModal = ({ onClick={() => { sendTransaction(request!) - if (['commitName', 'registerName'].includes(actionName)) { - trackEvent({ - eventName: - actionName === 'commitName' ? 'commit_wallet_opened' : 'register_wallet_opened', - }) - } + const eventName = match(actionName) + .with('commitName', () => 'commit_wallet_opened' as const) + .with('registerName', () => 'register_wallet_opened' as const) + .with('approveDnsRegistrar', () => 'dns_approve_registrar_wallet_opened' as const) + .with('importDnsName', () => 'dns_import_wallet_opened' as const) + .with('claimDnsName', () => 'dns_claim_wallet_opened' as const) + .otherwise(() => undefined) + if (eventName) trackEvent({ eventName }) }} data-testid="transaction-modal-confirm-button" > diff --git a/src/components/pages/AnnouncementBanner.tsx b/src/components/pages/AnnouncementBanner.tsx new file mode 100644 index 000000000..d9e0c2a4d --- /dev/null +++ b/src/components/pages/AnnouncementBanner.tsx @@ -0,0 +1,71 @@ +import Link from 'next/link' +import { useTranslation } from 'react-i18next' +import styled, { css } from 'styled-components' + +import { Button, Typography } from '@ensdomains/thorin' + +const Container = styled.div( + ({ theme }) => css` + display: flex; + flex-direction: column; + width: ${theme.space.full}; + max-width: 466px; + padding: ${theme.space['4']}; + align-items: center; + justify-content: space-between; + gap: ${theme.space['4']}; + align-self: center; + border-radius: ${theme.radii['2xLarge']}; + background-color: ${theme.colors.backgroundPrimary}; + + @media (max-width: 640px) { + a { + width: 100%; + } + } + + @media (min-width: 640px) { + flex-direction: row; + } + `, +) + +const TextContainer = styled.div( + ({ theme }) => css` + display: flex; + flex-direction: row; + align-items: center; + gap: ${theme.space['4']}; + + width: ${theme.space.full}; + `, +) + +const Text = styled.span( + ({ theme }) => css` + width: ${theme.space.full}; + `, +) + +export const AnnouncementBanner = () => { + const { t } = useTranslation('ensv2') + + return ( + + + + + + {t('banner.title')} + + {t('banner.caption')} + + + + + + + ) +} diff --git a/src/components/pages/import/[name]/steps/onchain/ImportTransaction.tsx b/src/components/pages/import/[name]/steps/onchain/ImportTransaction.tsx index d27f5715a..1e9cc13d2 100644 --- a/src/components/pages/import/[name]/steps/onchain/ImportTransaction.tsx +++ b/src/components/pages/import/[name]/steps/onchain/ImportTransaction.tsx @@ -15,6 +15,7 @@ import { useDnsImportData } from '@app/hooks/ensjs/dns/useDnsImportData' import { useDnsOwner } from '@app/hooks/ensjs/dns/useDnsOwner' import { usePrimaryName } from '@app/hooks/ensjs/public/usePrimaryName' import { useApprovedForAll } from '@app/hooks/useApprovedForAll' +import { useEventTracker } from '@app/hooks/useEventTracker' import { useTransactionFlow } from '@app/transaction-flow/TransactionFlowProvider' import { UpdateCallback, useCallbackOnTransaction } from '@app/utils/SyncProvider/SyncProvider' import useUserConfig from '@app/utils/useUserConfig' @@ -105,6 +106,7 @@ export const ImportTransaction = ({ const { t } = useTranslation('dnssec', { keyPrefix: 'steps.transaction' }) const { t: tc } = useTranslation('common') + const { trackEvent } = useEventTracker() const { data: gasPrice } = useGasPrice() const { userConfig, setCurrency } = useUserConfig() const currencyDisplay = userConfig.currency === 'fiat' ? userConfig.fiat : 'eth' @@ -179,8 +181,18 @@ export const ImportTransaction = ({ const resumable = getResumable(key) const startOrResumeFlow = () => { - if (!item.started) dispatch({ name: 'setStarted', selected }) - if (resumable) return resumeTransactionFlow(key) + if (!item.started) { + trackEvent({ + eventName: 'dns_claim_started', + customProperties: { name: selected.name, importType: 'onchain' }, + }) + dispatch({ name: 'setStarted', selected }) + } + + if (resumable) { + return resumeTransactionFlow(key) + } + return createTransactionFlow(key, { transactions, resumable: true, @@ -189,7 +201,6 @@ export const ImportTransaction = ({ resumeLink: `/import/${selected.name}`, }) } - const txCallback: UpdateCallback = useCallback( ({ action, status, key: cbKey }) => { if (action !== 'claimDnsName' && action !== 'importDnsName') return diff --git a/src/components/pages/import/[name]/steps/onchain/VerifyOnchainOwnership.tsx b/src/components/pages/import/[name]/steps/onchain/VerifyOnchainOwnership.tsx index 17bfba790..eea61570d 100644 --- a/src/components/pages/import/[name]/steps/onchain/VerifyOnchainOwnership.tsx +++ b/src/components/pages/import/[name]/steps/onchain/VerifyOnchainOwnership.tsx @@ -96,6 +96,10 @@ export const VerifyOnchainOwnership = ({ return tc(`error.${errorKey}`, { ns: 'dnssec' }) }, [tc, error, isLoading]) + const handleStartDNSImport = () => { + dispatch({ name: 'increaseStep', selected }) + } + return ( {t('title')} @@ -160,7 +164,7 @@ export const VerifyOnchainOwnership = ({ {isConnected ? ( dispatch({ name: 'increaseStep', selected })} + onClick={handleStartDNSImport} data-testid="import-next-button" {...(dnsOwnerStatus === 'mismatching' ? { diff --git a/src/components/pages/import/[name]/useDnsImportReducer.ts b/src/components/pages/import/[name]/useDnsImportReducer.ts index 53406876b..24a5af4a2 100644 --- a/src/components/pages/import/[name]/useDnsImportReducer.ts +++ b/src/components/pages/import/[name]/useDnsImportReducer.ts @@ -1,7 +1,9 @@ import { useEffect } from 'react' +import { match } from 'ts-pattern' import { Address } from 'viem' import { useChainId } from 'wagmi' +import { TrackEventParameters, useEventTracker } from '@app/hooks/useEventTracker' import { useLocalStorageReducer } from '@app/hooks/useLocalStorage' import { isBrowser } from '@app/utils/utils' @@ -105,57 +107,74 @@ export const getSelectedIndex = (state: DnsImportReducerData, selected: Selected } /* eslint-disable no-param-reassign */ -const reducer = (state: DnsImportReducerData, action: DnsImportReducerAction) => { - let selectedItemInx = getSelectedIndex(state, action.selected) +const reducer = + ({ trackEvent }: { trackEvent: (event: TrackEventParameters) => void }) => + (state: DnsImportReducerData, action: DnsImportReducerAction) => { + let selectedItemInx = getSelectedIndex(state, action.selected) - if (!isBrowser) return + if (!isBrowser) return - if (selectedItemInx === -1) { - selectedItemInx = state.items.push(createDefaultData(action.selected)) - 1 - } + if (selectedItemInx === -1) { + selectedItemInx = state.items.push(createDefaultData(action.selected)) - 1 + } - const selectedItem = state.items[selectedItemInx] - - switch (action.name) { - case 'increaseStep': - selectedItem.stepIndex += 1 - break - case 'decreaseStep': - selectedItem.stepIndex -= 1 - break - case 'setSteps': - selectedItem.steps = action.payload - break - case 'setType': - selectedItem.type = action.payload - break - case 'setStarted': - selectedItem.started = true - break - case 'setAddress': - selectedItem.address = action.payload - break - case 'resetItem': - state.items[selectedItemInx] = createDefaultData(action.selected) - break - case 'clearItem': - state.items.splice(selectedItemInx, 1) - break - case 'cleanupNonMatching': - for (let i = 0; i < state.items.length; i += 1) { - const item = state.items[i] - if (item !== selectedItem && state.items[i].started === false) { - state.items.splice(i, 1) - i -= 1 - } + const selectedItem = state.items[selectedItemInx] + + switch (action.name) { + case 'increaseStep': { + const currentStep = selectedItem.steps[selectedItem.stepIndex] + + const eventName = match(currentStep) + .with('selectType', () => 'dns_selected_import_type' as const) + .with('enableDnssec', () => 'dns_sec_enabled' as const) + .with('verifyOnchainOwnership', () => 'dns_verified_ownership' as const) + .with('transaction', () => 'dns_claimed' as const) + .with('verifyOffchainOwnership', () => 'dns_claimed' as const) + .otherwise(() => undefined) + if (eventName) + trackEvent({ + eventName, + customProperties: { name: selectedItem.name, importType: selectedItem.type }, + }) + selectedItem.stepIndex += 1 + return state } - break - default: - break - } + case 'decreaseStep': + selectedItem.stepIndex -= 1 + break + case 'setSteps': + selectedItem.steps = action.payload + break + case 'setType': + selectedItem.type = action.payload + break + case 'setStarted': + selectedItem.started = true + break + case 'setAddress': + selectedItem.address = action.payload + break + case 'resetItem': + state.items[selectedItemInx] = createDefaultData(action.selected) + break + case 'clearItem': + state.items.splice(selectedItemInx, 1) + break + case 'cleanupNonMatching': + for (let i = 0; i < state.items.length; i += 1) { + const item = state.items[i] + if (item !== selectedItem && state.items[i].started === false) { + state.items.splice(i, 1) + i -= 1 + } + } + break + default: + break + } - return state -} + return state + } /* eslint-enable no-param-reassign */ export const useDnsImportReducer = ({ @@ -166,10 +185,11 @@ export const useDnsImportReducer = ({ name: string }) => { const chainId = useChainId() + const { trackEvent } = useEventTracker() const selected = { address: address || null, name, chainId } as SelectedItemProperties const [state, dispatch] = useLocalStorageReducer( 'dns-import', - reducer, + reducer({ trackEvent }), { items: [] }, ) diff --git a/src/components/pages/migrate/Carousel.tsx b/src/components/pages/migrate/Carousel.tsx new file mode 100644 index 000000000..1f7f254a5 --- /dev/null +++ b/src/components/pages/migrate/Carousel.tsx @@ -0,0 +1,21 @@ +import { Splide, SplideSlide } from '@splidejs/react-splide' +import { ReactNode } from 'react' + +export const Carousel = ({ children }: { children: ReactNode[] }) => { + return ( + + {children.map((child, i) => ( + // eslint-disable-next-line react/no-array-index-key + {child} + ))} + + ) +} diff --git a/src/components/pages/profile/[name]/registration/Registration.tsx b/src/components/pages/profile/[name]/registration/Registration.tsx index 48ce3df24..3294b044d 100644 --- a/src/components/pages/profile/[name]/registration/Registration.tsx +++ b/src/components/pages/profile/[name]/registration/Registration.tsx @@ -359,11 +359,6 @@ const Registration = ({ nameDetails, isLoading }: Props) => { {t('steps.info.moonpayModalHeader')} - {chainId === 5 && ( - - {`${t('steps.info.moonpayTestCard')}: 4000 0209 5159 5032, 12/2030, 123`} - - )} export type SupportedChain = | typeof mainnetWithEns - | typeof goerliWithEns | typeof sepoliaWithEns | typeof holeskyWithEns | typeof localhostWithEns diff --git a/src/constants/resolverAddressData.test.ts b/src/constants/resolverAddressData.test.ts index 4e9b21134..085912d78 100644 --- a/src/constants/resolverAddressData.test.ts +++ b/src/constants/resolverAddressData.test.ts @@ -1,7 +1,7 @@ import { getChainContractAddress } from 'viem/utils' -import { describe, expect, it } from 'vitest' +import { expect, it } from 'vitest' -import { goerliWithEns, localhostWithEns, mainnetWithEns, sepoliaWithEns } from './chains' +import { mainnetWithEns, sepoliaWithEns } from './chains' ;(process.env as any).NODE_ENV = 'development' @@ -12,9 +12,6 @@ it('should have the most recent resolver as the first address', async () => { expect(KNOWN_RESOLVER_DATA['1']![0].address).toEqual( getChainContractAddress({ chain: mainnetWithEns, contract: 'ensPublicResolver' }), ) - expect(KNOWN_RESOLVER_DATA['5']![0].address).toEqual( - getChainContractAddress({ chain: goerliWithEns, contract: 'ensPublicResolver' }), - ) expect(KNOWN_RESOLVER_DATA['11155111']![0].address).toEqual( getChainContractAddress({ chain: sepoliaWithEns, contract: 'ensPublicResolver' }), ) diff --git a/src/constants/resolverAddressData.ts b/src/constants/resolverAddressData.ts index 76545ef89..eecb73d9d 100644 --- a/src/constants/resolverAddressData.ts +++ b/src/constants/resolverAddressData.ts @@ -123,9 +123,9 @@ export const KNOWN_RESOLVER_DATA: KnownResolverData = { ], }, ], - '5': [ + '11155111': [ { - address: '0xd7a4F6473f32aC2Af804B3686AE8F1932bC35750', + address: '0x8948458626811dd0c23EB25Cc74291247077cC51', deployer: 'ENS Labs', tag: 'latest', isNameWrapperAware: true, @@ -141,170 +141,10 @@ export const KNOWN_RESOLVER_DATA: KnownResolverData = { RESOLVER_INTERFACE_IDS.VersionableResolver, ], }, - { - address: '0x342cf18D3e41DE491aa1a3067574C849AdA6a2Ad', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - RESOLVER_INTERFACE_IDS.VersionableResolver, - ], - }, - { - address: '0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - RESOLVER_INTERFACE_IDS.VersionableResolver, - ], - }, - { - address: '0x2800Ec5BAB9CE9226d19E0ad5BC607e3cfC4347E', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - RESOLVER_INTERFACE_IDS.VersionableResolver, - ], - }, - { - address: '0x121304143ea8101E69335F309e2062d299A234B5', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - ], - }, - { - address: '0x4B1488B7a6B320d2D721406204aBc3eeAa9AD329', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - ], - }, - { - address: '0xfF77b96d6bafCec0D684bB528b22e0Ab09C70663', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - ], - }, - { - address: '0x6e1b40ed2d626b97A43d2c12e48a6De49A03c7A4', - deployer: 'ENS Labs', - tag: null, - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - ], - }, - { - address: '0xc1EA41786094D1fBE5aded033B5370d51F7a3F96', - deployer: 'ENS Labs', - tag: 'outdated', - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - ], - }, - { - address: '0xBbe3fD189D18C8b73BA54e9dD01F89E6b3Ee71f0', - deployer: 'ENS Labs', - tag: 'outdated', - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - ], - }, - { - address: '0x4B1488B7a6B320d2D721406204aBc3eeAa9AD329', - deployer: 'ENS Labs', - tag: 'outdated', - isNameWrapperAware: false, - supportedInterfaces: [ - RESOLVER_INTERFACE_IDS.AddressResolver, - RESOLVER_INTERFACE_IDS.NameResolver, - RESOLVER_INTERFACE_IDS.AbiResolver, - RESOLVER_INTERFACE_IDS.TextResolver, - RESOLVER_INTERFACE_IDS.ContentHashResolver, - RESOLVER_INTERFACE_IDS.DnsRecordResolver, - RESOLVER_INTERFACE_IDS.InterfaceResolver, - RESOLVER_INTERFACE_IDS.MultiCoinAddressResolver, - ], - }, - ], - '11155111': [ { address: '0x8FADE66B79cC9f707aB26799354482EB93a5B7dD', deployer: 'ENS Labs', - tag: 'latest', + tag: null, isNameWrapperAware: true, supportedInterfaces: [ RESOLVER_INTERFACE_IDS.AddressResolver, diff --git a/src/hooks/useEthPrice.ts b/src/hooks/useEthPrice.ts index 4fd8cef70..1861ed2a2 100644 --- a/src/hooks/useEthPrice.ts +++ b/src/hooks/useEthPrice.ts @@ -1,21 +1,16 @@ import { Address } from 'viem' -import { useChainId, useReadContract } from 'wagmi' -import { goerli } from 'wagmi/chains' +import { useReadContract } from 'wagmi' import { useAddressRecord } from './ensjs/public/useAddressRecord' const ORACLE_ENS = 'eth-usd.data.eth' -const ORACLE_GOERLI = '0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e' as const export const useEthPrice = () => { - const chainId = useChainId() - const { data: address_ } = useAddressRecord({ name: ORACLE_ENS, - enabled: chainId !== goerli.id, }) - const address = chainId === 5 ? ORACLE_GOERLI : (address_?.value as Address) || undefined + const address = (address_?.value as Address) || undefined return useReadContract({ abi: [ diff --git a/src/hooks/useEventTracker.ts b/src/hooks/useEventTracker.ts index 6e45ea058..b7257638d 100644 --- a/src/hooks/useEventTracker.ts +++ b/src/hooks/useEventTracker.ts @@ -8,7 +8,7 @@ import useUserConfig from '@app/utils/useUserConfig' import { useChainName } from './chain/useChainName' type SearchSelectEvent = { - eventName: 'search_selected_eth' | 'search_selected_box' + eventName: 'search_selected_eth' | 'search_selected_box' | 'search_selected_dns' customProperties: { name: string } } @@ -23,6 +23,19 @@ type PaymentEvent = { } } +type DNSImportTypeSelectedEvent = { + eventName: + | 'dns_selected_import_type' + | 'dns_sec_enabled' + | 'dns_verified_ownership' + | 'dns_claim_started' + | 'dns_claimed' + customProperties: { + importType: 'onchain' | 'offchain' | null + name: string + } +} + type DefaultEvent = { eventName: | 'commit_started' @@ -30,11 +43,22 @@ type DefaultEvent = { | 'register_started' | 'register_started_box' | 'register_wallet_opened' + | 'claim_domain_started_dns' + | 'commit_wallet_opened_dns' + | 'register_started_dns' + | 'register_wallet_opened_dns' | 'register_override_triggered' + | 'dns_approve_registrar_wallet_opened' + | 'dns_import_wallet_opened' + | 'dns_claim_wallet_opened' customProperties?: never } -export type TrackEventParameters = SearchSelectEvent | PaymentEvent | DefaultEvent +export type TrackEventParameters = + | SearchSelectEvent + | PaymentEvent + | DefaultEvent + | DNSImportTypeSelectedEvent export const useEventTracker = () => { const chain = useChainName() @@ -43,7 +67,9 @@ export const useEventTracker = () => { const trackEvent = (props: TrackEventParameters) => { match(props) .with( - { eventName: P.union('search_selected_eth', 'search_selected_box') }, + { + eventName: P.union('search_selected_eth', 'search_selected_box', 'search_selected_dns'), + }, ({ eventName, customProperties }) => { const { name } = customProperties sendTrackEvent(eventName, chain, { name }) @@ -57,7 +83,14 @@ export const useEventTracker = () => { 'register_started', 'register_started_box', 'register_wallet_opened', + 'claim_domain_started_dns', + 'commit_wallet_opened_dns', + 'register_started_dns', + 'register_wallet_opened_dns', 'register_override_triggered', + 'dns_approve_registrar_wallet_opened', + 'dns_import_wallet_opened', + 'dns_claim_wallet_opened', ), }, ({ eventName }) => sendTrackEvent(eventName, chain), @@ -75,6 +108,21 @@ export const useEventTracker = () => { paymentAmount, }) }) + .with( + { + eventName: P.union( + 'dns_selected_import_type', + 'dns_sec_enabled', + 'dns_verified_ownership', + 'dns_claim_started', + 'dns_claimed', + ), + }, + ({ eventName, customProperties }) => { + const { importType, name } = customProperties + sendTrackEvent(eventName, chain, { name, importType }) + }, + ) .exhaustive() } diff --git a/src/i18n.ts b/src/i18n.ts index 97889272a..ad7d9f964 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -6,6 +6,7 @@ import { initReactI18next } from 'react-i18next' import address from '../public/locales/en/address.json' import common from '../public/locales/en/common.json' import dnssec from '../public/locales/en/dnssec.json' +import ensv2 from '../public/locales/en/ensv2.json' import names from '../public/locales/en/names.json' import profile from '../public/locales/en/profile.json' import register from '../public/locales/en/register.json' @@ -33,6 +34,7 @@ i18n 'register', 'settings', 'transactionFlow', + 'ensv2', ], react: { useSuspense: false, @@ -48,5 +50,6 @@ i18n.addResourceBundle('en', 'profile', profile) i18n.addResourceBundle('en', 'register', register) i18n.addResourceBundle('en', 'settings', settings) i18n.addResourceBundle('en', 'transactionFlow', transactionFlow) +i18n.addResourceBundle('en', 'ensv2', ensv2) export default i18n diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 3c5d9dfb9..294ed4587 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,6 +1,7 @@ import { lightTheme, RainbowKitProvider, Theme } from '@rainbow-me/rainbowkit' import '@rainbow-me/rainbowkit/styles.css' +import '@splidejs/react-splide/css' import { NextPage } from 'next' import type { AppProps } from 'next/app' diff --git a/src/pages/ens-v2.tsx b/src/pages/ens-v2.tsx new file mode 100644 index 000000000..19cbde148 --- /dev/null +++ b/src/pages/ens-v2.tsx @@ -0,0 +1,392 @@ +/* stylelint-disable no-descending-specificity */ +import { useTranslation } from 'react-i18next' +import styled, { css } from 'styled-components' + +import { + Banner, + Button, + Card, + GasPumpSVG, + // InfoCircleSVG, + KeySVG, + mq, + // QuestionBubbleSVG, + // QuestionCircleSVG, + // RightArrowSVG, + // SpannerAltSVG, + Typography, + WalletSVG, +} from '@ensdomains/thorin' + +// import DAOSVG from '../assets/DAO.svg' +// import SocialX from '../assets/social/SocialX.svg' + +const Title = styled.h1` + font-weight: 830; + text-align: center; + + font-size: 36px; + line-height: 104%; + + @media (min-width: 640px) { + font-size: 52px; + } +` + +const Header = styled.header( + ({ theme }) => css` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: ${theme.space[4]}; + padding: ${theme.space[4]}; + padding-top: ${theme.space[16]}; + text-align: center; + `, +) + +const Main = styled.main( + ({ theme }) => css` + display: flex; + flex-direction: column; + gap: ${theme.space['16']}; + `, +) + +/* const PartnershipAnnouncement = styled.div( + ({ theme }) => css` + width: ${theme.space.full}; + padding: ${theme.space['4']}; + background-color: ${theme.colors.backgroundPrimary}; + border-radius: ${theme.radii['4xLarge']}; + font-size: ${theme.fontSizes.body}; + font-weight: ${theme.fontWeights.bold}; + display: flex; + justify-content: space-between; + & > a { + color: ${theme.colors.greenDim}; + cursor: pointer; + display: flex; + align-items: center; + gap: ${theme.space['2']}; + } + & > a:hover { + color: ${theme.colors.green}; + } + @media (min-width: 640px) { + border-radius: ${theme.radii['3xLarge']}; + } + `, +) */ + +/* const Footer = styled.div( + ({ theme }) => css` + display: flex; + flex-direction: column; + gap: ${theme.space['6']}; + h3 { + text-align: center; + } + + & > div { + display: grid; + grid-template-columns: repeat(1, 1fr); + gap: ${theme.space['4']}; + } + & > div a { + display: flex; + flex-direction: row; + align-items: center; + gap: ${theme.space['2']}; + color: ${theme.colors.green}; + } + & > div a:hover { + color: ${theme.colors.greenDim}; + } + & > div > div { + width: 100%; + display: flex; + align-items: center; + } + @media (min-width: 480px) { + & > div { + grid-template-columns: repeat(2, 1fr); + } + } + `, +) */ + +const AnnouncementBanner = styled.div( + ({ theme }) => css` + width: 312px; + height: 182px; + text-align: center; + & > a { + height: ${theme.space.full}; + justify-content: flex-start; + & > div { + height: ${theme.space.full}; + justify-content: flex-start; + } + } + `, +) + +/* const TopNav = styled.div( + ({ theme }) => css` + display: flex; + flex-direction: column; + gap: ${theme.space['6']}; + align-items: center; + position: sticky; + top: ${theme.space['4']}; + left: 0; + z-index: 1; + `, +) */ + +const CenteredCard = styled(Card)` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +` + +const CardWithEmoji = styled(CenteredCard)` + grid-column: 1 / -1; +` + +const GridOneToThree = styled.div( + ({ theme }) => css` + display: grid; + grid-template-rows: auto; + gap: ${theme.space['4']}; + text-align: center; + grid-template-columns: 1fr; + @media (min-width: 640px) { + grid-template-columns: repeat(3, 1fr); + } + `, +) + +const CardHeader = styled.h3( + ({ theme }) => css` + display: flex; + flex-direction: column; + font-size: ${theme.fontSizes.extraLarge}; + color: ${theme.colors.greenDim}; + font-weight: ${theme.fontWeights.bold}; + gap: ${theme.space['2']}; + align-items: center; + `, +) + +// const AnnouncementSlide = ({ +// title, +// text, +// href = '#', +// }: { +// title: string +// text: string +// href?: string +// }) => ( +// +// +// {text} +// +// +// ) + +const AnnouncementSlideTemp = ({ + title, + text, + href = '#', +}: { + title: string + text: string + href?: string +}) => ( + + + {text} + + +) + +const AnnouncementContainer = styled.div( + ({ theme }) => css` + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + gap: ${theme.space['4']}; + + ${mq.sm.min(css` + flex-direction: row; + `)} + `, +) + +const SlideshowContainer = styled.div( + ({ theme }) => css` + display: flex; + flex-direction: column; + gap: ${theme.space['6']}; + h3 { + text-align: center; + } + `, +) + +const YoutubeEmbed = styled.iframe( + ({ theme }) => css` + aspect-ratio: 16 / 9; + width: ${theme.space.full}; + `, +) + +export default function ENSv2() { + const { t } = useTranslation('ensv2') + return ( +
+ {/* + + {t('partnership.text')} + + {t('partnership.watch')} + + + */} +
+ {t('title')} + {t('caption')} +
+ + + + {t('learn-more.title')} + + {t('learn-more.caption')} + + + + + + {t('accessible.title')} + + {t('accessible.caption')} + + + + + + {t('accessible.gas.title')} + + {t('accessible.gas.text')} + + + + + {t('accessible.control.title')} + + {t('accessible.control.text')} + + + + + {t('accessible.multichain.title')} + + {t('accessible.multichain.text')} + + + + + {t('announcement.title')} + + {/* + + + + */} + + + + + + {/* */} +
+ ) +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 77fccae3c..2df5b1ac1 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -8,6 +8,7 @@ import FaucetBanner from '@app/components/@molecules/FaucetBanner' import Hamburger from '@app/components/@molecules/Hamburger/Hamburger' import { SearchInput } from '@app/components/@molecules/SearchInput/SearchInput' import { LeadingHeading } from '@app/components/LeadingHeading' +import { AnnouncementBanner } from '@app/components/pages/AnnouncementBanner' import { VerificationErrorDialog } from '@app/components/pages/VerificationErrorDialog' import { useVerificationOAuthHandler } from '@app/hooks/verification/useVerificationOAuthHandler/useVerificationOAuthHandler' @@ -114,6 +115,8 @@ export default function Page() { + + diff --git a/src/transaction-flow/input/ProfileReclaim-flow.tsx b/src/transaction-flow/input/ProfileReclaim-flow.tsx index a71448ecb..407a0727e 100644 --- a/src/transaction-flow/input/ProfileReclaim-flow.tsx +++ b/src/transaction-flow/input/ProfileReclaim-flow.tsx @@ -85,7 +85,6 @@ const ProfileReclaim = ({ data: { name, label, parent }, dispatch, onDismiss }: errorForRecordAtIndex, isDirtyForRecordAtIndex, } = useProfileEditorForm(existingRecords) - console.log(existingRecords) const handleSubmit = () => { const payload = [ createTransactionItem('createSubname', { diff --git a/src/utils/query/wagmi.ts b/src/utils/query/wagmi.ts index 4799fefbc..31e44228f 100644 --- a/src/utils/query/wagmi.ts +++ b/src/utils/query/wagmi.ts @@ -1,11 +1,10 @@ import { createClient, type FallbackTransport, type HttpTransport, type Transport } from 'viem' import { createConfig, createStorage, fallback, http } from 'wagmi' -import { goerli, holesky, localhost, mainnet, sepolia } from 'wagmi/chains' +import { holesky, localhost, mainnet, sepolia } from 'wagmi/chains' import { ccipRequest } from '@ensdomains/ensjs/utils' import { - goerliWithEns, holeskyWithEns, localhostWithEns, mainnetWithEns, @@ -24,12 +23,16 @@ const connectors = getDefaultWallets({ const infuraKey = process.env.NEXT_PUBLIC_INFURA_KEY || 'cfa6ae2501cc4354a74e20432507317c' const tenderlyKey = process.env.NEXT_PUBLIC_TENDERLY_KEY || '4imxc4hQfRjxrVB2kWKvTo' +const drpcKey = process.env.NEXT_PUBLIC_DRPC_KEY || 'AnmpasF2C0JBqeAEzxVO8aRuvzLTrWcR75hmDonbV6cR' export const infuraUrl = (chainName: string) => `https://${chainName}.infura.io/v3/${infuraKey}` -const cloudflareUrl = (chainName: string) => `https://web3.ens.domains/v1/${chainName}` const tenderlyUrl = (chainName: string) => `https://${chainName}.gateway.tenderly.co/${tenderlyKey}` +const drpcUrl = (chainName: string) => + `https://lb.drpc.org/ogrpc?network=${ + chainName === 'mainnet' ? 'ethereum' : chainName + }&dkey=${drpcKey}` -type SupportedUrlFunc = typeof infuraUrl | typeof cloudflareUrl | typeof tenderlyUrl +type SupportedUrlFunc = typeof infuraUrl | typeof drpcUrl | typeof tenderlyUrl const initialiseTransports = ( chainName: string, @@ -83,7 +86,6 @@ const localStorageWithInvertMiddleware = (): Storage | undefined => { const chains = [ ...(isLocalProvider ? ([localhostWithEns] as const) : ([] as const)), mainnetWithEns, - goerliWithEns, sepoliaWithEns, holeskyWithEns, ] as const @@ -97,10 +99,9 @@ const transports = { // this is a hack to make the types happy, dont remove pls [localhost.id]: HttpTransport })), - [mainnet.id]: initialiseTransports('mainnet', [infuraUrl, cloudflareUrl, tenderlyUrl]), - [sepolia.id]: initialiseTransports('sepolia', [infuraUrl, cloudflareUrl, tenderlyUrl]), - [goerli.id]: initialiseTransports('goerli', [infuraUrl, cloudflareUrl, tenderlyUrl]), - [holesky.id]: initialiseTransports('holesky', [tenderlyUrl]), + [mainnet.id]: initialiseTransports('mainnet', [drpcUrl, infuraUrl, tenderlyUrl]), + [sepolia.id]: initialiseTransports('sepolia', [drpcUrl, infuraUrl, tenderlyUrl]), + [holesky.id]: initialiseTransports('holesky', [drpcUrl, tenderlyUrl]), } as const const wagmiConfig_ = createConfig({