@ensdomains/ensjs 3.0.0-alpha.11 → 3.0.0-alpha.14

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 (76) hide show
  1. package/dist/cjs/contracts/index.d.ts +8 -8
  2. package/dist/cjs/functions/burnFuses.d.ts +31 -4
  3. package/dist/cjs/functions/burnFuses.js +36 -6
  4. package/dist/cjs/functions/commitName.d.ts +26 -0
  5. package/dist/cjs/functions/commitName.js +24 -0
  6. package/dist/cjs/functions/getFuses.d.ts +2 -1
  7. package/dist/cjs/functions/getFuses.js +9 -18
  8. package/dist/cjs/functions/getHistory.d.ts +0 -30
  9. package/dist/cjs/functions/getHistory.js +3 -99
  10. package/dist/cjs/functions/getName.d.ts +2 -2
  11. package/dist/cjs/functions/getName.js +1 -1
  12. package/dist/cjs/functions/getProfile.js +1 -1
  13. package/dist/cjs/functions/getSpecificRecord.d.ts +4 -4
  14. package/dist/cjs/functions/registerName.d.ts +11 -0
  15. package/dist/cjs/functions/registerName.js +19 -0
  16. package/dist/cjs/functions/renewName.d.ts +6 -0
  17. package/dist/cjs/functions/renewName.js +10 -0
  18. package/dist/cjs/index.d.ts +24 -35
  19. package/dist/cjs/index.js +8 -3
  20. package/dist/cjs/utils/fuses.d.ts +18 -17
  21. package/dist/cjs/utils/fuses.js +10 -4
  22. package/dist/cjs/utils/registerHelpers.d.ts +44 -16
  23. package/dist/cjs/utils/registerHelpers.js +43 -15
  24. package/dist/cjs/utils/wrapperExpiry.d.ts +1 -1
  25. package/dist/cjs/utils/writeTx.d.ts +18 -1
  26. package/dist/cjs/utils/writeTx.js +4 -1
  27. package/dist/esm/contracts/index.d.ts +8 -8
  28. package/dist/esm/functions/burnFuses.d.ts +31 -4
  29. package/dist/esm/functions/burnFuses.js +36 -3
  30. package/dist/esm/functions/commitName.d.ts +26 -0
  31. package/dist/esm/functions/commitName.js +21 -0
  32. package/dist/esm/functions/getFuses.d.ts +2 -1
  33. package/dist/esm/functions/getFuses.js +10 -19
  34. package/dist/esm/functions/getHistory.d.ts +0 -30
  35. package/dist/esm/functions/getHistory.js +2 -96
  36. package/dist/esm/functions/getName.d.ts +2 -2
  37. package/dist/esm/functions/getName.js +1 -1
  38. package/dist/esm/functions/getProfile.js +1 -1
  39. package/dist/esm/functions/getSpecificRecord.d.ts +4 -4
  40. package/dist/esm/functions/registerName.d.ts +11 -0
  41. package/dist/esm/functions/registerName.js +16 -0
  42. package/dist/esm/functions/renewName.d.ts +6 -0
  43. package/dist/esm/functions/renewName.js +7 -0
  44. package/dist/esm/index.d.ts +24 -35
  45. package/dist/esm/index.js +8 -3
  46. package/dist/esm/utils/fuses.d.ts +18 -17
  47. package/dist/esm/utils/fuses.js +9 -3
  48. package/dist/esm/utils/registerHelpers.d.ts +44 -16
  49. package/dist/esm/utils/registerHelpers.js +40 -14
  50. package/dist/esm/utils/wrapperExpiry.d.ts +1 -1
  51. package/dist/esm/utils/writeTx.d.ts +18 -1
  52. package/dist/esm/utils/writeTx.js +4 -1
  53. package/package.json +19 -22
  54. package/src/functions/burnFuses.test.ts +123 -15
  55. package/src/functions/burnFuses.ts +101 -10
  56. package/src/functions/commitName.test.ts +61 -0
  57. package/src/functions/commitName.ts +36 -0
  58. package/src/functions/getFuses.test.ts +33 -15
  59. package/src/functions/getFuses.ts +13 -25
  60. package/src/functions/getHistory.test.ts +0 -84
  61. package/src/functions/getHistory.ts +2 -127
  62. package/src/functions/getName.test.ts +1 -1
  63. package/src/functions/getName.ts +1 -1
  64. package/src/functions/getProfile.ts +1 -1
  65. package/src/functions/registerName.test.ts +59 -0
  66. package/src/functions/registerName.ts +38 -0
  67. package/src/functions/renewName.test.ts +44 -0
  68. package/src/functions/renewName.ts +22 -0
  69. package/src/index.ts +28 -25
  70. package/src/utils/fuses.ts +12 -4
  71. package/src/utils/registerHelpers.ts +107 -49
  72. package/src/utils/writeTx.ts +12 -2
  73. package/src/tests/populateTransaction.test.ts +0 -40
  74. package/src/tests/setup.ts +0 -58
  75. package/src/tests/signerInjection.test.ts +0 -46
  76. package/src/tests/withProvider.test.ts +0 -28
@@ -2,7 +2,6 @@ import { formatsByCoinType } from '@ensdomains/address-encoder'
2
2
  import { ethers } from 'ethers'
3
3
  import { ENSArgs } from '..'
4
4
  import { decodeContenthash } from '../utils/contentHash'
5
- import { makeOtherIndexes } from '../utils/makeHashIndexes'
6
5
 
7
6
  type DomainEvent = 'NewOwner' | 'NewResolver' | 'Transfer' | 'NewTTL'
8
7
  type RegistrationEvent = 'NameRegistered' | 'NameRenewed' | 'NameTransferred'
@@ -63,7 +62,7 @@ const eventFormat: Record<
63
62
  NameChanged: (args: any) => ({ name: args.name }),
64
63
  AbiChanged: (args: any) => ({ contentType: args.contentType }),
65
64
  PubkeyChanged: (args: any) => ({ x: args.x, y: args.y }),
66
- TextChanged: (args: any) => ({ key: args.key }),
65
+ TextChanged: (args: any) => ({ key: args.key, value: args.value }),
67
66
  ContenthashChanged: (args: any) => ({ hash: decodeContenthash(args.hash) }),
68
67
  InterfaceChanged: (args: any) => ({
69
68
  interfaceId: args.interfaceId,
@@ -86,37 +85,6 @@ const mapEvents = (eventArray: any[], type: EventTypes) =>
86
85
  data: eventFormat[type][event.__typename](event),
87
86
  }))
88
87
 
89
- const mapResultDetailDecode =
90
- (publicResolver: ethers.Contract) => (result: any) => {
91
- const hashIndexes = makeOtherIndexes(result.input, '10f13a8c')
92
- const abiLengths = hashIndexes.map((x: number) => ({
93
- index: x,
94
- length:
95
- x === 0
96
- ? ethers.utils.hexDataLength(result.input)
97
- : parseInt(ethers.utils.hexDataSlice(result.input, x - 32, x), 16),
98
- }))
99
- const ABIs = abiLengths.map(({ index, length }) =>
100
- ethers.utils.hexDataSlice(result.input, index, index + length),
101
- )
102
- return ABIs.map((abi: string) => {
103
- try {
104
- return publicResolver.interface.decodeFunctionData(
105
- 'setText(bytes32,string,string)',
106
- abi,
107
- )
108
- } catch {
109
- return
110
- }
111
- })
112
- }
113
-
114
- const expandDecode = (prev: any, curr: any) => {
115
- if (!curr) return [...prev, { value: null }]
116
- if (!curr.length) return [...prev, curr]
117
- return [...prev, ...curr]
118
- }
119
-
120
88
  export async function getHistory(
121
89
  { gqlInstance }: ENSArgs<'gqlInstance'>,
122
90
  name: string,
@@ -200,6 +168,7 @@ export async function getHistory(
200
168
  }
201
169
  ...on TextChanged {
202
170
  key
171
+ value
203
172
  }
204
173
  ...on ContenthashChanged {
205
174
  hash
@@ -251,97 +220,3 @@ export async function getHistory(
251
220
  resolver: resolverHistory,
252
221
  }
253
222
  }
254
-
255
- export async function getHistoryWithDetail(
256
- {
257
- contracts,
258
- gqlInstance,
259
- provider,
260
- }: ENSArgs<'contracts' | 'gqlInstance' | 'provider'>,
261
- name: string,
262
- ) {
263
- const historyRes = await getHistory({ gqlInstance }, name)
264
-
265
- if (!historyRes) return
266
-
267
- const { domain, registration, resolver: resolverHistory } = historyRes
268
-
269
- const textEvents = resolverHistory.filter(
270
- (event) => event.type === 'TextChanged',
271
- )
272
-
273
- const transactions = textEvents.reduce((prev, curr) => {
274
- if (prev.includes(curr.transactionHash)) {
275
- return prev
276
- }
277
- return [...prev, curr.transactionHash]
278
- }, [] as string[])
279
-
280
- const publicResolver = await contracts?.getPublicResolver()!
281
-
282
- const fetchResult = (
283
- await ethers.utils.fetchJson(
284
- provider!.connection,
285
- JSON.stringify(
286
- transactions.map((tx, i) => ({
287
- jsonrpc: '2.0',
288
- id: i,
289
- method: 'eth_getTransactionByHash',
290
- params: [tx],
291
- })),
292
- ),
293
- )
294
- )
295
- .map((result: any) => result.result)
296
- .map(mapResultDetailDecode(publicResolver))
297
- .reduce(expandDecode, [])
298
-
299
- const detailedResolverHistory = resolverHistory.map((event) => {
300
- if (event.type !== 'TextChanged') return event
301
- const { id } = event
302
- const matchedTextInx = textEvents.findIndex((x) => x.id === id)
303
- return {
304
- ...event,
305
- data: {
306
- ...event.data,
307
- value: fetchResult[matchedTextInx] && fetchResult[matchedTextInx].value,
308
- },
309
- }
310
- })
311
-
312
- return {
313
- domain,
314
- registration,
315
- resolver: detailedResolverHistory,
316
- }
317
- }
318
-
319
- export async function getHistoryDetailForTransactionHash(
320
- { contracts, provider }: ENSArgs<'contracts' | 'provider'>,
321
- hash: string,
322
- indexInTransaction?: number,
323
- ) {
324
- const publicResolver = await contracts?.getPublicResolver()!
325
- const transaction = await provider!.getTransaction(hash)
326
- if (!transaction) return
327
- const result = mapResultDetailDecode(publicResolver)({
328
- input: transaction.data,
329
- })
330
- if (!result || !result.length) return
331
- if (typeof indexInTransaction === 'number') {
332
- if (indexInTransaction + 1 > result.length) return
333
- const resultItem = result[indexInTransaction]
334
- if (
335
- !resultItem ||
336
- !resultItem.key ||
337
- (!resultItem.value && resultItem.value !== '')
338
- )
339
- return
340
- return { key: resultItem.key, value: resultItem.value }
341
- }
342
- return result.map((item: any) => {
343
- if (!item.key) return
344
- if (!item.value && item.value !== '') return { key: item.key, value: null }
345
- return { key: item.key, value: item.value }
346
- })
347
- }
@@ -31,7 +31,7 @@ describe('getName', () => {
31
31
  const result = await ENSInstance.getName(
32
32
  '0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0',
33
33
  )
34
- expect(result).toBeUndefined()
34
+ expect(result?.name).toBeUndefined()
35
35
  })
36
36
  it('should return with a false match for a name with no forward resolution', async () => {
37
37
  const tx = await ENSInstance.setName('with-profile.eth')
@@ -31,7 +31,7 @@ const decode = async (
31
31
  resolverAddress: result['3'],
32
32
  }
33
33
  } catch {
34
- return { name: null, match: false }
34
+ return { name: undefined }
35
35
  }
36
36
  }
37
37
 
@@ -362,7 +362,7 @@ const graphFetch = async (
362
362
  ;({ domain } = await client.request(query, { id }))
363
363
  resolverResponse = domain?.resolver
364
364
  } else {
365
- const resolverId = `${resolverAddress}-${id}`
365
+ const resolverId = `${resolverAddress.toLowerCase()}-${id}`
366
366
  ;({ resolver: resolverResponse, domain } = await client.request(
367
367
  customResolverQuery,
368
368
  { id, resolverId },
@@ -0,0 +1,59 @@
1
+ import { ethers } from 'ethers'
2
+ import { ENS } from '..'
3
+ import setup from '../tests/setup'
4
+ import { namehash } from '../utils/normalise'
5
+
6
+ let ENSInstance: ENS
7
+ let revert: Awaited<ReturnType<typeof setup>>['revert']
8
+ let provider: ethers.providers.JsonRpcProvider
9
+ let accounts: string[]
10
+
11
+ beforeAll(async () => {
12
+ ;({ ENSInstance, revert, provider } = await setup())
13
+ accounts = await provider.listAccounts()
14
+ })
15
+
16
+ afterAll(async () => {
17
+ await revert()
18
+ await provider.send('anvil_removeBlockTimestampInterval', [])
19
+ })
20
+
21
+ describe('registerName', () => {
22
+ beforeEach(async () => {
23
+ await revert()
24
+ })
25
+ it('should return a registration transaction and succeed', async () => {
26
+ const name = 'cool-swag.eth'
27
+ const duration = 31536000
28
+ const { customData, ...commitPopTx } =
29
+ await ENSInstance.commitName.populateTransaction(name, {
30
+ duration,
31
+ owner: accounts[1],
32
+ addressOrIndex: accounts[1],
33
+ })
34
+ const commitTx = await provider.getSigner().sendTransaction(commitPopTx)
35
+ await commitTx.wait()
36
+
37
+ await provider.send('evm_increaseTime', [60])
38
+ await provider.send('evm_mine', [])
39
+
40
+ const { secret, wrapperExpiry } = customData!
41
+
42
+ const controller = await ENSInstance.contracts!.getEthRegistrarController()!
43
+ const [price] = await controller.rentPrice(name, duration)
44
+
45
+ const tx = await ENSInstance.registerName(name, {
46
+ secret,
47
+ wrapperExpiry,
48
+ duration,
49
+ owner: accounts[1],
50
+ addressOrIndex: accounts[1],
51
+ value: price,
52
+ })
53
+ await tx.wait()
54
+
55
+ const nameWrapper = await ENSInstance.contracts!.getNameWrapper()!
56
+ const owner = await nameWrapper.ownerOf(namehash(name))
57
+ expect(owner).toBe(accounts[1])
58
+ })
59
+ })
@@ -0,0 +1,38 @@
1
+ import { BigNumber } from 'ethers'
2
+ import { ENSArgs } from '..'
3
+ import {
4
+ CommitmentParams,
5
+ makeRegistrationData,
6
+ } from '../utils/registerHelpers'
7
+
8
+ type Params = Omit<CommitmentParams, 'name' | 'resolver'> & {
9
+ resolverAddress?: string
10
+ secret: string
11
+ wrapperExpiry: number
12
+ value: BigNumber
13
+ }
14
+
15
+ export default async function (
16
+ { contracts }: ENSArgs<'contracts'>,
17
+ name: string,
18
+ { resolverAddress, value, ...params }: Params,
19
+ ) {
20
+ const labels = name.split('.')
21
+ if (labels.length !== 2 || labels[1] !== 'eth')
22
+ throw new Error('Currently only .eth TLD registrations are supported')
23
+
24
+ const controller = await contracts!.getEthRegistrarController()
25
+ const _resolver = await contracts!.getPublicResolver(
26
+ undefined,
27
+ resolverAddress,
28
+ )
29
+ const generatedParams = makeRegistrationData({
30
+ name,
31
+ resolver: _resolver,
32
+ ...params,
33
+ })
34
+
35
+ return controller.populateTransaction.register(...generatedParams, {
36
+ value,
37
+ })
38
+ }
@@ -0,0 +1,44 @@
1
+ import { ethers } from 'ethers'
2
+ import { ENS } from '..'
3
+ import setup from '../tests/setup'
4
+ import { labelhash } from '../utils/labels'
5
+
6
+ let ENSInstance: ENS
7
+ let revert: Awaited<ReturnType<typeof setup>>['revert']
8
+ let provider: ethers.providers.JsonRpcProvider
9
+ let accounts: string[]
10
+
11
+ beforeAll(async () => {
12
+ ;({ ENSInstance, revert, provider } = await setup())
13
+ accounts = await provider.listAccounts()
14
+ })
15
+
16
+ afterAll(async () => {
17
+ await revert()
18
+ })
19
+
20
+ describe('registerName', () => {
21
+ beforeEach(async () => {
22
+ await revert()
23
+ })
24
+ it('should return a renew transaction and succeed', async () => {
25
+ const name = 'to-be-renewed.eth'
26
+ const label = name.split('.')[0]
27
+ const duration = 31536000
28
+ const baseRegistrar = await ENSInstance.contracts!.getBaseRegistrar()!
29
+ const oldExpiry = await baseRegistrar.nameExpires(labelhash(label))
30
+
31
+ const controller = await ENSInstance.contracts!.getEthRegistrarController()!
32
+ const [price] = await controller.rentPrice(label, duration)
33
+
34
+ const tx = await ENSInstance.renewName(name, {
35
+ value: price.mul(2),
36
+ duration,
37
+ addressOrIndex: accounts[1],
38
+ })
39
+ await tx.wait()
40
+
41
+ const newExpiry = await baseRegistrar.nameExpires(labelhash(label))
42
+ expect(newExpiry.toNumber()).toBe(oldExpiry.add(31536000).toNumber())
43
+ })
44
+ })
@@ -0,0 +1,22 @@
1
+ import type { BigNumber } from 'ethers'
2
+ import { ENSArgs } from '..'
3
+
4
+ export default async function (
5
+ { contracts }: ENSArgs<'contracts'>,
6
+ name: string,
7
+ {
8
+ duration,
9
+ value,
10
+ }: {
11
+ duration: number
12
+ value: BigNumber
13
+ },
14
+ ) {
15
+ const labels = name.split('.')
16
+ if (labels.length !== 2 || labels[1] !== 'eth')
17
+ throw new Error('Currently only .eth TLD renewals are supported')
18
+
19
+ const controller = await contracts!.getEthRegistrarController()
20
+
21
+ return controller.populateTransaction.renew(labels[0], duration, { value })
22
+ }
package/src/index.ts CHANGED
@@ -10,16 +10,13 @@ import type {
10
10
  universalWrapper,
11
11
  } from './functions/batchWrappers'
12
12
  import type burnFuses from './functions/burnFuses'
13
+ import type commitName from './functions/commitName'
13
14
  import type createSubname from './functions/createSubname'
14
15
  import type deleteSubname from './functions/deleteSubname'
15
16
  import type getDNSOwner from './functions/getDNSOwner'
16
17
  import type getExpiry from './functions/getExpiry'
17
18
  import type getFuses from './functions/getFuses'
18
- import type {
19
- getHistory,
20
- getHistoryDetailForTransactionHash,
21
- getHistoryWithDetail,
22
- } from './functions/getHistory'
19
+ import type { getHistory } from './functions/getHistory'
23
20
  import type getName from './functions/getName'
24
21
  import type getNames from './functions/getNames'
25
22
  import type getOwner from './functions/getOwner'
@@ -36,6 +33,8 @@ import type {
36
33
  _getText,
37
34
  } from './functions/getSpecificRecord'
38
35
  import type getSubnames from './functions/getSubnames'
36
+ import registerName from './functions/registerName'
37
+ import renewName from './functions/renewName'
39
38
  import type setName from './functions/setName'
40
39
  import type setRecord from './functions/setRecord'
41
40
  import type setRecords from './functions/setRecords'
@@ -47,6 +46,7 @@ import type wrapName from './functions/wrapName'
47
46
  import GqlManager from './GqlManager'
48
47
  import singleCall from './utils/singleCall'
49
48
  import writeTx from './utils/writeTx'
49
+ import fuseEnum from './utils/fuses'
50
50
 
51
51
  type ENSOptions = {
52
52
  graphURI?: string | null
@@ -96,7 +96,11 @@ type OptionalWriteOptions<F> = F extends (
96
96
  : never
97
97
 
98
98
  interface WriteFunction<F extends (...args: any) => any> extends Function {
99
- (...args: Parameters<OptionalWriteOptions<F>>): Promise<ContractTransaction>
99
+ (...args: Parameters<OptionalWriteOptions<F>>): Promise<
100
+ ContractTransaction & {
101
+ customData?: Record<string, any>
102
+ }
103
+ >
100
104
  populateTransaction: (
101
105
  ...args: Parameters<OptionalWriteOptions<F>>
102
106
  ) => Promise<PopulatedTransaction>
@@ -154,6 +158,7 @@ export class ENS {
154
158
  contracts?: ContractManager
155
159
  getContractAddress = _getContractAddress
156
160
  gqlInstance = new GqlManager()
161
+ fuses = fuseEnum
157
162
 
158
163
  constructor(options?: ENSOptions) {
159
164
  this.options = options
@@ -437,22 +442,6 @@ export class ENS {
437
442
  'getHistory',
438
443
  )
439
444
 
440
- public getHistoryWithDetail = this.generateFunction<
441
- typeof getHistoryWithDetail
442
- >(
443
- 'getHistory',
444
- ['contracts', 'gqlInstance', 'provider'],
445
- 'getHistoryWithDetail',
446
- )
447
-
448
- public getHistoryDetailForTransactionHash = this.generateFunction<
449
- typeof getHistoryDetailForTransactionHash
450
- >(
451
- 'getHistory',
452
- ['contracts', 'provider'],
453
- 'getHistoryDetailForTransactionHash',
454
- )
455
-
456
445
  public getContentHash = this.generateRawFunction<typeof getContentHash>(
457
446
  'initialGetters',
458
447
  ['contracts', 'universalWrapper'],
@@ -519,6 +508,11 @@ export class ENS {
519
508
  'getPrice',
520
509
  )
521
510
 
511
+ public getDNSOwner = this.generateFunction<typeof getDNSOwner>(
512
+ 'getDNSOwner',
513
+ [],
514
+ )
515
+
522
516
  public universalWrapper = this.generateRawFunction<typeof universalWrapper>(
523
517
  'initialGetters',
524
518
  ['contracts'],
@@ -589,8 +583,17 @@ export class ENS {
589
583
  ['contracts', 'getExpiry'],
590
584
  )
591
585
 
592
- public getDNSOwner = this.generateFunction<typeof getDNSOwner>(
593
- 'getDNSOwner',
594
- [],
586
+ public commitName = this.generateWriteFunction<typeof commitName>(
587
+ 'commitName',
588
+ ['contracts'],
595
589
  )
590
+
591
+ public registerName = this.generateWriteFunction<typeof registerName>(
592
+ 'registerName',
593
+ ['contracts'],
594
+ )
595
+
596
+ public renewName = this.generateWriteFunction<typeof renewName>('renewName', [
597
+ 'contracts',
598
+ ])
596
599
  }
@@ -7,7 +7,7 @@ const CANNOT_CREATE_SUBDOMAIN = 32
7
7
  const PARENT_CANNOT_CONTROL = 64
8
8
  const CAN_DO_EVERYTHING = 0
9
9
 
10
- export const testable = {
10
+ export const fuseEnum = {
11
11
  CANNOT_UNWRAP,
12
12
  CANNOT_BURN_FUSES,
13
13
  CANNOT_TRANSFER,
@@ -15,9 +15,17 @@ export const testable = {
15
15
  CANNOT_SET_TTL,
16
16
  CANNOT_CREATE_SUBDOMAIN,
17
17
  PARENT_CANNOT_CONTROL,
18
- }
18
+ } as const
19
+
20
+ export const unnamedFuses = [
21
+ 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
22
+ 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864,
23
+ 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296,
24
+ ] as const
19
25
 
20
- export default {
21
- ...testable,
26
+ const fullFuseEnum = {
27
+ ...fuseEnum,
22
28
  CAN_DO_EVERYTHING,
23
29
  }
30
+
31
+ export default fullFuseEnum
@@ -6,12 +6,56 @@ import { labelhash } from './labels'
6
6
  import { namehash } from './normalise'
7
7
  import { generateRecordCallArray, RecordOptions } from './recordHelpers'
8
8
 
9
+ export type RegistrationParams = {
10
+ name: string
11
+ owner: string
12
+ duration: number
13
+ secret: string
14
+ resolver: PublicResolver
15
+ records?: RecordOptions
16
+ reverseRecord?: boolean
17
+ fuses?: FuseOptions
18
+ wrapperExpiry: number
19
+ }
20
+
21
+ export type CommitmentParams = Omit<
22
+ RegistrationParams,
23
+ 'secret' | 'wrapperExpiry'
24
+ > & {
25
+ secret?: string
26
+ wrapperExpiry?: number
27
+ }
28
+
29
+ export type RegistrationTuple = [
30
+ name: string,
31
+ owner: string,
32
+ duration: number,
33
+ secret: string,
34
+ resolver: string,
35
+ data: string[],
36
+ reverseRecord: boolean,
37
+ fuses: string,
38
+ wrapperExpiry: number,
39
+ ]
40
+
41
+ export type CommitmentTuple = [
42
+ labelhash: string,
43
+ owner: string,
44
+ duration: number,
45
+ resolver: string,
46
+ data: string[],
47
+ secret: string,
48
+ reverseRecord: boolean,
49
+ fuses: string,
50
+ wrapperExpiry: number,
51
+ ]
52
+
9
53
  export const randomSecret = () => {
10
54
  const bytes = Buffer.allocUnsafe(32)
11
55
  return '0x' + crypto.getRandomValues(bytes).toString('hex')
12
56
  }
13
57
 
14
- export const makeCommitment = ({
58
+ export const makeCommitmentData = ({
15
59
  name,
16
60
  owner,
17
61
  duration,
@@ -19,69 +63,83 @@ export const makeCommitment = ({
19
63
  records,
20
64
  reverseRecord,
21
65
  fuses,
22
- }: {
23
- name: string
24
- owner: string
25
- duration: number
26
- resolver: PublicResolver
27
- records?: RecordOptions
28
- reverseRecord?: boolean
29
- fuses?: FuseOptions
30
- }) => {
66
+ wrapperExpiry,
67
+ secret,
68
+ }: CommitmentParams & {
69
+ secret: string
70
+ }): CommitmentTuple => {
31
71
  const label = labelhash(name.split('.')[0])
32
72
  const hash = namehash(name)
33
73
  const resolverAddress = resolver.address
34
- const data = records ? generateRecordCallArray(hash, records, resolver) : []
35
- const secret = randomSecret()
36
74
  const fuseData = fuses ? generateFuseInput(fuses) : '0'
37
75
 
38
- const commitment = _makeCommitment({
39
- labelhash: label,
76
+ if (reverseRecord) {
77
+ if (!records) {
78
+ records = { coinTypes: [{ key: 'ETH', value: owner }] }
79
+ } else if (!records.coinTypes?.find((c) => c.key === 'ETH')) {
80
+ if (!records.coinTypes) records.coinTypes = []
81
+ records.coinTypes.push({ key: 'ETH', value: owner })
82
+ }
83
+ }
84
+
85
+ const data = records ? generateRecordCallArray(hash, records, resolver) : []
86
+
87
+ return [
88
+ label,
40
89
  owner,
41
90
  duration,
42
- secret,
43
- resolver: resolverAddress,
91
+ resolverAddress,
44
92
  data,
45
- reverseRecord: !!reverseRecord,
46
- fuses: fuseData,
93
+ secret,
94
+ !!reverseRecord,
95
+ fuseData,
96
+ wrapperExpiry || Math.floor(Date.now() / 1000) + duration,
97
+ ]
98
+ }
99
+
100
+ export const makeRegistrationData = (
101
+ params: RegistrationParams,
102
+ ): RegistrationTuple => {
103
+ const commitmentData = makeCommitmentData(params)
104
+ commitmentData[0] = params.name.split('.')[0]
105
+ const secret = commitmentData.splice(5, 1)[0]
106
+ commitmentData.splice(3, 0, secret)
107
+ return commitmentData as unknown as RegistrationTuple
108
+ }
109
+
110
+ export const makeCommitment = ({
111
+ secret = randomSecret(),
112
+ ...inputParams
113
+ }: CommitmentParams) => {
114
+ const generatedParams = makeCommitmentData({
115
+ ...inputParams,
116
+ secret,
47
117
  })
48
118
 
119
+ const commitment = _makeCommitment(generatedParams)
120
+
49
121
  return {
50
122
  secret,
51
123
  commitment,
124
+ wrapperExpiry: generatedParams[8],
52
125
  }
53
126
  }
54
127
 
55
- export const _makeCommitment = ({
56
- labelhash,
57
- owner,
58
- duration,
59
- secret,
60
- resolver,
61
- data,
62
- reverseRecord,
63
- fuses,
64
- }: {
65
- labelhash: string
66
- owner: string
67
- duration: number
68
- secret: string
69
- resolver: string
70
- data: string[]
71
- reverseRecord: boolean
72
- fuses: string
73
- }) => {
74
- return utils.solidityKeccak256(
75
- [
76
- 'bytes32',
77
- 'address',
78
- 'uint256',
79
- 'bytes32',
80
- 'address',
81
- 'bytes[]',
82
- 'bool',
83
- 'uint96',
84
- ],
85
- [labelhash, owner, duration, secret, resolver, data, reverseRecord, fuses],
128
+ export const _makeCommitment = (params: CommitmentTuple) => {
129
+ return utils.keccak256(
130
+ utils.defaultAbiCoder.encode(
131
+ [
132
+ 'bytes32',
133
+ 'address',
134
+ 'uint256',
135
+ 'address',
136
+ 'bytes[]',
137
+ 'bytes32',
138
+ 'bool',
139
+ 'uint32',
140
+ 'uint64',
141
+ ],
142
+ params,
143
+ ),
86
144
  )
87
145
  }