@ensdomains/ensjs 3.0.0-alpha.4 → 3.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/cjs/GqlManager.d.ts +3 -0
  2. package/dist/cjs/GqlManager.js +62 -2
  3. package/dist/cjs/functions/burnFuses.d.ts +3 -1
  4. package/dist/cjs/functions/burnFuses.js +2 -6
  5. package/dist/cjs/functions/createSubname.d.ts +1 -5
  6. package/dist/cjs/functions/createSubname.js +3 -7
  7. package/dist/cjs/functions/deleteSubname.d.ts +3 -3
  8. package/dist/cjs/functions/deleteSubname.js +5 -2
  9. package/dist/cjs/functions/setName.d.ts +4 -3
  10. package/dist/cjs/functions/setName.js +5 -10
  11. package/dist/cjs/functions/setRecords.d.ts +4 -1
  12. package/dist/cjs/functions/setRecords.js +11 -9
  13. package/dist/cjs/functions/setResolver.d.ts +4 -3
  14. package/dist/cjs/functions/setResolver.js +5 -11
  15. package/dist/cjs/functions/transferName.d.ts +4 -3
  16. package/dist/cjs/functions/transferName.js +8 -13
  17. package/dist/cjs/functions/transferSubname.d.ts +4 -3
  18. package/dist/cjs/functions/transferSubname.js +3 -7
  19. package/dist/cjs/functions/unwrapName.d.ts +4 -3
  20. package/dist/cjs/functions/unwrapName.js +3 -8
  21. package/dist/cjs/functions/wrapName.d.ts +5 -3
  22. package/dist/cjs/functions/wrapName.js +8 -12
  23. package/dist/cjs/index.d.ts +40 -44
  24. package/dist/cjs/index.js +39 -22
  25. package/dist/cjs/utils/normalise.d.ts +1 -1
  26. package/dist/cjs/utils/normalise.js +10 -3
  27. package/dist/cjs/utils/writeTx.d.ts +4 -0
  28. package/dist/cjs/utils/writeTx.js +3 -0
  29. package/dist/esm/GqlManager.d.ts +3 -0
  30. package/dist/esm/GqlManager.js +58 -2
  31. package/dist/esm/functions/burnFuses.d.ts +3 -1
  32. package/dist/esm/functions/burnFuses.js +2 -6
  33. package/dist/esm/functions/createSubname.d.ts +1 -5
  34. package/dist/esm/functions/createSubname.js +3 -7
  35. package/dist/esm/functions/deleteSubname.d.ts +3 -3
  36. package/dist/esm/functions/deleteSubname.js +5 -2
  37. package/dist/esm/functions/setName.d.ts +4 -3
  38. package/dist/esm/functions/setName.js +5 -10
  39. package/dist/esm/functions/setRecords.d.ts +4 -1
  40. package/dist/esm/functions/setRecords.js +11 -9
  41. package/dist/esm/functions/setResolver.d.ts +4 -3
  42. package/dist/esm/functions/setResolver.js +5 -11
  43. package/dist/esm/functions/transferName.d.ts +4 -3
  44. package/dist/esm/functions/transferName.js +8 -13
  45. package/dist/esm/functions/transferSubname.d.ts +4 -3
  46. package/dist/esm/functions/transferSubname.js +3 -7
  47. package/dist/esm/functions/unwrapName.d.ts +4 -3
  48. package/dist/esm/functions/unwrapName.js +3 -8
  49. package/dist/esm/functions/wrapName.d.ts +5 -3
  50. package/dist/esm/functions/wrapName.js +8 -12
  51. package/dist/esm/index.d.ts +40 -44
  52. package/dist/esm/index.js +39 -22
  53. package/dist/esm/utils/normalise.d.ts +1 -1
  54. package/dist/esm/utils/normalise.js +10 -3
  55. package/dist/esm/utils/writeTx.d.ts +4 -0
  56. package/dist/esm/utils/writeTx.js +1 -0
  57. package/package.json +7 -5
  58. package/src/GqlManager.test.ts +170 -0
  59. package/src/GqlManager.ts +67 -2
  60. package/src/functions/burnFuses.test.ts +9 -8
  61. package/src/functions/burnFuses.ts +7 -9
  62. package/src/functions/createSubname.test.ts +8 -11
  63. package/src/functions/createSubname.ts +5 -12
  64. package/src/functions/deleteSubname.test.ts +28 -27
  65. package/src/functions/deleteSubname.ts +9 -12
  66. package/src/functions/getFuses.test.ts +11 -9
  67. package/src/functions/getOwner.test.ts +3 -1
  68. package/src/functions/setName.test.ts +3 -2
  69. package/src/functions/setName.ts +15 -17
  70. package/src/functions/setRecords.test.ts +7 -5
  71. package/src/functions/setRecords.ts +19 -13
  72. package/src/functions/setResolver.test.ts +12 -15
  73. package/src/functions/setResolver.ts +14 -19
  74. package/src/functions/transferName.test.ts +27 -29
  75. package/src/functions/transferName.ts +17 -21
  76. package/src/functions/transferSubname.test.ts +30 -29
  77. package/src/functions/transferSubname.ts +19 -12
  78. package/src/functions/unwrapName.test.ts +22 -22
  79. package/src/functions/unwrapName.ts +18 -14
  80. package/src/functions/wrapName.test.ts +15 -12
  81. package/src/functions/wrapName.ts +20 -22
  82. package/src/index.ts +105 -30
  83. package/src/tests/populateTransaction.test.ts +40 -0
  84. package/src/tests/signerInjection.test.ts +46 -0
  85. package/src/utils/normalise.ts +10 -4
  86. 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',
@@ -94,10 +95,25 @@ class ENS {
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
- const dependenciesToForward = thisRef.forwardDependenciesFromArray(dependencies);
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
@@ -194,32 +221,22 @@ class ENS {
194
221
  universalWrapper = this.generateRawFunction('initialGetters', ['contracts'], 'universalWrapper');
195
222
  resolverMulticallWrapper = this.generateRawFunction('initialGetters', ['contracts'], 'resolverMulticallWrapper');
196
223
  multicallWrapper = this.generateRawFunction('initialGetters', ['contracts'], 'multicallWrapper');
197
- setName = this.generateFunction('setName', [
198
- 'contracts',
199
- 'provider',
200
- ]);
201
- setRecords = this.generateFunction('setRecords', [
202
- 'contracts',
203
- 'provider',
204
- 'getResolver',
205
- ]);
206
- setResolver = this.generateFunction('setResolver', ['contracts', 'provider']);
207
- transferName = this.generateFunction('transferName', ['contracts', 'provider']);
208
- wrapName = this.generateFunction('wrapName', [
224
+ setName = this.generateWriteFunction('setName', [
209
225
  'contracts',
210
- 'provider',
211
226
  ]);
212
- unwrapName = this.generateFunction('unwrapName', [
227
+ setRecords = this.generateWriteFunction('setRecords', ['contracts', 'provider', 'getResolver']);
228
+ setResolver = this.generateWriteFunction('setResolver', ['contracts']);
229
+ transferName = this.generateWriteFunction('transferName', ['contracts']);
230
+ wrapName = this.generateWriteFunction('wrapName', [
213
231
  'contracts',
214
- 'provider',
215
232
  ]);
216
- burnFuses = this.generateFunction('burnFuses', [
233
+ unwrapName = this.generateWriteFunction('unwrapName', ['contracts']);
234
+ burnFuses = this.generateWriteFunction('burnFuses', [
217
235
  'contracts',
218
- 'provider',
219
236
  ]);
220
- createSubname = this.generateFunction('createSubname', ['contracts', 'provider']);
221
- deleteSubname = this.generateFunction('deleteSubname', ['contracts', 'provider', 'transferSubname']);
222
- transferSubname = this.generateFunction('transferSubname', ['contracts', 'provider']);
237
+ createSubname = this.generateWriteFunction('createSubname', ['contracts']);
238
+ deleteSubname = this.generateWriteFunction('deleteSubname', ['transferSubname']);
239
+ transferSubname = this.generateWriteFunction('transferSubname', ['contracts']);
223
240
  getDNSOwner = this.generateFunction('getDNSOwner', []);
224
241
  }
225
242
  exports.ENS = ENS;
@@ -1,2 +1,2 @@
1
1
  export declare const normalise: (name: string) => any;
2
- export declare const namehash: (inputName: string) => string;
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 = (inputName) => {
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
- const labelSha = (0, utils_1.keccak256)((0, utils_1.toUtf8Bytes)(labels[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
+ }
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;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = (signer, populate) => (tx) => populate ? tx : signer.sendTransaction(tx);
@@ -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;
@@ -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 import('graphql-request');
8
- this.client = new imported.GraphQLClient(url);
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,3 +1,5 @@
1
1
  import { ENSArgs } from '..';
2
2
  import { FuseOptions } from '../@types/FuseOptions';
3
- export default function ({ contracts, provider }: ENSArgs<'contracts' | 'provider'>, name: string, fusesToBurn: FuseOptions): Promise<import("ethers").ContractTransaction>;
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
1
  import generateFuseInput from '../utils/generateFuseInput';
2
2
  import { namehash } from '../utils/normalise';
3
- export default async function ({ contracts, provider }, name, fusesToBurn) {
4
- const signer = provider?.getSigner();
5
- if (!signer) {
6
- throw new Error('No signer found');
7
- }
3
+ export default async function ({ contracts, signer }, name, { fusesToBurn, }) {
8
4
  const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
9
5
  const hash = namehash(name);
10
6
  const encodedFuses = generateFuseInput(fusesToBurn);
11
- return nameWrapper.burnFuses(hash, encodedFuses);
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, provider }: ENSArgs<'contracts' | 'provider'>, { name, owner, resolverAddress, contract, options, ...wrapperArgs }: Args): Promise<ethers.ContractTransaction>;
14
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { owner, resolverAddress, contract, ...wrapperArgs }: Args): Promise<ethers.PopulatedTransaction>;
19
15
  export {};
@@ -1,11 +1,7 @@
1
1
  import { ethers } from 'ethers';
2
2
  import generateFuseInput from '../utils/generateFuseInput';
3
3
  import { namehash } from '../utils/normalise';
4
- export default async function ({ contracts, provider }, { name, owner, resolverAddress, contract, options, ...wrapperArgs }) {
5
- const signer = provider?.getSigner(options?.addressOrIndex);
6
- if (!signer) {
7
- throw new Error('No signer found');
8
- }
4
+ export default async function ({ contracts, signer }, name, { owner, resolverAddress, contract, ...wrapperArgs }) {
9
5
  const labels = name.split('.');
10
6
  if (labels.length === 1) {
11
7
  throw new Error('Subnames in ENS.js can only be created for 2LDs, not TLDs');
@@ -22,14 +18,14 @@ export default async function ({ contracts, provider }, { name, owner, resolverA
22
18
  switch (contract) {
23
19
  case 'registry': {
24
20
  const registry = (await contracts?.getRegistry()).connect(signer);
25
- return registry.setSubnodeRecord(parentNodehash, labelhash, owner, resolverAddress, 0);
21
+ return registry.populateTransaction.setSubnodeRecord(parentNodehash, labelhash, owner, resolverAddress, 0);
26
22
  }
27
23
  case 'nameWrapper': {
28
24
  const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
29
25
  const generatedFuses = 'fuses' in wrapperArgs && wrapperArgs.fuses
30
26
  ? generateFuseInput(wrapperArgs.fuses)
31
27
  : '0';
32
- return nameWrapper.setSubnodeRecord(parentNodehash, label, owner, resolverAddress, 0, generatedFuses);
28
+ return nameWrapper.populateTransaction.setSubnodeRecord(parentNodehash, label, owner, resolverAddress, 0, generatedFuses);
33
29
  }
34
30
  default: {
35
31
  throw new Error(`Unknown contract: ${contract}`);
@@ -1,4 +1,4 @@
1
1
  import { ENSArgs } from '..';
2
- export default function ({ contracts, provider, transferSubname, }: ENSArgs<'contracts' | 'provider' | 'transferSubname'>, name: string, contract: 'registry' | 'nameWrapper', options?: {
3
- addressOrIndex?: string | number;
4
- }): Promise<import("ethers").ContractTransaction>;
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 ({ contracts, provider, transferSubname, }, name, contract, options) {
2
- return transferSubname(name, contract, '0x0000000000000000000000000000000000000000', options);
1
+ export default async function ({ transferSubname }, name, { contract, }) {
2
+ return transferSubname.populateTransaction(name, {
3
+ contract,
4
+ address: '0x0000000000000000000000000000000000000000',
5
+ });
3
6
  }
@@ -1,4 +1,5 @@
1
1
  import { ENSArgs } from '..';
2
- export default function ({ contracts, provider }: ENSArgs<'contracts' | 'provider'>, name: string, address?: string, resolver?: string, options?: {
3
- addressOrIndex?: string | number;
4
- }): Promise<import("ethers").ContractTransaction | undefined>;
2
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { address, resolver, }?: {
3
+ address?: string;
4
+ resolver?: string;
5
+ }): Promise<import("ethers").PopulatedTransaction>;
@@ -1,14 +1,9 @@
1
- export default async function ({ contracts, provider }, name, address, resolver, options) {
2
- const signerAddress = await provider
3
- ?.getSigner(options?.addressOrIndex)
4
- .getAddress();
5
- if (!signerAddress) {
6
- throw new Error('No signer found');
7
- }
8
- const reverseRegistrar = (await contracts?.getReverseRegistrar())?.connect(provider?.getSigner());
1
+ export default async function ({ contracts, signer }, name, { address, resolver, } = {}) {
2
+ const signerAddress = await signer.getAddress();
3
+ const reverseRegistrar = (await contracts?.getReverseRegistrar())?.connect(signer);
9
4
  if (address) {
10
5
  const publicResolver = await contracts?.getPublicResolver();
11
- return reverseRegistrar?.setNameForAddr(address, signerAddress, resolver || publicResolver.address, name);
6
+ return reverseRegistrar.populateTransaction.setNameForAddr(address, signerAddress, resolver || publicResolver.address, name);
12
7
  }
13
- return reverseRegistrar?.setName(name);
8
+ return reverseRegistrar.populateTransaction.setName(name);
14
9
  }
@@ -1,3 +1,6 @@
1
1
  import { ENSArgs } from '..';
2
2
  import { RecordOptions } from '../utils/recordHelpers';
3
- export default function ({ contracts, provider, getResolver, }: ENSArgs<'contracts' | 'provider' | 'getResolver'>, name: string, records: RecordOptions): Promise<import("ethers").ContractTransaction | undefined>;
3
+ export default function ({ contracts, provider, getResolver, signer, }: ENSArgs<'contracts' | 'provider' | 'getResolver' | 'signer'>, name: string, { records, resolverAddress, }: {
4
+ records: RecordOptions;
5
+ resolverAddress?: string;
6
+ }): Promise<import("ethers").PopulatedTransaction>;
@@ -1,19 +1,21 @@
1
1
  import { namehash } from '../utils/normalise';
2
2
  import { generateRecordCallArray } from '../utils/recordHelpers';
3
- export default async function ({ contracts, provider, getResolver, }, name, records) {
3
+ export default async function ({ contracts, provider, getResolver, signer, }, name, { records, resolverAddress, }) {
4
4
  if (!name.includes('.')) {
5
5
  throw new Error('Input is not an ENS name');
6
6
  }
7
- const resolverAddress = await getResolver(name);
8
- if (!resolverAddress) {
9
- throw new Error('No resolver found for input address');
7
+ let resolverToUse;
8
+ if (resolverAddress) {
9
+ resolverToUse = resolverAddress;
10
+ }
11
+ else {
12
+ resolverToUse = await getResolver(name);
10
13
  }
11
- const address = await provider?.getSigner().getAddress();
12
- if (!address) {
13
- throw new Error('No signer found');
14
+ if (!resolverToUse) {
15
+ throw new Error('No resolver found for input address');
14
16
  }
15
- const resolver = (await contracts?.getPublicResolver(provider, resolverAddress))?.connect(provider?.getSigner());
17
+ const resolver = (await contracts?.getPublicResolver(provider, resolverToUse))?.connect(signer);
16
18
  const hash = namehash(name);
17
19
  const calls = generateRecordCallArray(hash, records, resolver);
18
- return resolver?.multicall(calls);
20
+ return resolver.populateTransaction.multicall(calls);
19
21
  }
@@ -1,4 +1,5 @@
1
1
  import { ENSArgs } from '..';
2
- export default function ({ contracts, provider }: ENSArgs<'contracts' | 'provider'>, name: string, contract: 'registry' | 'nameWrapper', resolver?: string, options?: {
3
- addressOrIndex?: string | number;
4
- }): Promise<import("ethers").ContractTransaction>;
2
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { contract, resolver, }: {
3
+ contract: 'registry' | 'nameWrapper';
4
+ resolver?: string;
5
+ }): Promise<import("ethers").PopulatedTransaction>;
@@ -1,22 +1,16 @@
1
1
  import { namehash } from '../utils/normalise';
2
- export default async function ({ contracts, provider }, name, contract, resolver, options) {
3
- const address = await provider
4
- ?.getSigner(options?.addressOrIndex)
5
- .getAddress();
6
- if (!address) {
7
- throw new Error('No signer found');
8
- }
2
+ export default async function ({ contracts, signer }, name, { contract, resolver, }) {
9
3
  if (!resolver) {
10
4
  resolver = (await contracts?.getPublicResolver()).address;
11
5
  }
12
6
  switch (contract) {
13
7
  case 'registry': {
14
- const registry = (await contracts?.getRegistry()).connect(provider?.getSigner(options?.addressOrIndex));
15
- return registry.setResolver(namehash(name), resolver);
8
+ const registry = (await contracts?.getRegistry()).connect(signer);
9
+ return registry.populateTransaction.setResolver(namehash(name), resolver);
16
10
  }
17
11
  case 'nameWrapper': {
18
- const nameWrapper = (await contracts?.getNameWrapper()).connect(provider?.getSigner(options?.addressOrIndex));
19
- return nameWrapper.setResolver(namehash(name), resolver);
12
+ const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
13
+ return nameWrapper.populateTransaction.setResolver(namehash(name), resolver);
20
14
  }
21
15
  default: {
22
16
  throw new Error(`Unknown contract: ${contract}`);
@@ -1,5 +1,6 @@
1
1
  import { ethers } from 'ethers';
2
2
  import { ENSArgs } from '..';
3
- export default function ({ contracts, provider }: ENSArgs<'contracts' | 'provider'>, name: string, newOwner: string, contract: 'registry' | 'nameWrapper' | 'baseRegistrar', options?: {
4
- addressOrIndex?: string | number;
5
- }): Promise<ethers.ContractTransaction>;
3
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { newOwner, contract, }: {
4
+ newOwner: string;
5
+ contract: 'registry' | 'nameWrapper' | 'baseRegistrar';
6
+ }): Promise<ethers.PopulatedTransaction>;
@@ -1,28 +1,23 @@
1
1
  import { ethers } from 'ethers';
2
2
  import { namehash } from '../utils/normalise';
3
- export default async function ({ contracts, provider }, name, newOwner, contract, options) {
4
- const address = await provider
5
- ?.getSigner(options?.addressOrIndex)
6
- .getAddress();
7
- if (!address) {
8
- throw new Error('No signer found');
9
- }
3
+ export default async function ({ contracts, signer }, name, { newOwner, contract, }) {
4
+ const address = await signer.getAddress();
10
5
  switch (contract) {
11
6
  case 'registry': {
12
- const registry = (await contracts?.getRegistry()).connect(provider?.getSigner(options?.addressOrIndex));
13
- return registry.setOwner(namehash(name), newOwner);
7
+ const registry = (await contracts?.getRegistry()).connect(signer);
8
+ return registry.populateTransaction.setOwner(namehash(name), newOwner);
14
9
  }
15
10
  case 'baseRegistrar': {
16
- const baseRegistrar = (await contracts?.getBaseRegistrar()).connect(provider?.getSigner(options?.addressOrIndex));
11
+ const baseRegistrar = (await contracts?.getBaseRegistrar()).connect(signer);
17
12
  const labels = name.split('.');
18
13
  if (labels.length > 2 || labels[labels.length - 1] !== 'eth') {
19
14
  throw new Error('Invalid name for baseRegistrar');
20
15
  }
21
- 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]]));
22
17
  }
23
18
  case 'nameWrapper': {
24
- const nameWrapper = (await contracts?.getNameWrapper()).connect(provider?.getSigner(options?.addressOrIndex));
25
- return nameWrapper.safeTransferFrom(address, newOwner, namehash(name), 1, '0x');
19
+ const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
20
+ return nameWrapper.populateTransaction.safeTransferFrom(address, newOwner, namehash(name), 1, '0x');
26
21
  }
27
22
  default: {
28
23
  throw new Error(`Unknown contract: ${contract}`);
@@ -1,5 +1,6 @@
1
1
  import { ethers } from 'ethers';
2
2
  import { ENSArgs } from '..';
3
- export default function ({ contracts, provider }: ENSArgs<'contracts' | 'provider'>, name: string, contract: 'registry' | 'nameWrapper', address: string, options?: {
4
- addressOrIndex?: string | number;
5
- }): Promise<ethers.ContractTransaction>;
3
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { contract, address, }: {
4
+ contract: 'registry' | 'nameWrapper';
5
+ address: string;
6
+ }): Promise<ethers.PopulatedTransaction>;
@@ -1,10 +1,6 @@
1
1
  import { ethers } from 'ethers';
2
2
  import { namehash } from '../utils/normalise';
3
- export default async function ({ contracts, provider }, name, contract, address, options) {
4
- const signer = provider?.getSigner(options?.addressOrIndex);
5
- if (!signer) {
6
- throw new Error('No signer found');
7
- }
3
+ export default async function ({ contracts, signer }, name, { contract, address, }) {
8
4
  const labels = name.split('.');
9
5
  const label = labels.shift();
10
6
  const labelhash = ethers.utils.solidityKeccak256(['string'], [label]);
@@ -12,11 +8,11 @@ export default async function ({ contracts, provider }, name, contract, address,
12
8
  switch (contract) {
13
9
  case 'registry': {
14
10
  const registry = (await contracts?.getRegistry()).connect(signer);
15
- return registry.setSubnodeOwner(parentNodehash, labelhash, address);
11
+ return registry.populateTransaction.setSubnodeOwner(parentNodehash, labelhash, address);
16
12
  }
17
13
  case 'nameWrapper': {
18
14
  const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
19
- return nameWrapper.setSubnodeOwner(parentNodehash, label, address, '0');
15
+ return nameWrapper.populateTransaction.setSubnodeOwner(parentNodehash, label, address, '0');
20
16
  }
21
17
  default: {
22
18
  throw new Error(`Unknown contract: ${contract}`);
@@ -1,4 +1,5 @@
1
1
  import { ENSArgs } from '..';
2
- export default function ({ contracts, provider }: ENSArgs<'contracts' | 'provider'>, name: string, newController: string, newRegistrant?: string, options?: {
3
- addressOrIndex?: string | number;
4
- }): Promise<import("ethers").ContractTransaction>;
2
+ export default function ({ contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { newController, newRegistrant, }: {
3
+ newController: string;
4
+ newRegistrant?: string;
5
+ }): Promise<import("ethers").PopulatedTransaction>;
@@ -1,11 +1,6 @@
1
1
  import { utils } from 'ethers';
2
2
  import { namehash } from '../utils/normalise';
3
- export default async function ({ contracts, provider }, name, newController, newRegistrant, options) {
4
- const signer = provider?.getSigner(options?.addressOrIndex);
5
- const address = await signer?.getAddress();
6
- if (!signer || !address) {
7
- throw new Error('No signer found');
8
- }
3
+ export default async function ({ contracts, signer }, name, { newController, newRegistrant, }) {
9
4
  const labels = name.split('.');
10
5
  const labelhash = utils.solidityKeccak256(['string'], [labels[0]]);
11
6
  const parentNodehash = namehash(labels.slice(1).join('.'));
@@ -14,12 +9,12 @@ export default async function ({ contracts, provider }, name, newController, new
14
9
  if (!newRegistrant) {
15
10
  throw new Error('newRegistrant must be specified for .eth names');
16
11
  }
17
- return nameWrapper.unwrapETH2LD(labelhash, newRegistrant, newController);
12
+ return nameWrapper.populateTransaction.unwrapETH2LD(labelhash, newRegistrant, newController);
18
13
  }
19
14
  else {
20
15
  if (newRegistrant) {
21
16
  throw new Error('newRegistrant can only be specified for .eth names');
22
17
  }
23
- return nameWrapper.unwrap(parentNodehash, labelhash, newController);
18
+ return nameWrapper.populateTransaction.unwrap(parentNodehash, labelhash, newController);
24
19
  }
25
20
  }
@@ -1,6 +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, provider }: ENSArgs<'contracts' | 'provider'>, name: string, wrappedOwner: string, fuseOptions?: FuseOptions | string | number, resolverAddress?: string, options?: {
5
- addressOrIndex?: string | number;
6
- }): Promise<ethers.ContractTransaction>;
4
+ export default function ({ contracts, signer, populate }: ENSArgs<'contracts' | 'signer' | 'populate'>, name: string, { wrappedOwner, fuseOptions, resolverAddress, }: {
5
+ wrappedOwner: string;
6
+ fuseOptions?: FuseOptions | string | number;
7
+ resolverAddress?: string;
8
+ }): Promise<ethers.PopulatedTransaction>;
@@ -5,24 +5,20 @@ async function wrapETH({ contracts }, labels, wrappedOwner, decodedFuses, resolv
5
5
  const nameWrapper = await contracts?.getNameWrapper();
6
6
  const baseRegistrar = (await contracts?.getBaseRegistrar()).connect(signer);
7
7
  const labelhash = ethers.utils.solidityKeccak256(['string'], [labels[0]]);
8
- const data = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint96', 'address'], [labels[0], wrappedOwner, decodedFuses, resolverAddress]);
9
- return baseRegistrar['safeTransferFrom(address,address,uint256,bytes)'](address, nameWrapper.address, labelhash, data);
8
+ const data = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint32', 'uint64', 'address'], [labels[0], wrappedOwner, '0x0', decodedFuses, resolverAddress]);
9
+ return baseRegistrar.populateTransaction['safeTransferFrom(address,address,uint256,bytes)'](address, nameWrapper.address, labelhash, data);
10
10
  }
11
- async function wrapOther({ contracts }, name, wrappedOwner, decodedFuses, resolverAddress, address) {
12
- const nameWrapper = await contracts?.getNameWrapper();
11
+ async function wrapOther({ contracts }, name, wrappedOwner, decodedFuses, resolverAddress, address, signer) {
12
+ const nameWrapper = (await contracts?.getNameWrapper()).connect(signer);
13
13
  const registry = await contracts?.getRegistry();
14
14
  const hasApproval = await registry.isApprovedForAll(address, nameWrapper.address);
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, provider }, name, wrappedOwner, fuseOptions, resolverAddress, options) {
21
- const signer = provider?.getSigner(options?.addressOrIndex);
22
- const address = await signer?.getAddress();
23
- if (!signer || !address) {
24
- throw new Error('No signer found');
25
- }
20
+ export default async function ({ contracts, signer, populate }, name, { wrappedOwner, fuseOptions, resolverAddress, }) {
21
+ const address = await signer.getAddress();
26
22
  let decodedFuses;
27
23
  switch (typeof fuseOptions) {
28
24
  case 'object': {
@@ -53,6 +49,6 @@ export default async function ({ contracts, provider }, name, wrappedOwner, fuse
53
49
  return wrapETH({ contracts }, labels, wrappedOwner, decodedFuses, resolverAddress, signer, address);
54
50
  }
55
51
  else {
56
- return wrapOther({ contracts }, name, wrappedOwner, decodedFuses, resolverAddress, address);
52
+ return wrapOther({ contracts }, name, wrappedOwner, decodedFuses, resolverAddress, address, signer);
57
53
  }
58
54
  }