@ensdomains/ensjs 3.0.0-alpha.41 → 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 (190) hide show
  1. package/dist/cjs/contracts/getContractAddress.js +4 -4
  2. package/dist/cjs/functions/commitName.js +2 -3
  3. package/dist/cjs/functions/createSubname.js +2 -8
  4. package/dist/cjs/functions/getDecryptedName.js +111 -0
  5. package/dist/cjs/functions/getHistory.js +14 -7
  6. package/dist/cjs/functions/getNames.js +10 -6
  7. package/dist/cjs/functions/getOwner.js +28 -15
  8. package/dist/cjs/functions/getPrice.js +6 -6
  9. package/dist/cjs/functions/getProfile.js +11 -5
  10. package/dist/cjs/functions/getWrapperData.js +4 -5
  11. package/dist/cjs/functions/renewNames.js +13 -20
  12. package/dist/cjs/functions/{burnFuses.js → setFuses.js} +24 -6
  13. package/dist/cjs/functions/wrapName.js +9 -25
  14. package/dist/cjs/generated/factories/BaseRegistrarImplementation__factory.js +2 -2
  15. package/dist/cjs/generated/factories/BulkRenewal__factory.js +2 -2
  16. package/dist/cjs/generated/factories/DNSRegistrar__factory.js +2 -2
  17. package/dist/cjs/generated/factories/DNSSECImpl__factory.js +2 -2
  18. package/dist/cjs/generated/factories/DefaultReverseResolver__factory.js +2 -2
  19. package/dist/cjs/generated/factories/ENSRegistry__factory.js +2 -2
  20. package/dist/cjs/generated/factories/ETHRegistrarController__factory.js +8 -57
  21. package/dist/cjs/generated/factories/Multicall__factory.js +2 -2
  22. package/dist/cjs/generated/factories/NameWrapper__factory.js +92 -71
  23. package/dist/cjs/generated/factories/P256SHA256Algorithm__factory.js +2 -2
  24. package/dist/cjs/generated/factories/PublicResolver__factory.js +85 -2
  25. package/dist/cjs/generated/factories/RSASHA1Algorithm__factory.js +2 -2
  26. package/dist/cjs/generated/factories/RSASHA256Algorithm__factory.js +2 -2
  27. package/dist/cjs/generated/factories/ReverseRegistrar__factory.js +2 -2
  28. package/dist/cjs/generated/factories/Root__factory.js +2 -2
  29. package/dist/cjs/generated/factories/SHA1Digest__factory.js +2 -2
  30. package/dist/cjs/generated/factories/SHA1NSEC3Digest__factory.js +2 -2
  31. package/dist/cjs/generated/factories/SHA256Digest__factory.js +2 -2
  32. package/dist/cjs/generated/factories/StaticMetadataService__factory.js +2 -2
  33. package/dist/cjs/generated/factories/TLDPublicSuffixList__factory.js +2 -2
  34. package/dist/cjs/generated/factories/UniversalResolver__factory.js +69 -4
  35. package/dist/cjs/index.js +6 -4
  36. package/dist/cjs/utils/ccip.js +3 -3
  37. package/dist/cjs/utils/consts.js +3 -1
  38. package/dist/cjs/utils/fuses.js +218 -53
  39. package/dist/cjs/utils/hexEncodedName.js +2 -0
  40. package/dist/cjs/utils/labels.js +14 -8
  41. package/dist/cjs/utils/normalise.js +2 -2
  42. package/dist/cjs/utils/recordHelpers.js +4 -3
  43. package/dist/cjs/utils/registerHelpers.js +11 -25
  44. package/dist/cjs/utils/subgraph-types.js +16 -0
  45. package/dist/cjs/utils/wrapper.js +3 -3
  46. package/dist/esm/contracts/getContractAddress.mjs +4 -4
  47. package/dist/esm/functions/commitName.mjs +2 -3
  48. package/dist/esm/functions/createSubname.mjs +2 -2
  49. package/dist/esm/functions/getDecryptedName.mjs +96 -0
  50. package/dist/esm/functions/getHistory.mjs +14 -7
  51. package/dist/esm/functions/getNames.mjs +10 -6
  52. package/dist/esm/functions/getOwner.mjs +26 -13
  53. package/dist/esm/functions/getPrice.mjs +2 -2
  54. package/dist/esm/functions/getProfile.mjs +10 -4
  55. package/dist/esm/functions/getWrapperData.mjs +4 -5
  56. package/dist/esm/functions/renewNames.mjs +13 -20
  57. package/dist/esm/functions/setFuses.mjs +30 -0
  58. package/dist/esm/functions/wrapName.mjs +9 -19
  59. package/dist/esm/generated/factories/BaseRegistrarImplementation__factory.mjs +1 -1
  60. package/dist/esm/generated/factories/BulkRenewal__factory.mjs +1 -1
  61. package/dist/esm/generated/factories/DNSRegistrar__factory.mjs +1 -1
  62. package/dist/esm/generated/factories/DNSSECImpl__factory.mjs +1 -1
  63. package/dist/esm/generated/factories/DefaultReverseResolver__factory.mjs +1 -1
  64. package/dist/esm/generated/factories/ENSRegistry__factory.mjs +1 -1
  65. package/dist/esm/generated/factories/ETHRegistrarController__factory.mjs +7 -56
  66. package/dist/esm/generated/factories/Multicall__factory.mjs +1 -1
  67. package/dist/esm/generated/factories/NameWrapper__factory.mjs +91 -70
  68. package/dist/esm/generated/factories/P256SHA256Algorithm__factory.mjs +1 -1
  69. package/dist/esm/generated/factories/PublicResolver__factory.mjs +84 -1
  70. package/dist/esm/generated/factories/RSASHA1Algorithm__factory.mjs +1 -1
  71. package/dist/esm/generated/factories/RSASHA256Algorithm__factory.mjs +1 -1
  72. package/dist/esm/generated/factories/ReverseRegistrar__factory.mjs +1 -1
  73. package/dist/esm/generated/factories/Root__factory.mjs +1 -1
  74. package/dist/esm/generated/factories/SHA1Digest__factory.mjs +1 -1
  75. package/dist/esm/generated/factories/SHA1NSEC3Digest__factory.mjs +1 -1
  76. package/dist/esm/generated/factories/SHA256Digest__factory.mjs +1 -1
  77. package/dist/esm/generated/factories/StaticMetadataService__factory.mjs +1 -1
  78. package/dist/esm/generated/factories/TLDPublicSuffixList__factory.mjs +1 -1
  79. package/dist/esm/generated/factories/UniversalResolver__factory.mjs +68 -3
  80. package/dist/esm/index.mjs +6 -4
  81. package/dist/esm/utils/ccip.mjs +2 -2
  82. package/dist/esm/utils/consts.mjs +3 -1
  83. package/dist/esm/utils/fuses.mjs +218 -53
  84. package/dist/esm/utils/hexEncodedName.mjs +2 -0
  85. package/dist/esm/utils/labels.mjs +11 -8
  86. package/dist/esm/utils/normalise.mjs +1 -1
  87. package/dist/esm/utils/recordHelpers.mjs +2 -1
  88. package/dist/esm/utils/registerHelpers.mjs +10 -18
  89. package/dist/esm/utils/subgraph-types.mjs +0 -0
  90. package/dist/esm/utils/wrapper.mjs +2 -2
  91. package/dist/types/functions/commitName.d.ts +0 -1
  92. package/dist/types/functions/createSubname.d.ts +2 -2
  93. package/dist/types/functions/getDecryptedName.d.ts +9 -0
  94. package/dist/types/functions/getHistory.d.ts +1 -1
  95. package/dist/types/functions/getNames.d.ts +3 -3
  96. package/dist/types/functions/getOwner.d.ts +1 -0
  97. package/dist/types/functions/getPrice.d.ts +1 -1
  98. package/dist/types/functions/getProfile.d.ts +1 -0
  99. package/dist/types/functions/getRecords.d.ts +1 -0
  100. package/dist/types/functions/getWrapperData.d.ts +44 -5
  101. package/dist/types/functions/registerName.d.ts +1 -1
  102. package/dist/types/functions/renewNames.d.ts +5 -6
  103. package/dist/types/functions/setFuses.d.ts +7 -0
  104. package/dist/types/functions/types.d.ts +8 -4
  105. package/dist/types/functions/wrapName.d.ts +3 -3
  106. package/dist/types/generated/ETHRegistrarController.d.ts +13 -36
  107. package/dist/types/generated/NameWrapper.d.ts +97 -52
  108. package/dist/types/generated/PublicResolver.d.ts +50 -1
  109. package/dist/types/generated/UniversalResolver.d.ts +79 -32
  110. package/dist/types/generated/factories/UniversalResolver__factory.d.ts +15 -0
  111. package/dist/types/index.d.ts +60 -9
  112. package/dist/types/static.d.ts +1 -1
  113. package/dist/types/utils/consts.d.ts +1 -0
  114. package/dist/types/utils/fuses.d.ts +115 -45
  115. package/dist/types/utils/hexEncodedName.d.ts +1 -0
  116. package/dist/types/utils/labels.d.ts +2 -1
  117. package/dist/types/utils/registerHelpers.d.ts +7 -25
  118. package/dist/types/utils/subgraph-types.d.ts +284 -0
  119. package/dist/types/utils/wrapper.d.ts +1 -1
  120. package/package.json +5 -5
  121. package/src/contracts/getContractAddress.ts +4 -4
  122. package/src/functions/commitName.test.ts +0 -3
  123. package/src/functions/commitName.ts +1 -2
  124. package/src/functions/createSubname.ts +5 -6
  125. package/src/functions/getDecryptedName.test.ts +49 -0
  126. package/src/functions/getDecryptedName.ts +119 -0
  127. package/src/functions/getExpiry.ts +1 -1
  128. package/src/functions/getHistory.ts +59 -25
  129. package/src/functions/getNames.test.ts +2 -2
  130. package/src/functions/getNames.ts +26 -13
  131. package/src/functions/getOwner.test.ts +62 -3
  132. package/src/functions/getOwner.ts +33 -13
  133. package/src/functions/getPrice.ts +2 -2
  134. package/src/functions/getProfile.test.ts +7 -0
  135. package/src/functions/getProfile.ts +13 -4
  136. package/src/functions/getWrapperData.test.ts +11 -45
  137. package/src/functions/getWrapperData.ts +8 -6
  138. package/src/functions/registerName.test.ts +3 -3
  139. package/src/functions/registerName.ts +1 -1
  140. package/src/functions/renewNames.ts +18 -24
  141. package/src/functions/setFuses.test.ts +240 -0
  142. package/src/functions/setFuses.ts +44 -0
  143. package/src/functions/types.ts +8 -4
  144. package/src/functions/wrapName.test.ts +8 -7
  145. package/src/functions/wrapName.ts +11 -25
  146. package/src/generated/ETHRegistrarController.ts +12 -79
  147. package/src/generated/NameWrapper.ts +155 -99
  148. package/src/generated/PublicResolver.ts +123 -0
  149. package/src/generated/UniversalResolver.ts +157 -16
  150. package/src/generated/factories/BaseRegistrarImplementation__factory.ts +1 -1
  151. package/src/generated/factories/BulkRenewal__factory.ts +1 -1
  152. package/src/generated/factories/DNSRegistrar__factory.ts +1 -1
  153. package/src/generated/factories/DNSSECImpl__factory.ts +1 -1
  154. package/src/generated/factories/DefaultReverseResolver__factory.ts +1 -1
  155. package/src/generated/factories/ENSRegistry__factory.ts +1 -1
  156. package/src/generated/factories/ETHRegistrarController__factory.ts +7 -56
  157. package/src/generated/factories/Multicall__factory.ts +1 -1
  158. package/src/generated/factories/NameWrapper__factory.ts +91 -70
  159. package/src/generated/factories/P256SHA256Algorithm__factory.ts +1 -1
  160. package/src/generated/factories/PublicResolver__factory.ts +84 -1
  161. package/src/generated/factories/RSASHA1Algorithm__factory.ts +1 -1
  162. package/src/generated/factories/RSASHA256Algorithm__factory.ts +1 -1
  163. package/src/generated/factories/ReverseRegistrar__factory.ts +1 -1
  164. package/src/generated/factories/Root__factory.ts +1 -1
  165. package/src/generated/factories/SHA1Digest__factory.ts +1 -1
  166. package/src/generated/factories/SHA1NSEC3Digest__factory.ts +1 -1
  167. package/src/generated/factories/SHA256Digest__factory.ts +1 -1
  168. package/src/generated/factories/StaticMetadataService__factory.ts +1 -1
  169. package/src/generated/factories/TLDPublicSuffixList__factory.ts +1 -1
  170. package/src/generated/factories/UniversalResolver__factory.ts +68 -3
  171. package/src/index.ts +15 -14
  172. package/src/static.ts +1 -1
  173. package/src/utils/ccip.ts +2 -2
  174. package/src/utils/consts.ts +1 -0
  175. package/src/utils/fuses.ts +299 -102
  176. package/src/utils/hexEncodedName.ts +3 -0
  177. package/src/utils/labels.ts +13 -11
  178. package/src/utils/normalise.ts +1 -1
  179. package/src/utils/recordHelpers.ts +2 -1
  180. package/src/utils/registerHelpers.ts +14 -42
  181. package/src/utils/subgraph-types.ts +312 -0
  182. package/src/utils/wrapper.ts +2 -2
  183. package/dist/cjs/utils/generateFuseInput.js +0 -40
  184. package/dist/esm/functions/burnFuses.mjs +0 -12
  185. package/dist/esm/utils/generateFuseInput.mjs +0 -15
  186. package/dist/types/functions/burnFuses.d.ts +0 -3
  187. package/dist/types/utils/generateFuseInput.d.ts +0 -3
  188. package/src/functions/burnFuses.test.ts +0 -148
  189. package/src/functions/burnFuses.ts +0 -16
  190. package/src/utils/generateFuseInput.ts +0 -13
@@ -1,39 +1,33 @@
1
- import { BigNumber, BigNumberish } from '@ethersproject/bignumber/lib/bignumber'
1
+ import { BigNumber, BigNumberish } from '@ethersproject/bignumber'
2
2
  import { ENSArgs } from '..'
3
- import { FuseProps, validateFuses } from '../utils/fuses'
4
- import { MAX_INT_64 } from '../utils/registerHelpers'
3
+ import { MAX_INT_64 } from '../utils/consts'
4
+ import { labelhash } from '../utils/labels'
5
+ import { namehash } from '../utils/normalise'
5
6
 
6
7
  type BaseProps = {
7
8
  duration: number
8
9
  value: BigNumber
9
10
  }
10
11
 
11
- export async function renewNameWithData(
12
+ type WrappedProps = {
13
+ duration: BigNumberish
14
+ }
15
+
16
+ export async function extendWrappedName(
12
17
  { contracts }: ENSArgs<'contracts'>,
13
18
  name: string,
14
- {
15
- duration,
16
- value,
17
- fuses,
18
- wrapperExpiry = MAX_INT_64,
19
- }: BaseProps & {
20
- fuses?: FuseProps
21
- wrapperExpiry?: BigNumberish
22
- },
19
+ options?: WrappedProps,
23
20
  ) {
21
+ const expiry = options?.duration || MAX_INT_64
24
22
  const labels = name.split('.')
25
- if (labels.length !== 2 || labels[1] !== 'eth') {
26
- throw new Error('Currently only .eth TLD renewals are supported')
27
- }
23
+ const labelHash = labelhash(labels.shift()!)
24
+ const parentNode = namehash(labels.join('.'))
28
25
 
29
- const encodedFuses = fuses ? validateFuses(fuses) : 0
30
- const controller = await contracts!.getEthRegistrarController()
31
- return controller.populateTransaction.renewWithFuses(
32
- labels[0],
33
- duration,
34
- encodedFuses,
35
- wrapperExpiry,
36
- { value },
26
+ const nameWrapper = await contracts!.getNameWrapper()
27
+ return nameWrapper.populateTransaction.extendExpiry(
28
+ parentNode,
29
+ labelHash,
30
+ expiry,
37
31
  )
38
32
  }
39
33
 
@@ -0,0 +1,240 @@
1
+ import { ethers } from 'ethers'
2
+ import { ENS } from '../index'
3
+ import setup from '../tests/setup'
4
+ import { unnamedUserSettableFuses, userSettableFuseEnum } from '../utils/fuses'
5
+ import { namehash } from '../utils/normalise'
6
+
7
+ let ensInstance: ENS
8
+ let revert: Awaited<ReturnType<typeof setup>>['revert']
9
+ let provider: ethers.providers.JsonRpcProvider
10
+ let accounts: string[]
11
+
12
+ beforeAll(async () => {
13
+ ;({ ensInstance, revert, provider } = await setup())
14
+ accounts = await provider.listAccounts()
15
+ })
16
+
17
+ afterAll(async () => {
18
+ await revert()
19
+ })
20
+
21
+ const checkFuses = (
22
+ fuses: number,
23
+ expected: (keyof typeof userSettableFuseEnum)[],
24
+ ) => {
25
+ // eslint-disable-next-line guard-for-in
26
+ for (const fuse in userSettableFuseEnum) {
27
+ const active =
28
+ (fuses &
29
+ userSettableFuseEnum[fuse as keyof typeof userSettableFuseEnum]) >
30
+ 0
31
+ if (expected.includes(fuse as keyof typeof userSettableFuseEnum)) {
32
+ try {
33
+ expect(active).toBeTruthy()
34
+ } catch {
35
+ throw new Error(`${fuse} should be true but is false`)
36
+ }
37
+ } else if (active) {
38
+ try {
39
+ expect(active).toBeFalsy()
40
+ } catch {
41
+ throw new Error(`${fuse} should be false but is true`)
42
+ }
43
+ }
44
+ }
45
+ }
46
+
47
+ const checkUnnamedFuses = (
48
+ fuses: number,
49
+ expected: (keyof typeof unnamedUserSettableFuses)[],
50
+ ) => {
51
+ // eslint-disable-next-line guard-for-in
52
+ for (const fuse of unnamedUserSettableFuses) {
53
+ const active = (fuses & fuse) > 0
54
+ if (expected.includes(fuse as keyof typeof unnamedUserSettableFuses)) {
55
+ try {
56
+ expect(active).toBeTruthy()
57
+ } catch {
58
+ throw new Error(`${fuse} should be true but is false`)
59
+ }
60
+ } else if (active) {
61
+ try {
62
+ expect(active).toBeFalsy()
63
+ } catch {
64
+ throw new Error(`${fuse} should be false but is true`)
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ describe('setFuses', () => {
71
+ beforeEach(async () => {
72
+ await revert()
73
+ })
74
+ describe('Array', () => {
75
+ it('should return a setFuses transaction from a named fuse array and succeed', async () => {
76
+ const tx = await ensInstance.setFuses('wrapped.eth', {
77
+ named: ['CANNOT_UNWRAP', 'CANNOT_CREATE_SUBDOMAIN', 'CANNOT_SET_TTL'],
78
+ addressOrIndex: accounts[1],
79
+ })
80
+ expect(tx).toBeTruthy()
81
+ await tx.wait()
82
+
83
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
84
+ const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth'))
85
+ checkFuses(fuses, [
86
+ 'CANNOT_UNWRAP',
87
+ 'CANNOT_CREATE_SUBDOMAIN',
88
+ 'CANNOT_SET_TTL',
89
+ 'PARENT_CANNOT_CONTROL',
90
+ ])
91
+ })
92
+ it('should return a setFuses transaction from an unnamed fuse array and succeed', async () => {
93
+ const tx0 = await ensInstance.setFuses('wrapped.eth', {
94
+ named: ['CANNOT_UNWRAP'],
95
+ addressOrIndex: accounts[1],
96
+ })
97
+ expect(tx0).toBeTruthy()
98
+ await tx0.wait()
99
+
100
+ const tx = await ensInstance.setFuses('wrapped.eth', {
101
+ unnamed: [128, 256, 512],
102
+ addressOrIndex: accounts[1],
103
+ })
104
+ expect(tx).toBeTruthy()
105
+ await tx.wait()
106
+
107
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
108
+ const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth'))
109
+ checkUnnamedFuses(fuses, [128, 256, 512])
110
+ })
111
+ it('should return a setFuses transaction from both an unnamed and named fuse array and succeed', async () => {
112
+ const tx = await ensInstance.setFuses('wrapped.eth', {
113
+ named: ['CANNOT_UNWRAP', 'CANNOT_CREATE_SUBDOMAIN', 'CANNOT_SET_TTL'],
114
+ unnamed: [128, 256, 512],
115
+ addressOrIndex: accounts[1],
116
+ })
117
+ expect(tx).toBeTruthy()
118
+ await tx.wait()
119
+
120
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
121
+ const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth'))
122
+ checkFuses(fuses, [
123
+ 'CANNOT_UNWRAP',
124
+ 'CANNOT_CREATE_SUBDOMAIN',
125
+ 'CANNOT_SET_TTL',
126
+ 'PARENT_CANNOT_CONTROL',
127
+ ])
128
+ checkUnnamedFuses(fuses, [128, 256, 512])
129
+ })
130
+ it('should throw an error when trying to burn a named fuse in an unnamed fuse array', async () => {
131
+ try {
132
+ await ensInstance.setFuses('wrapped.eth', {
133
+ unnamed: [32] as any,
134
+ addressOrIndex: accounts[1],
135
+ })
136
+ expect(false).toBeTruthy()
137
+ } catch (e: any) {
138
+ expect(e.message).toBe(
139
+ '32 is not a valid unnamed fuse. If you are trying to set a named fuse, use the named property.',
140
+ )
141
+ }
142
+ })
143
+ it('should throw an error when trying to burn an unnamed fuse in a named fuse array', async () => {
144
+ try {
145
+ await ensInstance.setFuses('wrapped.eth', {
146
+ named: ['COOL_SWAG_FUSE'] as any,
147
+ })
148
+ expect(false).toBeTruthy()
149
+ } catch (e: any) {
150
+ expect(e.message).toBe('COOL_SWAG_FUSE is not a valid named fuse.')
151
+ }
152
+ })
153
+ })
154
+ describe('Number', () => {
155
+ it('should return a setFuses transaction from a number and succeed', async () => {
156
+ const tx = await ensInstance.setFuses('wrapped.eth', {
157
+ number: 49,
158
+ addressOrIndex: accounts[1],
159
+ })
160
+ expect(tx).toBeTruthy()
161
+ await tx.wait()
162
+
163
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
164
+ const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth'))
165
+ checkFuses(fuses, [
166
+ 'CANNOT_UNWRAP',
167
+ 'CANNOT_CREATE_SUBDOMAIN',
168
+ 'CANNOT_SET_TTL',
169
+ 'PARENT_CANNOT_CONTROL',
170
+ ])
171
+ })
172
+ it('should throw an error if the number is too high', async () => {
173
+ try {
174
+ await ensInstance.setFuses('wrapped.eth', {
175
+ number: 4294967297,
176
+ addressOrIndex: accounts[1],
177
+ })
178
+ expect(false).toBeTruthy()
179
+ } catch (e: any) {
180
+ expect(e.message).toBe(
181
+ 'Fuse number must be limited to uint32, 4294967297 was too high.',
182
+ )
183
+ }
184
+ })
185
+ it('should throw an error if the number is too low', async () => {
186
+ try {
187
+ await ensInstance.setFuses('wrapped.eth', {
188
+ number: -1,
189
+ addressOrIndex: accounts[1],
190
+ })
191
+ expect(false).toBeTruthy()
192
+ } catch (e: any) {
193
+ expect(e.message).toBe(
194
+ 'Fuse number must be limited to uint32, -1 was too low.',
195
+ )
196
+ }
197
+ })
198
+ it('should throw an error if the number is not an integer', async () => {
199
+ try {
200
+ await ensInstance.setFuses('wrapped.eth', {
201
+ number: 7.5,
202
+ })
203
+ expect(false).toBeTruthy()
204
+ } catch (e: any) {
205
+ expect(e.message).toBe('Fuse number must be an integer, 7.5 was not.')
206
+ }
207
+ })
208
+ })
209
+ })
210
+
211
+ describe('setChildFuses', () => {
212
+ it('should return a setChildFuses transaction and succeed', async () => {
213
+ const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
214
+ const setParentTx = await ensInstance.setFuses(
215
+ 'wrapped-with-subnames.eth',
216
+ {
217
+ named: ['CANNOT_UNWRAP'],
218
+ addressOrIndex: accounts[1],
219
+ },
220
+ )
221
+ expect(setParentTx).toBeTruthy()
222
+ await setParentTx.wait()
223
+
224
+ const tx = await ensInstance.setChildFuses(
225
+ 'test.wrapped-with-subnames.eth',
226
+ {
227
+ fuses: 65537,
228
+ addressOrIndex: accounts[1],
229
+ },
230
+ )
231
+ expect(tx).toBeTruthy()
232
+ await tx.wait()
233
+
234
+ const [, fuses] = await nameWrapper.getData(
235
+ namehash('test.wrapped-with-subnames.eth'),
236
+ )
237
+
238
+ checkFuses(fuses, ['CANNOT_UNWRAP', 'PARENT_CANNOT_CONTROL'])
239
+ })
240
+ })
@@ -0,0 +1,44 @@
1
+ import { ENSArgs } from '../index'
2
+ import { CombinedFuseInput, encodeFuses } from '../utils/fuses'
3
+ import { labelhash } from '../utils/labels'
4
+ import { namehash } from '../utils/normalise'
5
+
6
+ export async function setChildFuses(
7
+ { contracts, signer }: ENSArgs<'contracts' | 'signer'>,
8
+ name: string,
9
+ {
10
+ fuses,
11
+ expiry = 0,
12
+ }: {
13
+ fuses: Partial<CombinedFuseInput> | number
14
+ expiry?: number
15
+ },
16
+ ) {
17
+ const encodedFuses = encodeFuses(fuses)
18
+
19
+ const labels = name.split('.')
20
+ const labelHash = labelhash(labels.shift()!)
21
+ const parentNode = namehash(labels.join('.'))
22
+
23
+ const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer)
24
+
25
+ return nameWrapper.populateTransaction.setChildFuses(
26
+ parentNode,
27
+ labelHash,
28
+ encodedFuses,
29
+ expiry,
30
+ )
31
+ }
32
+
33
+ export default async function (
34
+ { contracts, signer }: ENSArgs<'contracts' | 'signer'>,
35
+ name: string,
36
+ props: CombinedFuseInput['child'],
37
+ ) {
38
+ const encodedFuses = encodeFuses(props, 'child')
39
+
40
+ const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer)
41
+ const hash = namehash(name)
42
+
43
+ return nameWrapper.populateTransaction.setFuses(hash, encodedFuses)
44
+ }
@@ -4,11 +4,11 @@ import type {
4
4
  resolverMulticallWrapper,
5
5
  universalWrapper,
6
6
  } from './batchWrappers'
7
- import type burnFuses from './burnFuses'
8
7
  import type commitName from './commitName'
9
8
  import type createSubname from './createSubname'
10
9
  import type deleteSubname from './deleteSubname'
11
10
  import type getAvailable from './getAvailable'
11
+ import type getDecryptedName from './getDecryptedName'
12
12
  import type getDNSOwner from './getDNSOwner'
13
13
  import type getExpiry from './getExpiry'
14
14
  import type { getHistory } from './getHistory'
@@ -36,8 +36,10 @@ import type registerName from './registerName'
36
36
  import type {
37
37
  // eslint-disable-next-line import/no-named-default
38
38
  default as renewNames,
39
- renewNameWithData,
39
+ extendWrappedName,
40
40
  } from './renewNames'
41
+ import type setFuses from './setFuses'
42
+ import type { setChildFuses } from './setFuses'
41
43
  import type setName from './setName'
42
44
  import type setRecord from './setRecord'
43
45
  import type setRecords from './setRecords'
@@ -54,11 +56,13 @@ type Function = {
54
56
  multicallWrapper: typeof multicallWrapper
55
57
  resolverMulticallWrapper: typeof resolverMulticallWrapper
56
58
  universalWrapper: typeof universalWrapper
57
- burnFuses: typeof burnFuses
59
+ setFuses: typeof setFuses
60
+ setChildFuses: typeof setChildFuses
58
61
  commitName: typeof commitName
59
62
  createSubname: typeof createSubname
60
63
  deleteSubname: typeof deleteSubname
61
64
  getAvailable: typeof getAvailable
65
+ getDecryptedName: typeof getDecryptedName
62
66
  getDNSOwner: typeof getDNSOwner
63
67
  getExpiry: typeof getExpiry
64
68
  getHistory: typeof getHistory
@@ -82,7 +86,7 @@ type Function = {
82
86
  importDNSSECName: typeof importDNSSECName
83
87
  registerName: typeof registerName
84
88
  renewNames: typeof renewNames
85
- renewNameWithData: typeof renewNameWithData
89
+ extendWrappedName: typeof extendWrappedName
86
90
  setName: typeof setName
87
91
  setRecord: typeof setRecord
88
92
  setRecords: typeof setRecords
@@ -46,15 +46,15 @@ describe('wrapName', () => {
46
46
  const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
47
47
  const [, fuses] = await nameWrapper.getData(namehash('test123.eth'))
48
48
 
49
- // parent cannot control
50
- expect(fuses).toBe(64)
49
+ expect(fuses).toBe(196608)
51
50
  })
52
51
  it('should allow initial fuses', async () => {
53
52
  const tx = await ensInstance.wrapName('test123.eth', {
54
53
  wrappedOwner: accounts[2],
55
54
  fuseOptions: {
56
- CANNOT_UNWRAP: true,
57
- CANNOT_SET_TTL: true,
55
+ child: {
56
+ named: ['CANNOT_UNWRAP', 'CANNOT_SET_TTL'],
57
+ },
58
58
  },
59
59
  addressOrIndex: 1,
60
60
  })
@@ -63,7 +63,7 @@ describe('wrapName', () => {
63
63
 
64
64
  const nameWrapper = await ensInstance.contracts!.getNameWrapper()!
65
65
  const [, fuses] = await nameWrapper.getData(namehash('test123.eth'))
66
- expect(fuses).toBe(81)
66
+ expect(fuses).toBe(196625)
67
67
  })
68
68
  it('should allow an initial resolver address', async () => {
69
69
  const tx = await ensInstance.wrapName('test123.eth', {
@@ -139,8 +139,9 @@ describe('wrapName', () => {
139
139
  ensInstance.wrapName('test.with-subnames.eth', {
140
140
  wrappedOwner: accounts[2],
141
141
  fuseOptions: {
142
- cannotUnwrap: true,
143
- cannotSetTtl: true,
142
+ child: {
143
+ named: ['CANNOT_UNWRAP', 'CANNOT_SET_TTL'],
144
+ },
144
145
  },
145
146
  addressOrIndex: 1,
146
147
  }),
@@ -1,19 +1,16 @@
1
- import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder'
1
+ import { defaultAbiCoder } from '@ethersproject/abi'
2
2
  import { Signer } from '@ethersproject/abstract-signer'
3
- import { BigNumber } from '@ethersproject/bignumber/lib/bignumber'
4
3
  import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
5
4
  import { ENSArgs } from '..'
6
- import { FuseOptions } from '../utils/fuses'
7
- import generateFuseInput from '../utils/generateFuseInput'
5
+ import { CombinedFuseInput, encodeFuses } from '../utils/fuses'
8
6
  import { hexEncodeName } from '../utils/hexEncodedName'
9
- import { Expiry, makeExpiry, wrappedLabelLengthCheck } from '../utils/wrapper'
7
+ import { Expiry, wrappedLabelLengthCheck } from '../utils/wrapper'
10
8
 
11
9
  async function wrapETH(
12
10
  { contracts }: ENSArgs<'contracts'>,
13
11
  labels: string[],
14
12
  wrappedOwner: string,
15
- expiry: BigNumber,
16
- decodedFuses: string,
13
+ decodedFuses: number,
17
14
  resolverAddress: string,
18
15
  signer: Signer,
19
16
  address: string,
@@ -24,8 +21,8 @@ async function wrapETH(
24
21
  const labelhash = solidityKeccak256(['string'], [labels[0]])
25
22
 
26
23
  const data = defaultAbiCoder.encode(
27
- ['string', 'address', 'uint32', 'uint64', 'address'],
28
- [labels[0], wrappedOwner, decodedFuses, expiry, resolverAddress],
24
+ ['string', 'address', 'uint16', 'address'],
25
+ [labels[0], wrappedOwner, decodedFuses, resolverAddress],
29
26
  )
30
27
 
31
28
  return baseRegistrar.populateTransaction[
@@ -63,11 +60,7 @@ async function wrapOther(
63
60
  }
64
61
 
65
62
  export default async function (
66
- {
67
- contracts,
68
- signer,
69
- getExpiry,
70
- }: ENSArgs<'contracts' | 'signer' | 'getExpiry'>,
63
+ { contracts, signer }: ENSArgs<'contracts' | 'signer'>,
71
64
  name: string,
72
65
  {
73
66
  wrappedOwner,
@@ -76,14 +69,14 @@ export default async function (
76
69
  resolverAddress,
77
70
  }: {
78
71
  wrappedOwner: string
79
- fuseOptions?: FuseOptions | string | number
72
+ fuseOptions?: Partial<CombinedFuseInput> | number
80
73
  expiry?: Expiry
81
74
  resolverAddress?: string
82
75
  },
83
76
  ) {
84
77
  const address = await signer.getAddress()
85
78
 
86
- let decodedFuses: string
79
+ let decodedFuses: number
87
80
 
88
81
  const publicResolver = await contracts?.getPublicResolver()!
89
82
  if (!resolverAddress) resolverAddress = publicResolver.address
@@ -94,19 +87,15 @@ export default async function (
94
87
  if (labels.length === 2 && labels[1] === 'eth') {
95
88
  switch (typeof fuseOptions) {
96
89
  case 'object': {
97
- decodedFuses = generateFuseInput(fuseOptions)
90
+ decodedFuses = encodeFuses(fuseOptions)
98
91
  break
99
92
  }
100
93
  case 'number': {
101
- decodedFuses = fuseOptions.toString(16)
102
- break
103
- }
104
- case 'string': {
105
94
  decodedFuses = fuseOptions
106
95
  break
107
96
  }
108
97
  case 'undefined': {
109
- decodedFuses = '0'
98
+ decodedFuses = 0
110
99
  break
111
100
  }
112
101
  default: {
@@ -114,13 +103,10 @@ export default async function (
114
103
  }
115
104
  }
116
105
 
117
- const expiryToUse = await makeExpiry({ getExpiry }, name, expiry)
118
-
119
106
  return wrapETH(
120
107
  { contracts },
121
108
  labels,
122
109
  wrappedOwner,
123
- expiryToUse,
124
110
  decodedFuses,
125
111
  resolverAddress,
126
112
  signer,