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/package.json b/package.json index d223d48ec..f724b4154 100644 --- a/package.json +++ b/package.json @@ -51,10 +51,11 @@ "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-alpha.5", "@ensdomains/thorin": "0.6.50", "@metamask/post-message-stream": "^6.1.2", "@metamask/providers": "^14.0.2", @@ -207,4 +208,4 @@ } }, "packageManager": "pnpm@9.3.0" -} \ No newline at end of file +} 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 8bd38f822..ed228aad9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,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 @@ -36,8 +39,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-alpha.5 + version: 4.0.2-alpha.5(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@17.0.2)(react@18.3.1)) @@ -424,6 +427,48 @@ importers: specifier: ^1.0.0-pre.53 version: 1.0.0-pre.53 + .yalc/@ensdomains/ens-test-env: + dependencies: + '@ethersproject/wallet': + specifier: ^5.6.0 + version: 5.7.0 + ansi-colors: + specifier: ^4.1.1 + version: 4.1.3 + cli-progress: + specifier: ^3.10.0 + version: 3.12.0 + commander: + specifier: ^9.3.0 + version: 9.5.0 + concurrently: + specifier: ^7.1.0 + version: 7.6.0 + docker-compose: + specifier: ^0.24.7 + version: 0.24.8 + dotenv: + specifier: ^16.0.1 + version: 16.4.5 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + lz4: + specifier: ^0.6.5 + version: 0.6.5 + progress-stream: + specifier: ^2.0.0 + version: 2.0.0 + tar-fs: + specifier: ^2.1.1 + version: 2.1.1 + viem: + specifier: ^2.21.37 + version: 2.21.40(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) + wait-on: + specifier: ^6.0.1 + version: 6.0.1 + packages: '@adobe/css-tools@4.3.3': @@ -435,6 +480,9 @@ packages: '@adraffy/ens-normalize@1.10.1': resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -1559,8 +1607,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-alpha.5': + resolution: {integrity: sha512-xDlnEg+JbZMs+vV5C3v0ks8nBrJciwVD9gYeFH5TzDpSM1zcGxb4KO4vvv0F+f8UI0aZFLLldZ7xyWfn4egjAw==} peerDependencies: viem: ^2.9.2 @@ -2327,6 +2375,10 @@ packages: '@noble/curves@1.4.0': resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + '@noble/curves@1.6.0': + resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} + engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.2.0': resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} @@ -2338,6 +2390,10 @@ packages: resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + '@noble/secp256k1@1.7.1': resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} @@ -2816,6 +2872,9 @@ packages: '@scure/base@1.1.6': resolution: {integrity: sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==} + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + '@scure/bip32@1.1.5': resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} @@ -2825,6 +2884,9 @@ packages: '@scure/bip32@1.4.0': resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + '@scure/bip32@1.5.0': + resolution: {integrity: sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==} + '@scure/bip39@1.1.1': resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} @@ -2834,6 +2896,9 @@ packages: '@scure/bip39@1.3.0': resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@scure/bip39@1.4.0': + resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==} + '@sentry/browser@7.43.0': resolution: {integrity: sha512-NlRkBYKb9o5IQdGY8Ktps19Hz9RdSuqS1tlLC7Sjr+MqZqSHmhKq8MWJKciRynxBeMbeGt0smExi9BqpVQdCEg==} engines: {node: '>=8'} @@ -3768,6 +3833,17 @@ packages: zod: optional: true + abitype@1.0.6: + resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -6547,6 +6623,11 @@ packages: peerDependencies: ws: '*' + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} @@ -9341,6 +9422,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==} @@ -9706,6 +9790,14 @@ packages: typescript: optional: true + viem@2.21.40: + resolution: {integrity: sha512-no/mE3l7B0mdUTtvO7z/cTLENttQ/M7+ombqFGXJqsQrxv9wrYsTIGpS3za+FA5a447hY+x9D8Wxny84q1zAaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + vite-node@2.0.5: resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} engines: {node: ^18.0.0 || >=20.0.0} @@ -10012,6 +10104,9 @@ packages: resolution: {integrity: sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA==} engines: {node: '>=8.0.0'} + webauthn-p256@0.0.10: + resolution: {integrity: sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==} + webauthn-p256@0.0.5: resolution: {integrity: sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==} @@ -10255,6 +10350,18 @@ packages: utf-8-validate: optional: true + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xhr-request-promise@0.1.3: resolution: {integrity: sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==} @@ -10423,6 +10530,8 @@ snapshots: '@adraffy/ens-normalize@1.10.1': {} + '@adraffy/ens-normalize@1.11.0': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -11803,7 +11912,7 @@ snapshots: '@ensdomains/ensjs@2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.25.0 '@ensdomains/address-encoder': 0.1.9 '@ensdomains/ens': 0.4.5 '@ensdomains/resolver': 0.2.4 @@ -11815,7 +11924,7 @@ 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-alpha.5(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 @@ -11826,6 +11935,7 @@ snapshots: 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 @@ -12686,7 +12796,7 @@ snapshots: '@motionone/easing': 10.17.0 '@motionone/types': 10.17.0 '@motionone/utils': 10.17.0 - tslib: 2.6.2 + tslib: 2.6.3 '@motionone/dom@10.17.0': dependencies: @@ -12695,12 +12805,12 @@ snapshots: '@motionone/types': 10.17.0 '@motionone/utils': 10.17.0 hey-listen: 1.0.8 - tslib: 2.6.2 + tslib: 2.6.3 '@motionone/easing@10.17.0': dependencies: '@motionone/utils': 10.17.0 - tslib: 2.6.2 + tslib: 2.6.3 '@motionone/generators@10.17.0': dependencies: @@ -12711,7 +12821,7 @@ snapshots: '@motionone/svelte@10.16.4': dependencies: '@motionone/dom': 10.17.0 - tslib: 2.6.2 + tslib: 2.6.3 '@motionone/types@10.17.0': {} @@ -12719,12 +12829,12 @@ snapshots: dependencies: '@motionone/types': 10.17.0 hey-listen: 1.0.8 - tslib: 2.6.2 + tslib: 2.6.3 '@motionone/vue@10.16.4': dependencies: '@motionone/dom': 10.17.0 - tslib: 2.6.2 + tslib: 2.6.3 '@mswjs/cookies@0.2.2': dependencies: @@ -12797,12 +12907,18 @@ snapshots: dependencies: '@noble/hashes': 1.4.0 + '@noble/curves@1.6.0': + dependencies: + '@noble/hashes': 1.5.0 + '@noble/hashes@1.2.0': {} '@noble/hashes@1.3.3': {} '@noble/hashes@1.4.0': {} + '@noble/hashes@1.5.0': {} + '@noble/secp256k1@1.7.1': {} '@nodelib/fs.scandir@2.1.5': @@ -13415,7 +13531,7 @@ snapshots: '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.21.1 - viem: 2.19.4(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) + viem: 2.21.40(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) transitivePeerDependencies: - bufferutil - typescript @@ -13426,6 +13542,8 @@ snapshots: '@scure/base@1.1.6': {} + '@scure/base@1.1.9': {} + '@scure/bip32@1.1.5': dependencies: '@noble/hashes': 1.2.0 @@ -13444,6 +13562,12 @@ snapshots: '@noble/hashes': 1.4.0 '@scure/base': 1.1.6 + '@scure/bip32@1.5.0': + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + '@scure/bip39@1.1.1': dependencies: '@noble/hashes': 1.2.0 @@ -13459,6 +13583,11 @@ snapshots: '@noble/hashes': 1.4.0 '@scure/base': 1.1.6 + '@scure/bip39@1.4.0': + dependencies: + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + '@sentry/browser@7.43.0': dependencies: '@sentry/core': 7.43.0 @@ -13816,7 +13945,7 @@ snapshots: '@swc/helpers@0.5.2': dependencies: - tslib: 2.6.2 + tslib: 2.6.3 '@szmarczak/http-timer@4.0.6': dependencies: @@ -14955,6 +15084,11 @@ snapshots: typescript: 5.4.5 zod: 3.23.8 + abitype@1.0.6(typescript@5.4.5)(zod@3.23.8): + optionalDependencies: + typescript: 5.4.5 + zod: 3.23.8 + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -15562,7 +15696,7 @@ snapshots: capnp-ts@0.7.0: dependencies: debug: 4.3.6 - tslib: 2.6.2 + tslib: 2.6.3 transitivePeerDependencies: - supports-color @@ -16326,7 +16460,7 @@ snapshots: dot-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.6.3 dotenv@16.4.5: {} @@ -18337,6 +18471,10 @@ snapshots: dependencies: ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + isows@1.0.6(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + isstream@0.1.2: {} istanbul-lib-coverage@3.2.2: {} @@ -18916,7 +19054,7 @@ snapshots: media-query-parser@2.0.2: dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.25.0 media-typer@0.3.0: {} @@ -19469,7 +19607,7 @@ snapshots: no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.6.2 + tslib: 2.6.3 nocache@3.0.4: {} @@ -20314,7 +20452,7 @@ snapshots: dependencies: react: 18.3.1 react-style-singleton: 2.2.1(@types/react@18.2.21)(react@18.3.1) - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: '@types/react': 18.2.21 @@ -20340,7 +20478,7 @@ snapshots: get-nonce: 1.0.1 invariant: 2.2.4 react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: '@types/react': 18.2.21 @@ -20486,7 +20624,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.25.0 regexp.prototype.flags@1.5.2: dependencies: @@ -20662,7 +20800,7 @@ snapshots: rtl-css-js@1.16.1: dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.25.0 run-async@2.4.1: {} @@ -20927,7 +21065,7 @@ snapshots: snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.6.3 socket.io-client@4.7.5(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: @@ -21628,6 +21766,8 @@ snapshots: ts-pattern@4.3.0: {} + ts-pattern@5.5.0: {} + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -21857,7 +21997,7 @@ snapshots: use-callback-ref@1.3.2(@types/react@18.2.21)(react@18.3.1): dependencies: react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: '@types/react': 18.2.21 @@ -21870,7 +22010,7 @@ snapshots: dependencies: detect-node-es: 1.1.0 react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: '@types/react': 18.2.21 @@ -21949,6 +22089,24 @@ snapshots: - utf-8-validate - zod + viem@2.21.40(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/bip32': 1.5.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.6(typescript@5.4.5)(zod@3.23.8) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + webauthn-p256: 0.0.10 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite-node@2.0.5(@types/node@18.19.33)(terser@5.31.5): dependencies: cac: 6.7.14 @@ -22541,6 +22699,11 @@ snapshots: - supports-color - utf-8-validate + webauthn-p256@0.0.10: + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + webauthn-p256@0.0.5: dependencies: '@noble/curves': 1.4.0 @@ -22812,6 +22975,11 @@ snapshots: bufferutil: 4.0.8 utf-8-validate: 5.0.10 + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + xhr-request-promise@0.1.3: dependencies: xhr-request: 1.1.0 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')} >