@ensdomains/ensjs 3.0.0-alpha.42 → 3.0.0-alpha.43

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 (121) hide show
  1. package/dist/cjs/functions/getDecryptedName.js +111 -0
  2. package/dist/cjs/functions/getOwner.js +3 -3
  3. package/dist/cjs/functions/getPrice.js +6 -6
  4. package/dist/cjs/functions/getProfile.js +11 -5
  5. package/dist/cjs/functions/getWrapperData.js +1 -1
  6. package/dist/cjs/functions/wrapName.js +2 -2
  7. package/dist/cjs/generated/factories/BaseRegistrarImplementation__factory.js +2 -2
  8. package/dist/cjs/generated/factories/BulkRenewal__factory.js +2 -2
  9. package/dist/cjs/generated/factories/DNSRegistrar__factory.js +2 -2
  10. package/dist/cjs/generated/factories/DNSSECImpl__factory.js +2 -2
  11. package/dist/cjs/generated/factories/DefaultReverseResolver__factory.js +2 -2
  12. package/dist/cjs/generated/factories/ENSRegistry__factory.js +2 -2
  13. package/dist/cjs/generated/factories/ETHRegistrarController__factory.js +2 -2
  14. package/dist/cjs/generated/factories/Multicall__factory.js +2 -2
  15. package/dist/cjs/generated/factories/NameWrapper__factory.js +2 -2
  16. package/dist/cjs/generated/factories/P256SHA256Algorithm__factory.js +2 -2
  17. package/dist/cjs/generated/factories/PublicResolver__factory.js +2 -2
  18. package/dist/cjs/generated/factories/RSASHA1Algorithm__factory.js +2 -2
  19. package/dist/cjs/generated/factories/RSASHA256Algorithm__factory.js +2 -2
  20. package/dist/cjs/generated/factories/ReverseRegistrar__factory.js +2 -2
  21. package/dist/cjs/generated/factories/Root__factory.js +2 -2
  22. package/dist/cjs/generated/factories/SHA1Digest__factory.js +2 -2
  23. package/dist/cjs/generated/factories/SHA1NSEC3Digest__factory.js +2 -2
  24. package/dist/cjs/generated/factories/SHA256Digest__factory.js +2 -2
  25. package/dist/cjs/generated/factories/StaticMetadataService__factory.js +2 -2
  26. package/dist/cjs/generated/factories/TLDPublicSuffixList__factory.js +2 -2
  27. package/dist/cjs/generated/factories/UniversalResolver__factory.js +2 -2
  28. package/dist/cjs/index.js +1 -0
  29. package/dist/cjs/utils/ccip.js +3 -3
  30. package/dist/cjs/utils/hexEncodedName.js +2 -0
  31. package/dist/cjs/utils/labels.js +14 -8
  32. package/dist/cjs/utils/registerHelpers.js +2 -2
  33. package/dist/cjs/utils/wrapper.js +1 -1
  34. package/dist/esm/functions/getDecryptedName.mjs +96 -0
  35. package/dist/esm/functions/getOwner.mjs +1 -1
  36. package/dist/esm/functions/getPrice.mjs +2 -2
  37. package/dist/esm/functions/getProfile.mjs +10 -4
  38. package/dist/esm/functions/getWrapperData.mjs +1 -1
  39. package/dist/esm/functions/wrapName.mjs +1 -1
  40. package/dist/esm/generated/factories/BaseRegistrarImplementation__factory.mjs +1 -1
  41. package/dist/esm/generated/factories/BulkRenewal__factory.mjs +1 -1
  42. package/dist/esm/generated/factories/DNSRegistrar__factory.mjs +1 -1
  43. package/dist/esm/generated/factories/DNSSECImpl__factory.mjs +1 -1
  44. package/dist/esm/generated/factories/DefaultReverseResolver__factory.mjs +1 -1
  45. package/dist/esm/generated/factories/ENSRegistry__factory.mjs +1 -1
  46. package/dist/esm/generated/factories/ETHRegistrarController__factory.mjs +1 -1
  47. package/dist/esm/generated/factories/Multicall__factory.mjs +1 -1
  48. package/dist/esm/generated/factories/NameWrapper__factory.mjs +1 -1
  49. package/dist/esm/generated/factories/P256SHA256Algorithm__factory.mjs +1 -1
  50. package/dist/esm/generated/factories/PublicResolver__factory.mjs +1 -1
  51. package/dist/esm/generated/factories/RSASHA1Algorithm__factory.mjs +1 -1
  52. package/dist/esm/generated/factories/RSASHA256Algorithm__factory.mjs +1 -1
  53. package/dist/esm/generated/factories/ReverseRegistrar__factory.mjs +1 -1
  54. package/dist/esm/generated/factories/Root__factory.mjs +1 -1
  55. package/dist/esm/generated/factories/SHA1Digest__factory.mjs +1 -1
  56. package/dist/esm/generated/factories/SHA1NSEC3Digest__factory.mjs +1 -1
  57. package/dist/esm/generated/factories/SHA256Digest__factory.mjs +1 -1
  58. package/dist/esm/generated/factories/StaticMetadataService__factory.mjs +1 -1
  59. package/dist/esm/generated/factories/TLDPublicSuffixList__factory.mjs +1 -1
  60. package/dist/esm/generated/factories/UniversalResolver__factory.mjs +1 -1
  61. package/dist/esm/index.mjs +1 -0
  62. package/dist/esm/utils/ccip.mjs +2 -2
  63. package/dist/esm/utils/hexEncodedName.mjs +2 -0
  64. package/dist/esm/utils/labels.mjs +11 -8
  65. package/dist/esm/utils/registerHelpers.mjs +1 -1
  66. package/dist/esm/utils/wrapper.mjs +1 -1
  67. package/dist/types/functions/getDecryptedName.d.ts +9 -0
  68. package/dist/types/functions/getPrice.d.ts +1 -1
  69. package/dist/types/functions/getProfile.d.ts +1 -0
  70. package/dist/types/functions/getRecords.d.ts +1 -0
  71. package/dist/types/functions/registerName.d.ts +1 -1
  72. package/dist/types/functions/renewNames.d.ts +1 -1
  73. package/dist/types/functions/types.d.ts +2 -0
  74. package/dist/types/index.d.ts +9 -0
  75. package/dist/types/static.d.ts +1 -1
  76. package/dist/types/utils/hexEncodedName.d.ts +1 -0
  77. package/dist/types/utils/labels.d.ts +2 -1
  78. package/dist/types/utils/wrapper.d.ts +1 -1
  79. package/package.json +1 -1
  80. package/src/functions/createSubname.ts +1 -1
  81. package/src/functions/getDecryptedName.test.ts +49 -0
  82. package/src/functions/getDecryptedName.ts +119 -0
  83. package/src/functions/getExpiry.ts +1 -1
  84. package/src/functions/getNames.test.ts +1 -1
  85. package/src/functions/getOwner.ts +2 -2
  86. package/src/functions/getPrice.ts +2 -2
  87. package/src/functions/getProfile.test.ts +7 -0
  88. package/src/functions/getProfile.ts +13 -4
  89. package/src/functions/getWrapperData.ts +1 -1
  90. package/src/functions/registerName.ts +1 -1
  91. package/src/functions/renewNames.ts +1 -1
  92. package/src/functions/types.ts +2 -0
  93. package/src/functions/wrapName.ts +1 -1
  94. package/src/generated/factories/BaseRegistrarImplementation__factory.ts +1 -1
  95. package/src/generated/factories/BulkRenewal__factory.ts +1 -1
  96. package/src/generated/factories/DNSRegistrar__factory.ts +1 -1
  97. package/src/generated/factories/DNSSECImpl__factory.ts +1 -1
  98. package/src/generated/factories/DefaultReverseResolver__factory.ts +1 -1
  99. package/src/generated/factories/ENSRegistry__factory.ts +1 -1
  100. package/src/generated/factories/ETHRegistrarController__factory.ts +1 -1
  101. package/src/generated/factories/Multicall__factory.ts +1 -1
  102. package/src/generated/factories/NameWrapper__factory.ts +1 -1
  103. package/src/generated/factories/P256SHA256Algorithm__factory.ts +1 -1
  104. package/src/generated/factories/PublicResolver__factory.ts +1 -1
  105. package/src/generated/factories/RSASHA1Algorithm__factory.ts +1 -1
  106. package/src/generated/factories/RSASHA256Algorithm__factory.ts +1 -1
  107. package/src/generated/factories/ReverseRegistrar__factory.ts +1 -1
  108. package/src/generated/factories/Root__factory.ts +1 -1
  109. package/src/generated/factories/SHA1Digest__factory.ts +1 -1
  110. package/src/generated/factories/SHA1NSEC3Digest__factory.ts +1 -1
  111. package/src/generated/factories/SHA256Digest__factory.ts +1 -1
  112. package/src/generated/factories/StaticMetadataService__factory.ts +1 -1
  113. package/src/generated/factories/TLDPublicSuffixList__factory.ts +1 -1
  114. package/src/generated/factories/UniversalResolver__factory.ts +1 -1
  115. package/src/index.ts +4 -0
  116. package/src/static.ts +1 -1
  117. package/src/utils/ccip.ts +2 -2
  118. package/src/utils/hexEncodedName.ts +3 -0
  119. package/src/utils/labels.ts +13 -11
  120. package/src/utils/registerHelpers.ts +1 -1
  121. package/src/utils/wrapper.ts +1 -1
@@ -49,18 +49,18 @@ function saveLabel(label) {
49
49
  }
50
50
  function saveName(name) {
51
51
  const nameArray = name.split(".");
52
- nameArray.forEach((label) => {
53
- saveLabel(label);
54
- });
52
+ for (const label of nameArray) {
53
+ if (!isEncodedLabelhash(label)) {
54
+ saveLabel(label);
55
+ }
56
+ }
55
57
  }
56
58
  function checkLabel(hash) {
57
59
  const labels = getLabels();
58
60
  if (isEncodedLabelhash(hash)) {
59
- return labels[decodeLabelhash(hash)];
60
- }
61
- if (hash.startsWith("0x")) {
62
- return labels[`${hash.slice(2)}`];
61
+ return labels[decodeLabelhash(hash)] || hash;
63
62
  }
63
+ return hash;
64
64
  }
65
65
  function encodeLabel(label) {
66
66
  try {
@@ -77,7 +77,7 @@ function checkIsDecrypted(string) {
77
77
  return !string?.includes("[");
78
78
  }
79
79
  function decryptName(name) {
80
- return name.split(".").map((label) => checkLabel(label) || label).join(".");
80
+ return name.split(".").map((label) => checkLabel(label)).join(".");
81
81
  }
82
82
  var truncateUndecryptedName = (name) => truncateFormat(name);
83
83
  function checkLocalStorageSize() {
@@ -91,6 +91,8 @@ function checkLocalStorageSize() {
91
91
  }
92
92
  return allStrings ? `${3 + allStrings.length * 16 / (8 * 1024)} KB` : "Empty (0 KB)";
93
93
  }
94
+ var encodedLabelRegex = /\[[a-fA-F0-9]{64}\]/g;
95
+ var getEncryptedLabelAmount = (name) => name.match(encodedLabelRegex)?.length || 0;
94
96
  export {
95
97
  checkIsDecrypted,
96
98
  checkLabel,
@@ -99,6 +101,7 @@ export {
99
101
  decryptName,
100
102
  encodeLabel,
101
103
  encodeLabelhash,
104
+ getEncryptedLabelAmount,
102
105
  isEncodedLabelhash,
103
106
  keccakFromString,
104
107
  labelhash,
@@ -1,5 +1,5 @@
1
1
  // src/utils/registerHelpers.ts
2
- import { defaultAbiCoder } from "@ethersproject/abi/lib.esm/abi-coder.js";
2
+ import { defaultAbiCoder } from "@ethersproject/abi";
3
3
  import { keccak256 } from "@ethersproject/keccak256";
4
4
  import { encodeFuses, hasFuses } from "./fuses.mjs";
5
5
  import { labelhash } from "./labels.mjs";
@@ -1,5 +1,5 @@
1
1
  // src/utils/wrapper.ts
2
- import { BigNumber } from "@ethersproject/bignumber/lib.esm/bignumber.js";
2
+ import { BigNumber } from "@ethersproject/bignumber";
3
3
  import { toUtf8Bytes } from "@ethersproject/strings";
4
4
  var MAX_EXPIRY = BigNumber.from(2).pow(64).sub(1);
5
5
  var makeExpiry = async ({ getExpiry }, name, expiry) => {
@@ -0,0 +1,9 @@
1
+ import { ENSArgs } from '../index';
2
+ declare const _default: {
3
+ raw: ({ contracts }: ENSArgs<"contracts">, name: string, allowIncomplete?: boolean | undefined) => Promise<{
4
+ to: string;
5
+ data: string;
6
+ }>;
7
+ decode: ({ contracts, gqlInstance }: ENSArgs<"contracts" | "gqlInstance">, data: string, name: string, allowIncomplete?: boolean) => Promise<any>;
8
+ };
9
+ export default _default;
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber';
1
+ import { BigNumber } from '@ethersproject/bignumber';
2
2
  import { ENSArgs } from '..';
3
3
  declare const _default: {
4
4
  raw: ({ contracts, multicallWrapper }: ENSArgs<"contracts" | "multicallWrapper">, nameOrNames: string | string[], duration: number, legacy?: boolean | undefined) => Promise<{
@@ -16,6 +16,7 @@ declare type ResolvedProfile = {
16
16
  createdAt: string | null;
17
17
  address?: string;
18
18
  name?: string | null;
19
+ decryptedName?: string | null;
19
20
  match?: boolean;
20
21
  message?: string;
21
22
  records?: {
@@ -10,6 +10,7 @@ export default function ({ getProfile }: ENSArgs<'getProfile'>, name: string, op
10
10
  createdAt: string | null;
11
11
  address?: string | undefined;
12
12
  name?: string | null | undefined;
13
+ decryptedName?: string | null | undefined;
13
14
  match?: boolean | undefined;
14
15
  message?: string | undefined;
15
16
  records?: {
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber';
1
+ import { BigNumber } from '@ethersproject/bignumber';
2
2
  import { ENSArgs } from '..';
3
3
  import { BaseRegistrationParams } from '../utils/registerHelpers';
4
4
  declare type Params = BaseRegistrationParams & {
@@ -1,4 +1,4 @@
1
- import { BigNumber, BigNumberish } from '@ethersproject/bignumber/lib/bignumber';
1
+ import { BigNumber, BigNumberish } from '@ethersproject/bignumber';
2
2
  import { ENSArgs } from '..';
3
3
  declare type BaseProps = {
4
4
  duration: number;
@@ -4,6 +4,7 @@ import type commitName from './commitName';
4
4
  import type createSubname from './createSubname';
5
5
  import type deleteSubname from './deleteSubname';
6
6
  import type getAvailable from './getAvailable';
7
+ import type getDecryptedName from './getDecryptedName';
7
8
  import type getDNSOwner from './getDNSOwner';
8
9
  import type getExpiry from './getExpiry';
9
10
  import type { getHistory } from './getHistory';
@@ -43,6 +44,7 @@ declare type Function = {
43
44
  createSubname: typeof createSubname;
44
45
  deleteSubname: typeof deleteSubname;
45
46
  getAvailable: typeof getAvailable;
47
+ getDecryptedName: typeof getDecryptedName;
46
48
  getDNSOwner: typeof getDNSOwner;
47
49
  getExpiry: typeof getExpiry;
48
50
  getHistory: typeof getHistory;
@@ -154,6 +154,7 @@ export declare class ENS {
154
154
  createdAt: string | null;
155
155
  address?: string | undefined;
156
156
  name?: string | null | undefined;
157
+ decryptedName?: string | null | undefined;
157
158
  match?: boolean | undefined;
158
159
  message?: string | undefined;
159
160
  records?: {
@@ -185,6 +186,7 @@ export declare class ENS {
185
186
  createdAt: string | null;
186
187
  address?: string | undefined;
187
188
  name?: string | null | undefined;
189
+ decryptedName?: string | null | undefined;
188
190
  match?: boolean | undefined;
189
191
  message?: string | undefined;
190
192
  records?: {
@@ -490,6 +492,13 @@ export declare class ENS {
490
492
  }>;
491
493
  decode: ({ contracts }: ENSArgs<"contracts">, data: string) => Promise<boolean | undefined>;
492
494
  }>;
495
+ getDecryptedName: GeneratedRawFunction<{
496
+ raw: ({ contracts }: ENSArgs<"contracts">, name: string, allowIncomplete?: boolean | undefined) => Promise<{
497
+ to: string;
498
+ data: string;
499
+ }>;
500
+ decode: ({ contracts, gqlInstance }: ENSArgs<"contracts" | "gqlInstance">, data: string, name: string, allowIncomplete?: boolean) => Promise<any>;
501
+ }>;
493
502
  universalWrapper: GeneratedRawFunction<{
494
503
  raw: ({ contracts }: ENSArgs<"contracts">, name: string, data: string) => Promise<{
495
504
  to: string;
@@ -1,4 +1,4 @@
1
- import type { StaticJsonRpcProvider } from '@ethersproject/providers/lib/url-json-rpc-provider';
1
+ import type { StaticJsonRpcProvider } from '@ethersproject/providers';
2
2
  import { gql, GraphQLClient } from 'graphql-request';
3
3
  import { ENS, FunctionSubtype } from './index';
4
4
  import type Factories from './contracts/factories';
@@ -1 +1,2 @@
1
1
  export declare const hexEncodeName: (name: string) => string;
2
+ export declare const hexDecodeName: (hex: string) => string;
@@ -5,10 +5,11 @@ export declare function encodeLabelhash(hash: string): string;
5
5
  export declare function isEncodedLabelhash(hash: string): boolean;
6
6
  export declare function saveLabel(label: string): string;
7
7
  export declare function saveName(name: string): void;
8
- export declare function checkLabel(hash: string): string | undefined;
8
+ export declare function checkLabel(hash: string): string;
9
9
  export declare function encodeLabel(label: any): any;
10
10
  export declare function parseName(name: string): string;
11
11
  export declare function checkIsDecrypted(string: string | string[]): boolean;
12
12
  export declare function decryptName(name: string): string;
13
13
  export declare const truncateUndecryptedName: (name: string) => string;
14
14
  export declare function checkLocalStorageSize(): string;
15
+ export declare const getEncryptedLabelAmount: (name: string) => number;
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber';
1
+ 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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ensdomains/ensjs",
3
- "version": "3.0.0-alpha.42",
3
+ "version": "3.0.0-alpha.43",
4
4
  "description": "ENS javascript library for contract interaction",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.mjs",
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { BigNumber } from '@ethersproject/bignumber'
2
2
  import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
3
3
  import { ENSArgs } from '..'
4
4
  import { CombinedFuseInput, encodeFuses } from '../utils/fuses'
@@ -0,0 +1,49 @@
1
+ import { ENS } from '../index'
2
+ import setup from '../tests/setup'
3
+
4
+ let ensInstance: ENS
5
+
6
+ beforeAll(async () => {
7
+ ;({ ensInstance } = await setup())
8
+ })
9
+
10
+ describe('getDecryptedName', () => {
11
+ it('should decrypt a wrapped name with on-chain data', async () => {
12
+ const result = await ensInstance.getDecryptedName(
13
+ '[9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658].wrapped-with-subnames.eth',
14
+ )
15
+ expect(result).toBeDefined()
16
+ expect(result).toBe('test.wrapped-with-subnames.eth')
17
+ })
18
+ it('should decrypt a name via namehash lookup', async () => {
19
+ const result = await ensInstance.getDecryptedName(
20
+ '[f81b517a242b218999ec8eec0ea6e2ddbef2a367a14e93f4a32a39e260f686ad].eth',
21
+ )
22
+ expect(result).toBeDefined()
23
+ expect(result).toBe('test123.eth')
24
+ })
25
+ it('should decrypt a name via labelhash lookup', async () => {
26
+ const result = await ensInstance.getDecryptedName(
27
+ '[4d2920c35d976f8478bee89292ba85074d1bbea73f1571363b41a1629e1bac68].with-unknown-subnames.eth',
28
+ )
29
+ expect(result).toBeDefined()
30
+ expect(result).toBe('aaa123.with-unknown-subnames.eth')
31
+ })
32
+ it('should partially decrypt a name when allowIncomplete is true', async () => {
33
+ const result = await ensInstance.getDecryptedName(
34
+ '[7bffb6e3ebf801bbc438fea5c11d957ba49978bdc8d52b71cba974139d22edea].[6c14e1739568670447af1d5af8a571008f7a582068af18bcd7ac2dbc13bb37c1].eth',
35
+ true,
36
+ )
37
+ expect(result).toBeDefined()
38
+ expect(result).toBe(
39
+ '[7bffb6e3ebf801bbc438fea5c11d957ba49978bdc8d52b71cba974139d22edea].with-unknown-subnames.eth',
40
+ )
41
+ })
42
+ it('should not partially decrypt a name when allowIncomplete is false', async () => {
43
+ const result = await ensInstance.getDecryptedName(
44
+ '[7bffb6e3ebf801bbc438fea5c11d957ba49978bdc8d52b71cba974139d22edea].[6c14e1739568670447af1d5af8a571008f7a582068af18bcd7ac2dbc13bb37c1].eth',
45
+ false,
46
+ )
47
+ expect(result).toBeUndefined()
48
+ })
49
+ })
@@ -0,0 +1,119 @@
1
+ import { hexStripZeros } from '@ethersproject/bytes'
2
+ import { ENSArgs } from '../index'
3
+ import { hexDecodeName } from '../utils/hexEncodedName'
4
+ import {
5
+ checkIsDecrypted,
6
+ decodeLabelhash,
7
+ getEncryptedLabelAmount,
8
+ isEncodedLabelhash,
9
+ } from '../utils/labels'
10
+ import { namehash } from '../utils/normalise'
11
+
12
+ const raw = async (
13
+ { contracts }: ENSArgs<'contracts'>,
14
+ name: string,
15
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
16
+ allowIncomplete?: boolean,
17
+ ) => {
18
+ const nameWrapper = await contracts?.getNameWrapper()!
19
+
20
+ return {
21
+ to: nameWrapper.address,
22
+ data: nameWrapper.interface.encodeFunctionData('names', [namehash(name)]),
23
+ }
24
+ }
25
+
26
+ const generateNameQuery = (labels: string[]) => {
27
+ let query = ''
28
+
29
+ for (let i = 0; i < labels.length; i += 1) {
30
+ const label = labels[i]
31
+ if (isEncodedLabelhash(label)) {
32
+ query += `
33
+ label${i}: domains(where: { labelhash: "${decodeLabelhash(
34
+ label,
35
+ ).toLowerCase()}", labelName_not: null }) {
36
+ labelName
37
+ }
38
+ `
39
+ }
40
+ }
41
+
42
+ return query
43
+ }
44
+
45
+ const decode = async (
46
+ { contracts, gqlInstance }: ENSArgs<'contracts' | 'gqlInstance'>,
47
+ data: string,
48
+ name: string,
49
+ allowIncomplete: boolean = false,
50
+ ) => {
51
+ if (data !== null) {
52
+ const nameWrapper = await contracts?.getNameWrapper()!
53
+ try {
54
+ const result = nameWrapper.interface.decodeFunctionResult('names', data)
55
+ if (hexStripZeros(result['0']) !== '0x') {
56
+ const decoded = hexDecodeName(result['0'])
57
+ if (decoded && decoded !== '.') return decoded
58
+ }
59
+ } catch (e: any) {
60
+ console.error('Error decoding name: ', e)
61
+ return
62
+ }
63
+ }
64
+
65
+ if (checkIsDecrypted(name)) return name
66
+ // if the name isn't wrapped, try to fetch the name from an existing Domain entity
67
+ // also try to fetch the label names from any Domain entities that have a corresponding labelhash
68
+ const labels = name.split('.')
69
+ const decryptedNameQuery = gqlInstance.gql`
70
+ query decodedName($id: String!) {
71
+ namehashLookup: domains(where: { id: $id }) {
72
+ name
73
+ }
74
+ ${generateNameQuery(labels)}
75
+ }
76
+ `
77
+
78
+ const decryptedNameResult = await gqlInstance.client.request(
79
+ decryptedNameQuery,
80
+ {
81
+ id: namehash(name),
82
+ },
83
+ )
84
+
85
+ if (!decryptedNameResult) return
86
+
87
+ const namehashLookupResult = decryptedNameResult?.namehashLookup[0]?.name
88
+ let bestResult: string | undefined = namehashLookupResult
89
+ if (namehashLookupResult && checkIsDecrypted(namehashLookupResult)) {
90
+ return namehashLookupResult
91
+ }
92
+
93
+ const { namehashLookup: _, ...labelNames } = decryptedNameResult
94
+ if (Object.keys(labelNames).length !== 0) {
95
+ for (const [key, value] of Object.entries<[{ labelName?: string }]>(
96
+ labelNames,
97
+ )) {
98
+ if (value.length && value[0].labelName) {
99
+ labels[parseInt(key.replace('label', ''))] = value[0].labelName
100
+ }
101
+ }
102
+ const labelLookupResult = labels.join('.')
103
+ if (
104
+ !namehashLookupResult ||
105
+ getEncryptedLabelAmount(namehashLookupResult) >
106
+ getEncryptedLabelAmount(labelLookupResult)
107
+ )
108
+ bestResult = labelLookupResult
109
+ }
110
+
111
+ if (!bestResult || (!allowIncomplete && !checkIsDecrypted(bestResult))) return
112
+
113
+ return bestResult
114
+ }
115
+
116
+ export default {
117
+ raw,
118
+ decode,
119
+ }
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { BigNumber } from '@ethersproject/bignumber'
2
2
  import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
3
3
  import { ENSArgs } from '..'
4
4
  import { namehash } from '../utils/normalise'
@@ -29,7 +29,7 @@ const letterItems = [
29
29
  ]
30
30
 
31
31
  const domainLetterItems = [
32
- '[',
32
+ ...Array(3).fill('['),
33
33
  'x',
34
34
  'w',
35
35
  't',
@@ -1,5 +1,5 @@
1
- import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder'
2
- import type { Result } from '@ethersproject/abi/lib/coders/abstract-coder'
1
+ import type { Result } from '@ethersproject/abi'
2
+ import { defaultAbiCoder } from '@ethersproject/abi'
3
3
  import { hexStripZeros } from '@ethersproject/bytes'
4
4
  import { ENSArgs } from '..'
5
5
  import { labelhash } from '../utils/labels'
@@ -1,5 +1,5 @@
1
- import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder'
2
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { defaultAbiCoder } from '@ethersproject/abi'
2
+ import { BigNumber } from '@ethersproject/bignumber'
3
3
  import { ENSArgs } from '..'
4
4
 
5
5
  const raw = async (
@@ -119,6 +119,13 @@ describe('getProfile', () => {
119
119
  deploymentAddresses.LegacyPublicResolver,
120
120
  )
121
121
  })
122
+ it('should return the decoded name for a name with encoded labels', async () => {
123
+ const result = await ensInstance.getProfile(
124
+ '[9dd2c369a187b4e6b9c402f030e50743e619301ea62aa4c0737d4ef7e10a3d49].with-subnames.eth',
125
+ )
126
+ expect(result).toBeDefined()
127
+ expect(result?.decryptedName).toBe('xyz.with-subnames.eth')
128
+ })
122
129
  it('should return undefined for an unregistered name', async () => {
123
130
  const result = await ensInstance.getProfile('test123123123cool.eth')
124
131
  expect(result).toBeUndefined()
@@ -1,5 +1,5 @@
1
1
  import { formatsByName } from '@ensdomains/address-encoder'
2
- import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder'
2
+ import { defaultAbiCoder } from '@ethersproject/abi'
3
3
  import { hexStripZeros, isBytesLike } from '@ethersproject/bytes'
4
4
  import { ENSArgs } from '..'
5
5
  import { decodeContenthash, DecodedContentHash } from '../utils/contentHash'
@@ -37,6 +37,7 @@ type ResolvedProfile = {
37
37
  createdAt: string | null
38
38
  address?: string
39
39
  name?: string | null
40
+ decryptedName?: string | null
40
41
  match?: boolean
41
42
  message?: string
42
43
  records?: {
@@ -360,6 +361,7 @@ const graphFetch = async (
360
361
  const query = gqlInstance.gql`
361
362
  query getRecords($id: String!) {
362
363
  domain(id: $id) {
364
+ name
363
365
  isMigrated
364
366
  createdAt
365
367
  resolver {
@@ -377,6 +379,7 @@ const graphFetch = async (
377
379
  const customResolverQuery = gqlInstance.gql`
378
380
  query getRecordsWithCustomResolver($id: String!, $resolverId: String!) {
379
381
  domain(id: $id) {
382
+ name
380
383
  isMigrated
381
384
  createdAt
382
385
  }
@@ -414,11 +417,12 @@ const graphFetch = async (
414
417
 
415
418
  if (!domain) return
416
419
 
417
- const { isMigrated, createdAt } = domain
420
+ const { isMigrated, createdAt, name: decryptedName } = domain
418
421
 
419
422
  const returnedRecords: ProfileResponse = {}
420
423
 
421
- if (!resolverResponse || !wantedRecords) return { isMigrated, createdAt }
424
+ if (!resolverResponse || !wantedRecords)
425
+ return { isMigrated, createdAt, decryptedName }
422
426
 
423
427
  Object.keys(wantedRecords).forEach((key: string) => {
424
428
  const data = wantedRecords[key as keyof ProfileOptions]
@@ -433,6 +437,7 @@ const graphFetch = async (
433
437
 
434
438
  return {
435
439
  ...returnedRecords,
440
+ decryptedName,
436
441
  isMigrated,
437
442
  createdAt,
438
443
  }
@@ -486,6 +491,7 @@ const getProfileFromName = async (
486
491
  )
487
492
  let isMigrated: boolean | null = null
488
493
  let createdAt: string | null = null
494
+ let decryptedName: string | null = null
489
495
  let result: Awaited<ReturnType<typeof getDataForName>> | null = null
490
496
  if (!graphResult) {
491
497
  if (!fallback) return
@@ -506,13 +512,16 @@ const getProfileFromName = async (
506
512
  const {
507
513
  isMigrated: _isMigrated,
508
514
  createdAt: _createdAt,
515
+ decryptedName: _decryptedName,
509
516
  ...wantedRecords
510
517
  }: {
511
518
  isMigrated: boolean
512
519
  createdAt: string
520
+ decryptedName: string
513
521
  } & InternalProfileOptions = graphResult
514
522
  isMigrated = _isMigrated
515
523
  createdAt = _createdAt
524
+ decryptedName = _decryptedName
516
525
  let recordsWithFallback = usingOptions
517
526
  ? wantedRecords
518
527
  : (_options as InternalProfileOptions)
@@ -547,7 +556,7 @@ const getProfileFromName = async (
547
556
  ? "Records fetch didn't complete"
548
557
  : "Name doesn't have a resolver",
549
558
  }
550
- return { ...result, isMigrated, createdAt, message: undefined }
559
+ return { ...result, isMigrated, createdAt, decryptedName, message: undefined }
551
560
  }
552
561
 
553
562
  const getProfileFromAddress = async (
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { BigNumber } from '@ethersproject/bignumber'
2
2
  import { ENSArgs } from '../index'
3
3
  import { decodeFuses } from '../utils/fuses'
4
4
  import { namehash } from '../utils/normalise'
@@ -1,4 +1,4 @@
1
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { BigNumber } from '@ethersproject/bignumber'
2
2
  import { ENSArgs } from '..'
3
3
  import {
4
4
  BaseRegistrationParams,
@@ -1,4 +1,4 @@
1
- import { BigNumber, BigNumberish } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { BigNumber, BigNumberish } from '@ethersproject/bignumber'
2
2
  import { ENSArgs } from '..'
3
3
  import { MAX_INT_64 } from '../utils/consts'
4
4
  import { labelhash } from '../utils/labels'
@@ -8,6 +8,7 @@ import type commitName from './commitName'
8
8
  import type createSubname from './createSubname'
9
9
  import type deleteSubname from './deleteSubname'
10
10
  import type getAvailable from './getAvailable'
11
+ import type getDecryptedName from './getDecryptedName'
11
12
  import type getDNSOwner from './getDNSOwner'
12
13
  import type getExpiry from './getExpiry'
13
14
  import type { getHistory } from './getHistory'
@@ -61,6 +62,7 @@ type Function = {
61
62
  createSubname: typeof createSubname
62
63
  deleteSubname: typeof deleteSubname
63
64
  getAvailable: typeof getAvailable
65
+ getDecryptedName: typeof getDecryptedName
64
66
  getDNSOwner: typeof getDNSOwner
65
67
  getExpiry: typeof getExpiry
66
68
  getHistory: typeof getHistory
@@ -1,4 +1,4 @@
1
- import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder'
1
+ import { defaultAbiCoder } from '@ethersproject/abi'
2
2
  import { Signer } from '@ethersproject/abstract-signer'
3
3
  import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
4
4
  import { ENSArgs } from '..'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
- import { Interface } from '@ethersproject/abi/lib/interface'
5
+ import { Interface } from '@ethersproject/abi'
6
6
  import { Signer } from '@ethersproject/abstract-signer'
7
7
  import { Contract } from '@ethersproject/contracts'
8
8
  import type { Provider } from '@ethersproject/providers'