@ensdomains/ensjs 3.0.0-alpha.43 → 3.0.0-alpha.44
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/dist/cjs/contracts/getContractAddress.js +3 -3
- package/dist/cjs/functions/batch.js +14 -6
- package/dist/cjs/functions/getExpiry.js +2 -1
- package/dist/cjs/functions/getHistory.js +16 -9
- package/dist/cjs/functions/getOwner.js +2 -1
- package/dist/cjs/functions/getWrapperData.js +1 -1
- package/dist/cjs/functions/unwrapName.js +2 -1
- package/dist/cjs/functions/wrapName.js +2 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/utils/ccip.js +1 -1
- package/dist/cjs/utils/fuses.js +3 -2
- package/dist/cjs/utils/singleCall.js +9 -1
- package/dist/cjs/utils/validation.js +2 -0
- package/dist/esm/contracts/getContractAddress.mjs +3 -3
- package/dist/esm/functions/batch.mjs +14 -6
- package/dist/esm/functions/getExpiry.mjs +2 -1
- package/dist/esm/functions/getHistory.mjs +16 -9
- package/dist/esm/functions/getOwner.mjs +2 -1
- package/dist/esm/functions/getWrapperData.mjs +1 -1
- package/dist/esm/functions/unwrapName.mjs +2 -1
- package/dist/esm/functions/wrapName.mjs +2 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/utils/ccip.mjs +1 -1
- package/dist/esm/utils/fuses.mjs +3 -2
- package/dist/esm/utils/singleCall.mjs +9 -1
- package/dist/esm/utils/validation.mjs +2 -0
- package/dist/types/functions/batch.d.ts +8 -1
- package/dist/types/functions/getHistory.d.ts +16 -0
- package/dist/types/index.d.ts +23 -1
- package/dist/types/utils/fuses.d.ts +1 -0
- package/dist/types/utils/singleCall.d.ts +1 -0
- package/dist/types/utils/validation.d.ts +1 -0
- package/package.json +2 -2
- package/src/contracts/getContractAddress.ts +3 -3
- package/src/functions/batch.ts +15 -5
- package/src/functions/ccip.test.ts +62 -0
- package/src/functions/getExpiry.ts +2 -1
- package/src/functions/getHistory.test.ts +11 -0
- package/src/functions/getHistory.ts +16 -9
- package/src/functions/getOwner.ts +2 -1
- package/src/functions/getWrapperData.test.ts +3 -0
- package/src/functions/getWrapperData.ts +1 -1
- package/src/functions/unwrapName.ts +2 -1
- package/src/functions/wrapName.ts +2 -1
- package/src/index.ts +1 -1
- package/src/utils/ccip.ts +1 -1
- package/src/utils/fuses.ts +4 -4
- package/src/utils/singleCall.ts +11 -6
- package/src/utils/validation.ts +3 -0
- package/src/functions/getProfile-ccip.test.ts +0 -29
|
@@ -37,19 +37,19 @@ const addresses = {
|
|
|
37
37
|
"1": "0x283af0b28c62c092c9727f1ee09c02ca627eb7f5",
|
|
38
38
|
"3": "0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8",
|
|
39
39
|
"4": "0x283af0b28c62c092c9727f1ee09c02ca627eb7f5",
|
|
40
|
-
"5": "
|
|
40
|
+
"5": "0x603A4F2e7615d0099244496883062bA2eFBbeaf0"
|
|
41
41
|
},
|
|
42
42
|
Multicall: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
43
43
|
NameWrapper: {
|
|
44
44
|
"1": "0x0000000000000000000000000000000000000000",
|
|
45
45
|
"3": "0xF82155e2a43Be0871821E9654Fc8Ae894FB8307C",
|
|
46
46
|
"4": "0x0000000000000000000000000000000000000000",
|
|
47
|
-
"5": "
|
|
47
|
+
"5": "0x060f1546642E67c485D56248201feA2f9AB1803C"
|
|
48
48
|
},
|
|
49
49
|
PublicResolver: {
|
|
50
50
|
"1": "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41",
|
|
51
51
|
"3": "0x13F0659Ee6bb7484C884FEeFb7F75C93951ef837",
|
|
52
|
-
"5": "
|
|
52
|
+
"5": "0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001"
|
|
53
53
|
},
|
|
54
54
|
ENSRegistry: {
|
|
55
55
|
"1": "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e",
|
|
@@ -30,16 +30,24 @@ const raw = async ({ multicallWrapper }, ...items) => {
|
|
|
30
30
|
return rawRef(...args);
|
|
31
31
|
})
|
|
32
32
|
);
|
|
33
|
-
|
|
33
|
+
const response = await multicallWrapper.raw(rawDataArr);
|
|
34
|
+
return { ...response, passthrough: rawDataArr };
|
|
34
35
|
};
|
|
35
|
-
const decode = async ({ multicallWrapper }, data, ...items) => {
|
|
36
|
-
const response = await multicallWrapper.decode(data);
|
|
36
|
+
const decode = async ({ multicallWrapper }, data, passthrough, ...items) => {
|
|
37
|
+
const response = await multicallWrapper.decode(data, passthrough);
|
|
37
38
|
if (!response)
|
|
38
39
|
return;
|
|
39
40
|
return Promise.all(
|
|
40
|
-
response.map(
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
response.map((ret, i) => {
|
|
42
|
+
if (passthrough[i].passthrough) {
|
|
43
|
+
return items[i].decode(
|
|
44
|
+
ret.returnData,
|
|
45
|
+
passthrough[i].passthrough,
|
|
46
|
+
...items[i].args
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return items[i].decode(ret.returnData, ...items[i].args);
|
|
50
|
+
})
|
|
43
51
|
);
|
|
44
52
|
};
|
|
45
53
|
var batch_default = {
|
|
@@ -23,6 +23,7 @@ __export(getExpiry_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(getExpiry_exports);
|
|
24
24
|
var import_solidity = require("@ethersproject/solidity");
|
|
25
25
|
var import_normalise = require("../utils/normalise");
|
|
26
|
+
var import_validation = require("../utils/validation");
|
|
26
27
|
const getRegistrarExpiry = async ({ contracts, multicallWrapper }, labels) => {
|
|
27
28
|
if (labels.length > 2 || labels[1] !== "eth") {
|
|
28
29
|
throw new Error("Only .eth names have expiry dates on the registrar");
|
|
@@ -56,7 +57,7 @@ const getWrapperExpiry = async ({ contracts }, labels) => {
|
|
|
56
57
|
const getContractToUse = (contract, labels) => {
|
|
57
58
|
if (contract)
|
|
58
59
|
return contract;
|
|
59
|
-
if (
|
|
60
|
+
if ((0, import_validation.checkIsDotEth)(labels)) {
|
|
60
61
|
return "registrar";
|
|
61
62
|
}
|
|
62
63
|
return "nameWrapper";
|
|
@@ -24,8 +24,8 @@ module.exports = __toCommonJS(getHistory_exports);
|
|
|
24
24
|
var import_address_encoder = require("@ensdomains/address-encoder");
|
|
25
25
|
var import_bytes = require("@ethersproject/bytes");
|
|
26
26
|
var import_contentHash = require("../utils/contentHash");
|
|
27
|
-
var import_labels = require("../utils/labels");
|
|
28
27
|
var import_normalise = require("../utils/normalise");
|
|
28
|
+
var import_validation = require("../utils/validation");
|
|
29
29
|
const eventFormat = {
|
|
30
30
|
Domain: {
|
|
31
31
|
NewOwner: (args) => ({ owner: args.owner.id }),
|
|
@@ -106,7 +106,7 @@ const mapEvents = (eventArray, type) => eventArray.map(
|
|
|
106
106
|
async function getHistory({ gqlInstance }, name) {
|
|
107
107
|
const { client } = gqlInstance;
|
|
108
108
|
const query = gqlInstance.gql`
|
|
109
|
-
query getHistory($namehash: String
|
|
109
|
+
query getHistory($namehash: String!) {
|
|
110
110
|
domain(id: $namehash) {
|
|
111
111
|
events {
|
|
112
112
|
id
|
|
@@ -226,32 +226,39 @@ async function getHistory({ gqlInstance }, name) {
|
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
`;
|
|
229
|
-
const label = name.split(".")[0];
|
|
230
229
|
const nameHash = (0, import_normalise.namehash)(name);
|
|
231
|
-
const
|
|
230
|
+
const labels = name.split(".");
|
|
231
|
+
const is2ldEth = (0, import_validation.checkIsDotEth)(labels);
|
|
232
232
|
const response = await client.request(query, {
|
|
233
|
-
namehash: nameHash
|
|
234
|
-
labelhash: labelHash
|
|
233
|
+
namehash: nameHash
|
|
235
234
|
});
|
|
236
235
|
const domain = response == null ? void 0 : response.domain;
|
|
237
236
|
if (!domain)
|
|
238
237
|
return;
|
|
239
238
|
const {
|
|
240
239
|
events: domainEvents,
|
|
241
|
-
registration: { events: registrationEvents },
|
|
242
240
|
resolver: { events: resolverEvents }
|
|
243
241
|
} = domain;
|
|
244
242
|
const domainHistory = mapEvents(domainEvents, "Domain");
|
|
245
|
-
const registrationHistory = mapEvents(registrationEvents, "Registration");
|
|
246
243
|
const resolverHistory = mapEvents(
|
|
247
244
|
resolverEvents.filter(
|
|
248
245
|
(event) => !event.coinType || event.coinType !== "60"
|
|
249
246
|
),
|
|
250
247
|
"Resolver"
|
|
251
248
|
);
|
|
249
|
+
if (is2ldEth) {
|
|
250
|
+
const {
|
|
251
|
+
registration: { events: registrationEvents }
|
|
252
|
+
} = domain;
|
|
253
|
+
const registrationHistory = mapEvents(registrationEvents, "Registration");
|
|
254
|
+
return {
|
|
255
|
+
domain: domainHistory,
|
|
256
|
+
registration: registrationHistory,
|
|
257
|
+
resolver: resolverHistory
|
|
258
|
+
};
|
|
259
|
+
}
|
|
252
260
|
return {
|
|
253
261
|
domain: domainHistory,
|
|
254
|
-
registration: registrationHistory,
|
|
255
262
|
resolver: resolverHistory
|
|
256
263
|
};
|
|
257
264
|
}
|
|
@@ -25,6 +25,7 @@ var import_abi = require("@ethersproject/abi");
|
|
|
25
25
|
var import_bytes = require("@ethersproject/bytes");
|
|
26
26
|
var import_labels = require("../utils/labels");
|
|
27
27
|
var import_normalise = require("../utils/normalise");
|
|
28
|
+
var import_validation = require("../utils/validation");
|
|
28
29
|
const singleContractOwnerRaw = async ({ contracts }, contract, namehash, labels) => {
|
|
29
30
|
switch (contract) {
|
|
30
31
|
case "nameWrapper": {
|
|
@@ -82,7 +83,7 @@ const raw = async ({ contracts, multicallWrapper }, name, contract) => {
|
|
|
82
83
|
labels
|
|
83
84
|
);
|
|
84
85
|
const data = [registryData, nameWrapperData];
|
|
85
|
-
if (
|
|
86
|
+
if ((0, import_validation.checkIsDotEth)(labels)) {
|
|
86
87
|
data.push(registrarData);
|
|
87
88
|
}
|
|
88
89
|
return multicallWrapper.raw(data);
|
|
@@ -39,7 +39,7 @@ const decode = async ({ contracts }, data) => {
|
|
|
39
39
|
data
|
|
40
40
|
);
|
|
41
41
|
const fuseObj = (0, import_fuses.decodeFuses)(fuses);
|
|
42
|
-
const expiryDate = expiry.gt(0) && expiry.lt(import_bignumber.BigNumber.from(2).pow(32)) ? new Date(expiry.mul(1e3).
|
|
42
|
+
const expiryDate = expiry.gt(0) && expiry.lt(import_bignumber.BigNumber.from(2).pow(32)) ? new Date(expiry.mul(1e3).toNumber()) : void 0;
|
|
43
43
|
return {
|
|
44
44
|
...fuseObj,
|
|
45
45
|
expiryDate,
|
|
@@ -23,6 +23,7 @@ __export(unwrapName_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(unwrapName_exports);
|
|
24
24
|
var import_solidity = require("@ethersproject/solidity");
|
|
25
25
|
var import_normalise = require("../utils/normalise");
|
|
26
|
+
var import_validation = require("../utils/validation");
|
|
26
27
|
async function unwrapName_default({ contracts, signer }, name, {
|
|
27
28
|
newController,
|
|
28
29
|
newRegistrant
|
|
@@ -31,7 +32,7 @@ async function unwrapName_default({ contracts, signer }, name, {
|
|
|
31
32
|
const labelhash = (0, import_solidity.keccak256)(["string"], [labels[0]]);
|
|
32
33
|
const parentNodehash = (0, import_normalise.namehash)(labels.slice(1).join("."));
|
|
33
34
|
const nameWrapper = (await contracts.getNameWrapper()).connect(signer);
|
|
34
|
-
if (
|
|
35
|
+
if ((0, import_validation.checkIsDotEth)(labels)) {
|
|
35
36
|
if (!newRegistrant) {
|
|
36
37
|
throw new Error("newRegistrant must be specified for .eth names");
|
|
37
38
|
}
|
|
@@ -25,6 +25,7 @@ var import_abi = require("@ethersproject/abi");
|
|
|
25
25
|
var import_solidity = require("@ethersproject/solidity");
|
|
26
26
|
var import_fuses = require("../utils/fuses");
|
|
27
27
|
var import_hexEncodedName = require("../utils/hexEncodedName");
|
|
28
|
+
var import_validation = require("../utils/validation");
|
|
28
29
|
var import_wrapper = require("../utils/wrapper");
|
|
29
30
|
async function wrapETH({ contracts }, labels, wrappedOwner, decodedFuses, resolverAddress, signer, address) {
|
|
30
31
|
const nameWrapper = await (contracts == null ? void 0 : contracts.getNameWrapper());
|
|
@@ -67,7 +68,7 @@ async function wrapName_default({ contracts, signer }, name, {
|
|
|
67
68
|
resolverAddress = publicResolver.address;
|
|
68
69
|
const labels = name.split(".");
|
|
69
70
|
(0, import_wrapper.wrappedLabelLengthCheck)(labels[0]);
|
|
70
|
-
if (
|
|
71
|
+
if ((0, import_validation.checkIsDotEth)(labels)) {
|
|
71
72
|
switch (typeof fuseOptions) {
|
|
72
73
|
case "object": {
|
|
73
74
|
decodedFuses = (0, import_fuses.encodeFuses)(fuseOptions);
|
package/dist/cjs/index.js
CHANGED
|
@@ -281,7 +281,7 @@ class ENS {
|
|
|
281
281
|
this.getDecryptedName = this.generateRawFunction("getDecryptedName", ["contracts", "gqlInstance"]);
|
|
282
282
|
this.universalWrapper = this.generateRawFunction("initialGetters", ["contracts"], "universalWrapper");
|
|
283
283
|
this.resolverMulticallWrapper = this.generateRawFunction("initialGetters", ["contracts"], "resolverMulticallWrapper");
|
|
284
|
-
this.multicallWrapper = this.generateRawFunction("initialGetters", ["contracts"], "multicallWrapper");
|
|
284
|
+
this.multicallWrapper = this.generateRawFunction("initialGetters", ["contracts", "provider"], "multicallWrapper");
|
|
285
285
|
this.setName = this.generateWriteFunction(
|
|
286
286
|
"setName",
|
|
287
287
|
["contracts"]
|
package/dist/cjs/utils/ccip.js
CHANGED
|
@@ -115,7 +115,7 @@ const ccipLookup = async (provider, transaction, result) => {
|
|
|
115
115
|
throw new Error("CCIP Read disabled or provided no URLs");
|
|
116
116
|
}
|
|
117
117
|
const tx = {
|
|
118
|
-
to:
|
|
118
|
+
to: txSender,
|
|
119
119
|
data: (0, import_bytes.hexConcat)([
|
|
120
120
|
callbackSelector,
|
|
121
121
|
encodeBytes([ccipResult, extraData])
|
package/dist/cjs/utils/fuses.js
CHANGED
|
@@ -74,6 +74,7 @@ const userSettableFuseEnum = {
|
|
|
74
74
|
};
|
|
75
75
|
const fullFuseEnum = {
|
|
76
76
|
...userSettableFuseEnum,
|
|
77
|
+
...fullParentFuseEnum,
|
|
77
78
|
CAN_DO_EVERYTHING
|
|
78
79
|
};
|
|
79
80
|
const unnamedChildFuses = [
|
|
@@ -256,14 +257,14 @@ const decodeNamedFuses = (fuses, arr) => {
|
|
|
256
257
|
const fuseObj = Object.fromEntries(
|
|
257
258
|
arr.map((fuse) => [
|
|
258
259
|
fuse,
|
|
259
|
-
(fuses &
|
|
260
|
+
(fuses & fullFuseEnum[fuse]) === fullFuseEnum[fuse]
|
|
260
261
|
])
|
|
261
262
|
);
|
|
262
263
|
return fuseObj;
|
|
263
264
|
};
|
|
264
265
|
const decodeUnnamedFuses = (fuses, arr) => {
|
|
265
266
|
const fuseObj = Object.fromEntries(
|
|
266
|
-
arr.map((fuse) => [fuse, (fuses & fuse)
|
|
267
|
+
arr.map((fuse) => [fuse, (fuses & fuse) === fuse])
|
|
267
268
|
);
|
|
268
269
|
return fuseObj;
|
|
269
270
|
};
|
|
@@ -21,4 +21,12 @@ __export(singleCall_exports, {
|
|
|
21
21
|
default: () => singleCall_default
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(singleCall_exports);
|
|
24
|
-
var singleCall_default = async (provider, ensData, func, ...data) =>
|
|
24
|
+
var singleCall_default = async (provider, ensData, func, ...data) => {
|
|
25
|
+
const { passthrough, ...rawData } = await func.raw(ensData, ...data);
|
|
26
|
+
const result = await provider.call({ ...rawData, ccipReadEnabled: true }).catch(() => null);
|
|
27
|
+
if (!result)
|
|
28
|
+
return;
|
|
29
|
+
if (passthrough)
|
|
30
|
+
return func.decode(ensData, result, passthrough, ...data);
|
|
31
|
+
return func.decode(ensData, result, ...data);
|
|
32
|
+
};
|
|
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var validation_exports = {};
|
|
20
20
|
__export(validation_exports, {
|
|
21
|
+
checkIsDotEth: () => checkIsDotEth,
|
|
21
22
|
parseInputType: () => parseInputType,
|
|
22
23
|
validateName: () => validateName,
|
|
23
24
|
validateTLD: () => validateTLD
|
|
@@ -84,3 +85,4 @@ const parseInputType = (input) => {
|
|
|
84
85
|
type: "label"
|
|
85
86
|
};
|
|
86
87
|
};
|
|
88
|
+
const checkIsDotEth = (labels) => labels.length === 2 && labels[1] === "eth";
|
|
@@ -15,19 +15,19 @@ var addresses = {
|
|
|
15
15
|
"1": "0x283af0b28c62c092c9727f1ee09c02ca627eb7f5",
|
|
16
16
|
"3": "0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8",
|
|
17
17
|
"4": "0x283af0b28c62c092c9727f1ee09c02ca627eb7f5",
|
|
18
|
-
"5": "
|
|
18
|
+
"5": "0x603A4F2e7615d0099244496883062bA2eFBbeaf0"
|
|
19
19
|
},
|
|
20
20
|
Multicall: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
|
21
21
|
NameWrapper: {
|
|
22
22
|
"1": "0x0000000000000000000000000000000000000000",
|
|
23
23
|
"3": "0xF82155e2a43Be0871821E9654Fc8Ae894FB8307C",
|
|
24
24
|
"4": "0x0000000000000000000000000000000000000000",
|
|
25
|
-
"5": "
|
|
25
|
+
"5": "0x060f1546642E67c485D56248201feA2f9AB1803C"
|
|
26
26
|
},
|
|
27
27
|
PublicResolver: {
|
|
28
28
|
"1": "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41",
|
|
29
29
|
"3": "0x13F0659Ee6bb7484C884FEeFb7F75C93951ef837",
|
|
30
|
-
"5": "
|
|
30
|
+
"5": "0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001"
|
|
31
31
|
},
|
|
32
32
|
ENSRegistry: {
|
|
33
33
|
"1": "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e",
|
|
@@ -8,16 +8,24 @@ var raw = async ({ multicallWrapper }, ...items) => {
|
|
|
8
8
|
return rawRef(...args);
|
|
9
9
|
})
|
|
10
10
|
);
|
|
11
|
-
|
|
11
|
+
const response = await multicallWrapper.raw(rawDataArr);
|
|
12
|
+
return { ...response, passthrough: rawDataArr };
|
|
12
13
|
};
|
|
13
|
-
var decode = async ({ multicallWrapper }, data, ...items) => {
|
|
14
|
-
const response = await multicallWrapper.decode(data);
|
|
14
|
+
var decode = async ({ multicallWrapper }, data, passthrough, ...items) => {
|
|
15
|
+
const response = await multicallWrapper.decode(data, passthrough);
|
|
15
16
|
if (!response)
|
|
16
17
|
return;
|
|
17
18
|
return Promise.all(
|
|
18
|
-
response.map(
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
response.map((ret, i) => {
|
|
20
|
+
if (passthrough[i].passthrough) {
|
|
21
|
+
return items[i].decode(
|
|
22
|
+
ret.returnData,
|
|
23
|
+
passthrough[i].passthrough,
|
|
24
|
+
...items[i].args
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return items[i].decode(ret.returnData, ...items[i].args);
|
|
28
|
+
})
|
|
21
29
|
);
|
|
22
30
|
};
|
|
23
31
|
var batch_default = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/functions/getExpiry.ts
|
|
2
2
|
import { keccak256 as solidityKeccak256 } from "@ethersproject/solidity";
|
|
3
3
|
import { namehash } from "../utils/normalise.mjs";
|
|
4
|
+
import { checkIsDotEth } from "../utils/validation.mjs";
|
|
4
5
|
var getRegistrarExpiry = async ({ contracts, multicallWrapper }, labels) => {
|
|
5
6
|
if (labels.length > 2 || labels[1] !== "eth") {
|
|
6
7
|
throw new Error("Only .eth names have expiry dates on the registrar");
|
|
@@ -34,7 +35,7 @@ var getWrapperExpiry = async ({ contracts }, labels) => {
|
|
|
34
35
|
var getContractToUse = (contract, labels) => {
|
|
35
36
|
if (contract)
|
|
36
37
|
return contract;
|
|
37
|
-
if (labels
|
|
38
|
+
if (checkIsDotEth(labels)) {
|
|
38
39
|
return "registrar";
|
|
39
40
|
}
|
|
40
41
|
return "nameWrapper";
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { formatsByCoinType } from "@ensdomains/address-encoder";
|
|
3
3
|
import { hexStripZeros } from "@ethersproject/bytes";
|
|
4
4
|
import { decodeContenthash } from "../utils/contentHash.mjs";
|
|
5
|
-
import { labelhash } from "../utils/labels.mjs";
|
|
6
5
|
import { namehash } from "../utils/normalise.mjs";
|
|
6
|
+
import { checkIsDotEth } from "../utils/validation.mjs";
|
|
7
7
|
var eventFormat = {
|
|
8
8
|
Domain: {
|
|
9
9
|
NewOwner: (args) => ({ owner: args.owner.id }),
|
|
@@ -84,7 +84,7 @@ var mapEvents = (eventArray, type) => eventArray.map(
|
|
|
84
84
|
async function getHistory({ gqlInstance }, name) {
|
|
85
85
|
const { client } = gqlInstance;
|
|
86
86
|
const query = gqlInstance.gql`
|
|
87
|
-
query getHistory($namehash: String
|
|
87
|
+
query getHistory($namehash: String!) {
|
|
88
88
|
domain(id: $namehash) {
|
|
89
89
|
events {
|
|
90
90
|
id
|
|
@@ -204,32 +204,39 @@ async function getHistory({ gqlInstance }, name) {
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
`;
|
|
207
|
-
const label = name.split(".")[0];
|
|
208
207
|
const nameHash = namehash(name);
|
|
209
|
-
const
|
|
208
|
+
const labels = name.split(".");
|
|
209
|
+
const is2ldEth = checkIsDotEth(labels);
|
|
210
210
|
const response = await client.request(query, {
|
|
211
|
-
namehash: nameHash
|
|
212
|
-
labelhash: labelHash
|
|
211
|
+
namehash: nameHash
|
|
213
212
|
});
|
|
214
213
|
const domain = response?.domain;
|
|
215
214
|
if (!domain)
|
|
216
215
|
return;
|
|
217
216
|
const {
|
|
218
217
|
events: domainEvents,
|
|
219
|
-
registration: { events: registrationEvents },
|
|
220
218
|
resolver: { events: resolverEvents }
|
|
221
219
|
} = domain;
|
|
222
220
|
const domainHistory = mapEvents(domainEvents, "Domain");
|
|
223
|
-
const registrationHistory = mapEvents(registrationEvents, "Registration");
|
|
224
221
|
const resolverHistory = mapEvents(
|
|
225
222
|
resolverEvents.filter(
|
|
226
223
|
(event) => !event.coinType || event.coinType !== "60"
|
|
227
224
|
),
|
|
228
225
|
"Resolver"
|
|
229
226
|
);
|
|
227
|
+
if (is2ldEth) {
|
|
228
|
+
const {
|
|
229
|
+
registration: { events: registrationEvents }
|
|
230
|
+
} = domain;
|
|
231
|
+
const registrationHistory = mapEvents(registrationEvents, "Registration");
|
|
232
|
+
return {
|
|
233
|
+
domain: domainHistory,
|
|
234
|
+
registration: registrationHistory,
|
|
235
|
+
resolver: resolverHistory
|
|
236
|
+
};
|
|
237
|
+
}
|
|
230
238
|
return {
|
|
231
239
|
domain: domainHistory,
|
|
232
|
-
registration: registrationHistory,
|
|
233
240
|
resolver: resolverHistory
|
|
234
241
|
};
|
|
235
242
|
}
|
|
@@ -3,6 +3,7 @@ import { defaultAbiCoder } from "@ethersproject/abi";
|
|
|
3
3
|
import { hexStripZeros } from "@ethersproject/bytes";
|
|
4
4
|
import { labelhash } from "../utils/labels.mjs";
|
|
5
5
|
import { namehash as makeNamehash } from "../utils/normalise.mjs";
|
|
6
|
+
import { checkIsDotEth } from "../utils/validation.mjs";
|
|
6
7
|
var singleContractOwnerRaw = async ({ contracts }, contract, namehash, labels) => {
|
|
7
8
|
switch (contract) {
|
|
8
9
|
case "nameWrapper": {
|
|
@@ -60,7 +61,7 @@ var raw = async ({ contracts, multicallWrapper }, name, contract) => {
|
|
|
60
61
|
labels
|
|
61
62
|
);
|
|
62
63
|
const data = [registryData, nameWrapperData];
|
|
63
|
-
if (labels
|
|
64
|
+
if (checkIsDotEth(labels)) {
|
|
64
65
|
data.push(registrarData);
|
|
65
66
|
}
|
|
66
67
|
return multicallWrapper.raw(data);
|
|
@@ -17,7 +17,7 @@ var decode = async ({ contracts }, data) => {
|
|
|
17
17
|
data
|
|
18
18
|
);
|
|
19
19
|
const fuseObj = decodeFuses(fuses);
|
|
20
|
-
const expiryDate = expiry.gt(0) && expiry.lt(BigNumber.from(2).pow(32)) ? new Date(expiry.mul(1e3).
|
|
20
|
+
const expiryDate = expiry.gt(0) && expiry.lt(BigNumber.from(2).pow(32)) ? new Date(expiry.mul(1e3).toNumber()) : void 0;
|
|
21
21
|
return {
|
|
22
22
|
...fuseObj,
|
|
23
23
|
expiryDate,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/functions/unwrapName.ts
|
|
2
2
|
import { keccak256 as solidityKeccak256 } from "@ethersproject/solidity";
|
|
3
3
|
import { namehash } from "../utils/normalise.mjs";
|
|
4
|
+
import { checkIsDotEth } from "../utils/validation.mjs";
|
|
4
5
|
async function unwrapName_default({ contracts, signer }, name, {
|
|
5
6
|
newController,
|
|
6
7
|
newRegistrant
|
|
@@ -9,7 +10,7 @@ async function unwrapName_default({ contracts, signer }, name, {
|
|
|
9
10
|
const labelhash = solidityKeccak256(["string"], [labels[0]]);
|
|
10
11
|
const parentNodehash = namehash(labels.slice(1).join("."));
|
|
11
12
|
const nameWrapper = (await contracts.getNameWrapper()).connect(signer);
|
|
12
|
-
if (labels
|
|
13
|
+
if (checkIsDotEth(labels)) {
|
|
13
14
|
if (!newRegistrant) {
|
|
14
15
|
throw new Error("newRegistrant must be specified for .eth names");
|
|
15
16
|
}
|
|
@@ -3,6 +3,7 @@ import { defaultAbiCoder } from "@ethersproject/abi";
|
|
|
3
3
|
import { keccak256 as solidityKeccak256 } from "@ethersproject/solidity";
|
|
4
4
|
import { encodeFuses } from "../utils/fuses.mjs";
|
|
5
5
|
import { hexEncodeName } from "../utils/hexEncodedName.mjs";
|
|
6
|
+
import { checkIsDotEth } from "../utils/validation.mjs";
|
|
6
7
|
import { wrappedLabelLengthCheck } from "../utils/wrapper.mjs";
|
|
7
8
|
async function wrapETH({ contracts }, labels, wrappedOwner, decodedFuses, resolverAddress, signer, address) {
|
|
8
9
|
const nameWrapper = await contracts?.getNameWrapper();
|
|
@@ -45,7 +46,7 @@ async function wrapName_default({ contracts, signer }, name, {
|
|
|
45
46
|
resolverAddress = publicResolver.address;
|
|
46
47
|
const labels = name.split(".");
|
|
47
48
|
wrappedLabelLengthCheck(labels[0]);
|
|
48
|
-
if (labels
|
|
49
|
+
if (checkIsDotEth(labels)) {
|
|
49
50
|
switch (typeof fuseOptions) {
|
|
50
51
|
case "object": {
|
|
51
52
|
decodedFuses = encodeFuses(fuseOptions);
|
package/dist/esm/index.mjs
CHANGED
|
@@ -258,7 +258,7 @@ var ENS = class {
|
|
|
258
258
|
getDecryptedName = this.generateRawFunction("getDecryptedName", ["contracts", "gqlInstance"]);
|
|
259
259
|
universalWrapper = this.generateRawFunction("initialGetters", ["contracts"], "universalWrapper");
|
|
260
260
|
resolverMulticallWrapper = this.generateRawFunction("initialGetters", ["contracts"], "resolverMulticallWrapper");
|
|
261
|
-
multicallWrapper = this.generateRawFunction("initialGetters", ["contracts"], "multicallWrapper");
|
|
261
|
+
multicallWrapper = this.generateRawFunction("initialGetters", ["contracts", "provider"], "multicallWrapper");
|
|
262
262
|
setName = this.generateWriteFunction(
|
|
263
263
|
"setName",
|
|
264
264
|
["contracts"]
|
package/dist/esm/utils/ccip.mjs
CHANGED
|
@@ -97,7 +97,7 @@ var ccipLookup = async (provider, transaction, result) => {
|
|
|
97
97
|
throw new Error("CCIP Read disabled or provided no URLs");
|
|
98
98
|
}
|
|
99
99
|
const tx = {
|
|
100
|
-
to:
|
|
100
|
+
to: txSender,
|
|
101
101
|
data: hexConcat([
|
|
102
102
|
callbackSelector,
|
|
103
103
|
encodeBytes([ccipResult, extraData])
|
package/dist/esm/utils/fuses.mjs
CHANGED
|
@@ -34,6 +34,7 @@ var userSettableFuseEnum = {
|
|
|
34
34
|
};
|
|
35
35
|
var fullFuseEnum = {
|
|
36
36
|
...userSettableFuseEnum,
|
|
37
|
+
...fullParentFuseEnum,
|
|
37
38
|
CAN_DO_EVERYTHING
|
|
38
39
|
};
|
|
39
40
|
var unnamedChildFuses = [
|
|
@@ -216,14 +217,14 @@ var decodeNamedFuses = (fuses, arr) => {
|
|
|
216
217
|
const fuseObj = Object.fromEntries(
|
|
217
218
|
arr.map((fuse) => [
|
|
218
219
|
fuse,
|
|
219
|
-
(fuses &
|
|
220
|
+
(fuses & fullFuseEnum[fuse]) === fullFuseEnum[fuse]
|
|
220
221
|
])
|
|
221
222
|
);
|
|
222
223
|
return fuseObj;
|
|
223
224
|
};
|
|
224
225
|
var decodeUnnamedFuses = (fuses, arr) => {
|
|
225
226
|
const fuseObj = Object.fromEntries(
|
|
226
|
-
arr.map((fuse) => [fuse, (fuses & fuse)
|
|
227
|
+
arr.map((fuse) => [fuse, (fuses & fuse) === fuse])
|
|
227
228
|
);
|
|
228
229
|
return fuseObj;
|
|
229
230
|
};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// src/utils/singleCall.ts
|
|
2
|
-
var singleCall_default = async (provider, ensData, func, ...data) =>
|
|
2
|
+
var singleCall_default = async (provider, ensData, func, ...data) => {
|
|
3
|
+
const { passthrough, ...rawData } = await func.raw(ensData, ...data);
|
|
4
|
+
const result = await provider.call({ ...rawData, ccipReadEnabled: true }).catch(() => null);
|
|
5
|
+
if (!result)
|
|
6
|
+
return;
|
|
7
|
+
if (passthrough)
|
|
8
|
+
return func.decode(ensData, result, passthrough, ...data);
|
|
9
|
+
return func.decode(ensData, result, ...data);
|
|
10
|
+
};
|
|
3
11
|
export {
|
|
4
12
|
singleCall_default as default
|
|
5
13
|
};
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import { TransactionRequest } from '@ethersproject/abstract-provider';
|
|
1
2
|
import { BatchFunctionResult, ENSArgs, RawFunction } from '..';
|
|
2
3
|
declare const _default: {
|
|
3
4
|
raw: ({ multicallWrapper }: ENSArgs<"multicallWrapper">, ...items: BatchFunctionResult<RawFunction>[]) => Promise<{
|
|
5
|
+
passthrough: {
|
|
6
|
+
to: string;
|
|
7
|
+
data: string;
|
|
8
|
+
}[];
|
|
4
9
|
to: string;
|
|
5
10
|
data: string;
|
|
6
11
|
}>;
|
|
7
|
-
decode: ({ multicallWrapper }: ENSArgs<"multicallWrapper">, data: string,
|
|
12
|
+
decode: ({ multicallWrapper }: ENSArgs<"multicallWrapper">, data: string, passthrough: TransactionRequest & {
|
|
13
|
+
passthrough?: any;
|
|
14
|
+
}[], ...items: BatchFunctionResult<RawFunction>[]) => Promise<any[] | undefined>;
|
|
8
15
|
};
|
|
9
16
|
export default _default;
|
|
@@ -24,5 +24,21 @@ export declare function getHistory({ gqlInstance }: ENSArgs<'gqlInstance'>, name
|
|
|
24
24
|
id: string;
|
|
25
25
|
data: object;
|
|
26
26
|
}[];
|
|
27
|
+
} | {
|
|
28
|
+
domain: {
|
|
29
|
+
type: DomainEvent;
|
|
30
|
+
blockNumber: number;
|
|
31
|
+
transactionHash: string;
|
|
32
|
+
id: string;
|
|
33
|
+
data: object;
|
|
34
|
+
}[];
|
|
35
|
+
resolver: {
|
|
36
|
+
type: ResolverEvent;
|
|
37
|
+
blockNumber: number;
|
|
38
|
+
transactionHash: string;
|
|
39
|
+
id: string;
|
|
40
|
+
data: object;
|
|
41
|
+
}[];
|
|
42
|
+
registration?: undefined;
|
|
27
43
|
} | undefined>;
|
|
28
44
|
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -133,10 +133,16 @@ export declare class ENS {
|
|
|
133
133
|
withProvider: (provider: JsonRpcProvider) => ENS;
|
|
134
134
|
batch: GeneratedBatchFunction<{
|
|
135
135
|
raw: ({ multicallWrapper }: ENSArgs<"multicallWrapper">, ...items: BatchFunctionResult<RawFunction>[]) => Promise<{
|
|
136
|
+
passthrough: {
|
|
137
|
+
to: string;
|
|
138
|
+
data: string;
|
|
139
|
+
}[];
|
|
136
140
|
to: string;
|
|
137
141
|
data: string;
|
|
138
142
|
}>;
|
|
139
|
-
decode: ({ multicallWrapper }: ENSArgs<"multicallWrapper">, data: string,
|
|
143
|
+
decode: ({ multicallWrapper }: ENSArgs<"multicallWrapper">, data: string, passthrough: import("@ethersproject/abstract-provider").TransactionRequest & {
|
|
144
|
+
passthrough?: any;
|
|
145
|
+
}[], ...items: BatchFunctionResult<RawFunction>[]) => Promise<any[] | undefined>;
|
|
140
146
|
}>;
|
|
141
147
|
getProfile: (nameOrAddress: string, options?: ({
|
|
142
148
|
contentHash?: boolean | undefined;
|
|
@@ -306,6 +312,22 @@ export declare class ENS {
|
|
|
306
312
|
id: string;
|
|
307
313
|
data: object;
|
|
308
314
|
}[];
|
|
315
|
+
} | {
|
|
316
|
+
domain: {
|
|
317
|
+
type: "Transfer" | "NewOwner" | "NewResolver" | "NewTTL" | "ExpiryExtended" | "FusesSet" | "NameUnwrapped" | "NameWrapped" | "WrappedTransfer";
|
|
318
|
+
blockNumber: number;
|
|
319
|
+
transactionHash: string;
|
|
320
|
+
id: string;
|
|
321
|
+
data: object;
|
|
322
|
+
}[];
|
|
323
|
+
resolver: {
|
|
324
|
+
type: "AddrChanged" | "ContenthashChanged" | "InterfaceChanged" | "NameChanged" | "PubkeyChanged" | "TextChanged" | "VersionChanged" | "MulticoinAddrChanged" | "AbiChanged" | "AuthorisationChanged";
|
|
325
|
+
blockNumber: number;
|
|
326
|
+
transactionHash: string;
|
|
327
|
+
id: string;
|
|
328
|
+
data: object;
|
|
329
|
+
}[];
|
|
330
|
+
registration?: undefined;
|
|
309
331
|
} | undefined>;
|
|
310
332
|
getContentHash: GeneratedRawFunction<{
|
|
311
333
|
raw: ({ contracts, universalWrapper }: ENSArgs<"contracts" | "universalWrapper">, name: string) => Promise<{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ensdomains/ensjs",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.44",
|
|
4
4
|
"description": "ENS javascript library for contract interaction",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.mjs",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@ensdomains/buffer": "^0.0.13",
|
|
72
|
-
"@ensdomains/ens-contracts": "^0.0.
|
|
72
|
+
"@ensdomains/ens-contracts": "^0.0.17",
|
|
73
73
|
"@ensdomains/ens-test-env": "0.3.7",
|
|
74
74
|
"@ethersproject/abi": "^5.6.4",
|
|
75
75
|
"@ethersproject/abstract-provider": "^5.7.0",
|
|
@@ -20,19 +20,19 @@ const addresses: Record<
|
|
|
20
20
|
'1': '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5',
|
|
21
21
|
'3': '0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8',
|
|
22
22
|
'4': '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5',
|
|
23
|
-
'5': '
|
|
23
|
+
'5': '0x603A4F2e7615d0099244496883062bA2eFBbeaf0',
|
|
24
24
|
},
|
|
25
25
|
Multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
|
26
26
|
NameWrapper: {
|
|
27
27
|
'1': '0x0000000000000000000000000000000000000000',
|
|
28
28
|
'3': '0xF82155e2a43Be0871821E9654Fc8Ae894FB8307C',
|
|
29
29
|
'4': '0x0000000000000000000000000000000000000000',
|
|
30
|
-
'5': '
|
|
30
|
+
'5': '0x060f1546642E67c485D56248201feA2f9AB1803C',
|
|
31
31
|
},
|
|
32
32
|
PublicResolver: {
|
|
33
33
|
'1': '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41',
|
|
34
34
|
'3': '0x13F0659Ee6bb7484C884FEeFb7F75C93951ef837',
|
|
35
|
-
'5': '
|
|
35
|
+
'5': '0x19c2d5D0f035563344dBB7bE5fD09c8dad62b001',
|
|
36
36
|
},
|
|
37
37
|
ENSRegistry: {
|
|
38
38
|
'1': '0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e',
|
package/src/functions/batch.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TransactionRequest } from '@ethersproject/abstract-provider'
|
|
1
2
|
import { BatchFunctionResult, ENSArgs, RawFunction } from '..'
|
|
2
3
|
|
|
3
4
|
const raw = async (
|
|
@@ -12,21 +13,30 @@ const raw = async (
|
|
|
12
13
|
return rawRef(...args)
|
|
13
14
|
}),
|
|
14
15
|
)
|
|
15
|
-
|
|
16
|
+
const response = await multicallWrapper.raw(rawDataArr)
|
|
17
|
+
return { ...response, passthrough: rawDataArr }
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
const decode = async (
|
|
19
21
|
{ multicallWrapper }: ENSArgs<'multicallWrapper'>,
|
|
20
22
|
data: string,
|
|
23
|
+
passthrough: TransactionRequest & { passthrough?: any }[],
|
|
21
24
|
...items: BatchFunctionResult<RawFunction>[]
|
|
22
25
|
): Promise<any[] | undefined> => {
|
|
23
|
-
const response = await multicallWrapper.decode(data)
|
|
26
|
+
const response = await multicallWrapper.decode(data, passthrough)
|
|
24
27
|
if (!response) return
|
|
25
28
|
|
|
26
29
|
return Promise.all(
|
|
27
|
-
response.map((ret: any, i: number) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
response.map((ret: any, i: number) => {
|
|
31
|
+
if (passthrough[i].passthrough) {
|
|
32
|
+
return items[i].decode(
|
|
33
|
+
ret.returnData,
|
|
34
|
+
passthrough[i].passthrough,
|
|
35
|
+
...items[i].args,
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
return items[i].decode(ret.returnData, ...items[i].args)
|
|
39
|
+
}),
|
|
30
40
|
)
|
|
31
41
|
}
|
|
32
42
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import dotenv from 'dotenv'
|
|
2
|
+
import { ENS } from '..'
|
|
3
|
+
import setup from '../tests/setup'
|
|
4
|
+
|
|
5
|
+
dotenv.config()
|
|
6
|
+
|
|
7
|
+
let ensInstance: ENS
|
|
8
|
+
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
;({ ensInstance } = await setup(true))
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
jest.setTimeout(20000)
|
|
14
|
+
|
|
15
|
+
describe('CCIP', () => {
|
|
16
|
+
describe('getProfile', () => {
|
|
17
|
+
it('should return a profile from a ccip-read name', async () => {
|
|
18
|
+
const result = await ensInstance.getProfile('1.offchainexample.eth', {
|
|
19
|
+
fallback: {
|
|
20
|
+
texts: ['email', 'description'],
|
|
21
|
+
contentHash: true,
|
|
22
|
+
coinTypes: ['LTC', '60'],
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
expect(result).toBeTruthy()
|
|
26
|
+
if (result) {
|
|
27
|
+
expect(result.address).toBe(
|
|
28
|
+
'0x41563129cDbbD0c5D3e1c86cf9563926b243834d',
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
describe('batch', () => {
|
|
34
|
+
it('allows batch ccip', async () => {
|
|
35
|
+
const result = await ensInstance.batch(
|
|
36
|
+
ensInstance.getAddr.batch('1.offchainexample.eth'),
|
|
37
|
+
ensInstance.getAddr.batch('1.offchainexample.eth', 'LTC'),
|
|
38
|
+
ensInstance.getText.batch('1.offchainexample.eth', 'email'),
|
|
39
|
+
)
|
|
40
|
+
expect(result).toBeTruthy()
|
|
41
|
+
if (result) {
|
|
42
|
+
expect(result[0]).toBe('0x41563129cDbbD0c5D3e1c86cf9563926b243834d')
|
|
43
|
+
expect(result[1]).toStrictEqual({
|
|
44
|
+
coin: 'LTC',
|
|
45
|
+
addr: 'MQMcJhpWHYVeQArcZR3sBgyPZxxRtnH441',
|
|
46
|
+
})
|
|
47
|
+
expect(result[2]).toBe('nick@ens.domains')
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
it('allows nested batch ccip', async () => {
|
|
51
|
+
const result = await ensInstance.batch(
|
|
52
|
+
ensInstance.batch.batch(
|
|
53
|
+
ensInstance.getAddr.batch('1.offchainexample.eth'),
|
|
54
|
+
),
|
|
55
|
+
)
|
|
56
|
+
expect(result).toBeTruthy()
|
|
57
|
+
if (result) {
|
|
58
|
+
expect(result[0]![0]).toBe('0x41563129cDbbD0c5D3e1c86cf9563926b243834d')
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
})
|
|
@@ -2,6 +2,7 @@ import { BigNumber } from '@ethersproject/bignumber'
|
|
|
2
2
|
import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
|
|
3
3
|
import { ENSArgs } from '..'
|
|
4
4
|
import { namehash } from '../utils/normalise'
|
|
5
|
+
import { checkIsDotEth } from '../utils/validation'
|
|
5
6
|
|
|
6
7
|
type ContractOption = 'registrar' | 'nameWrapper'
|
|
7
8
|
|
|
@@ -56,7 +57,7 @@ const getContractToUse = (
|
|
|
56
57
|
labels: string[],
|
|
57
58
|
) => {
|
|
58
59
|
if (contract) return contract
|
|
59
|
-
if (labels
|
|
60
|
+
if (checkIsDotEth(labels)) {
|
|
60
61
|
return 'registrar'
|
|
61
62
|
}
|
|
62
63
|
return 'nameWrapper'
|
|
@@ -35,4 +35,15 @@ describe('getHistory', () => {
|
|
|
35
35
|
expect(result).toHaveProperty('registration')
|
|
36
36
|
}
|
|
37
37
|
})
|
|
38
|
+
it('should return the history of a subname', async () => {
|
|
39
|
+
const result = await ensInstance.getHistory(
|
|
40
|
+
'test.wrapped-with-subnames.eth',
|
|
41
|
+
)
|
|
42
|
+
expect(result).toBeTruthy()
|
|
43
|
+
if (result) {
|
|
44
|
+
expect(result).toHaveProperty('domain')
|
|
45
|
+
expect(result).toHaveProperty('resolver')
|
|
46
|
+
expect(result).not.toHaveProperty('registration')
|
|
47
|
+
}
|
|
48
|
+
})
|
|
38
49
|
})
|
|
@@ -2,7 +2,6 @@ import { formatsByCoinType } from '@ensdomains/address-encoder'
|
|
|
2
2
|
import { hexStripZeros } from '@ethersproject/bytes'
|
|
3
3
|
import { ENSArgs } from '..'
|
|
4
4
|
import { decodeContenthash } from '../utils/contentHash'
|
|
5
|
-
import { labelhash } from '../utils/labels'
|
|
6
5
|
import { namehash } from '../utils/normalise'
|
|
7
6
|
import {
|
|
8
7
|
AbiChanged,
|
|
@@ -28,6 +27,7 @@ import {
|
|
|
28
27
|
VersionChanged,
|
|
29
28
|
WrappedTransfer,
|
|
30
29
|
} from '../utils/subgraph-types'
|
|
30
|
+
import { checkIsDotEth } from '../utils/validation'
|
|
31
31
|
|
|
32
32
|
type DomainEvent =
|
|
33
33
|
| 'NewOwner'
|
|
@@ -154,7 +154,7 @@ export async function getHistory(
|
|
|
154
154
|
) {
|
|
155
155
|
const { client } = gqlInstance
|
|
156
156
|
const query = gqlInstance.gql`
|
|
157
|
-
query getHistory($namehash: String
|
|
157
|
+
query getHistory($namehash: String!) {
|
|
158
158
|
domain(id: $namehash) {
|
|
159
159
|
events {
|
|
160
160
|
id
|
|
@@ -275,14 +275,12 @@ export async function getHistory(
|
|
|
275
275
|
}
|
|
276
276
|
`
|
|
277
277
|
|
|
278
|
-
const label = name.split('.')[0]
|
|
279
|
-
|
|
280
278
|
const nameHash = namehash(name)
|
|
281
|
-
const
|
|
279
|
+
const labels = name.split('.')
|
|
280
|
+
const is2ldEth = checkIsDotEth(labels)
|
|
282
281
|
|
|
283
282
|
const response = await client.request(query, {
|
|
284
283
|
namehash: nameHash,
|
|
285
|
-
labelhash: labelHash,
|
|
286
284
|
})
|
|
287
285
|
const domain = response?.domain
|
|
288
286
|
|
|
@@ -290,12 +288,10 @@ export async function getHistory(
|
|
|
290
288
|
|
|
291
289
|
const {
|
|
292
290
|
events: domainEvents,
|
|
293
|
-
registration: { events: registrationEvents },
|
|
294
291
|
resolver: { events: resolverEvents },
|
|
295
292
|
} = domain
|
|
296
293
|
|
|
297
294
|
const domainHistory = mapEvents(domainEvents, 'Domain')
|
|
298
|
-
const registrationHistory = mapEvents(registrationEvents, 'Registration')
|
|
299
295
|
const resolverHistory = mapEvents(
|
|
300
296
|
// remove duplicate events for ETH cointype
|
|
301
297
|
resolverEvents.filter(
|
|
@@ -304,9 +300,20 @@ export async function getHistory(
|
|
|
304
300
|
'Resolver',
|
|
305
301
|
)
|
|
306
302
|
|
|
303
|
+
if (is2ldEth) {
|
|
304
|
+
const {
|
|
305
|
+
registration: { events: registrationEvents },
|
|
306
|
+
} = domain
|
|
307
|
+
const registrationHistory = mapEvents(registrationEvents, 'Registration')
|
|
308
|
+
return {
|
|
309
|
+
domain: domainHistory,
|
|
310
|
+
registration: registrationHistory,
|
|
311
|
+
resolver: resolverHistory,
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
307
315
|
return {
|
|
308
316
|
domain: domainHistory,
|
|
309
|
-
registration: registrationHistory,
|
|
310
317
|
resolver: resolverHistory,
|
|
311
318
|
}
|
|
312
319
|
}
|
|
@@ -4,6 +4,7 @@ import { hexStripZeros } from '@ethersproject/bytes'
|
|
|
4
4
|
import { ENSArgs } from '..'
|
|
5
5
|
import { labelhash } from '../utils/labels'
|
|
6
6
|
import { namehash as makeNamehash } from '../utils/normalise'
|
|
7
|
+
import { checkIsDotEth } from '../utils/validation'
|
|
7
8
|
|
|
8
9
|
type Owner = {
|
|
9
10
|
registrant?: string
|
|
@@ -87,7 +88,7 @@ const raw = async (
|
|
|
87
88
|
|
|
88
89
|
const data: { to: string; data: string }[] = [registryData, nameWrapperData]
|
|
89
90
|
|
|
90
|
-
if (labels
|
|
91
|
+
if (checkIsDotEth(labels)) {
|
|
91
92
|
data.push(registrarData)
|
|
92
93
|
}
|
|
93
94
|
|
|
@@ -52,13 +52,16 @@ describe('getWrapperData', () => {
|
|
|
52
52
|
expect(result.child.CANNOT_UNWRAP).toBe(true)
|
|
53
53
|
expect(result.child.CANNOT_CREATE_SUBDOMAIN).toBe(true)
|
|
54
54
|
expect(result.child.CANNOT_SET_TTL).toBe(true)
|
|
55
|
+
expect(result.parent.IS_DOT_ETH).toBe(true)
|
|
55
56
|
}
|
|
56
57
|
})
|
|
57
58
|
it('should return correct expiry', async () => {
|
|
58
59
|
const result = await ensInstance.getWrapperData('wrapped.eth')
|
|
59
60
|
expect(result).toBeTruthy()
|
|
60
61
|
if (result) {
|
|
62
|
+
console.log(result.expiryDate)
|
|
61
63
|
expect(result.expiryDate).toBeInstanceOf(Date)
|
|
64
|
+
expect(Number.isNaN(result.expiryDate?.getTime())).toBe(false)
|
|
62
65
|
}
|
|
63
66
|
})
|
|
64
67
|
})
|
|
@@ -23,7 +23,7 @@ const decode = async ({ contracts }: ENSArgs<'contracts'>, data: string) => {
|
|
|
23
23
|
|
|
24
24
|
const expiryDate =
|
|
25
25
|
expiry.gt(0) && expiry.lt(BigNumber.from(2).pow(32))
|
|
26
|
-
? new Date(expiry.mul(1000).
|
|
26
|
+
? new Date(expiry.mul(1000).toNumber())
|
|
27
27
|
: undefined
|
|
28
28
|
|
|
29
29
|
return {
|
|
@@ -2,6 +2,7 @@ import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
|
|
|
2
2
|
|
|
3
3
|
import { ENSArgs } from '..'
|
|
4
4
|
import { namehash } from '../utils/normalise'
|
|
5
|
+
import { checkIsDotEth } from '../utils/validation'
|
|
5
6
|
|
|
6
7
|
export default async function (
|
|
7
8
|
{ contracts, signer }: ENSArgs<'contracts' | 'signer'>,
|
|
@@ -20,7 +21,7 @@ export default async function (
|
|
|
20
21
|
|
|
21
22
|
const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer)
|
|
22
23
|
|
|
23
|
-
if (labels
|
|
24
|
+
if (checkIsDotEth(labels)) {
|
|
24
25
|
if (!newRegistrant) {
|
|
25
26
|
throw new Error('newRegistrant must be specified for .eth names')
|
|
26
27
|
}
|
|
@@ -4,6 +4,7 @@ import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity'
|
|
|
4
4
|
import { ENSArgs } from '..'
|
|
5
5
|
import { CombinedFuseInput, encodeFuses } from '../utils/fuses'
|
|
6
6
|
import { hexEncodeName } from '../utils/hexEncodedName'
|
|
7
|
+
import { checkIsDotEth } from '../utils/validation'
|
|
7
8
|
import { Expiry, wrappedLabelLengthCheck } from '../utils/wrapper'
|
|
8
9
|
|
|
9
10
|
async function wrapETH(
|
|
@@ -84,7 +85,7 @@ export default async function (
|
|
|
84
85
|
const labels = name.split('.')
|
|
85
86
|
wrappedLabelLengthCheck(labels[0])
|
|
86
87
|
|
|
87
|
-
if (labels
|
|
88
|
+
if (checkIsDotEth(labels)) {
|
|
88
89
|
switch (typeof fuseOptions) {
|
|
89
90
|
case 'object': {
|
|
90
91
|
decodedFuses = encodeFuses(fuseOptions)
|
package/src/index.ts
CHANGED
|
@@ -562,7 +562,7 @@ export class ENS {
|
|
|
562
562
|
|
|
563
563
|
public multicallWrapper = this.generateRawFunction<
|
|
564
564
|
FunctionTypes['multicallWrapper']
|
|
565
|
-
>('initialGetters', ['contracts'], 'multicallWrapper')
|
|
565
|
+
>('initialGetters', ['contracts', 'provider'], 'multicallWrapper')
|
|
566
566
|
|
|
567
567
|
public setName = this.generateWriteFunction<FunctionTypes['setName']>(
|
|
568
568
|
'setName',
|
package/src/utils/ccip.ts
CHANGED
package/src/utils/fuses.ts
CHANGED
|
@@ -45,6 +45,7 @@ export const userSettableFuseEnum = {
|
|
|
45
45
|
|
|
46
46
|
export const fullFuseEnum = {
|
|
47
47
|
...userSettableFuseEnum,
|
|
48
|
+
...fullParentFuseEnum,
|
|
48
49
|
CAN_DO_EVERYTHING,
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -303,9 +304,8 @@ const decodeNamedFuses = (fuses: number, arr: readonly string[]) => {
|
|
|
303
304
|
const fuseObj = Object.fromEntries(
|
|
304
305
|
arr.map((fuse) => [
|
|
305
306
|
fuse,
|
|
306
|
-
(fuses &
|
|
307
|
-
|
|
308
|
-
0,
|
|
307
|
+
(fuses & fullFuseEnum[fuse as keyof typeof fullFuseEnum]) ===
|
|
308
|
+
fullFuseEnum[fuse as keyof typeof fullFuseEnum],
|
|
309
309
|
]),
|
|
310
310
|
)
|
|
311
311
|
|
|
@@ -314,7 +314,7 @@ const decodeNamedFuses = (fuses: number, arr: readonly string[]) => {
|
|
|
314
314
|
|
|
315
315
|
const decodeUnnamedFuses = (fuses: number, arr: readonly number[]) => {
|
|
316
316
|
const fuseObj = Object.fromEntries(
|
|
317
|
-
arr.map((fuse) => [fuse, (fuses & fuse)
|
|
317
|
+
arr.map((fuse) => [fuse, (fuses & fuse) === fuse]),
|
|
318
318
|
)
|
|
319
319
|
|
|
320
320
|
return fuseObj
|
package/src/utils/singleCall.ts
CHANGED
|
@@ -4,13 +4,18 @@ export default async (
|
|
|
4
4
|
provider: Provider,
|
|
5
5
|
ensData: any,
|
|
6
6
|
func: {
|
|
7
|
-
raw: (
|
|
7
|
+
raw: (
|
|
8
|
+
...args: any[]
|
|
9
|
+
) => Promise<{ to: string; data: string; passthrough?: any }>
|
|
8
10
|
decode: (...args: any[]) => Promise<any>
|
|
9
11
|
},
|
|
10
12
|
...data: any[]
|
|
11
|
-
) =>
|
|
12
|
-
func
|
|
13
|
-
|
|
14
|
-
.
|
|
13
|
+
) => {
|
|
14
|
+
const { passthrough, ...rawData } = await func.raw(ensData, ...data)
|
|
15
|
+
const result = await provider
|
|
16
|
+
.call({ ...rawData, ccipReadEnabled: true })
|
|
15
17
|
.catch(() => null)
|
|
16
|
-
|
|
18
|
+
if (!result) return
|
|
19
|
+
if (passthrough) return func.decode(ensData, result, passthrough, ...data)
|
|
20
|
+
return func.decode(ensData, result, ...data)
|
|
21
|
+
}
|
package/src/utils/validation.ts
CHANGED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import dotenv from 'dotenv'
|
|
2
|
-
import { ENS } from '..'
|
|
3
|
-
import setup from '../tests/setup'
|
|
4
|
-
|
|
5
|
-
dotenv.config()
|
|
6
|
-
|
|
7
|
-
let ensInstance: ENS
|
|
8
|
-
|
|
9
|
-
beforeAll(async () => {
|
|
10
|
-
;({ ensInstance } = await setup(true))
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
jest.setTimeout(20000)
|
|
14
|
-
|
|
15
|
-
describe('getProfile', () => {
|
|
16
|
-
it('should return a profile from a ccip-read name', async () => {
|
|
17
|
-
const result = await ensInstance.getProfile('1.offchainexample.eth', {
|
|
18
|
-
fallback: {
|
|
19
|
-
texts: ['email', 'description'],
|
|
20
|
-
contentHash: true,
|
|
21
|
-
coinTypes: ['0', '60'],
|
|
22
|
-
},
|
|
23
|
-
})
|
|
24
|
-
expect(result).toBeTruthy()
|
|
25
|
-
if (result) {
|
|
26
|
-
expect(result.address).toBe('0x41563129cDbbD0c5D3e1c86cf9563926b243834d')
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
})
|