@ensdomains/ensjs 3.0.0-alpha.5 → 3.0.0-alpha.8
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/GqlManager.d.ts +3 -0
- package/dist/cjs/GqlManager.js +62 -2
- package/dist/cjs/functions/burnFuses.d.ts +1 -1
- package/dist/cjs/functions/burnFuses.js +1 -1
- package/dist/cjs/functions/createSubname.d.ts +1 -1
- package/dist/cjs/functions/createSubname.js +2 -2
- package/dist/cjs/functions/deleteSubname.d.ts +1 -1
- package/dist/cjs/functions/deleteSubname.js +1 -1
- package/dist/cjs/functions/getProfile.d.ts +4 -1
- package/dist/cjs/functions/getProfile.js +62 -18
- package/dist/cjs/functions/getRecords.d.ts +1 -0
- package/dist/cjs/functions/setName.d.ts +1 -1
- package/dist/cjs/functions/setName.js +2 -2
- package/dist/cjs/functions/setRecords.d.ts +1 -1
- package/dist/cjs/functions/setRecords.js +1 -1
- package/dist/cjs/functions/setResolver.d.ts +1 -1
- package/dist/cjs/functions/setResolver.js +2 -2
- package/dist/cjs/functions/transferName.d.ts +1 -1
- package/dist/cjs/functions/transferName.js +3 -3
- package/dist/cjs/functions/transferSubname.d.ts +1 -1
- package/dist/cjs/functions/transferSubname.js +2 -2
- package/dist/cjs/functions/unwrapName.d.ts +1 -1
- package/dist/cjs/functions/unwrapName.js +2 -2
- package/dist/cjs/functions/wrapName.d.ts +2 -2
- package/dist/cjs/functions/wrapName.js +3 -3
- package/dist/cjs/index.d.ts +34 -52
- package/dist/cjs/index.js +10 -6
- package/dist/cjs/utils/labels.js +4 -3
- package/dist/cjs/utils/normalise.d.ts +1 -1
- package/dist/cjs/utils/normalise.js +10 -3
- 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 +1 -1
- package/dist/esm/functions/burnFuses.js +1 -1
- package/dist/esm/functions/createSubname.d.ts +1 -1
- package/dist/esm/functions/createSubname.js +2 -2
- package/dist/esm/functions/deleteSubname.d.ts +1 -1
- package/dist/esm/functions/deleteSubname.js +1 -1
- package/dist/esm/functions/getProfile.d.ts +4 -1
- package/dist/esm/functions/getProfile.js +62 -18
- package/dist/esm/functions/getRecords.d.ts +1 -0
- package/dist/esm/functions/setName.d.ts +1 -1
- package/dist/esm/functions/setName.js +2 -2
- package/dist/esm/functions/setRecords.d.ts +1 -1
- package/dist/esm/functions/setRecords.js +1 -1
- package/dist/esm/functions/setResolver.d.ts +1 -1
- package/dist/esm/functions/setResolver.js +2 -2
- package/dist/esm/functions/transferName.d.ts +1 -1
- package/dist/esm/functions/transferName.js +3 -3
- package/dist/esm/functions/transferSubname.d.ts +1 -1
- package/dist/esm/functions/transferSubname.js +2 -2
- package/dist/esm/functions/unwrapName.d.ts +1 -1
- package/dist/esm/functions/unwrapName.js +2 -2
- package/dist/esm/functions/wrapName.d.ts +2 -2
- package/dist/esm/functions/wrapName.js +3 -3
- package/dist/esm/index.d.ts +34 -52
- package/dist/esm/index.js +10 -6
- package/dist/esm/utils/labels.js +4 -3
- package/dist/esm/utils/normalise.d.ts +1 -1
- package/dist/esm/utils/normalise.js +10 -3
- package/dist/esm/utils/writeTx.d.ts +4 -0
- package/dist/esm/utils/writeTx.js +1 -0
- package/package.json +7 -5
- package/src/GqlManager.test.ts +170 -0
- package/src/GqlManager.ts +67 -2
- package/src/functions/burnFuses.ts +1 -1
- package/src/functions/createSubname.ts +2 -2
- package/src/functions/deleteSubname.ts +1 -1
- package/src/functions/getProfile.test.ts +16 -1
- package/src/functions/getProfile.ts +82 -19
- package/src/functions/getRecords.ts +1 -0
- package/src/functions/setName.ts +5 -5
- package/src/functions/setRecords.ts +2 -2
- package/src/functions/setResolver.ts +5 -2
- package/src/functions/transferName.ts +5 -3
- package/src/functions/transferSubname.ts +11 -2
- package/src/functions/unwrapName.ts +10 -2
- package/src/functions/wrapName.ts +5 -8
- package/src/index.ts +37 -12
- package/src/tests/populateTransaction.test.ts +40 -0
- package/src/tests/signerInjection.test.ts +7 -3
- package/src/utils/labels.ts +5 -3
- package/src/utils/normalise.ts +10 -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,29 +90,29 @@ 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 && subFunc
|
|
99
|
-
? mod[exportName][subFunc]
|
|
100
|
-
: mod[exportName];
|
|
100
|
+
const func = subFunc && !writeable ? mod[exportName][subFunc] : mod[exportName];
|
|
101
101
|
// get the dependencies to forward to the function as the first arg
|
|
102
102
|
let dependenciesToForward = thisRef.forwardDependenciesFromArray(dependencies);
|
|
103
103
|
// if func is write func, inject signer into dependencies
|
|
104
|
-
if (
|
|
104
|
+
if (writeable) {
|
|
105
105
|
const options = (args[1] || {});
|
|
106
106
|
const signer = options.signer ||
|
|
107
107
|
thisRef.provider?.getSigner(options.addressOrIndex);
|
|
108
|
+
const populate = subFunc === 'populateTransaction';
|
|
108
109
|
if (!signer) {
|
|
109
110
|
throw new Error('No signer specified');
|
|
110
111
|
}
|
|
111
112
|
delete options.addressOrIndex;
|
|
112
113
|
delete options.signer;
|
|
113
114
|
dependenciesToForward = { ...dependenciesToForward, signer };
|
|
114
|
-
return func(dependenciesToForward, args[0], options);
|
|
115
|
+
return func(dependenciesToForward, args[0], options).then((0, writeTx_1.default)(signer, populate));
|
|
115
116
|
}
|
|
116
117
|
// return the function with the dependencies forwarded
|
|
117
118
|
return func(dependenciesToForward, ...args);
|
|
@@ -129,6 +130,9 @@ class ENS {
|
|
|
129
130
|
mainFunc.decode = this.importGenerator(path, dependencies, exportName, 'decode');
|
|
130
131
|
mainFunc.batch = this.importGenerator(path, dependencies, exportName, 'batch', { raw: mainFunc.raw, decode: mainFunc.decode });
|
|
131
132
|
}
|
|
133
|
+
else if (subFunc === 'write') {
|
|
134
|
+
mainFunc.populateTransaction = this.importGenerator(path, dependencies, exportName, 'populateTransaction');
|
|
135
|
+
}
|
|
132
136
|
return mainFunc;
|
|
133
137
|
};
|
|
134
138
|
/**
|
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);
|
|
@@ -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,2 +1,2 @@
|
|
|
1
1
|
export declare const normalise: (name: string) => any;
|
|
2
|
-
export declare const namehash: (
|
|
2
|
+
export declare const namehash: (name: string) => string;
|
|
@@ -6,17 +6,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.namehash = exports.normalise = void 0;
|
|
7
7
|
const utils_1 = require("ethers/lib/utils");
|
|
8
8
|
const uts46bundle_js_1 = __importDefault(require("idna-uts46-hx/uts46bundle.js"));
|
|
9
|
+
const labels_1 = require("./labels");
|
|
9
10
|
const zeros = new Uint8Array(32);
|
|
10
11
|
zeros.fill(0);
|
|
11
12
|
const normalise = (name) => name ? uts46bundle_js_1.default.toUnicode(name, { useStd3ASCII: true }) : name;
|
|
12
13
|
exports.normalise = normalise;
|
|
13
|
-
const namehash = (
|
|
14
|
+
const namehash = (name) => {
|
|
14
15
|
let result = zeros;
|
|
15
|
-
const name = (0, exports.normalise)(inputName);
|
|
16
16
|
if (name) {
|
|
17
17
|
const labels = name.split('.');
|
|
18
18
|
for (var i = labels.length - 1; i >= 0; i--) {
|
|
19
|
-
|
|
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
|
+
}
|
|
20
27
|
result = (0, utils_1.keccak256)((0, utils_1.concat)([result, labelSha]));
|
|
21
28
|
}
|
|
22
29
|
}
|
|
@@ -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 {
|
|
@@ -2,4 +2,4 @@ import { ENSArgs } from '..';
|
|
|
2
2
|
import { FuseOptions } from '../@types/FuseOptions';
|
|
3
3
|
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { fusesToBurn, }: {
|
|
4
4
|
fusesToBurn: FuseOptions;
|
|
5
|
-
}): Promise<import("ethers").
|
|
5
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -4,5 +4,5 @@ export default async function ({ contracts, signer }, name, { fusesToBurn, }) {
|
|
|
4
4
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
5
5
|
const hash = namehash(name);
|
|
6
6
|
const encodedFuses = generateFuseInput(fusesToBurn);
|
|
7
|
-
return nameWrapper.burnFuses(hash, encodedFuses);
|
|
7
|
+
return nameWrapper.populateTransaction.burnFuses(hash, encodedFuses);
|
|
8
8
|
}
|
|
@@ -11,5 +11,5 @@ declare type NameWrapperArgs = {
|
|
|
11
11
|
fuses?: FuseOptions;
|
|
12
12
|
} & BaseArgs;
|
|
13
13
|
declare type Args = BaseArgs | NameWrapperArgs;
|
|
14
|
-
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { owner, resolverAddress, contract, ...wrapperArgs }: Args): Promise<ethers.
|
|
14
|
+
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { owner, resolverAddress, contract, ...wrapperArgs }: Args): Promise<ethers.PopulatedTransaction>;
|
|
15
15
|
export {};
|
|
@@ -18,14 +18,14 @@ export default async function ({ contracts, signer }, name, { owner, resolverAdd
|
|
|
18
18
|
switch (contract) {
|
|
19
19
|
case 'registry': {
|
|
20
20
|
const registry = (await contracts?.getRegistry()).connect(signer);
|
|
21
|
-
return registry.setSubnodeRecord(parentNodehash, labelhash, owner, resolverAddress, 0);
|
|
21
|
+
return registry.populateTransaction.setSubnodeRecord(parentNodehash, labelhash, owner, resolverAddress, 0);
|
|
22
22
|
}
|
|
23
23
|
case 'nameWrapper': {
|
|
24
24
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
25
25
|
const generatedFuses = 'fuses' in wrapperArgs && wrapperArgs.fuses
|
|
26
26
|
? generateFuseInput(wrapperArgs.fuses)
|
|
27
27
|
: '0';
|
|
28
|
-
return nameWrapper.setSubnodeRecord(parentNodehash, label, owner, resolverAddress, 0, generatedFuses);
|
|
28
|
+
return nameWrapper.populateTransaction.setSubnodeRecord(parentNodehash, label, owner, resolverAddress, 0, generatedFuses);
|
|
29
29
|
}
|
|
30
30
|
default: {
|
|
31
31
|
throw new Error(`Unknown contract: ${contract}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ENSArgs } from '..';
|
|
2
2
|
export default function ({ transferSubname }: ENSArgs<'transferSubname'>, name: string, { contract, }: {
|
|
3
3
|
contract: 'registry' | 'nameWrapper';
|
|
4
|
-
}): Promise<import("ethers").
|
|
4
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -26,5 +26,8 @@ declare type ProfileOptions = {
|
|
|
26
26
|
texts?: boolean | string[];
|
|
27
27
|
coinTypes?: boolean | string[];
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
declare type InputProfileOptions = ProfileOptions & {
|
|
30
|
+
resolverAddress?: string;
|
|
31
|
+
};
|
|
32
|
+
export default function ({ contracts, gqlInstance, getName, _getAddr, _getContentHash, _getText, resolverMulticallWrapper, multicallWrapper, }: ENSArgs<'contracts' | 'gqlInstance' | 'getName' | '_getText' | '_getAddr' | '_getContentHash' | 'resolverMulticallWrapper' | 'multicallWrapper'>, nameOrAddress: string, options?: InputProfileOptions): Promise<ResolvedProfile | undefined>;
|
|
30
33
|
export {};
|
|
@@ -2,6 +2,7 @@ import { formatsByName } from '@ensdomains/address-encoder';
|
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import { decodeContenthash } from '../utils/contentHash';
|
|
4
4
|
import { hexEncodeName } from '../utils/hexEncodedName';
|
|
5
|
+
import { namehash } from '../utils/normalise';
|
|
5
6
|
import { parseInputType } from '../utils/validation';
|
|
6
7
|
const makeMulticallData = async ({ _getAddr, _getContentHash, _getText, resolverMulticallWrapper, }, name, options) => {
|
|
7
8
|
let calls = [];
|
|
@@ -47,13 +48,19 @@ const fetchWithoutResolverMulticall = async ({ multicallWrapper }, calls, resolv
|
|
|
47
48
|
}));
|
|
48
49
|
return (await multicallWrapper(callsWithResolver)).map((x) => x[1]);
|
|
49
50
|
};
|
|
50
|
-
const getDataForName = async ({ contracts, _getAddr, _getContentHash, _getText, resolverMulticallWrapper, multicallWrapper, }, name, options, fallbackResolver) => {
|
|
51
|
+
const getDataForName = async ({ contracts, _getAddr, _getContentHash, _getText, resolverMulticallWrapper, multicallWrapper, }, name, options, fallbackResolver, specificResolver) => {
|
|
51
52
|
const universalResolver = await contracts?.getUniversalResolver();
|
|
52
53
|
const { data, calls } = await makeMulticallData({ _getAddr, _getContentHash, _getText, resolverMulticallWrapper }, name, options);
|
|
53
54
|
let resolvedData;
|
|
54
55
|
let useFallbackResolver = false;
|
|
55
56
|
try {
|
|
56
|
-
|
|
57
|
+
if (specificResolver) {
|
|
58
|
+
const publicResolver = await contracts?.getPublicResolver(undefined, specificResolver);
|
|
59
|
+
resolvedData = await publicResolver?.callStatic.multicall(calls.map((x) => x.data));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
resolvedData = await universalResolver?.resolve(hexEncodeName(name), data);
|
|
63
|
+
}
|
|
57
64
|
}
|
|
58
65
|
catch {
|
|
59
66
|
useFallbackResolver = true;
|
|
@@ -61,12 +68,18 @@ const getDataForName = async ({ contracts, _getAddr, _getContentHash, _getText,
|
|
|
61
68
|
let resolverAddress;
|
|
62
69
|
let recordData;
|
|
63
70
|
if (useFallbackResolver) {
|
|
64
|
-
resolverAddress = fallbackResolver;
|
|
71
|
+
resolverAddress = specificResolver || fallbackResolver;
|
|
65
72
|
recordData = await fetchWithoutResolverMulticall({ multicallWrapper }, calls, resolverAddress);
|
|
66
73
|
}
|
|
67
74
|
else {
|
|
68
|
-
resolverAddress = resolvedData['1'];
|
|
69
|
-
|
|
75
|
+
resolverAddress = specificResolver || resolvedData['1'];
|
|
76
|
+
if (specificResolver) {
|
|
77
|
+
recordData = resolvedData;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
;
|
|
81
|
+
[recordData] = await resolverMulticallWrapper.decode(resolvedData['0']);
|
|
82
|
+
}
|
|
70
83
|
}
|
|
71
84
|
const matchAddress = recordData[calls.findIndex((x) => x.key === '60')];
|
|
72
85
|
return {
|
|
@@ -158,10 +171,10 @@ const formatRecords = async ({ _getText, _getAddr, _getContentHash, }, data, cal
|
|
|
158
171
|
}
|
|
159
172
|
return returnedResponse;
|
|
160
173
|
};
|
|
161
|
-
const graphFetch = async ({ gqlInstance }, name, wantedRecords) => {
|
|
174
|
+
const graphFetch = async ({ gqlInstance }, name, wantedRecords, resolverAddress) => {
|
|
162
175
|
const query = gqlInstance.gql `
|
|
163
|
-
query getRecords($
|
|
164
|
-
|
|
176
|
+
query getRecords($id: String!) {
|
|
177
|
+
domain(id: $id) {
|
|
165
178
|
isMigrated
|
|
166
179
|
createdAt
|
|
167
180
|
resolver {
|
|
@@ -175,12 +188,39 @@ const graphFetch = async ({ gqlInstance }, name, wantedRecords) => {
|
|
|
175
188
|
}
|
|
176
189
|
}
|
|
177
190
|
}
|
|
191
|
+
`;
|
|
192
|
+
const customResolverQuery = gqlInstance.gql `
|
|
193
|
+
query getRecordsWithCustomResolver($id: String!, $resolverId: String!) {
|
|
194
|
+
domain(id: $id) {
|
|
195
|
+
isMigrated
|
|
196
|
+
createdAt
|
|
197
|
+
}
|
|
198
|
+
resolver(id: $resolverId) {
|
|
199
|
+
texts
|
|
200
|
+
coinTypes
|
|
201
|
+
contentHash
|
|
202
|
+
addr {
|
|
203
|
+
id
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
178
207
|
`;
|
|
179
208
|
const client = gqlInstance.client;
|
|
180
|
-
const
|
|
181
|
-
|
|
209
|
+
const id = namehash(name);
|
|
210
|
+
let domain;
|
|
211
|
+
let resolverResponse;
|
|
212
|
+
if (!resolverAddress) {
|
|
213
|
+
;
|
|
214
|
+
({ domain } = await client.request(query, { id }));
|
|
215
|
+
resolverResponse = domain?.resolver;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
const resolverId = `${resolverAddress}-${id}`;
|
|
219
|
+
({ resolver: resolverResponse, domain } = await client.request(customResolverQuery, { id, resolverId }));
|
|
220
|
+
}
|
|
221
|
+
if (!domain)
|
|
182
222
|
return;
|
|
183
|
-
const
|
|
223
|
+
const { isMigrated, createdAt } = domain;
|
|
184
224
|
let returnedRecords = {};
|
|
185
225
|
if (!resolverResponse)
|
|
186
226
|
return { isMigrated, createdAt };
|
|
@@ -188,7 +228,7 @@ const graphFetch = async ({ gqlInstance }, name, wantedRecords) => {
|
|
|
188
228
|
return {
|
|
189
229
|
isMigrated,
|
|
190
230
|
createdAt,
|
|
191
|
-
graphResolverAddress: resolverResponse.address,
|
|
231
|
+
graphResolverAddress: resolverResponse.address || resolverAddress,
|
|
192
232
|
};
|
|
193
233
|
Object.keys(wantedRecords).forEach((key) => {
|
|
194
234
|
const data = wantedRecords[key];
|
|
@@ -205,18 +245,22 @@ const graphFetch = async ({ gqlInstance }, name, wantedRecords) => {
|
|
|
205
245
|
...returnedRecords,
|
|
206
246
|
isMigrated,
|
|
207
247
|
createdAt,
|
|
208
|
-
graphResolverAddress: resolverResponse.address,
|
|
248
|
+
graphResolverAddress: resolverResponse.address || resolverAddress,
|
|
209
249
|
};
|
|
210
250
|
};
|
|
211
251
|
const getProfileFromName = async ({ contracts, gqlInstance, _getAddr, _getContentHash, _getText, resolverMulticallWrapper, multicallWrapper, }, name, options) => {
|
|
212
|
-
const
|
|
213
|
-
|
|
252
|
+
const { resolverAddress, ..._options } = options || {};
|
|
253
|
+
const optsLength = Object.keys(_options).length;
|
|
254
|
+
const usingOptions = !optsLength || _options?.texts === true || _options?.coinTypes === true
|
|
255
|
+
? optsLength
|
|
256
|
+
? _options
|
|
257
|
+
: { contentHash: true, texts: true, coinTypes: true }
|
|
214
258
|
: undefined;
|
|
215
|
-
const graphResult = await graphFetch({ gqlInstance }, name, usingOptions);
|
|
259
|
+
const graphResult = await graphFetch({ gqlInstance }, name, usingOptions, resolverAddress);
|
|
216
260
|
if (!graphResult)
|
|
217
261
|
return;
|
|
218
262
|
const { isMigrated, createdAt, graphResolverAddress, ...wantedRecords } = graphResult;
|
|
219
|
-
if (!graphResolverAddress)
|
|
263
|
+
if (!graphResolverAddress && !options?.resolverAddress)
|
|
220
264
|
return { isMigrated, createdAt, message: "Name doesn't have a resolver" };
|
|
221
265
|
const result = await getDataForName({
|
|
222
266
|
contracts,
|
|
@@ -225,7 +269,7 @@ const getProfileFromName = async ({ contracts, gqlInstance, _getAddr, _getConten
|
|
|
225
269
|
_getText,
|
|
226
270
|
resolverMulticallWrapper,
|
|
227
271
|
multicallWrapper,
|
|
228
|
-
}, name, usingOptions ? wantedRecords : options, graphResolverAddress);
|
|
272
|
+
}, name, usingOptions ? wantedRecords : options, graphResolverAddress, options?.resolverAddress);
|
|
229
273
|
if (!result)
|
|
230
274
|
return { isMigrated, createdAt, message: "Records fetch didn't complete" };
|
|
231
275
|
return { ...result, isMigrated, createdAt, message: undefined };
|
|
@@ -3,6 +3,7 @@ declare type ProfileOptions = {
|
|
|
3
3
|
contentHash?: boolean;
|
|
4
4
|
texts?: boolean | string[];
|
|
5
5
|
coinTypes?: boolean | string[];
|
|
6
|
+
resolverAddress?: string;
|
|
6
7
|
};
|
|
7
8
|
export default function ({ getProfile }: ENSArgs<'getProfile'>, name: string, options?: ProfileOptions): Promise<{
|
|
8
9
|
isMigrated: boolean | null;
|
|
@@ -2,4 +2,4 @@ import { ENSArgs } from '..';
|
|
|
2
2
|
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { address, resolver, }?: {
|
|
3
3
|
address?: string;
|
|
4
4
|
resolver?: string;
|
|
5
|
-
}): Promise<import("ethers").
|
|
5
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -3,7 +3,7 @@ export default async function ({ contracts, signer }, name, { address, resolver,
|
|
|
3
3
|
const reverseRegistrar = (await contracts?.getReverseRegistrar())?.connect(signer);
|
|
4
4
|
if (address) {
|
|
5
5
|
const publicResolver = await contracts?.getPublicResolver();
|
|
6
|
-
return reverseRegistrar
|
|
6
|
+
return reverseRegistrar.populateTransaction.setNameForAddr(address, signerAddress, resolver || publicResolver.address, name);
|
|
7
7
|
}
|
|
8
|
-
return reverseRegistrar
|
|
8
|
+
return reverseRegistrar.populateTransaction.setName(name);
|
|
9
9
|
}
|
|
@@ -3,4 +3,4 @@ import { RecordOptions } from '../utils/recordHelpers';
|
|
|
3
3
|
export default function ({ contracts, provider, getResolver, signer, }: ENSArgs<'contracts' | 'provider' | 'getResolver' | 'signer'>, name: string, { records, resolverAddress, }: {
|
|
4
4
|
records: RecordOptions;
|
|
5
5
|
resolverAddress?: string;
|
|
6
|
-
}): Promise<import("ethers").
|
|
6
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -17,5 +17,5 @@ export default async function ({ contracts, provider, getResolver, signer, }, na
|
|
|
17
17
|
const resolver = (await contracts?.getPublicResolver(provider, resolverToUse))?.connect(signer);
|
|
18
18
|
const hash = namehash(name);
|
|
19
19
|
const calls = generateRecordCallArray(hash, records, resolver);
|
|
20
|
-
return resolver
|
|
20
|
+
return resolver.populateTransaction.multicall(calls);
|
|
21
21
|
}
|
|
@@ -2,4 +2,4 @@ import { ENSArgs } from '..';
|
|
|
2
2
|
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { contract, resolver, }: {
|
|
3
3
|
contract: 'registry' | 'nameWrapper';
|
|
4
4
|
resolver?: string;
|
|
5
|
-
}): Promise<import("ethers").
|
|
5
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -6,11 +6,11 @@ export default async function ({ contracts, signer }, name, { contract, resolver
|
|
|
6
6
|
switch (contract) {
|
|
7
7
|
case 'registry': {
|
|
8
8
|
const registry = (await contracts?.getRegistry()).connect(signer);
|
|
9
|
-
return registry.setResolver(namehash(name), resolver);
|
|
9
|
+
return registry.populateTransaction.setResolver(namehash(name), resolver);
|
|
10
10
|
}
|
|
11
11
|
case 'nameWrapper': {
|
|
12
12
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
13
|
-
return nameWrapper.setResolver(namehash(name), resolver);
|
|
13
|
+
return nameWrapper.populateTransaction.setResolver(namehash(name), resolver);
|
|
14
14
|
}
|
|
15
15
|
default: {
|
|
16
16
|
throw new Error(`Unknown contract: ${contract}`);
|
|
@@ -3,4 +3,4 @@ import { ENSArgs } from '..';
|
|
|
3
3
|
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { newOwner, contract, }: {
|
|
4
4
|
newOwner: string;
|
|
5
5
|
contract: 'registry' | 'nameWrapper' | 'baseRegistrar';
|
|
6
|
-
}): Promise<ethers.
|
|
6
|
+
}): Promise<ethers.PopulatedTransaction>;
|
|
@@ -5,7 +5,7 @@ export default async function ({ contracts, signer }, name, { newOwner, contract
|
|
|
5
5
|
switch (contract) {
|
|
6
6
|
case 'registry': {
|
|
7
7
|
const registry = (await contracts?.getRegistry()).connect(signer);
|
|
8
|
-
return registry.setOwner(namehash(name), newOwner);
|
|
8
|
+
return registry.populateTransaction.setOwner(namehash(name), newOwner);
|
|
9
9
|
}
|
|
10
10
|
case 'baseRegistrar': {
|
|
11
11
|
const baseRegistrar = (await contracts?.getBaseRegistrar()).connect(signer);
|
|
@@ -13,11 +13,11 @@ export default async function ({ contracts, signer }, name, { newOwner, contract
|
|
|
13
13
|
if (labels.length > 2 || labels[labels.length - 1] !== 'eth') {
|
|
14
14
|
throw new Error('Invalid name for baseRegistrar');
|
|
15
15
|
}
|
|
16
|
-
return baseRegistrar['safeTransferFrom(address,address,uint256)'](address, newOwner, ethers.utils.solidityKeccak256(['string'], [labels[0]]));
|
|
16
|
+
return baseRegistrar.populateTransaction['safeTransferFrom(address,address,uint256)'](address, newOwner, ethers.utils.solidityKeccak256(['string'], [labels[0]]));
|
|
17
17
|
}
|
|
18
18
|
case 'nameWrapper': {
|
|
19
19
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
20
|
-
return nameWrapper.safeTransferFrom(address, newOwner, namehash(name), 1, '0x');
|
|
20
|
+
return nameWrapper.populateTransaction.safeTransferFrom(address, newOwner, namehash(name), 1, '0x');
|
|
21
21
|
}
|
|
22
22
|
default: {
|
|
23
23
|
throw new Error(`Unknown contract: ${contract}`);
|
|
@@ -3,4 +3,4 @@ import { ENSArgs } from '..';
|
|
|
3
3
|
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { contract, address, }: {
|
|
4
4
|
contract: 'registry' | 'nameWrapper';
|
|
5
5
|
address: string;
|
|
6
|
-
}): Promise<ethers.
|
|
6
|
+
}): Promise<ethers.PopulatedTransaction>;
|
|
@@ -8,11 +8,11 @@ export default async function ({ contracts, signer }, name, { contract, address,
|
|
|
8
8
|
switch (contract) {
|
|
9
9
|
case 'registry': {
|
|
10
10
|
const registry = (await contracts?.getRegistry()).connect(signer);
|
|
11
|
-
return registry.setSubnodeOwner(parentNodehash, labelhash, address);
|
|
11
|
+
return registry.populateTransaction.setSubnodeOwner(parentNodehash, labelhash, address);
|
|
12
12
|
}
|
|
13
13
|
case 'nameWrapper': {
|
|
14
14
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
15
|
-
return nameWrapper.setSubnodeOwner(parentNodehash, label, address, '0');
|
|
15
|
+
return nameWrapper.populateTransaction.setSubnodeOwner(parentNodehash, label, address, '0');
|
|
16
16
|
}
|
|
17
17
|
default: {
|
|
18
18
|
throw new Error(`Unknown contract: ${contract}`);
|
|
@@ -2,4 +2,4 @@ import { ENSArgs } from '..';
|
|
|
2
2
|
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { newController, newRegistrant, }: {
|
|
3
3
|
newController: string;
|
|
4
4
|
newRegistrant?: string;
|
|
5
|
-
}): Promise<import("ethers").
|
|
5
|
+
}): Promise<import("ethers").PopulatedTransaction>;
|
|
@@ -9,12 +9,12 @@ export default async function ({ contracts, signer }, name, { newController, new
|
|
|
9
9
|
if (!newRegistrant) {
|
|
10
10
|
throw new Error('newRegistrant must be specified for .eth names');
|
|
11
11
|
}
|
|
12
|
-
return nameWrapper.unwrapETH2LD(labelhash, newRegistrant, newController);
|
|
12
|
+
return nameWrapper.populateTransaction.unwrapETH2LD(labelhash, newRegistrant, newController);
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
15
|
if (newRegistrant) {
|
|
16
16
|
throw new Error('newRegistrant can only be specified for .eth names');
|
|
17
17
|
}
|
|
18
|
-
return nameWrapper.unwrap(parentNodehash, labelhash, newController);
|
|
18
|
+
return nameWrapper.populateTransaction.unwrap(parentNodehash, labelhash, newController);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
2
|
import { ENSArgs } from '..';
|
|
3
3
|
import type { FuseOptions } from '../@types/FuseOptions';
|
|
4
|
-
export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { wrappedOwner, fuseOptions, resolverAddress, }: {
|
|
4
|
+
export default function ({ contracts, signer, populate }: ENSArgs<'contracts' | 'signer' | 'populate'>, name: string, { wrappedOwner, fuseOptions, resolverAddress, }: {
|
|
5
5
|
wrappedOwner: string;
|
|
6
6
|
fuseOptions?: FuseOptions | string | number;
|
|
7
7
|
resolverAddress?: string;
|
|
8
|
-
}): Promise<ethers.
|
|
8
|
+
}): Promise<ethers.PopulatedTransaction>;
|
|
@@ -6,7 +6,7 @@ async function wrapETH({ contracts }, labels, wrappedOwner, decodedFuses, resolv
|
|
|
6
6
|
const baseRegistrar = (await contracts?.getBaseRegistrar()).connect(signer);
|
|
7
7
|
const labelhash = ethers.utils.solidityKeccak256(['string'], [labels[0]]);
|
|
8
8
|
const data = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint32', 'uint64', 'address'], [labels[0], wrappedOwner, '0x0', decodedFuses, resolverAddress]);
|
|
9
|
-
return baseRegistrar['safeTransferFrom(address,address,uint256,bytes)'](address, nameWrapper.address, labelhash, data);
|
|
9
|
+
return baseRegistrar.populateTransaction['safeTransferFrom(address,address,uint256,bytes)'](address, nameWrapper.address, labelhash, data);
|
|
10
10
|
}
|
|
11
11
|
async function wrapOther({ contracts }, name, wrappedOwner, decodedFuses, resolverAddress, address, signer) {
|
|
12
12
|
const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
|
|
@@ -15,9 +15,9 @@ async function wrapOther({ contracts }, name, wrappedOwner, decodedFuses, resolv
|
|
|
15
15
|
if (!hasApproval) {
|
|
16
16
|
throw new Error('NameWrapper must have approval to wrap a name from this address.');
|
|
17
17
|
}
|
|
18
|
-
return nameWrapper.wrap(hexEncodeName(name), wrappedOwner, decodedFuses, resolverAddress);
|
|
18
|
+
return nameWrapper.populateTransaction.wrap(hexEncodeName(name), wrappedOwner, decodedFuses, resolverAddress);
|
|
19
19
|
}
|
|
20
|
-
export default async function ({ contracts, signer }, name, { wrappedOwner, fuseOptions, resolverAddress, }) {
|
|
20
|
+
export default async function ({ contracts, signer, populate }, name, { wrappedOwner, fuseOptions, resolverAddress, }) {
|
|
21
21
|
const address = await signer.getAddress();
|
|
22
22
|
let decodedFuses;
|
|
23
23
|
switch (typeof fuseOptions) {
|