@ensdomains/ensjs 3.0.0-alpha.46 → 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.
@@ -23,17 +23,17 @@ __export(deleteSubname_exports, {
23
23
  module.exports = __toCommonJS(deleteSubname_exports);
24
24
  var import_solidity = require("@ethersproject/solidity");
25
25
  var import_normalise = require("../utils/normalise");
26
- async function deleteSubname_default({ contracts, signer }, name, { contract }) {
26
+ async function deleteSubname_default({ contracts, signer }, name, { contract, ...args }) {
27
27
  const labels = name.split(".");
28
28
  if (labels.length < 3) {
29
29
  throw new Error(`${name} is not a valid subname`);
30
30
  }
31
- const label = labels.shift();
32
- const labelhash = (0, import_solidity.keccak256)(["string"], [label]);
33
- const parentNodehash = (0, import_normalise.namehash)(labels.join("."));
34
31
  switch (contract) {
35
32
  case "registry": {
36
33
  const registry = (await contracts.getRegistry()).connect(signer);
34
+ const label = labels.shift();
35
+ const labelhash = (0, import_solidity.keccak256)(["string"], [label]);
36
+ const parentNodehash = (0, import_normalise.namehash)(labels.join("."));
37
37
  return registry.populateTransaction.setSubnodeRecord(
38
38
  parentNodehash,
39
39
  labelhash,
@@ -44,12 +44,22 @@ async function deleteSubname_default({ contracts, signer }, name, { contract })
44
44
  }
45
45
  case "nameWrapper": {
46
46
  const nameWrapper = (await contracts.getNameWrapper()).connect(signer);
47
- return nameWrapper.populateTransaction.setSubnodeRecord(
47
+ const { method } = args;
48
+ if (method === "setRecord") {
49
+ const node = (0, import_normalise.namehash)(name);
50
+ return nameWrapper.populateTransaction.setRecord(
51
+ node,
52
+ "0x0000000000000000000000000000000000000000",
53
+ "0x0000000000000000000000000000000000000000",
54
+ 0
55
+ );
56
+ }
57
+ const label = labels.shift();
58
+ const parentNodehash = (0, import_normalise.namehash)(labels.join("."));
59
+ return nameWrapper.populateTransaction.setSubnodeOwner(
48
60
  parentNodehash,
49
61
  label,
50
62
  "0x0000000000000000000000000000000000000000",
51
- "0x0000000000000000000000000000000000000000",
52
- 0,
53
63
  0,
54
64
  0
55
65
  );
@@ -24,11 +24,7 @@ module.exports = __toCommonJS(transferSubname_exports);
24
24
  var import_solidity = require("@ethersproject/solidity");
25
25
  var import_normalise = require("../utils/normalise");
26
26
  var import_wrapper = require("../utils/wrapper");
27
- async function transferSubname_default({
28
- contracts,
29
- signer,
30
- getExpiry
31
- }, name, { contract, owner, resolverAddress, ...wrapperArgs }) {
27
+ async function transferSubname_default({ contracts, signer }, name, { contract, owner, resolverAddress, ...wrapperArgs }) {
32
28
  const labels = name.split(".");
33
29
  const label = labels.shift();
34
30
  const labelhash = (0, import_solidity.keccak256)(["string"], [label]);
@@ -44,10 +40,9 @@ async function transferSubname_default({
44
40
  }
45
41
  case "nameWrapper": {
46
42
  const nameWrapper = (await contracts.getNameWrapper()).connect(signer);
47
- const expiry = await (0, import_wrapper.makeExpiry)(
48
- { getExpiry },
49
- labels.join("."),
50
- "expiry" in wrapperArgs ? wrapperArgs.expiry : void 0
43
+ const expiry = (0, import_wrapper.expiryToBigNumber)(
44
+ wrapperArgs.expiry,
45
+ 0
51
46
  );
52
47
  return nameWrapper.populateTransaction.setSubnodeOwner(
53
48
  parentNodehash,
package/dist/cjs/index.js CHANGED
@@ -316,7 +316,7 @@ class ENS {
316
316
  this.importDNSSECName = this.generateWriteFunction("importDNSSECName", ["contracts", "provider", "signer"]);
317
317
  this.createSubname = this.generateWriteFunction("createSubname", ["contracts", "getExpiry"]);
318
318
  this.deleteSubname = this.generateWriteFunction("deleteSubname", ["contracts"]);
319
- this.transferSubname = this.generateWriteFunction("transferSubname", ["contracts", "getExpiry"]);
319
+ this.transferSubname = this.generateWriteFunction("transferSubname", ["contracts"]);
320
320
  this.commitName = this.generateWriteFunction(
321
321
  "commitName",
322
322
  ["contracts"]
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var registry_exports = {};
20
+ __export(registry_exports, {
21
+ makeResolver: () => makeResolver
22
+ });
23
+ module.exports = __toCommonJS(registry_exports);
24
+ var import_normalise = require("./normalise");
25
+ const makeResolver = async ({ contracts }, name, resolver) => {
26
+ if (resolver)
27
+ return resolver;
28
+ const registry = await contracts.getRegistry();
29
+ const node = (0, import_normalise.namehash)(name);
30
+ const _resolver = await registry.resolver(node);
31
+ return _resolver;
32
+ };
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var wrapper_exports = {};
20
20
  __export(wrapper_exports, {
21
21
  MAX_EXPIRY: () => MAX_EXPIRY,
22
+ expiryToBigNumber: () => expiryToBigNumber,
22
23
  makeExpiry: () => makeExpiry,
23
24
  wrappedLabelLengthCheck: () => wrappedLabelLengthCheck
24
25
  });
@@ -26,16 +27,20 @@ module.exports = __toCommonJS(wrapper_exports);
26
27
  var import_bignumber = require("@ethersproject/bignumber");
27
28
  var import_strings = require("@ethersproject/strings");
28
29
  const MAX_EXPIRY = import_bignumber.BigNumber.from(2).pow(64).sub(1);
29
- const makeExpiry = async ({ getExpiry }, name, expiry) => {
30
- if (expiry) {
31
- if (expiry instanceof Date) {
32
- return import_bignumber.BigNumber.from(expiry.getTime() / 1e3);
33
- }
34
- if (expiry instanceof import_bignumber.BigNumber) {
35
- return expiry;
36
- }
37
- return import_bignumber.BigNumber.from(expiry);
30
+ const expiryToBigNumber = (expiry, defaultValue = 0) => {
31
+ if (!expiry)
32
+ return import_bignumber.BigNumber.from(defaultValue);
33
+ if (expiry instanceof Date) {
34
+ return import_bignumber.BigNumber.from(expiry.getTime() / 1e3);
35
+ }
36
+ if (expiry instanceof import_bignumber.BigNumber) {
37
+ return expiry;
38
38
  }
39
+ return import_bignumber.BigNumber.from(expiry);
40
+ };
41
+ const makeExpiry = async ({ getExpiry }, name, expiry) => {
42
+ if (expiry)
43
+ return expiryToBigNumber(expiry);
39
44
  if (name.endsWith(".eth")) {
40
45
  const expResponse = await getExpiry(name);
41
46
  if (!(expResponse == null ? void 0 : expResponse.expiry))
@@ -1,17 +1,17 @@
1
1
  // src/functions/deleteSubname.ts
2
2
  import { keccak256 as solidityKeccak256 } from "@ethersproject/solidity";
3
3
  import { namehash } from "../utils/normalise.mjs";
4
- async function deleteSubname_default({ contracts, signer }, name, { contract }) {
4
+ async function deleteSubname_default({ contracts, signer }, name, { contract, ...args }) {
5
5
  const labels = name.split(".");
6
6
  if (labels.length < 3) {
7
7
  throw new Error(`${name} is not a valid subname`);
8
8
  }
9
- const label = labels.shift();
10
- const labelhash = solidityKeccak256(["string"], [label]);
11
- const parentNodehash = namehash(labels.join("."));
12
9
  switch (contract) {
13
10
  case "registry": {
14
11
  const registry = (await contracts.getRegistry()).connect(signer);
12
+ const label = labels.shift();
13
+ const labelhash = solidityKeccak256(["string"], [label]);
14
+ const parentNodehash = namehash(labels.join("."));
15
15
  return registry.populateTransaction.setSubnodeRecord(
16
16
  parentNodehash,
17
17
  labelhash,
@@ -22,12 +22,22 @@ async function deleteSubname_default({ contracts, signer }, name, { contract })
22
22
  }
23
23
  case "nameWrapper": {
24
24
  const nameWrapper = (await contracts.getNameWrapper()).connect(signer);
25
- return nameWrapper.populateTransaction.setSubnodeRecord(
25
+ const { method } = args;
26
+ if (method === "setRecord") {
27
+ const node = namehash(name);
28
+ return nameWrapper.populateTransaction.setRecord(
29
+ node,
30
+ "0x0000000000000000000000000000000000000000",
31
+ "0x0000000000000000000000000000000000000000",
32
+ 0
33
+ );
34
+ }
35
+ const label = labels.shift();
36
+ const parentNodehash = namehash(labels.join("."));
37
+ return nameWrapper.populateTransaction.setSubnodeOwner(
26
38
  parentNodehash,
27
39
  label,
28
40
  "0x0000000000000000000000000000000000000000",
29
- "0x0000000000000000000000000000000000000000",
30
- 0,
31
41
  0,
32
42
  0
33
43
  );
@@ -1,12 +1,8 @@
1
1
  // src/functions/transferSubname.ts
2
2
  import { keccak256 as solidityKeccak256 } from "@ethersproject/solidity";
3
3
  import { namehash } from "../utils/normalise.mjs";
4
- import { makeExpiry } from "../utils/wrapper.mjs";
5
- async function transferSubname_default({
6
- contracts,
7
- signer,
8
- getExpiry
9
- }, name, { contract, owner, resolverAddress, ...wrapperArgs }) {
4
+ import { expiryToBigNumber } from "../utils/wrapper.mjs";
5
+ async function transferSubname_default({ contracts, signer }, name, { contract, owner, resolverAddress, ...wrapperArgs }) {
10
6
  const labels = name.split(".");
11
7
  const label = labels.shift();
12
8
  const labelhash = solidityKeccak256(["string"], [label]);
@@ -22,10 +18,9 @@ async function transferSubname_default({
22
18
  }
23
19
  case "nameWrapper": {
24
20
  const nameWrapper = (await contracts.getNameWrapper()).connect(signer);
25
- const expiry = await makeExpiry(
26
- { getExpiry },
27
- labels.join("."),
28
- "expiry" in wrapperArgs ? wrapperArgs.expiry : void 0
21
+ const expiry = expiryToBigNumber(
22
+ wrapperArgs.expiry,
23
+ 0
29
24
  );
30
25
  return nameWrapper.populateTransaction.setSubnodeOwner(
31
26
  parentNodehash,
@@ -293,7 +293,7 @@ var ENS = class {
293
293
  importDNSSECName = this.generateWriteFunction("importDNSSECName", ["contracts", "provider", "signer"]);
294
294
  createSubname = this.generateWriteFunction("createSubname", ["contracts", "getExpiry"]);
295
295
  deleteSubname = this.generateWriteFunction("deleteSubname", ["contracts"]);
296
- transferSubname = this.generateWriteFunction("transferSubname", ["contracts", "getExpiry"]);
296
+ transferSubname = this.generateWriteFunction("transferSubname", ["contracts"]);
297
297
  commitName = this.generateWriteFunction(
298
298
  "commitName",
299
299
  ["contracts"]
@@ -0,0 +1,13 @@
1
+ // src/utils/registry.ts
2
+ import { namehash } from "./normalise.mjs";
3
+ var makeResolver = async ({ contracts }, name, resolver) => {
4
+ if (resolver)
5
+ return resolver;
6
+ const registry = await contracts.getRegistry();
7
+ const node = namehash(name);
8
+ const _resolver = await registry.resolver(node);
9
+ return _resolver;
10
+ };
11
+ export {
12
+ makeResolver
13
+ };
@@ -2,16 +2,20 @@
2
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
- var makeExpiry = async ({ getExpiry }, name, expiry) => {
6
- if (expiry) {
7
- if (expiry instanceof Date) {
8
- return BigNumber.from(expiry.getTime() / 1e3);
9
- }
10
- if (expiry instanceof BigNumber) {
11
- return expiry;
12
- }
13
- return BigNumber.from(expiry);
5
+ var expiryToBigNumber = (expiry, defaultValue = 0) => {
6
+ if (!expiry)
7
+ return BigNumber.from(defaultValue);
8
+ if (expiry instanceof Date) {
9
+ return BigNumber.from(expiry.getTime() / 1e3);
10
+ }
11
+ if (expiry instanceof BigNumber) {
12
+ return expiry;
14
13
  }
14
+ return BigNumber.from(expiry);
15
+ };
16
+ var makeExpiry = async ({ getExpiry }, name, expiry) => {
17
+ if (expiry)
18
+ return expiryToBigNumber(expiry);
15
19
  if (name.endsWith(".eth")) {
16
20
  const expResponse = await getExpiry(name);
17
21
  if (!expResponse?.expiry)
@@ -27,6 +31,7 @@ var wrappedLabelLengthCheck = (label) => {
27
31
  };
28
32
  export {
29
33
  MAX_EXPIRY,
34
+ expiryToBigNumber,
30
35
  makeExpiry,
31
36
  wrappedLabelLengthCheck
32
37
  };
@@ -1,6 +1,12 @@
1
1
  import { ENSArgs } from '..';
2
- declare type Args = {
2
+ declare type BaseArgs = {
3
3
  contract: 'registry' | 'nameWrapper';
4
+ method?: 'setRecord' | 'setSubnodeOwner';
4
5
  };
5
- export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer' | 'getExpiry'>, name: string, { contract }: Args): Promise<import("ethers").PopulatedTransaction>;
6
+ declare type NameWrapperArgs = {
7
+ contract: 'nameWrapper';
8
+ method: 'setRecord' | 'setSubnodeOwner';
9
+ };
10
+ declare type Args = BaseArgs | NameWrapperArgs;
11
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { contract, ...args }: Args): Promise<import("ethers").PopulatedTransaction>;
6
12
  export {};
@@ -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 {};
@@ -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.46",
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
 
@@ -172,10 +173,19 @@ describe('getNames', () => {
172
173
  type: 'wrappedOwner',
173
174
  page: 0,
174
175
  })
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
+
175
185
  // length of page one should be all the names on 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
176
186
  // minus 1 for the PCC expired name.
177
187
  // the result here implies that the PCC expired name is not returned
178
- expect(pageOne).toHaveLength(4)
188
+ expect(pageOne).toHaveLength(nameCout - 1)
179
189
  })
180
190
  describe('orderBy', () => {
181
191
  describe('registrations', () => {