@ensdomains/ensjs 3.0.0-alpha.2 → 3.0.0-alpha.3

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 (38) hide show
  1. package/dist/cjs/functions/getDNSOwner.d.ts +7 -0
  2. package/dist/cjs/functions/getDNSOwner.js +81 -0
  3. package/dist/cjs/index.d.ts +1 -0
  4. package/dist/cjs/index.js +4 -0
  5. package/dist/esm/functions/getDNSOwner.d.ts +7 -0
  6. package/dist/esm/functions/getDNSOwner.js +51 -0
  7. package/dist/esm/index.d.ts +1 -0
  8. package/dist/esm/index.js +4 -0
  9. package/package.json +10 -5
  10. package/src/@types/dns-packet/index.d.ts +114 -0
  11. package/src/{tests → functions}/batch.test.ts +1 -1
  12. package/src/{tests → functions}/batchWrappers.test.ts +1 -1
  13. package/src/{tests → functions}/burnFuses.test.ts +1 -1
  14. package/src/{tests → functions}/createSubname.test.ts +1 -1
  15. package/src/{tests → functions}/deleteSubname.test.ts +1 -1
  16. package/src/functions/getDNSOwner.test.ts +122 -0
  17. package/src/functions/getDNSOwner.ts +61 -0
  18. package/src/{tests → functions}/getExpiry.test.ts +1 -1
  19. package/src/{tests → functions}/getFuses.test.ts +1 -1
  20. package/src/{tests → functions}/getHistory.test.ts +1 -1
  21. package/src/{tests → functions}/getName.test.ts +1 -1
  22. package/src/{tests → functions}/getNames.test.ts +1 -1
  23. package/src/{tests → functions}/getOwner.test.ts +1 -1
  24. package/src/{tests → functions}/getProfile.test.ts +1 -1
  25. package/src/{tests → functions}/getResolver.test.ts +1 -1
  26. package/src/{tests → functions}/getSpecificRecord.test.ts +1 -1
  27. package/src/{tests → functions}/getSubnames.test.ts +1 -1
  28. package/src/{tests → functions}/makeCommitment.test.ts +1 -1
  29. package/src/{tests → functions}/normalise.test.ts +0 -0
  30. package/src/{tests → functions}/setName.test.ts +1 -1
  31. package/src/{tests → functions}/setRecords.test.ts +1 -1
  32. package/src/{tests → functions}/setResolver.test.ts +1 -1
  33. package/src/{tests → functions}/transferName.test.ts +1 -1
  34. package/src/{tests → functions}/transferSubname.test.ts +1 -1
  35. package/src/{tests → functions}/unwrapName.test.ts +1 -1
  36. package/src/{tests → functions}/wrapName.test.ts +1 -1
  37. package/src/index.ts +9 -0
  38. package/src/tests/withProvider.test.ts +1 -1
@@ -0,0 +1,7 @@
1
+ import * as packet from 'dns-packet';
2
+ export declare function encodeURLParams(p: {
3
+ [key: string]: string;
4
+ }): string;
5
+ export declare const getDNS: (q: packet.Packet) => Promise<packet.Packet>;
6
+ export declare const dnsQuery: (qtype: string, qname: string) => Promise<packet.Packet>;
7
+ export default function (dnsName: string): Promise<any>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.dnsQuery = exports.getDNS = exports.encodeURLParams = void 0;
27
+ const packet = __importStar(require("dns-packet"));
28
+ function encodeURLParams(p) {
29
+ return Object.entries(p)
30
+ .map((kv) => kv.map(encodeURIComponent).join('='))
31
+ .join('&');
32
+ }
33
+ exports.encodeURLParams = encodeURLParams;
34
+ const getDNS = async (q) => {
35
+ const response = await global.fetch(`https://cloudflare-dns.com/dns-query?${encodeURLParams({
36
+ ct: 'application/dns-udpwireformat',
37
+ dns: packet.encode(q)?.toString('base64'),
38
+ ts: Date.now().toString(),
39
+ })}`);
40
+ const arrayBuffer = await response.arrayBuffer();
41
+ // @ts-ignore:next-line
42
+ const fromArrayBuffer = Buffer.from(arrayBuffer);
43
+ return packet.decode(fromArrayBuffer);
44
+ };
45
+ exports.getDNS = getDNS;
46
+ const dnsQuery = async (qtype, qname) => {
47
+ const query = {
48
+ type: 'query',
49
+ id: 1,
50
+ flags: packet.RECURSION_DESIRED,
51
+ questions: [
52
+ {
53
+ type: qtype,
54
+ class: 'IN',
55
+ name: qname,
56
+ },
57
+ ],
58
+ additionals: [
59
+ {
60
+ type: 'OPT',
61
+ class: 'IN',
62
+ name: '.',
63
+ udpPayloadSize: 4096,
64
+ flags: packet.DNSSEC_OK,
65
+ },
66
+ ],
67
+ answers: [],
68
+ };
69
+ const response = await (0, exports.getDNS)(query);
70
+ if (response.rcode !== 'NOERROR') {
71
+ throw new Error(`DNS query failed: ${response.rcode}`);
72
+ }
73
+ return response;
74
+ };
75
+ exports.dnsQuery = dnsQuery;
76
+ async function default_1(dnsName) {
77
+ const result = await (0, exports.dnsQuery)('TXT', `_ens.${dnsName}`);
78
+ const address = result?.answers?.[0]?.data?.[0]?.toString()?.split('=')?.[1];
79
+ return address;
80
+ }
81
+ exports.default = default_1;
@@ -466,5 +466,6 @@ export declare class ENS {
466
466
  transferSubname: (name: string, contract: "nameWrapper" | "registry", address: string, options?: {
467
467
  addressOrIndex?: string | number | undefined;
468
468
  } | undefined) => Promise<ethers.ContractTransaction>;
469
+ getDNSOwner: () => Promise<any>;
469
470
  }
470
471
  export {};
package/dist/cjs/index.js CHANGED
@@ -96,6 +96,9 @@ class ENS {
96
96
  if (subFunc !== 'combine') {
97
97
  // get the function to call
98
98
  const func = subFunc ? mod[exportName][subFunc] : mod[exportName];
99
+ if (dependencies.length === 0) {
100
+ return func(...args);
101
+ }
99
102
  // get the dependencies to forward to the function as the first arg
100
103
  const dependenciesToForward = thisRef.forwardDependenciesFromArray(dependencies);
101
104
  // return the function with the dependencies forwarded
@@ -220,5 +223,6 @@ class ENS {
220
223
  createSubname = this.generateFunction('createSubname', ['contracts', 'provider']);
221
224
  deleteSubname = this.generateFunction('deleteSubname', ['contracts', 'provider', 'transferSubname']);
222
225
  transferSubname = this.generateFunction('transferSubname', ['contracts', 'provider']);
226
+ getDNSOwner = this.generateFunction('getDNSOwner', []);
223
227
  }
224
228
  exports.ENS = ENS;
@@ -0,0 +1,7 @@
1
+ import * as packet from 'dns-packet';
2
+ export declare function encodeURLParams(p: {
3
+ [key: string]: string;
4
+ }): string;
5
+ export declare const getDNS: (q: packet.Packet) => Promise<packet.Packet>;
6
+ export declare const dnsQuery: (qtype: string, qname: string) => Promise<packet.Packet>;
7
+ export default function (dnsName: string): Promise<any>;
@@ -0,0 +1,51 @@
1
+ import * as packet from 'dns-packet';
2
+ export function encodeURLParams(p) {
3
+ return Object.entries(p)
4
+ .map((kv) => kv.map(encodeURIComponent).join('='))
5
+ .join('&');
6
+ }
7
+ export const getDNS = async (q) => {
8
+ const response = await global.fetch(`https://cloudflare-dns.com/dns-query?${encodeURLParams({
9
+ ct: 'application/dns-udpwireformat',
10
+ dns: packet.encode(q)?.toString('base64'),
11
+ ts: Date.now().toString(),
12
+ })}`);
13
+ const arrayBuffer = await response.arrayBuffer();
14
+ // @ts-ignore:next-line
15
+ const fromArrayBuffer = Buffer.from(arrayBuffer);
16
+ return packet.decode(fromArrayBuffer);
17
+ };
18
+ export const dnsQuery = async (qtype, qname) => {
19
+ const query = {
20
+ type: 'query',
21
+ id: 1,
22
+ flags: packet.RECURSION_DESIRED,
23
+ questions: [
24
+ {
25
+ type: qtype,
26
+ class: 'IN',
27
+ name: qname,
28
+ },
29
+ ],
30
+ additionals: [
31
+ {
32
+ type: 'OPT',
33
+ class: 'IN',
34
+ name: '.',
35
+ udpPayloadSize: 4096,
36
+ flags: packet.DNSSEC_OK,
37
+ },
38
+ ],
39
+ answers: [],
40
+ };
41
+ const response = await getDNS(query);
42
+ if (response.rcode !== 'NOERROR') {
43
+ throw new Error(`DNS query failed: ${response.rcode}`);
44
+ }
45
+ return response;
46
+ };
47
+ export default async function (dnsName) {
48
+ const result = await dnsQuery('TXT', `_ens.${dnsName}`);
49
+ const address = result?.answers?.[0]?.data?.[0]?.toString()?.split('=')?.[1];
50
+ return address;
51
+ }
@@ -466,5 +466,6 @@ export declare class ENS {
466
466
  transferSubname: (name: string, contract: "nameWrapper" | "registry", address: string, options?: {
467
467
  addressOrIndex?: string | number | undefined;
468
468
  } | undefined) => Promise<ethers.ContractTransaction>;
469
+ getDNSOwner: () => Promise<any>;
469
470
  }
470
471
  export {};
package/dist/esm/index.js CHANGED
@@ -59,6 +59,9 @@ export class ENS {
59
59
  if (subFunc !== 'combine') {
60
60
  // get the function to call
61
61
  const func = subFunc ? mod[exportName][subFunc] : mod[exportName];
62
+ if (dependencies.length === 0) {
63
+ return func(...args);
64
+ }
62
65
  // get the dependencies to forward to the function as the first arg
63
66
  const dependenciesToForward = thisRef.forwardDependenciesFromArray(dependencies);
64
67
  // return the function with the dependencies forwarded
@@ -183,6 +186,7 @@ export class ENS {
183
186
  this.createSubname = this.generateFunction('createSubname', ['contracts', 'provider']);
184
187
  this.deleteSubname = this.generateFunction('deleteSubname', ['contracts', 'provider', 'transferSubname']);
185
188
  this.transferSubname = this.generateFunction('transferSubname', ['contracts', 'provider']);
189
+ this.getDNSOwner = this.generateFunction('getDNSOwner', []);
186
190
  this.options = options;
187
191
  this.getContractAddress = options?.getContractAddress || _getContractAddress;
188
192
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ensdomains/ensjs",
3
- "version": "3.0.0-alpha.2",
3
+ "version": "3.0.0-alpha.3",
4
4
  "description": "ENS javascript library for contract interaction",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "types": "./dist/cjs/index.d.ts",
@@ -27,13 +27,16 @@
27
27
  "generate-types": "ts-node scripts/runTypechain.ts",
28
28
  "generate-abis": "hardhat export-abi",
29
29
  "start": "ts-node --files src/index.test.ts",
30
- "test": "jest --run-in-band src/tests",
30
+ "test": "jest --run-in-band",
31
+ "test:watch": "jest --watch --run-in-band",
31
32
  "test:specific": "ts-node --files ",
32
33
  "clean": "rm -rf ./dist ./README.md ./LICENSE",
33
34
  "build:esm": "tsc --project tsconfig.esm.json",
34
35
  "build:cjs": "tsc --project tsconfig.cjs.json",
35
36
  "build": "yarn clean && yarn build:esm && yarn build:cjs",
36
- "prepublish": "yarn build && cp ../../{README.md,LICENSE} ./"
37
+ "prepublish": "yarn build && cp ../../{README.md,LICENSE} ./",
38
+ "remove-stableVersion": "ex -c '%s/,\\n\\s\\+\"stableVersion\".*\"//g' -cwq ./package.json",
39
+ "version:create": "yarn remove-stableVersion && yarn version"
37
40
  },
38
41
  "packageManager": "yarn@3.2.0",
39
42
  "dependencies": {
@@ -48,7 +51,7 @@
48
51
  },
49
52
  "devDependencies": {
50
53
  "@ensdomains/buffer": "^0.0.13",
51
- "@ensdomains/ens-test-env": "0.2.0",
54
+ "@ensdomains/ens-test-env": "0.1.0",
52
55
  "@ethersproject/abi": "^5.6.0",
53
56
  "@ethersproject/providers": "^5.6.2",
54
57
  "@nomiclabs/hardhat-ethers": "^2.0.5",
@@ -66,6 +69,8 @@
66
69
  "jest": "^27.5.1",
67
70
  "jest-environment-node": "^27.5.1",
68
71
  "jest-localstorage-mock": "^2.4.21",
72
+ "nock": "^13.2.8",
73
+ "node-fetch": "^3.2.6",
69
74
  "solc": "^0.8.13",
70
75
  "ts-jest": "^27.1.4",
71
76
  "ts-node": "^10.7.0",
@@ -76,5 +81,5 @@
76
81
  "peerDependencies": {
77
82
  "ethers": "*"
78
83
  },
79
- "stableVersion": "3.0.0-alpha.1"
84
+ "stableVersion": "3.0.0-alpha.2"
80
85
  }
@@ -0,0 +1,114 @@
1
+ declare module 'dns-packet' {
2
+ const AUTHORITATIVE_ANSWER: number
3
+ const TRUNCATED_RESPONSE: number
4
+ const RECURSION_DESIRED: number
5
+ const RECURSION_AVAILABLE: number
6
+ const AUTHENTIC_DATA: number
7
+ const CHECKING_DISABLED: number
8
+ const DNSSEC_OK: number
9
+
10
+ interface decoder<T> {
11
+ (buf: Buffer, offset?: number): T
12
+ bytes: number;
13
+ }
14
+
15
+ const decode: decoder<Packet>;
16
+
17
+ interface encoder<T> {
18
+ (packet: T, buf?: Buffer, offset?: number): Buffer
19
+ bytes: number;
20
+ }
21
+
22
+ const encode: encoder<Packet>;
23
+
24
+ interface Packet {
25
+ id?: number
26
+ type: 'query' | 'response'
27
+ flags?: number
28
+ rcode?: string
29
+ questions: Question[]
30
+ answers?: Answer[]
31
+ authorities?: Answer[]
32
+ additionals?: Answer[]
33
+ }
34
+
35
+ interface Question {
36
+ type: string
37
+ class: string
38
+ name: string
39
+ }
40
+
41
+ interface AnswerBase {
42
+ type: string
43
+ class: string
44
+ name: string
45
+ ttl?: number
46
+ }
47
+
48
+ interface A extends AnswerBase {
49
+ type: 'A'
50
+ data: string
51
+ }
52
+
53
+ interface Dnskey extends AnswerBase {
54
+ type: 'DNSKEY'
55
+ data: {
56
+ flags: number
57
+ algorithm: number
58
+ key: Buffer
59
+ }
60
+ }
61
+
62
+ interface Ds extends AnswerBase {
63
+ type: 'DS'
64
+ data: {
65
+ keyTag: number
66
+ algorithm: number
67
+ digestType: number
68
+ digest: Buffer
69
+ }
70
+ }
71
+
72
+ interface Opt extends AnswerBase {
73
+ type: 'OPT'
74
+ udpPayloadSize?: number
75
+ extendedRcode?: number
76
+ ednsVersion?: number
77
+ flags?: number
78
+ data?: any
79
+ }
80
+
81
+ interface Rrsig extends AnswerBase {
82
+ type: 'RRSIG'
83
+ data: {
84
+ typeCovered: string
85
+ algorithm: number
86
+ labels: number
87
+ originalTTL: number
88
+ expiration: number
89
+ inception: number
90
+ keyTag: number
91
+ signersName: string
92
+ signature: Buffer
93
+ }
94
+ }
95
+
96
+ interface Rtxt extends AnswerBase {
97
+ type: 'TXT'
98
+ data: Buffer[]
99
+ }
100
+
101
+ type Answer = A|Dnskey|Ds|Opt|Rrsig|Rtxt
102
+
103
+ interface Encodable<T> {
104
+ decode: decoder<T>
105
+ encode: encoder<T>
106
+ }
107
+
108
+ const record: (type: string) => Encodable<Answer>
109
+ const answer: Encodable<Answer>
110
+ const dnskey: Encodable<Dnskey['data']>
111
+ const name: Encodable<string>
112
+ const rrsig: Encodable<Rrsig['data']>
113
+ }
114
+
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,7 +1,7 @@
1
1
  import { BigNumber, ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -0,0 +1,122 @@
1
+ import * as packet from 'dns-packet'
2
+ import fetch from 'node-fetch'
3
+ import nock from 'nock'
4
+
5
+ import getDNSOwner, { encodeURLParams } from './getDNSOwner'
6
+
7
+ function hex_decode(string: string) {
8
+ let bytes: any[] = []
9
+ string.replace(/../g, function (pair) {
10
+ bytes.push(parseInt(pair, 16))
11
+ })
12
+ return new Uint8Array(bytes).buffer
13
+ }
14
+
15
+ describe('encodeURLParams', () => {
16
+ it('should encodeURLParams', () => {
17
+ const p: { [key: string]: string } = {
18
+ a: 'b',
19
+ c: 'd',
20
+ }
21
+ const expected = 'a=b&c=d'
22
+ const actual = encodeURLParams(p)
23
+ expect(actual).toEqual(expected)
24
+ })
25
+ })
26
+
27
+ describe('getDNSOwner', () => {
28
+ beforeAll(() => {
29
+ global.fetch = fetch
30
+ })
31
+ afterAll(() => {
32
+ global.fetch = undefined
33
+ })
34
+ it('should return the address from the result of a dnsQuery', async () => {
35
+ const dnsName = 'brantly.xyz'
36
+
37
+ const scope = nock('https://cloudflare-dns.com:443', {
38
+ encodedQueryParams: true,
39
+ })
40
+ .get('/dns-query')
41
+ .query((queryObject) => {
42
+ console.log('queryObject: ', queryObject)
43
+ return (
44
+ queryObject.ct === 'application/dns-udpwireformat' &&
45
+ queryObject.dns ===
46
+ 'AAEBAAABAAAAAAABBF9lbnMHYnJhbnRseQN4eXoAABAAAQAAKRAAAACAAAAA'
47
+ )
48
+ })
49
+ .reply(
50
+ 200,
51
+ Buffer.from(
52
+ hex_decode(
53
+ '000181a00001000200000001045f656e73076272616e746c790378797a0000100001c00c0010000100000e10002d2c613d307839383331313033303936323044393131373331416330393332323139616630363039316236373434c00c002e000100000e10009f0010080300000e1062df366962c23569d89d076272616e746c790378797a0039c894ca1d7a60c1356e478066d39961a78ec1edbe62e1eb0f13d7947bb72097654648dc79be075ca32625f02e60267f45e88d7c05e9c3ec0cf21ab2dca67a8fbeb8e995644726357628446b888a144cafef5cbfca120c6511fe36de9d3c62dee27680825190c5404ca503904b98dbf62d9122f6fda393dc04b14a89ceb68c7a00002904d0000080000000',
54
+ ),
55
+ ),
56
+ [
57
+ 'Server',
58
+ 'cloudflare',
59
+ 'Date',
60
+ 'Wed, 06 Jul 2022 23:37:28 GMT',
61
+ 'Content-Type',
62
+ 'application/dns-message',
63
+ 'Connection',
64
+ 'close',
65
+ 'Access-Control-Allow-Origin',
66
+ '*',
67
+ 'Content-Length',
68
+ '273',
69
+ 'CF-RAY',
70
+ '726c2b1d3bab6b74-TPE',
71
+ ],
72
+ )
73
+ expect(await getDNSOwner(dnsName)).toEqual(
74
+ '0x983110309620D911731Ac0932219af06091b6744',
75
+ )
76
+ })
77
+ it('should throw if there is an error in the DNS query', async () => {
78
+ const dnsName = 'nick.xyz'
79
+
80
+ const scope = nock('https://cloudflare-dns.com:443', {
81
+ encodedQueryParams: true,
82
+ })
83
+ .get('/dns-query')
84
+ .query((queryObject) => {
85
+ console.log('queryObject: ', queryObject)
86
+ return (
87
+ queryObject.ct === 'application/dns-udpwireformat' &&
88
+ queryObject.dns ===
89
+ 'AAEBAAABAAAAAAABBF9lbnMEbmljawN4eXoAABAAAQAAKRAAAACAAAAA'
90
+ )
91
+ })
92
+ .reply(
93
+ 200,
94
+ Buffer.from(
95
+ hex_decode(
96
+ '000181830001000000010001045f656e73046e69636b0378797a0000100001c0110006000100000258003b046e7337310d646f6d61696e636f6e74726f6c03636f6d0003646e73056a6f6d6178036e6574007876d1800000708000001c2000093a800000025800002904d0000080000000',
97
+ ),
98
+ ),
99
+ [
100
+ 'Server',
101
+ 'cloudflare',
102
+ 'Date',
103
+ 'Wed, 06 Jul 2022 23:37:28 GMT',
104
+ 'Content-Type',
105
+ 'application/dns-message',
106
+ 'Connection',
107
+ 'close',
108
+ 'Access-Control-Allow-Origin',
109
+ '*',
110
+ 'Content-Length',
111
+ '273',
112
+ 'CF-RAY',
113
+ '726c2b1d3bab6b74-TPE',
114
+ ],
115
+ )
116
+ try {
117
+ await getDNSOwner(dnsName)
118
+ } catch (error) {
119
+ expect(error.message).toEqual('DNS query failed: NXDOMAIN')
120
+ }
121
+ })
122
+ })
@@ -0,0 +1,61 @@
1
+ import * as packet from 'dns-packet'
2
+
3
+ export function encodeURLParams(p: { [key: string]: string }): string {
4
+ return Object.entries(p)
5
+ .map((kv) => kv.map(encodeURIComponent).join('='))
6
+ .join('&')
7
+ }
8
+
9
+ export const getDNS = async (q: packet.Packet): Promise<packet.Packet> => {
10
+ const response = await global.fetch(
11
+ `https://cloudflare-dns.com/dns-query?${encodeURLParams({
12
+ ct: 'application/dns-udpwireformat',
13
+ dns: packet.encode(q)?.toString('base64'),
14
+ ts: Date.now().toString(),
15
+ })}`,
16
+ )
17
+ const arrayBuffer = await response.arrayBuffer()
18
+ // @ts-ignore:next-line
19
+ const fromArrayBuffer = Buffer.from(arrayBuffer);
20
+ return packet.decode(fromArrayBuffer)
21
+ }
22
+
23
+ export const dnsQuery = async (
24
+ qtype: string,
25
+ qname: string,
26
+ ): Promise<packet.Packet> => {
27
+ const query: packet.Packet = {
28
+ type: 'query',
29
+ id: 1,
30
+ flags: packet.RECURSION_DESIRED,
31
+ questions: [
32
+ {
33
+ type: qtype,
34
+ class: 'IN',
35
+ name: qname,
36
+ },
37
+ ],
38
+ additionals: [
39
+ {
40
+ type: 'OPT',
41
+ class: 'IN',
42
+ name: '.',
43
+ udpPayloadSize: 4096,
44
+ flags: packet.DNSSEC_OK,
45
+ },
46
+ ],
47
+ answers: [],
48
+ }
49
+
50
+ const response = await getDNS(query)
51
+ if (response.rcode !== 'NOERROR') {
52
+ throw new Error(`DNS query failed: ${response.rcode}`)
53
+ }
54
+ return response
55
+ }
56
+
57
+ export default async function (dnsName: string) {
58
+ const result = await dnsQuery('TXT', `_ens.${dnsName}`)
59
+ const address = result?.answers?.[0]?.data?.[0]?.toString()?.split('=')?.[1]
60
+ return address
61
+ }
@@ -1,6 +1,6 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,6 +1,6 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,6 +1,6 @@
1
1
  import { ENS } from '..'
2
2
  import { OwnedName, Registration } from '../functions/getNames'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { ENS } from '..'
2
- import setup from './setup'
2
+ import setup from '../tests/setup'
3
3
 
4
4
  let ENSInstance: ENS
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { ENS } from '..'
2
2
  import { makeCommitment } from '../utils/registerHelpers'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
 
File without changes
@@ -1,7 +1,7 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { hexEncodeName } from '../utils/hexEncodedName'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ENS } from '..'
2
2
  import { hexEncodeName } from '../utils/hexEncodedName'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { hexEncodeName } from '../utils/hexEncodedName'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ethers, utils } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -1,7 +1,7 @@
1
1
  import { ethers, utils } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { namehash } from '../utils/normalise'
4
- import setup from './setup'
4
+ import setup from '../tests/setup'
5
5
 
6
6
  let ENSInstance: ENS
7
7
  let revert: Awaited<ReturnType<typeof setup>>['revert']
@@ -2,7 +2,7 @@ import { BigNumber, ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import { hexEncodeName } from '../utils/hexEncodedName'
4
4
  import { namehash } from '../utils/normalise'
5
- import setup from './setup'
5
+ import setup from '../tests/setup'
6
6
 
7
7
  let ENSInstance: ENS
8
8
  let revert: Awaited<ReturnType<typeof setup>>['revert']
package/src/index.ts CHANGED
@@ -41,6 +41,7 @@ import type transferName from './functions/transferName'
41
41
  import type transferSubname from './functions/transferSubname'
42
42
  import type unwrapName from './functions/unwrapName'
43
43
  import type wrapName from './functions/wrapName'
44
+ import type getDNSOwner from './functions/getDNSOwner'
44
45
  import GqlManager from './GqlManager'
45
46
  import singleCall from './utils/singleCall'
46
47
 
@@ -194,6 +195,9 @@ export class ENS {
194
195
  if (subFunc !== 'combine') {
195
196
  // get the function to call
196
197
  const func = subFunc ? mod[exportName][subFunc] : mod[exportName]
198
+ if(dependencies.length === 0) {
199
+ return func(...args)
200
+ }
197
201
  // get the dependencies to forward to the function as the first arg
198
202
  const dependenciesToForward =
199
203
  thisRef.forwardDependenciesFromArray<F>(dependencies)
@@ -504,4 +508,9 @@ export class ENS {
504
508
  'transferSubname',
505
509
  ['contracts', 'provider'],
506
510
  )
511
+
512
+ public getDNSOwner = this.generateFunction<typeof getDNSOwner>(
513
+ 'getDNSOwner',
514
+ [],
515
+ )
507
516
  }
@@ -1,6 +1,6 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
  let providerFake: ethers.providers.JsonRpcProvider