@ensdomains/ensjs 3.0.0-alpha.1 → 3.0.0-alpha.10
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.
- package/README.md +2 -0
- package/dist/cjs/GqlManager.d.ts +3 -0
- package/dist/cjs/GqlManager.js +62 -2
- package/dist/cjs/functions/burnFuses.d.ts +3 -2
- package/dist/cjs/functions/burnFuses.js +4 -8
- package/dist/cjs/functions/createSubname.d.ts +1 -5
- package/dist/cjs/functions/createSubname.js +5 -8
- package/dist/cjs/functions/deleteSubname.d.ts +3 -3
- package/dist/cjs/functions/deleteSubname.js +5 -2
- package/dist/cjs/functions/getDNSOwner.d.ts +7 -0
- package/dist/cjs/functions/getDNSOwner.js +81 -0
- package/dist/cjs/functions/getFuses.js +3 -2
- package/dist/cjs/functions/getOwner.js +7 -6
- package/dist/cjs/functions/getProfile.d.ts +4 -1
- package/dist/cjs/functions/getProfile.js +102 -24
- package/dist/cjs/functions/getRecords.d.ts +1 -0
- package/dist/cjs/functions/getSpecificRecord.js +22 -5
- package/dist/cjs/functions/getSubnames.js +6 -6
- package/dist/cjs/functions/setName.d.ts +4 -3
- package/dist/cjs/functions/setName.js +5 -10
- package/dist/cjs/functions/setRecord.d.ts +18 -0
- package/dist/cjs/functions/setRecord.js +27 -0
- package/dist/cjs/functions/setRecords.d.ts +4 -2
- package/dist/cjs/functions/setRecords.js +14 -12
- package/dist/cjs/functions/setResolver.d.ts +4 -4
- package/dist/cjs/functions/setResolver.js +6 -12
- package/dist/cjs/functions/transferName.d.ts +4 -3
- package/dist/cjs/functions/transferName.js +9 -13
- package/dist/cjs/functions/transferSubname.d.ts +4 -3
- package/dist/cjs/functions/transferSubname.js +5 -8
- package/dist/cjs/functions/unwrapName.d.ts +4 -3
- package/dist/cjs/functions/unwrapName.js +5 -9
- package/dist/cjs/functions/wrapName.d.ts +5 -3
- package/dist/cjs/functions/wrapName.js +8 -12
- package/dist/cjs/index.d.ts +48 -46
- package/dist/cjs/index.js +43 -19
- package/dist/cjs/utils/labels.js +5 -4
- package/dist/cjs/utils/makeHashIndexes.js +2 -2
- package/dist/cjs/utils/normalise.d.ts +1 -0
- package/dist/cjs/utils/normalise.js +27 -1
- package/dist/cjs/utils/recordHelpers.d.ts +3 -0
- package/dist/cjs/utils/recordHelpers.js +42 -15
- package/dist/cjs/utils/registerHelpers.js +3 -4
- package/dist/cjs/utils/writeTx.d.ts +4 -0
- package/dist/cjs/utils/writeTx.js +3 -0
- package/dist/esm/GqlManager.d.ts +3 -0
- package/dist/esm/GqlManager.js +58 -2
- package/dist/esm/functions/burnFuses.d.ts +3 -2
- package/dist/esm/functions/burnFuses.js +4 -8
- package/dist/esm/functions/createSubname.d.ts +1 -5
- package/dist/esm/functions/createSubname.js +5 -8
- package/dist/esm/functions/deleteSubname.d.ts +3 -3
- package/dist/esm/functions/deleteSubname.js +5 -2
- package/dist/esm/functions/getDNSOwner.d.ts +7 -0
- package/dist/esm/functions/getDNSOwner.js +51 -0
- package/dist/esm/functions/getFuses.js +4 -3
- package/dist/esm/functions/getOwner.js +7 -6
- package/dist/esm/functions/getProfile.d.ts +4 -1
- package/dist/esm/functions/getProfile.js +102 -24
- package/dist/esm/functions/getRecords.d.ts +1 -0
- package/dist/esm/functions/getSpecificRecord.js +22 -5
- package/dist/esm/functions/getSubnames.js +3 -3
- package/dist/esm/functions/setName.d.ts +4 -3
- package/dist/esm/functions/setName.js +5 -10
- package/dist/esm/functions/setRecord.d.ts +18 -0
- package/dist/esm/functions/setRecord.js +24 -0
- package/dist/esm/functions/setRecords.d.ts +4 -2
- package/dist/esm/functions/setRecords.js +14 -12
- package/dist/esm/functions/setResolver.d.ts +4 -4
- package/dist/esm/functions/setResolver.js +6 -12
- package/dist/esm/functions/transferName.d.ts +4 -3
- package/dist/esm/functions/transferName.js +9 -13
- package/dist/esm/functions/transferSubname.d.ts +4 -3
- package/dist/esm/functions/transferSubname.js +5 -8
- package/dist/esm/functions/unwrapName.d.ts +4 -3
- package/dist/esm/functions/unwrapName.js +5 -9
- package/dist/esm/functions/wrapName.d.ts +5 -3
- package/dist/esm/functions/wrapName.js +8 -12
- package/dist/esm/index.d.ts +48 -46
- package/dist/esm/index.js +43 -19
- package/dist/esm/utils/labels.js +5 -4
- package/dist/esm/utils/makeHashIndexes.js +2 -2
- package/dist/esm/utils/normalise.d.ts +1 -0
- package/dist/esm/utils/normalise.js +25 -0
- package/dist/esm/utils/recordHelpers.d.ts +3 -0
- package/dist/esm/utils/recordHelpers.js +40 -14
- package/dist/esm/utils/registerHelpers.js +3 -4
- package/dist/esm/utils/writeTx.d.ts +4 -0
- package/dist/esm/utils/writeTx.js +1 -0
- package/package.json +15 -7
- package/src/@types/dns-packet/index.d.ts +114 -0
- package/src/GqlManager.test.ts +170 -0
- package/src/GqlManager.ts +67 -2
- package/src/{tests → functions}/batch.test.ts +1 -1
- package/src/{tests → functions}/batchWrappers.test.ts +1 -1
- package/src/{tests → functions}/burnFuses.test.ts +12 -10
- package/src/functions/burnFuses.ts +9 -11
- package/src/{tests → functions}/createSubname.test.ts +12 -16
- package/src/functions/createSubname.ts +7 -13
- package/src/{tests → functions}/deleteSubname.test.ts +32 -32
- package/src/functions/deleteSubname.ts +9 -12
- package/src/functions/getDNSOwner.test.ts +122 -0
- package/src/functions/getDNSOwner.ts +61 -0
- package/src/{tests → functions}/getExpiry.test.ts +1 -1
- package/src/{tests → functions}/getFuses.test.ts +12 -10
- package/src/functions/getFuses.ts +4 -3
- package/src/{tests → functions}/getHistory.test.ts +1 -1
- package/src/{tests → functions}/getName.test.ts +1 -1
- package/src/{tests → functions}/getNames.test.ts +1 -1
- package/src/{tests → functions}/getOwner.test.ts +14 -2
- package/src/functions/getOwner.ts +7 -7
- package/src/{tests → functions}/getProfile.test.ts +45 -12
- package/src/functions/getProfile.ts +151 -24
- package/src/functions/getRecords.ts +1 -0
- package/src/{tests → functions}/getResolver.test.ts +1 -1
- package/src/{tests → functions}/getSpecificRecord.test.ts +1 -1
- package/src/functions/getSpecificRecord.ts +28 -8
- package/src/{tests → functions}/getSubnames.test.ts +1 -1
- package/src/functions/getSubnames.ts +68 -66
- package/src/{tests → functions}/makeCommitment.test.ts +1 -1
- package/src/functions/normalise.test.ts +22 -0
- package/src/{tests → functions}/setName.test.ts +3 -2
- package/src/functions/setName.ts +15 -17
- package/src/functions/setRecord.test.ts +100 -0
- package/src/functions/setRecord.ts +63 -0
- package/src/{tests → functions}/setRecords.test.ts +12 -10
- package/src/functions/setRecords.ts +22 -16
- package/src/{tests → functions}/setResolver.test.ts +12 -15
- package/src/functions/setResolver.ts +15 -20
- package/src/{tests → functions}/transferName.test.ts +30 -31
- package/src/functions/transferName.ts +19 -22
- package/src/{tests → functions}/transferSubname.test.ts +34 -34
- package/src/functions/transferSubname.ts +21 -13
- package/src/{tests → functions}/unwrapName.test.ts +24 -23
- package/src/functions/unwrapName.ts +20 -15
- package/src/{tests → functions}/wrapName.test.ts +19 -19
- package/src/functions/wrapName.ts +20 -22
- package/src/index.ts +115 -26
- package/src/tests/populateTransaction.test.ts +40 -0
- package/src/tests/signerInjection.test.ts +46 -0
- package/src/tests/withProvider.test.ts +1 -1
- package/src/utils/labels.ts +6 -4
- package/src/utils/makeHashIndexes.ts +4 -4
- package/src/utils/normalise.ts +29 -0
- package/src/utils/recordHelpers.ts +52 -18
- package/src/utils/registerHelpers.ts +3 -4
- package/src/utils/writeTx.ts +6 -0
package/dist/cjs/index.js
CHANGED
|
@@ -31,6 +31,7 @@ const contracts_1 = __importDefault(require("./contracts"));
|
|
|
31
31
|
const getContractAddress_1 = require("./contracts/getContractAddress");
|
|
32
32
|
const GqlManager_1 = __importDefault(require("./GqlManager"));
|
|
33
33
|
const singleCall_1 = __importDefault(require("./utils/singleCall"));
|
|
34
|
+
const writeTx_1 = __importDefault(require("./utils/writeTx"));
|
|
34
35
|
const graphURIEndpoints = {
|
|
35
36
|
1: 'https://api.thegraph.com/subgraphs/name/ensdomains/ens',
|
|
36
37
|
3: 'https://api.thegraph.com/subgraphs/name/ensdomains/ensropsten',
|
|
@@ -89,15 +90,30 @@ class ENS {
|
|
|
89
90
|
await thisRef.checkInitialProvider();
|
|
90
91
|
// import the module dynamically
|
|
91
92
|
const mod = await Promise.resolve().then(() => __importStar(require(
|
|
92
|
-
/* webpackMode: "lazy", webpackChunkName: "[request]", webpackPreload: true */
|
|
93
|
+
/* webpackMode: "lazy", webpackChunkName: "[request]", webpackPreload: true, webpackExclude: /.*\.ts$/ */
|
|
93
94
|
`./functions/${path}`)));
|
|
94
95
|
// if combine isn't specified, run normally
|
|
95
96
|
// otherwise, create a function from the raw and decode functions
|
|
96
97
|
if (subFunc !== 'combine') {
|
|
98
|
+
const writeable = subFunc === 'write' || subFunc === 'populateTransaction';
|
|
97
99
|
// get the function to call
|
|
98
|
-
const func = subFunc ? mod[exportName][subFunc] : mod[exportName];
|
|
100
|
+
const func = subFunc && !writeable ? mod[exportName][subFunc] : mod[exportName];
|
|
99
101
|
// get the dependencies to forward to the function as the first arg
|
|
100
|
-
|
|
102
|
+
let dependenciesToForward = thisRef.forwardDependenciesFromArray(dependencies);
|
|
103
|
+
// if func is write func, inject signer into dependencies
|
|
104
|
+
if (writeable) {
|
|
105
|
+
const options = (args[1] || {});
|
|
106
|
+
const signer = options.signer ||
|
|
107
|
+
thisRef.provider?.getSigner(options.addressOrIndex);
|
|
108
|
+
const populate = subFunc === 'populateTransaction';
|
|
109
|
+
if (!signer) {
|
|
110
|
+
throw new Error('No signer specified');
|
|
111
|
+
}
|
|
112
|
+
delete options.addressOrIndex;
|
|
113
|
+
delete options.signer;
|
|
114
|
+
dependenciesToForward = { ...dependenciesToForward, signer };
|
|
115
|
+
return func(dependenciesToForward, args[0], options).then((0, writeTx_1.default)(signer, populate));
|
|
116
|
+
}
|
|
101
117
|
// return the function with the dependencies forwarded
|
|
102
118
|
return func(dependenciesToForward, ...args);
|
|
103
119
|
}
|
|
@@ -114,6 +130,9 @@ class ENS {
|
|
|
114
130
|
mainFunc.decode = this.importGenerator(path, dependencies, exportName, 'decode');
|
|
115
131
|
mainFunc.batch = this.importGenerator(path, dependencies, exportName, 'batch', { raw: mainFunc.raw, decode: mainFunc.decode });
|
|
116
132
|
}
|
|
133
|
+
else if (subFunc === 'write') {
|
|
134
|
+
mainFunc.populateTransaction = this.importGenerator(path, dependencies, exportName, 'populateTransaction');
|
|
135
|
+
}
|
|
117
136
|
return mainFunc;
|
|
118
137
|
};
|
|
119
138
|
/**
|
|
@@ -124,6 +143,14 @@ class ENS {
|
|
|
124
143
|
* @returns {OmitFirstArg} - The generated wrapped function
|
|
125
144
|
*/
|
|
126
145
|
generateFunction = (path, dependencies, exportName = 'default') => this.importGenerator(path, dependencies, exportName);
|
|
146
|
+
/**
|
|
147
|
+
* Generates a write wrapped function
|
|
148
|
+
* @param {string} path - The path of the exported function
|
|
149
|
+
* @param {FunctionDeps} dependencies - An array of ENS properties
|
|
150
|
+
* @param {string} exportName - The export name of the target function
|
|
151
|
+
* @returns {OmitFirstArg} - The generated wrapped function
|
|
152
|
+
*/
|
|
153
|
+
generateWriteFunction = (path, dependencies, exportName = 'default') => this.importGenerator(path, dependencies, exportName, 'write');
|
|
127
154
|
/**
|
|
128
155
|
* Generates a wrapped function from raw and decode exports
|
|
129
156
|
* @param {string} path - The path of the exported function
|
|
@@ -166,6 +193,7 @@ class ENS {
|
|
|
166
193
|
'gqlInstance',
|
|
167
194
|
'getName',
|
|
168
195
|
'resolverMulticallWrapper',
|
|
196
|
+
'multicallWrapper',
|
|
169
197
|
'_getAddr',
|
|
170
198
|
'_getContentHash',
|
|
171
199
|
'_getText',
|
|
@@ -193,31 +221,27 @@ class ENS {
|
|
|
193
221
|
universalWrapper = this.generateRawFunction('initialGetters', ['contracts'], 'universalWrapper');
|
|
194
222
|
resolverMulticallWrapper = this.generateRawFunction('initialGetters', ['contracts'], 'resolverMulticallWrapper');
|
|
195
223
|
multicallWrapper = this.generateRawFunction('initialGetters', ['contracts'], 'multicallWrapper');
|
|
196
|
-
setName = this.
|
|
224
|
+
setName = this.generateWriteFunction('setName', [
|
|
197
225
|
'contracts',
|
|
198
|
-
'provider',
|
|
199
226
|
]);
|
|
200
|
-
setRecords = this.
|
|
227
|
+
setRecords = this.generateWriteFunction('setRecords', ['contracts', 'provider', 'getResolver']);
|
|
228
|
+
setRecord = this.generateWriteFunction('setRecord', [
|
|
201
229
|
'contracts',
|
|
202
230
|
'provider',
|
|
203
231
|
'getResolver',
|
|
204
232
|
]);
|
|
205
|
-
setResolver = this.
|
|
206
|
-
transferName = this.
|
|
207
|
-
wrapName = this.
|
|
233
|
+
setResolver = this.generateWriteFunction('setResolver', ['contracts']);
|
|
234
|
+
transferName = this.generateWriteFunction('transferName', ['contracts']);
|
|
235
|
+
wrapName = this.generateWriteFunction('wrapName', [
|
|
208
236
|
'contracts',
|
|
209
|
-
'provider',
|
|
210
237
|
]);
|
|
211
|
-
unwrapName = this.
|
|
238
|
+
unwrapName = this.generateWriteFunction('unwrapName', ['contracts']);
|
|
239
|
+
burnFuses = this.generateWriteFunction('burnFuses', [
|
|
212
240
|
'contracts',
|
|
213
|
-
'provider',
|
|
214
|
-
]);
|
|
215
|
-
burnFuses = this.generateFunction('burnFuses', [
|
|
216
|
-
'contracts',
|
|
217
|
-
'provider',
|
|
218
241
|
]);
|
|
219
|
-
createSubname = this.
|
|
220
|
-
deleteSubname = this.
|
|
221
|
-
transferSubname = this.
|
|
242
|
+
createSubname = this.generateWriteFunction('createSubname', ['contracts']);
|
|
243
|
+
deleteSubname = this.generateWriteFunction('deleteSubname', ['transferSubname']);
|
|
244
|
+
transferSubname = this.generateWriteFunction('transferSubname', ['contracts']);
|
|
245
|
+
getDNSOwner = this.generateFunction('getDNSOwner', []);
|
|
222
246
|
}
|
|
223
247
|
exports.ENS = ENS;
|
package/dist/cjs/utils/labels.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.checkLocalStorageSize = exports.truncateUndecryptedName = exports.decryptName = exports.checkIsDecrypted = exports.parseName = exports.encodeLabel = exports.checkLabel = exports.saveName = exports.saveLabel = exports.isEncodedLabelhash = exports.encodeLabelhash = exports.decodeLabelhash = exports.keccakFromString = exports.labelhash = void 0;
|
|
4
4
|
const utils_1 = require("ethers/lib/utils");
|
|
5
5
|
const format_1 = require("./format");
|
|
6
|
+
const hasLocalStorage = typeof localStorage !== 'undefined';
|
|
6
7
|
const labelhash = (input) => (0, utils_1.solidityKeccak256)(['string'], [input]);
|
|
7
8
|
exports.labelhash = labelhash;
|
|
8
9
|
const keccakFromString = (input) => (0, exports.labelhash)(input);
|
|
@@ -14,7 +15,7 @@ function decodeLabelhash(hash) {
|
|
|
14
15
|
if (hash.length !== 66) {
|
|
15
16
|
throw Error('Expected encoded labelhash to have a length of 66');
|
|
16
17
|
}
|
|
17
|
-
return
|
|
18
|
+
return `0x${hash.slice(1, -1)}`;
|
|
18
19
|
}
|
|
19
20
|
exports.decodeLabelhash = decodeLabelhash;
|
|
20
21
|
function encodeLabelhash(hash) {
|
|
@@ -32,12 +33,12 @@ function isEncodedLabelhash(hash) {
|
|
|
32
33
|
}
|
|
33
34
|
exports.isEncodedLabelhash = isEncodedLabelhash;
|
|
34
35
|
function getLabels() {
|
|
35
|
-
return
|
|
36
|
+
return hasLocalStorage
|
|
36
37
|
? JSON.parse(localStorage.getItem('ensjs:labels')) || {}
|
|
37
38
|
: {};
|
|
38
39
|
}
|
|
39
40
|
function _saveLabel(hash, label) {
|
|
40
|
-
if (!
|
|
41
|
+
if (!hasLocalStorage)
|
|
41
42
|
return hash;
|
|
42
43
|
const labels = getLabels();
|
|
43
44
|
localStorage.setItem('ensjs:labels', JSON.stringify({
|
|
@@ -97,7 +98,7 @@ exports.decryptName = decryptName;
|
|
|
97
98
|
const truncateUndecryptedName = (name) => (0, format_1.truncateFormat)(name);
|
|
98
99
|
exports.truncateUndecryptedName = truncateUndecryptedName;
|
|
99
100
|
function checkLocalStorageSize() {
|
|
100
|
-
if (!
|
|
101
|
+
if (!hasLocalStorage)
|
|
101
102
|
return 'Empty (0 KB)';
|
|
102
103
|
let allStrings = '';
|
|
103
104
|
for (const key in window.localStorage) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeNamehashIndexes = exports.makeOtherIndexes = void 0;
|
|
4
|
-
const
|
|
4
|
+
const normalise_1 = require("./normalise");
|
|
5
5
|
const makeOtherIndexes = (data, findStr) => Array.from(data.matchAll(findStr)).map((x) => x.index / 2 - 1);
|
|
6
6
|
exports.makeOtherIndexes = makeOtherIndexes;
|
|
7
|
-
const makeNamehashIndexes = (data, name) => Array.from(data.matchAll(
|
|
7
|
+
const makeNamehashIndexes = (data, name) => Array.from(data.matchAll((0, normalise_1.namehash)(name).substring(2))).map((x) => x.index / 2 - 1);
|
|
8
8
|
exports.makeNamehashIndexes = makeNamehashIndexes;
|
|
@@ -3,7 +3,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.normalise = void 0;
|
|
6
|
+
exports.namehash = exports.normalise = void 0;
|
|
7
|
+
const utils_1 = require("ethers/lib/utils");
|
|
7
8
|
const uts46bundle_js_1 = __importDefault(require("idna-uts46-hx/uts46bundle.js"));
|
|
9
|
+
const labels_1 = require("./labels");
|
|
10
|
+
const zeros = new Uint8Array(32);
|
|
11
|
+
zeros.fill(0);
|
|
8
12
|
const normalise = (name) => name ? uts46bundle_js_1.default.toUnicode(name, { useStd3ASCII: true }) : name;
|
|
9
13
|
exports.normalise = normalise;
|
|
14
|
+
const namehash = (name) => {
|
|
15
|
+
let result = zeros;
|
|
16
|
+
if (name) {
|
|
17
|
+
const labels = name.split('.');
|
|
18
|
+
for (var i = labels.length - 1; i >= 0; i--) {
|
|
19
|
+
let labelSha;
|
|
20
|
+
if ((0, labels_1.isEncodedLabelhash)(labels[i])) {
|
|
21
|
+
labelSha = (0, labels_1.decodeLabelhash)(labels[i]);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const normalised = (0, exports.normalise)(labels[i]);
|
|
25
|
+
labelSha = (0, utils_1.keccak256)((0, utils_1.toUtf8Bytes)(normalised));
|
|
26
|
+
}
|
|
27
|
+
result = (0, utils_1.keccak256)((0, utils_1.concat)([result, labelSha]));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
result = (0, utils_1.hexlify)(zeros);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
exports.namehash = namehash;
|
|
@@ -9,5 +9,8 @@ export declare type RecordOptions = {
|
|
|
9
9
|
coinTypes?: RecordItem[];
|
|
10
10
|
};
|
|
11
11
|
export declare const generateSetAddr: (namehash: string, coinType: string, address: string, resolver: PublicResolver) => string;
|
|
12
|
+
export declare type RecordTypes = 'contentHash' | 'text' | 'addr';
|
|
13
|
+
export declare type RecordInput<T extends RecordTypes> = T extends 'contentHash' ? string : RecordItem;
|
|
14
|
+
export declare function generateSingleRecordCall<T extends RecordTypes>(namehash: string, resolver: PublicResolver, type: T): (record: RecordInput<T>) => string;
|
|
12
15
|
export declare const generateRecordCallArray: (namehash: string, records: RecordOptions, resolver: PublicResolver) => string[];
|
|
13
16
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateRecordCallArray = exports.generateSetAddr = void 0;
|
|
3
|
+
exports.generateRecordCallArray = exports.generateSingleRecordCall = exports.generateSetAddr = void 0;
|
|
4
4
|
const address_encoder_1 = require("@ensdomains/address-encoder");
|
|
5
5
|
const contentHash_1 = require("./contentHash");
|
|
6
6
|
const generateSetAddr = (namehash, coinType, address, resolver) => {
|
|
@@ -16,28 +16,55 @@ const generateSetAddr = (namehash, coinType, address, resolver) => {
|
|
|
16
16
|
return resolver?.interface.encodeFunctionData('setAddr(bytes32,uint256,bytes)', [namehash, inputCoinType, encodedAddress]);
|
|
17
17
|
};
|
|
18
18
|
exports.generateSetAddr = generateSetAddr;
|
|
19
|
+
function generateSingleRecordCall(namehash, resolver, type) {
|
|
20
|
+
if (type === 'contentHash') {
|
|
21
|
+
return (_r) => {
|
|
22
|
+
const record = _r;
|
|
23
|
+
let _contentHash = '';
|
|
24
|
+
if (record !== _contentHash) {
|
|
25
|
+
const encoded = (0, contentHash_1.encodeContenthash)(record);
|
|
26
|
+
if (encoded.error)
|
|
27
|
+
throw new Error(encoded.error);
|
|
28
|
+
_contentHash = encoded.encoded;
|
|
29
|
+
}
|
|
30
|
+
return resolver.interface.encodeFunctionData('setContenthash', [
|
|
31
|
+
namehash,
|
|
32
|
+
_contentHash,
|
|
33
|
+
]);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return (_r) => {
|
|
38
|
+
const record = _r;
|
|
39
|
+
if (type === 'text') {
|
|
40
|
+
return resolver.interface.encodeFunctionData('setText', [
|
|
41
|
+
namehash,
|
|
42
|
+
record.key,
|
|
43
|
+
record.value,
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return (0, exports.generateSetAddr)(namehash, record.key, record.value, resolver);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.generateSingleRecordCall = generateSingleRecordCall;
|
|
19
53
|
const generateRecordCallArray = (namehash, records, resolver) => {
|
|
20
54
|
const calls = [];
|
|
21
55
|
if (records.contentHash) {
|
|
22
|
-
const
|
|
23
|
-
const data = resolver?.interface.encodeFunctionData('setContenthash', [namehash, contentHash]);
|
|
56
|
+
const data = generateSingleRecordCall(namehash, resolver, 'contentHash')(records.contentHash);
|
|
24
57
|
data && calls.push(data);
|
|
25
58
|
}
|
|
26
59
|
if (records.texts && records.texts.length > 0) {
|
|
27
|
-
records.texts
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
key,
|
|
31
|
-
value,
|
|
32
|
-
]);
|
|
33
|
-
data && calls.push(data);
|
|
34
|
-
});
|
|
60
|
+
records.texts
|
|
61
|
+
.map(generateSingleRecordCall(namehash, resolver, 'text'))
|
|
62
|
+
.forEach((call) => calls.push(call));
|
|
35
63
|
}
|
|
36
64
|
if (records.coinTypes && records.coinTypes.length > 0) {
|
|
37
|
-
records.coinTypes
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
65
|
+
records.coinTypes
|
|
66
|
+
.map(generateSingleRecordCall(namehash, resolver, 'addr'))
|
|
67
|
+
.forEach((call) => calls.push(call));
|
|
41
68
|
}
|
|
42
69
|
return calls;
|
|
43
70
|
};
|
|
@@ -7,6 +7,7 @@ exports._makeCommitment = exports.makeCommitment = exports.randomSecret = void 0
|
|
|
7
7
|
const ethers_1 = require("ethers");
|
|
8
8
|
const generateFuseInput_1 = __importDefault(require("./generateFuseInput"));
|
|
9
9
|
const labels_1 = require("./labels");
|
|
10
|
+
const normalise_1 = require("./normalise");
|
|
10
11
|
const recordHelpers_1 = require("./recordHelpers");
|
|
11
12
|
const randomSecret = () => {
|
|
12
13
|
const bytes = Buffer.allocUnsafe(32);
|
|
@@ -15,11 +16,9 @@ const randomSecret = () => {
|
|
|
15
16
|
exports.randomSecret = randomSecret;
|
|
16
17
|
const makeCommitment = ({ name, owner, duration, resolver, records, reverseRecord, fuses, }) => {
|
|
17
18
|
const label = (0, labels_1.labelhash)(name.split('.')[0]);
|
|
18
|
-
const
|
|
19
|
+
const hash = (0, normalise_1.namehash)(name);
|
|
19
20
|
const resolverAddress = resolver.address;
|
|
20
|
-
const data = records
|
|
21
|
-
? (0, recordHelpers_1.generateRecordCallArray)(namehash, records, resolver)
|
|
22
|
-
: [];
|
|
21
|
+
const data = records ? (0, recordHelpers_1.generateRecordCallArray)(hash, records, resolver) : [];
|
|
23
22
|
const secret = (0, exports.randomSecret)();
|
|
24
23
|
const fuseData = fuses ? (0, generateFuseInput_1.default)(fuses) : '0';
|
|
25
24
|
const commitment = (0, exports._makeCommitment)({
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { JsonRpcSigner } from '@ethersproject/providers';
|
|
2
|
+
import type { PopulatedTransaction } from 'ethers';
|
|
3
|
+
declare const _default: (signer: JsonRpcSigner, populate: boolean) => (tx: PopulatedTransaction) => PopulatedTransaction | Promise<import("@ethersproject/abstract-provider").TransactionResponse>;
|
|
4
|
+
export default _default;
|
package/dist/esm/GqlManager.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export declare const enter: (node: any) => any;
|
|
2
|
+
export declare const requestMiddleware: (visit: any, parse: any) => (request: any) => any;
|
|
3
|
+
export declare const responseMiddleware: (traverse: any) => (response: any) => any;
|
|
1
4
|
export default class GqlManager {
|
|
2
5
|
gql: any;
|
|
3
6
|
client?: any | null;
|
package/dist/esm/GqlManager.js
CHANGED
|
@@ -1,11 +1,67 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { namehash } from './utils/normalise';
|
|
3
|
+
const generateSelection = (selection) => ({
|
|
4
|
+
kind: 'Field',
|
|
5
|
+
name: {
|
|
6
|
+
kind: 'Name',
|
|
7
|
+
value: selection,
|
|
8
|
+
},
|
|
9
|
+
arguments: [],
|
|
10
|
+
directives: [],
|
|
11
|
+
alias: undefined,
|
|
12
|
+
selectionSet: undefined,
|
|
13
|
+
});
|
|
14
|
+
export const enter = (node) => {
|
|
15
|
+
if (node.kind === 'SelectionSet') {
|
|
16
|
+
const id = node.selections.find((x) => x.name && x.name.value === 'id');
|
|
17
|
+
const name = node.selections.find((x) => x.name && x.name.value === 'name');
|
|
18
|
+
if (!id && name) {
|
|
19
|
+
node.selections = [...node.selections, generateSelection('id')];
|
|
20
|
+
return node;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
export const requestMiddleware = (visit, parse) => (request) => {
|
|
25
|
+
const requestBody = JSON.parse(request.body);
|
|
26
|
+
const rawQuery = requestBody.query;
|
|
27
|
+
const parsedQuery = parse(rawQuery);
|
|
28
|
+
const updatedQuery = visit(parsedQuery, { enter });
|
|
29
|
+
const updatedBody = { ...requestBody, query: updatedQuery.loc.source.body };
|
|
30
|
+
return {
|
|
31
|
+
...request,
|
|
32
|
+
body: JSON.stringify(updatedBody),
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export const responseMiddleware = (traverse) => (response) => {
|
|
36
|
+
traverse(response).forEach(function (responseItem) {
|
|
37
|
+
if (responseItem instanceof Object && responseItem.name) {
|
|
38
|
+
//Name already in hashed form
|
|
39
|
+
if (responseItem.name && responseItem.name.includes('[')) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const hashedName = namehash(responseItem.name);
|
|
43
|
+
if (responseItem.id !== hashedName) {
|
|
44
|
+
this.update({ ...responseItem, name: hashedName, invalidName: true });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return response;
|
|
49
|
+
};
|
|
1
50
|
export default class GqlManager {
|
|
2
51
|
constructor() {
|
|
3
52
|
this.gql = () => null;
|
|
4
53
|
this.client = null;
|
|
5
54
|
this.setUrl = async (url) => {
|
|
6
55
|
if (url) {
|
|
7
|
-
const imported = await
|
|
8
|
-
|
|
56
|
+
const [imported, traverse, { visit, parse }] = await Promise.all([
|
|
57
|
+
import('graphql-request'),
|
|
58
|
+
import('traverse'),
|
|
59
|
+
import('graphql/language'),
|
|
60
|
+
]);
|
|
61
|
+
this.client = new imported.GraphQLClient(url, {
|
|
62
|
+
requestMiddleware: requestMiddleware(visit, parse),
|
|
63
|
+
responseMiddleware: responseMiddleware(traverse.default),
|
|
64
|
+
});
|
|
9
65
|
this.gql = imported.gql;
|
|
10
66
|
}
|
|
11
67
|
else {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
1
|
import { ENSArgs } from '..';
|
|
3
2
|
import { FuseOptions } from '../@types/FuseOptions';
|
|
4
|
-
export default function ({ contracts,
|
|
3
|
+
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { fusesToBurn, }: {
|
|
4
|
+
fusesToBurn: FuseOptions;
|
|
5
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
1
|
import generateFuseInput from '../utils/generateFuseInput';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!signer) {
|
|
6
|
-
throw new Error('No signer found');
|
|
7
|
-
}
|
|
2
|
+
import { namehash } from '../utils/normalise';
|
|
3
|
+
export default async function ({ contracts, signer }, name, { fusesToBurn, }) {
|
|
8
4
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
9
|
-
const
|
|
5
|
+
const hash = namehash(name);
|
|
10
6
|
const encodedFuses = generateFuseInput(fusesToBurn);
|
|
11
|
-
return nameWrapper.burnFuses(
|
|
7
|
+
return nameWrapper.populateTransaction.burnFuses(hash, encodedFuses);
|
|
12
8
|
}
|
|
@@ -2,18 +2,14 @@ import { ethers } from 'ethers';
|
|
|
2
2
|
import { ENSArgs } from '..';
|
|
3
3
|
import { FuseOptions } from '../@types/FuseOptions';
|
|
4
4
|
declare type BaseArgs = {
|
|
5
|
-
name: string;
|
|
6
5
|
owner: string;
|
|
7
6
|
resolverAddress?: string;
|
|
8
7
|
contract: 'registry' | 'nameWrapper';
|
|
9
|
-
options?: {
|
|
10
|
-
addressOrIndex?: string | number;
|
|
11
|
-
};
|
|
12
8
|
};
|
|
13
9
|
declare type NameWrapperArgs = {
|
|
14
10
|
contract: 'nameWrapper';
|
|
15
11
|
fuses?: FuseOptions;
|
|
16
12
|
} & BaseArgs;
|
|
17
13
|
declare type Args = BaseArgs | NameWrapperArgs;
|
|
18
|
-
export default function ({ contracts,
|
|
14
|
+
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { owner, resolverAddress, contract, ...wrapperArgs }: Args): Promise<ethers.PopulatedTransaction>;
|
|
19
15
|
export {};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
2
|
import generateFuseInput from '../utils/generateFuseInput';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!signer) {
|
|
6
|
-
throw new Error('No signer found');
|
|
7
|
-
}
|
|
3
|
+
import { namehash } from '../utils/normalise';
|
|
4
|
+
export default async function ({ contracts, signer }, name, { owner, resolverAddress, contract, ...wrapperArgs }) {
|
|
8
5
|
const labels = name.split('.');
|
|
9
6
|
if (labels.length === 1) {
|
|
10
7
|
throw new Error('Subnames in ENS.js can only be created for 2LDs, not TLDs');
|
|
@@ -17,18 +14,18 @@ export default async function ({ contracts, provider }, { name, owner, resolverA
|
|
|
17
14
|
}
|
|
18
15
|
const label = labels.shift();
|
|
19
16
|
const labelhash = ethers.utils.solidityKeccak256(['string'], [label]);
|
|
20
|
-
const parentNodehash =
|
|
17
|
+
const parentNodehash = namehash(labels.join('.'));
|
|
21
18
|
switch (contract) {
|
|
22
19
|
case 'registry': {
|
|
23
20
|
const registry = (await contracts?.getRegistry()).connect(signer);
|
|
24
|
-
return registry.setSubnodeRecord(parentNodehash, labelhash, owner, resolverAddress, 0);
|
|
21
|
+
return registry.populateTransaction.setSubnodeRecord(parentNodehash, labelhash, owner, resolverAddress, 0);
|
|
25
22
|
}
|
|
26
23
|
case 'nameWrapper': {
|
|
27
24
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
28
25
|
const generatedFuses = 'fuses' in wrapperArgs && wrapperArgs.fuses
|
|
29
26
|
? generateFuseInput(wrapperArgs.fuses)
|
|
30
27
|
: '0';
|
|
31
|
-
return nameWrapper.setSubnodeRecord(parentNodehash, label, owner, resolverAddress, 0, generatedFuses);
|
|
28
|
+
return nameWrapper.populateTransaction.setSubnodeRecord(parentNodehash, label, owner, resolverAddress, 0, generatedFuses);
|
|
32
29
|
}
|
|
33
30
|
default: {
|
|
34
31
|
throw new Error(`Unknown contract: ${contract}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ENSArgs } from '..';
|
|
2
|
-
export default function ({
|
|
3
|
-
|
|
4
|
-
}): Promise<import("ethers").
|
|
2
|
+
export default function ({ transferSubname }: ENSArgs<'transferSubname'>, name: string, { contract, }: {
|
|
3
|
+
contract: 'registry' | 'nameWrapper';
|
|
4
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
export default async function ({
|
|
2
|
-
return transferSubname(name,
|
|
1
|
+
export default async function ({ transferSubname }, name, { contract, }) {
|
|
2
|
+
return transferSubname.populateTransaction(name, {
|
|
3
|
+
contract,
|
|
4
|
+
address: '0x0000000000000000000000000000000000000000',
|
|
5
|
+
});
|
|
3
6
|
}
|
|
@@ -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 (_: any, 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
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { utils } from 'ethers';
|
|
2
2
|
import { testable as fuseEnums } from '../utils/fuses';
|
|
3
|
+
import { namehash } from '../utils/normalise';
|
|
3
4
|
const NameSafety = [
|
|
4
5
|
'Safe',
|
|
5
6
|
'RegistrantNotWrapped',
|
|
@@ -12,7 +13,7 @@ const raw = async ({ contracts }, name) => {
|
|
|
12
13
|
return {
|
|
13
14
|
to: nameWrapper.address,
|
|
14
15
|
data: nameWrapper.interface.encodeFunctionData('getFuses', [
|
|
15
|
-
|
|
16
|
+
namehash(name),
|
|
16
17
|
]),
|
|
17
18
|
};
|
|
18
19
|
};
|
|
@@ -36,7 +37,7 @@ const decode = async ({ contracts }, data, name) => {
|
|
|
36
37
|
if (utils.hexStripZeros(vulnerableNode) !== '0x') {
|
|
37
38
|
name.split('.').forEach((label, index, arr) => {
|
|
38
39
|
const node = arr.slice(index).join('.');
|
|
39
|
-
const nodehash =
|
|
40
|
+
const nodehash = namehash(node);
|
|
40
41
|
if (nodehash === vulnerableNode) {
|
|
41
42
|
returnVulnerableNode = node;
|
|
42
43
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
2
|
import { labelhash } from '../utils/labels';
|
|
3
|
+
import { namehash as makeNamehash } from '../utils/normalise';
|
|
3
4
|
const singleContractOwnerRaw = async ({ contracts }, contract, namehash, labels) => {
|
|
4
5
|
switch (contract) {
|
|
5
6
|
case 'nameWrapper': {
|
|
@@ -28,10 +29,10 @@ const singleContractOwnerRaw = async ({ contracts }, contract, namehash, labels)
|
|
|
28
29
|
}
|
|
29
30
|
};
|
|
30
31
|
const raw = async ({ contracts, multicallWrapper }, name, contract) => {
|
|
31
|
-
const namehash =
|
|
32
|
+
const namehash = makeNamehash(name);
|
|
32
33
|
const labels = name.split('.');
|
|
33
|
-
if (contract) {
|
|
34
|
-
return await singleContractOwnerRaw({ contracts }, contract, namehash, labels);
|
|
34
|
+
if (contract || labels.length === 1) {
|
|
35
|
+
return await singleContractOwnerRaw({ contracts }, contract || 'registry', namehash, labels);
|
|
35
36
|
}
|
|
36
37
|
const registryData = await singleContractOwnerRaw({ contracts }, 'registry', namehash, labels);
|
|
37
38
|
const nameWrapperData = await singleContractOwnerRaw({ contracts }, 'nameWrapper', namehash, labels);
|
|
@@ -46,10 +47,11 @@ const singleContractOwnerDecode = (data) => ethers.utils.defaultAbiCoder.decode(
|
|
|
46
47
|
const decode = async ({ contracts, multicallWrapper }, data, name, contract) => {
|
|
47
48
|
if (data === null)
|
|
48
49
|
return;
|
|
49
|
-
|
|
50
|
+
const labels = name.split('.');
|
|
51
|
+
if (contract || labels.length === 1) {
|
|
50
52
|
const singleOwner = singleContractOwnerDecode(data);
|
|
51
53
|
let obj = {
|
|
52
|
-
ownershipLevel: contract,
|
|
54
|
+
ownershipLevel: contract || 'registry',
|
|
53
55
|
};
|
|
54
56
|
if (contract === 'registrar') {
|
|
55
57
|
return {
|
|
@@ -74,7 +76,6 @@ const decode = async ({ contracts, multicallWrapper }, data, name, contract) =>
|
|
|
74
76
|
const registryOwner = decodedData[0][0];
|
|
75
77
|
const nameWrapperOwner = decodedData[1][0];
|
|
76
78
|
const registrarOwner = decodedData[2]?.[0];
|
|
77
|
-
const labels = name.split('.');
|
|
78
79
|
// check for only .eth names
|
|
79
80
|
if (labels[labels.length - 1] === 'eth') {
|
|
80
81
|
// if the owner on the registrar is the namewrapper, then the namewrapper owner is the owner
|