@ensdomains/ensjs 3.0.0-alpha.45 → 3.0.0-alpha.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/cjs/functions/deleteSubname.js +17 -7
  2. package/dist/cjs/functions/getNames.js +25 -13
  3. package/dist/cjs/functions/getSubnames.js +32 -8
  4. package/dist/cjs/functions/transferSubname.js +4 -9
  5. package/dist/cjs/index.js +1 -1
  6. package/dist/cjs/utils/consts.js +1 -1
  7. package/dist/cjs/utils/fuses.js +2 -0
  8. package/dist/cjs/utils/registry.js +32 -0
  9. package/dist/cjs/utils/wrapper.js +14 -9
  10. package/dist/esm/functions/deleteSubname.mjs +17 -7
  11. package/dist/esm/functions/getNames.mjs +26 -14
  12. package/dist/esm/functions/getSubnames.mjs +32 -8
  13. package/dist/esm/functions/transferSubname.mjs +5 -10
  14. package/dist/esm/index.mjs +1 -1
  15. package/dist/esm/utils/consts.mjs +1 -1
  16. package/dist/esm/utils/fuses.mjs +2 -0
  17. package/dist/esm/utils/registry.mjs +13 -0
  18. package/dist/esm/utils/wrapper.mjs +14 -9
  19. package/dist/types/functions/deleteSubname.d.ts +8 -2
  20. package/dist/types/functions/getSubnames.d.ts +16 -4
  21. package/dist/types/functions/transferSubname.d.ts +1 -1
  22. package/dist/types/index.d.ts +62 -4
  23. package/dist/types/utils/fuses.d.ts +1 -0
  24. package/dist/types/utils/registry.d.ts +2 -0
  25. package/dist/types/utils/wrapper.d.ts +1 -0
  26. package/package.json +1 -1
  27. package/src/functions/deleteSubname.test.ts +139 -6
  28. package/src/functions/deleteSubname.ts +28 -11
  29. package/src/functions/getNames.test.ts +15 -2
  30. package/src/functions/getNames.ts +46 -22
  31. package/src/functions/getSubnames.test.ts +1227 -322
  32. package/src/functions/getSubnames.ts +62 -13
  33. package/src/functions/getWrapperData.test.ts +0 -1
  34. package/src/functions/transferSubname.test.ts +120 -18
  35. package/src/functions/transferSubname.ts +5 -10
  36. package/src/index.ts +1 -1
  37. package/src/utils/consts.ts +1 -1
  38. package/src/utils/fuses.ts +3 -0
  39. package/src/utils/registry.ts +14 -0
  40. package/src/utils/wrapper.ts +12 -9
@@ -1,15 +1,27 @@
1
1
  import { ENSArgs } from '..';
2
- declare type Subname = {
2
+ import { AllCurrentFuses } from '../utils/fuses';
3
+ declare type BaseSubname = {
3
4
  id: string;
4
5
  labelName: string | null;
5
6
  truncatedName?: string;
6
7
  labelhash: string;
7
8
  isMigrated: boolean;
8
9
  name: string;
9
- owner: {
10
- id: string;
11
- };
10
+ owner: string | undefined;
12
11
  };
12
+ declare type UnwrappedSubname = BaseSubname & {
13
+ fuses?: never;
14
+ expiryDate?: never;
15
+ pccExpired?: never;
16
+ type: 'domain';
17
+ };
18
+ declare type WrappedSubname = BaseSubname & {
19
+ fuses: AllCurrentFuses;
20
+ expiryDate: Date;
21
+ pccExpired: boolean;
22
+ type: 'wrappedDomain';
23
+ };
24
+ declare type Subname = WrappedSubname | UnwrappedSubname;
13
25
  declare type Params = {
14
26
  name: string;
15
27
  page?: number;
@@ -10,5 +10,5 @@ declare type NameWrapperArgs = {
10
10
  expiry?: Expiry;
11
11
  } & BaseArgs;
12
12
  declare type Args = BaseArgs | NameWrapperArgs;
13
- export default function ({ contracts, signer, getExpiry, }: ENSArgs<'contracts' | 'signer' | 'getExpiry'>, name: string, { contract, owner, resolverAddress, ...wrapperArgs }: Args): Promise<import("ethers").PopulatedTransaction>;
13
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { contract, owner, resolverAddress, ...wrapperArgs }: Args): Promise<import("ethers").PopulatedTransaction>;
14
14
  export {};
@@ -461,17 +461,75 @@ export declare class ENS {
461
461
  lastSubnames?: any[] | undefined;
462
462
  search?: string | undefined;
463
463
  }) => Promise<{
464
- subnames: {
464
+ subnames: (({
465
465
  id: string;
466
466
  labelName: string | null;
467
467
  truncatedName?: string | undefined;
468
468
  labelhash: string;
469
469
  isMigrated: boolean;
470
470
  name: string;
471
- owner: {
472
- id: string;
471
+ owner: string | undefined;
472
+ } & {
473
+ fuses?: undefined;
474
+ expiryDate?: undefined;
475
+ pccExpired?: undefined;
476
+ type: "domain";
477
+ }) | ({
478
+ id: string;
479
+ labelName: string | null;
480
+ truncatedName?: string | undefined;
481
+ labelhash: string;
482
+ isMigrated: boolean;
483
+ name: string;
484
+ owner: string | undefined;
485
+ } & {
486
+ fuses: {
487
+ parent: {
488
+ unnamed: {
489
+ 524288: boolean;
490
+ 1048576: boolean;
491
+ 2097152: boolean;
492
+ 4194304: boolean;
493
+ 8388608: boolean;
494
+ 16777216: boolean;
495
+ 33554432: boolean;
496
+ 67108864: boolean;
497
+ 134217728: boolean;
498
+ 268435456: boolean;
499
+ 536870912: boolean;
500
+ 1073741824: boolean;
501
+ 2147483648: boolean;
502
+ };
503
+ IS_DOT_ETH: boolean;
504
+ PARENT_CANNOT_CONTROL: boolean;
505
+ CAN_EXTEND_EXPIRY: boolean;
506
+ };
507
+ child: {
508
+ CAN_DO_EVERYTHING: boolean;
509
+ unnamed: {
510
+ 1024: boolean;
511
+ 64: boolean;
512
+ 128: boolean;
513
+ 256: boolean;
514
+ 512: boolean;
515
+ 2048: boolean;
516
+ 4096: boolean;
517
+ 8192: boolean;
518
+ 16384: boolean;
519
+ 32768: boolean;
520
+ };
521
+ CANNOT_UNWRAP: boolean;
522
+ CANNOT_BURN_FUSES: boolean;
523
+ CANNOT_TRANSFER: boolean;
524
+ CANNOT_SET_RESOLVER: boolean;
525
+ CANNOT_SET_TTL: boolean;
526
+ CANNOT_CREATE_SUBDOMAIN: boolean;
527
+ };
473
528
  };
474
- }[];
529
+ expiryDate: Date;
530
+ pccExpired: boolean;
531
+ type: "wrappedDomain";
532
+ }))[];
475
533
  subnameCount: number;
476
534
  }>;
477
535
  getNames: (args_0: {
@@ -128,5 +128,6 @@ export declare const decodeFuses: (fuses: number) => {
128
128
  CANNOT_CREATE_SUBDOMAIN: boolean;
129
129
  };
130
130
  };
131
+ export declare const checkPCCBurned: (fuses: number) => boolean;
131
132
  export declare type AllCurrentFuses = ReturnType<typeof decodeFuses>;
132
133
  export default fullFuseEnum;
@@ -0,0 +1,2 @@
1
+ import { ENSArgs } from '../index';
2
+ export declare const makeResolver: ({ contracts }: ENSArgs<'contracts'>, name: string, resolver?: string) => Promise<string>;
@@ -2,5 +2,6 @@ import { BigNumber } from '@ethersproject/bignumber';
2
2
  import { ENSArgs } from '../index';
3
3
  export declare type Expiry = string | number | Date | BigNumber;
4
4
  export declare const MAX_EXPIRY: BigNumber;
5
+ export declare const expiryToBigNumber: (expiry?: Expiry, defaultValue?: number) => BigNumber;
5
6
  export declare const makeExpiry: ({ getExpiry }: ENSArgs<'getExpiry'>, name: string, expiry?: Expiry) => Promise<BigNumber>;
6
7
  export declare const wrappedLabelLengthCheck: (label: string) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ensdomains/ensjs",
3
- "version": "3.0.0-alpha.45",
3
+ "version": "3.0.0-alpha.47",
4
4
  "description": "ENS javascript library for contract interaction",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.mjs",
@@ -1,12 +1,20 @@
1
+ import { ethers } from 'ethers'
1
2
  import { ENS } from '..'
2
3
  import setup from '../tests/setup'
3
4
  import { namehash } from '../utils/normalise'
4
5
 
5
6
  let ensInstance: ENS
6
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
8
+ let provider: ethers.providers.JsonRpcProvider
9
+ let accounts: string[]
7
10
 
8
11
  beforeAll(async () => {
9
- ;({ ensInstance, revert } = await setup())
12
+ ;({ ensInstance, revert, provider } = await setup())
13
+ accounts = await provider.listAccounts()
14
+ })
15
+
16
+ beforeEach(async () => {
17
+ await revert()
10
18
  })
11
19
 
12
20
  afterAll(async () => {
@@ -17,27 +25,34 @@ describe('deleteSubname', () => {
17
25
  beforeEach(async () => {
18
26
  await revert()
19
27
  })
20
- it('should allow deleting a subname on the registry', async () => {
28
+ it('should allow deleting a subname on the registry by parent owner', async () => {
29
+ const registry = await ensInstance.contracts!.getRegistry()!
30
+ const parentOwner = await registry.owner(namehash('with-subnames.eth'))
31
+
21
32
  const tx = await ensInstance.deleteSubname('test.with-subnames.eth', {
22
33
  contract: 'registry',
23
- addressOrIndex: 1,
34
+ addressOrIndex: parentOwner,
24
35
  })
25
36
  expect(tx).toBeTruthy()
26
37
  await tx.wait()
27
38
 
28
- const registry = await ensInstance.contracts!.getRegistry()!
29
39
  const result = await registry.owner(namehash('test.with-subnames.eth'))
30
40
  expect(result).toBe('0x0000000000000000000000000000000000000000')
31
41
  })
32
42
 
33
- it('should allow deleting a subname on the nameWrapper', async () => {
43
+ it('should allow deleting a subname on the nameWrapper by parent owner', async () => {
34
44
  const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
35
45
 
46
+ const parentOwner = await nameWrapper.ownerOf(
47
+ namehash('wrapped-with-subnames.eth'),
48
+ )
49
+
36
50
  const tx = await ensInstance.deleteSubname(
37
51
  'test.wrapped-with-subnames.eth',
38
52
  {
39
53
  contract: 'nameWrapper',
40
- addressOrIndex: 1,
54
+ method: 'setSubnodeOwner',
55
+ addressOrIndex: parentOwner,
41
56
  },
42
57
  )
43
58
  expect(tx).toBeTruthy()
@@ -49,10 +64,128 @@ describe('deleteSubname', () => {
49
64
  expect(result).toBe('0x0000000000000000000000000000000000000000')
50
65
  })
51
66
 
67
+ it('should allow deleting a subname on the nameWrapper by name owner', async () => {
68
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
69
+
70
+ const nameOwner = await nameWrapper.ownerOf(
71
+ namehash('addr.wrapped-with-subnames.eth'),
72
+ )
73
+
74
+ await ensInstance.deleteSubname('addr.wrapped-with-subnames.eth', {
75
+ contract: 'nameWrapper',
76
+ method: 'setRecord',
77
+ addressOrIndex: nameOwner,
78
+ })
79
+
80
+ const result = await nameWrapper.ownerOf(
81
+ namehash('addr.wrapped-with-subnames.eth'),
82
+ )
83
+ expect(result).toBe('0x0000000000000000000000000000000000000000')
84
+ })
85
+
86
+ it('should allow deleting a subname on the nameWrapper with PCC burned by name owner', async () => {
87
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
88
+
89
+ const parentOwner = await nameWrapper.ownerOf(
90
+ namehash('wrapped-with-subnames.eth'),
91
+ )
92
+
93
+ const tx0 = await ensInstance.setFuses('wrapped-with-subnames.eth', {
94
+ named: ['CANNOT_UNWRAP'],
95
+ addressOrIndex: parentOwner,
96
+ })
97
+ expect(tx0).toBeTruthy()
98
+ await tx0.wait()
99
+
100
+ const tx1 = await ensInstance.setChildFuses(
101
+ 'xyz.wrapped-with-subnames.eth',
102
+ {
103
+ fuses: {
104
+ parent: {
105
+ named: ['PARENT_CANNOT_CONTROL'],
106
+ },
107
+ },
108
+ addressOrIndex: parentOwner,
109
+ },
110
+ )
111
+ expect(tx1).toBeTruthy()
112
+ await tx1.wait()
113
+
114
+ const nameOwner = await nameWrapper.ownerOf(
115
+ namehash('xyz.wrapped-with-subnames.eth'),
116
+ )
117
+
118
+ expect(parentOwner === nameOwner).toBe(false)
119
+
120
+ const tx = await ensInstance.deleteSubname(
121
+ 'xyz.wrapped-with-subnames.eth',
122
+ {
123
+ contract: 'nameWrapper',
124
+ method: 'setRecord',
125
+ addressOrIndex: nameOwner,
126
+ },
127
+ )
128
+ expect(tx).toBeTruthy()
129
+ await tx.wait()
130
+
131
+ const result = await nameWrapper.ownerOf(
132
+ namehash('xyz.wrapped-with-subnames.eth'),
133
+ )
134
+ expect(result).toBe('0x0000000000000000000000000000000000000000')
135
+ })
136
+
137
+ it('should NOT allow deleting a subname on the nameWrapper with PCC burned by parent owner', async () => {
138
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
139
+
140
+ const parentOwner = await nameWrapper.ownerOf(
141
+ namehash('wrapped-with-subnames.eth'),
142
+ )
143
+
144
+ const tx0 = await ensInstance.setFuses('wrapped-with-subnames.eth', {
145
+ named: ['CANNOT_UNWRAP'],
146
+ addressOrIndex: parentOwner,
147
+ })
148
+ expect(tx0).toBeTruthy()
149
+ await tx0.wait()
150
+
151
+ const tx1 = await ensInstance.setChildFuses(
152
+ 'legacy.wrapped-with-subnames.eth',
153
+ {
154
+ fuses: {
155
+ parent: {
156
+ named: ['PARENT_CANNOT_CONTROL'],
157
+ },
158
+ },
159
+ addressOrIndex: parentOwner,
160
+ },
161
+ )
162
+ expect(tx1).toBeTruthy()
163
+ await tx1.wait()
164
+
165
+ const checkOwner = await nameWrapper.ownerOf(
166
+ namehash('legacy.wrapped-with-subnames.eth'),
167
+ )
168
+ expect(checkOwner).toBe(accounts[2])
169
+
170
+ await expect(
171
+ ensInstance.deleteSubname('legacy.wrapped-with-subnames.eth', {
172
+ contract: 'nameWrapper',
173
+ method: 'setSubnodeOwner',
174
+ addressOrIndex: parentOwner,
175
+ }),
176
+ ).rejects.toThrow()
177
+
178
+ const result = await nameWrapper.ownerOf(
179
+ namehash('legacy.wrapped-with-subnames.eth'),
180
+ )
181
+ expect(result).toBe(accounts[2])
182
+ })
183
+
52
184
  it('should not allow deleting 1LD', async () => {
53
185
  await expect(
54
186
  ensInstance.deleteSubname('eth', {
55
187
  contract: 'nameWrapper',
188
+ method: 'setRecord',
56
189
  addressOrIndex: 1,
57
190
  }),
58
191
  ).rejects.toThrow()
@@ -2,28 +2,34 @@ import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
2
2
  import { ENSArgs } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
4
 
5
- type Args = {
5
+ type BaseArgs = {
6
6
  contract: 'registry' | 'nameWrapper'
7
+ method?: 'setRecord' | 'setSubnodeOwner'
7
8
  }
8
9
 
10
+ type NameWrapperArgs = {
11
+ contract: 'nameWrapper'
12
+ method: 'setRecord' | 'setSubnodeOwner'
13
+ }
14
+
15
+ type Args = BaseArgs | NameWrapperArgs
16
+
9
17
  export default async function (
10
- { contracts, signer }: ENSArgs<'contracts' | 'signer' | 'getExpiry'>,
18
+ { contracts, signer }: ENSArgs<'contracts' | 'signer'>,
11
19
  name: string,
12
- { contract }: Args,
20
+ { contract, ...args }: Args,
13
21
  ) {
14
22
  const labels = name.split('.')
15
-
16
23
  if (labels.length < 3) {
17
24
  throw new Error(`${name} is not a valid subname`)
18
25
  }
19
26
 
20
- const label = labels.shift() as string
21
- const labelhash = solidityKeccak256(['string'], [label])
22
- const parentNodehash = namehash(labels.join('.'))
23
-
24
27
  switch (contract) {
25
28
  case 'registry': {
26
29
  const registry = (await contracts!.getRegistry()!).connect(signer)
30
+ const label = labels.shift() as string
31
+ const labelhash = solidityKeccak256(['string'], [label])
32
+ const parentNodehash = namehash(labels.join('.'))
27
33
 
28
34
  return registry.populateTransaction.setSubnodeRecord(
29
35
  parentNodehash,
@@ -35,13 +41,24 @@ export default async function (
35
41
  }
36
42
  case 'nameWrapper': {
37
43
  const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer)
44
+ const { method } = args as NameWrapperArgs
45
+
46
+ if (method === 'setRecord') {
47
+ const node = namehash(name)
48
+ return nameWrapper.populateTransaction.setRecord(
49
+ node,
50
+ '0x0000000000000000000000000000000000000000',
51
+ '0x0000000000000000000000000000000000000000',
52
+ 0,
53
+ )
54
+ }
38
55
 
39
- return nameWrapper.populateTransaction.setSubnodeRecord(
56
+ const label = labels.shift() as string
57
+ const parentNodehash = namehash(labels.join('.'))
58
+ return nameWrapper.populateTransaction.setSubnodeOwner(
40
59
  parentNodehash,
41
60
  label,
42
61
  '0x0000000000000000000000000000000000000000',
43
- '0x0000000000000000000000000000000000000000',
44
- 0,
45
62
  0,
46
63
  0,
47
64
  )
@@ -1,6 +1,7 @@
1
1
  import { ENS } from '..'
2
2
  import setup from '../tests/setup'
3
3
  import { Name } from './getNames'
4
+ import { names as wrappedNames } from '../../deploy/00_register_wrapped'
4
5
 
5
6
  let ensInstance: ENS
6
7
 
@@ -166,13 +167,25 @@ describe('getNames', () => {
166
167
  })
167
168
  expect(pageFive).toHaveLength(totalOwnedNames % 10)
168
169
  })
169
- it('should get wrapped domains for an address with pagination', async () => {
170
+ it('should get wrapped domains for an address with pagination, and filter out pcc expired names', async () => {
170
171
  const pageOne = await ensInstance.getNames({
171
172
  address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
172
173
  type: 'wrappedOwner',
173
174
  page: 0,
174
175
  })
175
- expect(pageOne).toHaveLength(2)
176
+
177
+ const nameCout = wrappedNames.reduce<number>((count, name) => {
178
+ if (name.namedOwner === 'owner2') count += 1
179
+ ;(name.subnames || []).forEach((subname: any) => {
180
+ if (subname.namedOwner === 'owner2') count += 1
181
+ })
182
+ return count
183
+ }, 0)
184
+
185
+ // length of page one should be all the names on 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
186
+ // minus 1 for the PCC expired name.
187
+ // the result here implies that the PCC expired name is not returned
188
+ expect(pageOne).toHaveLength(nameCout - 1)
176
189
  })
177
190
  describe('orderBy', () => {
178
191
  describe('registrations', () => {
@@ -1,6 +1,6 @@
1
1
  import { ENSArgs } from '..'
2
2
  import { truncateFormat } from '../utils/format'
3
- import { AllCurrentFuses, decodeFuses } from '../utils/fuses'
3
+ import { AllCurrentFuses, checkPCCBurned, decodeFuses } from '../utils/fuses'
4
4
  import { decryptName } from '../utils/labels'
5
5
  import { Domain, Registration, WrappedDomain } from '../utils/subgraph-types'
6
6
 
@@ -60,8 +60,21 @@ type Params = BaseParams &
60
60
 
61
61
  const mapDomain = ({ name, ...domain }: Domain) => {
62
62
  const decrypted = name ? decryptName(name) : undefined
63
+
63
64
  return {
64
65
  ...domain,
66
+ ...(domain.registration
67
+ ? {
68
+ registration: {
69
+ expiryDate: new Date(
70
+ parseInt(domain.registration.expiryDate) * 1000,
71
+ ),
72
+ registrationDate: new Date(
73
+ parseInt(domain.registration.registrationDate) * 1000,
74
+ ),
75
+ },
76
+ }
77
+ : {}),
65
78
  name: decrypted,
66
79
  truncatedName: decrypted ? truncateFormat(decrypted) : undefined,
67
80
  createdAt: new Date(parseInt(domain.createdAt) * 1000),
@@ -70,27 +83,27 @@ const mapDomain = ({ name, ...domain }: Domain) => {
70
83
  }
71
84
 
72
85
  const mapWrappedDomain = (wrappedDomain: WrappedDomain) => {
73
- const domain = mapDomain(wrappedDomain.domain) as Omit<
74
- ReturnType<typeof mapDomain>,
75
- 'registration'
76
- > & {
77
- registration?: {
78
- expiryDate: string | Date
79
- registrationDate: string | Date
80
- }
81
- }
82
- if (domain.registration) {
83
- domain.registration = {
84
- expiryDate: new Date(
85
- parseInt(domain.registration.expiryDate as string) * 1000,
86
- ),
87
- registrationDate: new Date(
88
- parseInt(domain.registration.registrationDate as string) * 1000,
89
- ),
90
- }
86
+ const expiryDate =
87
+ wrappedDomain.expiryDate && wrappedDomain.expiryDate !== '0'
88
+ ? new Date(parseInt(wrappedDomain.expiryDate) * 1000)
89
+ : undefined
90
+ if (
91
+ expiryDate &&
92
+ expiryDate < new Date() &&
93
+ checkPCCBurned(wrappedDomain.fuses)
94
+ ) {
95
+ // PCC was burned previously and now the fuses are expired meaning that the
96
+ // owner is now 0x0 so we need to filter this out
97
+ // if a user's local time is out of sync with the blockchain, this could potentially
98
+ // be incorrect. the likelihood of that happening though is very low, and devs
99
+ // shouldn't be relying on this value for anything critical anyway.
100
+ return null
91
101
  }
102
+
103
+ const domain = mapDomain(wrappedDomain.domain)
104
+
92
105
  return {
93
- expiryDate: new Date(parseInt(wrappedDomain.expiryDate) * 1000),
106
+ expiryDate,
94
107
  fuses: decodeFuses(wrappedDomain.fuses),
95
108
  ...domain,
96
109
  type: 'wrappedDomain',
@@ -156,6 +169,10 @@ const getNames = async (
156
169
  domains(first: 1000) {
157
170
  ${domainQueryData}
158
171
  createdAt
172
+ registration {
173
+ registrationDate
174
+ expiryDate
175
+ }
159
176
  }
160
177
  wrappedDomains(first: 1000) {
161
178
  expiryDate
@@ -187,6 +204,10 @@ const getNames = async (
187
204
  domains(orderBy: $orderBy, orderDirection: $orderDirection) {
188
205
  ${domainQueryData}
189
206
  createdAt
207
+ registration {
208
+ registrationDate
209
+ expiryDate
210
+ }
190
211
  }
191
212
  }
192
213
  }
@@ -366,7 +387,8 @@ const getNames = async (
366
387
  return [
367
388
  ...(account?.domains.map(mapDomain) || []),
368
389
  ...(account?.registrations.map(mapRegistration) || []),
369
- ...(account?.wrappedDomains.map(mapWrappedDomain) || []),
390
+ ...(account?.wrappedDomains.map(mapWrappedDomain).filter((d: any) => d) ||
391
+ []),
370
392
  ].sort((a, b) => {
371
393
  if (orderDirection === 'desc') {
372
394
  if (orderBy === 'labelName') {
@@ -384,7 +406,9 @@ const getNames = async (
384
406
  return (account?.domains.map(mapDomain) || []) as Name[]
385
407
  }
386
408
  if (type === 'wrappedOwner') {
387
- return (account?.wrappedDomains.map(mapWrappedDomain) || []) as Name[]
409
+ return (account?.wrappedDomains
410
+ .map(mapWrappedDomain)
411
+ .filter((d: any) => d) || []) as Name[]
388
412
  }
389
413
  return (account?.registrations.map(mapRegistration) || []) as Name[]
390
414
  }