@ensdomains/ensjs 3.0.0-alpha.31 → 3.0.0-alpha.33

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.
@@ -86,8 +86,23 @@ const raw = async ({ contracts, multicallWrapper }, name, contract) => {
86
86
  }
87
87
  return multicallWrapper.raw(data);
88
88
  };
89
+ const registrantQuery = `
90
+ query GetRegistrant($namehash: String!) {
91
+ domain(id: $namehash) {
92
+ registration {
93
+ registrant {
94
+ id
95
+ }
96
+ }
97
+ }
98
+ }
99
+ `;
89
100
  const singleContractOwnerDecode = (data) => import_ethers.ethers.utils.defaultAbiCoder.decode(["address"], data)[0];
90
- const decode = async ({ contracts, multicallWrapper }, data, name, contract) => {
101
+ const decode = async ({
102
+ contracts,
103
+ multicallWrapper,
104
+ gqlInstance
105
+ }, data, name, contract) => {
91
106
  if (!data)
92
107
  return;
93
108
  const labels = name.split(".");
@@ -116,8 +131,17 @@ const decode = async ({ contracts, multicallWrapper }, data, name, contract) =>
116
131
  );
117
132
  const registryOwner = decodedData[0][0];
118
133
  const nameWrapperOwner = decodedData[1][0];
119
- const registrarOwner = decodedData[2]?.[0];
134
+ let registrarOwner = decodedData[2]?.[0];
120
135
  if (labels[labels.length - 1] === "eth") {
136
+ if (!registrarOwner && labels.length === 2) {
137
+ const graphRegistrantResult = await gqlInstance?.request(
138
+ registrantQuery,
139
+ {
140
+ namehash: (0, import_normalise.namehash)(name)
141
+ }
142
+ );
143
+ registrarOwner = graphRegistrantResult.domain?.registration?.registrant?.id;
144
+ }
121
145
  if (registrarOwner === nameWrapper.address) {
122
146
  return {
123
147
  owner: nameWrapperOwner,
@@ -131,7 +155,14 @@ const decode = async ({ contracts, multicallWrapper }, data, name, contract) =>
131
155
  ownershipLevel: "registrar"
132
156
  };
133
157
  }
134
- if (labels.length > 2 && import_ethers.ethers.utils.hexStripZeros(registryOwner) !== "0x") {
158
+ if (import_ethers.ethers.utils.hexStripZeros(registryOwner) !== "0x") {
159
+ if (labels.length === 2) {
160
+ return {
161
+ registrant: void 0,
162
+ owner: registryOwner,
163
+ ownershipLevel: "registrar"
164
+ };
165
+ }
135
166
  if (registryOwner === nameWrapper.address && nameWrapperOwner && import_ethers.ethers.utils.hexStripZeros(nameWrapperOwner) !== "0x") {
136
167
  return {
137
168
  owner: nameWrapperOwner,
package/dist/cjs/index.js CHANGED
@@ -234,7 +234,7 @@ class ENS {
234
234
  );
235
235
  getOwner = this.generateRawFunction(
236
236
  "initialGetters",
237
- ["contracts", "multicallWrapper"],
237
+ ["contracts", "multicallWrapper", "gqlInstance"],
238
238
  "getOwner"
239
239
  );
240
240
  getExpiry = this.generateRawFunction(
@@ -64,8 +64,23 @@ var raw = async ({ contracts, multicallWrapper }, name, contract) => {
64
64
  }
65
65
  return multicallWrapper.raw(data);
66
66
  };
67
+ var registrantQuery = `
68
+ query GetRegistrant($namehash: String!) {
69
+ domain(id: $namehash) {
70
+ registration {
71
+ registrant {
72
+ id
73
+ }
74
+ }
75
+ }
76
+ }
77
+ `;
67
78
  var singleContractOwnerDecode = (data) => ethers.utils.defaultAbiCoder.decode(["address"], data)[0];
68
- var decode = async ({ contracts, multicallWrapper }, data, name, contract) => {
79
+ var decode = async ({
80
+ contracts,
81
+ multicallWrapper,
82
+ gqlInstance
83
+ }, data, name, contract) => {
69
84
  if (!data)
70
85
  return;
71
86
  const labels = name.split(".");
@@ -94,8 +109,17 @@ var decode = async ({ contracts, multicallWrapper }, data, name, contract) => {
94
109
  );
95
110
  const registryOwner = decodedData[0][0];
96
111
  const nameWrapperOwner = decodedData[1][0];
97
- const registrarOwner = decodedData[2]?.[0];
112
+ let registrarOwner = decodedData[2]?.[0];
98
113
  if (labels[labels.length - 1] === "eth") {
114
+ if (!registrarOwner && labels.length === 2) {
115
+ const graphRegistrantResult = await gqlInstance?.request(
116
+ registrantQuery,
117
+ {
118
+ namehash: makeNamehash(name)
119
+ }
120
+ );
121
+ registrarOwner = graphRegistrantResult.domain?.registration?.registrant?.id;
122
+ }
99
123
  if (registrarOwner === nameWrapper.address) {
100
124
  return {
101
125
  owner: nameWrapperOwner,
@@ -109,7 +133,14 @@ var decode = async ({ contracts, multicallWrapper }, data, name, contract) => {
109
133
  ownershipLevel: "registrar"
110
134
  };
111
135
  }
112
- if (labels.length > 2 && ethers.utils.hexStripZeros(registryOwner) !== "0x") {
136
+ if (ethers.utils.hexStripZeros(registryOwner) !== "0x") {
137
+ if (labels.length === 2) {
138
+ return {
139
+ registrant: void 0,
140
+ owner: registryOwner,
141
+ ownershipLevel: "registrar"
142
+ };
143
+ }
113
144
  if (registryOwner === nameWrapper.address && nameWrapperOwner && ethers.utils.hexStripZeros(nameWrapperOwner) !== "0x") {
114
145
  return {
115
146
  owner: nameWrapperOwner,
@@ -206,7 +206,7 @@ var ENS = class {
206
206
  );
207
207
  getOwner = this.generateRawFunction(
208
208
  "initialGetters",
209
- ["contracts", "multicallWrapper"],
209
+ ["contracts", "multicallWrapper", "gqlInstance"],
210
210
  "getOwner"
211
211
  );
212
212
  getExpiry = this.generateRawFunction(
@@ -9,6 +9,6 @@ declare const _default: {
9
9
  to: string;
10
10
  data: string;
11
11
  }>;
12
- decode: ({ contracts, multicallWrapper }: ENSArgs<"contracts" | "multicallWrapper">, data: string, name: string, contract?: "nameWrapper" | "registrar" | "registry" | undefined) => Promise<Owner | undefined>;
12
+ decode: ({ contracts, multicallWrapper, gqlInstance, }: ENSArgs<"contracts" | "gqlInstance" | "multicallWrapper">, data: string, name: string, contract?: "nameWrapper" | "registrar" | "registry" | undefined) => Promise<Owner | undefined>;
13
13
  };
14
14
  export default _default;
@@ -7,6 +7,7 @@ import type burnFuses from './functions/burnFuses';
7
7
  import type commitName from './functions/commitName';
8
8
  import type createSubname from './functions/createSubname';
9
9
  import type deleteSubname from './functions/deleteSubname';
10
+ import importDNSSECName from './functions/importDNSSECName';
10
11
  import type registerName from './functions/registerName';
11
12
  import type { default as renewNames, renewNameWithData } from './functions/renewNames';
12
13
  import type setName from './functions/setName';
@@ -19,7 +20,6 @@ import type transferSubname from './functions/transferSubname';
19
20
  import type unwrapName from './functions/unwrapName';
20
21
  import type wrapName from './functions/wrapName';
21
22
  import GqlManager from './GqlManager';
22
- import importDNSSECName from './functions/importDNSSECName';
23
23
  export type { Fuse, FuseArrayPossibilities, FuseObj, NamedFusesToBurn, UnnamedFuseType, UnnamedFuseValues, } from './utils/fuses';
24
24
  declare type ENSOptions = {
25
25
  graphURI?: string | null;
@@ -344,7 +344,7 @@ export declare class ENS {
344
344
  to: string;
345
345
  data: string;
346
346
  }>;
347
- decode: ({ contracts, multicallWrapper }: ENSArgs<"contracts" | "multicallWrapper">, data: string, name: string, contract?: "nameWrapper" | "registrar" | "registry" | undefined) => Promise<{
347
+ decode: ({ contracts, multicallWrapper, gqlInstance, }: ENSArgs<"contracts" | "gqlInstance" | "multicallWrapper">, data: string, name: string, contract?: "nameWrapper" | "registrar" | "registry" | undefined) => Promise<{
348
348
  registrant?: string | undefined;
349
349
  owner?: string | undefined;
350
350
  ownershipLevel: "nameWrapper" | "registrar" | "registry";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ensdomains/ensjs",
3
- "version": "3.0.0-alpha.31",
3
+ "version": "3.0.0-alpha.33",
4
4
  "description": "ENS javascript library for contract interaction",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.mjs",
@@ -52,7 +52,7 @@
52
52
  "author": "TateB <yo@taytems.xyz>",
53
53
  "license": "MIT",
54
54
  "dependencies": {
55
- "@ensdomains/address-encoder": "0.2.16",
55
+ "@ensdomains/address-encoder": "^0.2.18",
56
56
  "@ensdomains/content-hash": "^2.5.7",
57
57
  "@ensdomains/dnsprovejs": "^0.4.1",
58
58
  "@ensdomains/dnssecoraclejs": "^0.2.7",
@@ -66,7 +66,7 @@
66
66
  "devDependencies": {
67
67
  "@ensdomains/buffer": "^0.0.13",
68
68
  "@ensdomains/ens-contracts": "^0.0.15",
69
- "@ensdomains/ens-test-env": "0.3.2",
69
+ "@ensdomains/ens-test-env": "0.3.5",
70
70
  "@ethersproject/abi": "^5.6.0",
71
71
  "@ethersproject/providers": "^5.6.2",
72
72
  "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
@@ -91,11 +91,27 @@ const raw = async (
91
91
  return multicallWrapper.raw(data)
92
92
  }
93
93
 
94
+ const registrantQuery = `
95
+ query GetRegistrant($namehash: String!) {
96
+ domain(id: $namehash) {
97
+ registration {
98
+ registrant {
99
+ id
100
+ }
101
+ }
102
+ }
103
+ }
104
+ `
105
+
94
106
  const singleContractOwnerDecode = (data: string) =>
95
107
  ethers.utils.defaultAbiCoder.decode(['address'], data)[0]
96
108
 
97
109
  const decode = async (
98
- { contracts, multicallWrapper }: ENSArgs<'contracts' | 'multicallWrapper'>,
110
+ {
111
+ contracts,
112
+ multicallWrapper,
113
+ gqlInstance,
114
+ }: ENSArgs<'contracts' | 'multicallWrapper' | 'gqlInstance'>,
99
115
  data: string,
100
116
  name: string,
101
117
  contract?: 'nameWrapper' | 'registry' | 'registrar',
@@ -131,12 +147,20 @@ const decode = async (
131
147
 
132
148
  const registryOwner = (decodedData[0] as ethers.utils.Result)[0]
133
149
  const nameWrapperOwner = (decodedData[1] as ethers.utils.Result)[0]
134
- const registrarOwner = (
135
- decodedData[2] as ethers.utils.Result | undefined
136
- )?.[0]
150
+ let registrarOwner = (decodedData[2] as ethers.utils.Result | undefined)?.[0]
137
151
 
138
152
  // check for only .eth names
139
153
  if (labels[labels.length - 1] === 'eth') {
154
+ if (!registrarOwner && labels.length === 2) {
155
+ const graphRegistrantResult = await gqlInstance?.request(
156
+ registrantQuery,
157
+ {
158
+ namehash: makeNamehash(name),
159
+ },
160
+ )
161
+ registrarOwner =
162
+ graphRegistrantResult.domain?.registration?.registrant?.id
163
+ }
140
164
  // if the owner on the registrar is the namewrapper, then the namewrapper owner is the owner
141
165
  // there is no "registrant" for wrapped names
142
166
  if (registrarOwner === nameWrapper.address) {
@@ -156,10 +180,16 @@ const decode = async (
156
180
  ownershipLevel: 'registrar',
157
181
  }
158
182
  }
159
- if (
160
- labels.length > 2 &&
161
- ethers.utils.hexStripZeros(registryOwner) !== '0x'
162
- ) {
183
+ if (ethers.utils.hexStripZeros(registryOwner) !== '0x') {
184
+ // if there is no registrar owner, but the label length is two, then the domain is an expired 2LD .eth
185
+ // so we still want to return the ownership values
186
+ if (labels.length === 2) {
187
+ return {
188
+ registrant: undefined,
189
+ owner: registryOwner,
190
+ ownershipLevel: 'registrar',
191
+ }
192
+ }
163
193
  // this means that the subname is wrapped
164
194
  if (
165
195
  registryOwner === nameWrapper.address &&
@@ -52,7 +52,7 @@ describe('getProfile', () => {
52
52
  it('should return a profile object with specified records', async () => {
53
53
  const result = await ensInstance.getProfile(
54
54
  '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
55
- { texts: ['description', 'url'], coinTypes: ['ETC', '0'] },
55
+ { texts: ['description', 'url'], coinTypes: ['ETC_LEGACY', '0'] },
56
56
  )
57
57
  expect(result).toBeDefined()
58
58
  if (result) {
@@ -86,7 +86,7 @@ describe('getProfile', () => {
86
86
  it('should return a profile object with specified records', async () => {
87
87
  const result = await ensInstance.getProfile('with-profile.eth', {
88
88
  texts: ['description', 'url'],
89
- coinTypes: ['ETC', '0'],
89
+ coinTypes: ['ETC_LEGACY', '0'],
90
90
  })
91
91
  expect((result as any).address).toBe(
92
92
  '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
@@ -55,21 +55,21 @@ describe('getSpecificRecord', () => {
55
55
  expect((result as any).addr).toBe(
56
56
  '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
57
57
  )
58
- expect((result as any).coin).toBe('ETC')
58
+ expect((result as any).coin).toBe('ETC_LEGACY')
59
59
  })
60
60
  it('should return the correct address based on a coin ID input as a string', async () => {
61
61
  const result = await ensInstance.getAddr('with-profile.eth', '61')
62
62
  expect((result as any).addr).toBe(
63
63
  '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
64
64
  )
65
- expect((result as any).coin).toBe('ETC')
65
+ expect((result as any).coin).toBe('ETC_LEGACY')
66
66
  })
67
67
  it('should return the correct address based on a coin name', async () => {
68
- const result = await ensInstance.getAddr('with-profile.eth', 'ETC')
68
+ const result = await ensInstance.getAddr('with-profile.eth', 'ETC_LEGACY')
69
69
  expect((result as any).addr).toBe(
70
70
  '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
71
71
  )
72
- expect((result as any).coin).toBe('ETC')
72
+ expect((result as any).coin).toBe('ETC_LEGACY')
73
73
  })
74
74
  it('should return null for a non-existent coin', async () => {
75
75
  const result = await ensInstance.getAddr('with-profile.eth', 'BNB')
@@ -45,7 +45,7 @@ describe('setRecord', () => {
45
45
  const tx = await ensInstance.setRecord('test123.eth', {
46
46
  type: 'addr',
47
47
  record: {
48
- key: 'ETC',
48
+ key: 'ETC_LEGACY',
49
49
  value: '0x42D63ae25990889E35F215bC95884039Ba354115',
50
50
  },
51
51
  addressOrIndex: 1,
@@ -19,7 +19,10 @@ describe('setRecords', () => {
19
19
  const tx = await ensInstance.setRecords('test123.eth', {
20
20
  records: {
21
21
  coinTypes: [
22
- { key: 'ETC', value: '0x42D63ae25990889E35F215bC95884039Ba354115' },
22
+ {
23
+ key: 'ETC_LEGACY',
24
+ value: '0x42D63ae25990889E35F215bC95884039Ba354115',
25
+ },
23
26
  ],
24
27
  texts: [{ key: 'foo', value: 'bar' }],
25
28
  },
package/src/index.ts CHANGED
@@ -33,6 +33,7 @@ import type {
33
33
  } from './functions/getSpecificRecord'
34
34
  import type getSubnames from './functions/getSubnames'
35
35
  import type getWrapperData from './functions/getWrapperData'
36
+ import importDNSSECName from './functions/importDNSSECName'
36
37
  import type registerName from './functions/registerName'
37
38
  import type {
38
39
  // eslint-disable-next-line import/no-named-default
@@ -51,7 +52,6 @@ import type wrapName from './functions/wrapName'
51
52
  import GqlManager from './GqlManager'
52
53
  import singleCall from './utils/singleCall'
53
54
  import writeTx from './utils/writeTx'
54
- import importDNSSECName from './functions/importDNSSECName'
55
55
 
56
56
  export type {
57
57
  Fuse,
@@ -500,7 +500,7 @@ export class ENS {
500
500
 
501
501
  public getOwner = this.generateRawFunction<typeof getOwner>(
502
502
  'initialGetters',
503
- ['contracts', 'multicallWrapper'],
503
+ ['contracts', 'multicallWrapper', 'gqlInstance'],
504
504
  'getOwner',
505
505
  )
506
506