@ensdomains/ensjs 3.0.0-alpha.12 → 3.0.0-alpha.15

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 (64) 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/getProfile.js +1 -1
  9. package/dist/cjs/functions/getSpecificRecord.d.ts +4 -4
  10. package/dist/cjs/functions/registerName.d.ts +11 -0
  11. package/dist/cjs/functions/registerName.js +19 -0
  12. package/dist/cjs/functions/renewName.d.ts +6 -0
  13. package/dist/cjs/functions/renewName.js +10 -0
  14. package/dist/cjs/index.d.ts +22 -3
  15. package/dist/cjs/index.js +8 -1
  16. package/dist/cjs/utils/fuses.d.ts +18 -17
  17. package/dist/cjs/utils/fuses.js +10 -4
  18. package/dist/cjs/utils/registerHelpers.d.ts +44 -16
  19. package/dist/cjs/utils/registerHelpers.js +43 -15
  20. package/dist/cjs/utils/wrapperExpiry.d.ts +1 -1
  21. package/dist/cjs/utils/writeTx.d.ts +18 -1
  22. package/dist/cjs/utils/writeTx.js +4 -1
  23. package/dist/esm/contracts/index.d.ts +8 -8
  24. package/dist/esm/functions/burnFuses.d.ts +31 -4
  25. package/dist/esm/functions/burnFuses.js +36 -3
  26. package/dist/esm/functions/commitName.d.ts +26 -0
  27. package/dist/esm/functions/commitName.js +21 -0
  28. package/dist/esm/functions/getFuses.d.ts +2 -1
  29. package/dist/esm/functions/getFuses.js +10 -19
  30. package/dist/esm/functions/getProfile.js +1 -1
  31. package/dist/esm/functions/getSpecificRecord.d.ts +4 -4
  32. package/dist/esm/functions/registerName.d.ts +11 -0
  33. package/dist/esm/functions/registerName.js +16 -0
  34. package/dist/esm/functions/renewName.d.ts +6 -0
  35. package/dist/esm/functions/renewName.js +7 -0
  36. package/dist/esm/index.d.ts +22 -3
  37. package/dist/esm/index.js +8 -1
  38. package/dist/esm/utils/fuses.d.ts +18 -17
  39. package/dist/esm/utils/fuses.js +9 -3
  40. package/dist/esm/utils/registerHelpers.d.ts +44 -16
  41. package/dist/esm/utils/registerHelpers.js +40 -14
  42. package/dist/esm/utils/wrapperExpiry.d.ts +1 -1
  43. package/dist/esm/utils/writeTx.d.ts +18 -1
  44. package/dist/esm/utils/writeTx.js +4 -1
  45. package/package.json +19 -22
  46. package/src/functions/burnFuses.test.ts +123 -15
  47. package/src/functions/burnFuses.ts +101 -10
  48. package/src/functions/commitName.test.ts +61 -0
  49. package/src/functions/commitName.ts +36 -0
  50. package/src/functions/getFuses.test.ts +33 -15
  51. package/src/functions/getFuses.ts +13 -25
  52. package/src/functions/getProfile.ts +1 -1
  53. package/src/functions/registerName.test.ts +59 -0
  54. package/src/functions/registerName.ts +38 -0
  55. package/src/functions/renewName.test.ts +44 -0
  56. package/src/functions/renewName.ts +22 -0
  57. package/src/index.ts +27 -4
  58. package/src/utils/fuses.ts +12 -4
  59. package/src/utils/registerHelpers.ts +107 -49
  60. package/src/utils/writeTx.ts +12 -2
  61. package/src/tests/populateTransaction.test.ts +0 -40
  62. package/src/tests/setup.ts +0 -57
  63. package/src/tests/signerInjection.test.ts +0 -46
  64. package/src/tests/withProvider.test.ts +0 -28
@@ -1,4 +1,4 @@
1
- import { ethers } from 'ethers'
1
+ import { BigNumber, ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
3
  import setup from '../tests/setup'
4
4
 
@@ -9,6 +9,22 @@ let provider: ethers.providers.JsonRpcProvider
9
9
  let accounts: string[]
10
10
  let withWrappedSnapshot: any
11
11
 
12
+ const unwrappedNameDefault = {
13
+ expiryDate: new Date(0).toString(),
14
+ fuseObj: {
15
+ CANNOT_BURN_FUSES: false,
16
+ CANNOT_CREATE_SUBDOMAIN: false,
17
+ CANNOT_SET_RESOLVER: false,
18
+ CANNOT_SET_TTL: false,
19
+ CANNOT_TRANSFER: false,
20
+ CANNOT_UNWRAP: false,
21
+ PARENT_CANNOT_CONTROL: false,
22
+ canDoEverything: true,
23
+ },
24
+ owner: '0x0000000000000000000000000000000000000000',
25
+ rawFuses: BigNumber.from(0),
26
+ }
27
+
12
28
  beforeAll(async () => {
13
29
  ;({ ENSInstance, revert, provider, createSnapshot } = await setup())
14
30
  accounts = await provider.listAccounts()
@@ -26,9 +42,11 @@ afterAll(async () => {
26
42
  })
27
43
 
28
44
  describe('getFuses', () => {
29
- it('should return null for an unwrapped name', async () => {
45
+ it('should return default data for an unwrapped name', async () => {
30
46
  const result = await ENSInstance.getFuses('with-profile.eth')
31
- expect(result).toBeUndefined()
47
+ expect({ ...result, expiryDate: result?.expiryDate.toString() }).toEqual(
48
+ unwrappedNameDefault,
49
+ )
32
50
  })
33
51
  it('should return with canDoEverything set to true for a name with no fuses burned', async () => {
34
52
  const nameWrapper = await ENSInstance.contracts!.getNameWrapper()!
@@ -47,11 +65,11 @@ describe('getFuses', () => {
47
65
  })
48
66
  it('should return with other correct fuses', async () => {
49
67
  const tx = await ENSInstance.burnFuses('wrapped.eth', {
50
- fusesToBurn: {
51
- cannotUnwrap: true,
52
- cannotSetTtl: true,
53
- cannotCreateSubdomain: true,
54
- },
68
+ namedFusesToBurn: [
69
+ 'CANNOT_UNWRAP',
70
+ 'CANNOT_CREATE_SUBDOMAIN',
71
+ 'CANNOT_SET_TTL',
72
+ ],
55
73
  addressOrIndex: 1,
56
74
  })
57
75
  await tx.wait()
@@ -60,13 +78,13 @@ describe('getFuses', () => {
60
78
  expect(result).toBeTruthy()
61
79
  if (result) {
62
80
  expect(result.fuseObj).toMatchObject({
63
- cannotUnwrap: true,
64
- cannotBurnFuses: false,
65
- cannotTransfer: false,
66
- cannotSetResolver: false,
67
- cannotSetTtl: true,
68
- cannotCreateSubdomain: true,
69
- parentCannotControl: true,
81
+ CANNOT_UNWRAP: true,
82
+ CANNOT_BURN_FUSES: false,
83
+ CANNOT_TRANSFER: false,
84
+ CANNOT_SET_RESOLVER: false,
85
+ CANNOT_SET_TTL: true,
86
+ CANNOT_CREATE_SUBDOMAIN: true,
87
+ PARENT_CANNOT_CONTROL: true,
70
88
  canDoEverything: false,
71
89
  })
72
90
  expect(result.rawFuses.toHexString()).toBe('0x71')
@@ -1,48 +1,34 @@
1
1
  import { BigNumber } from 'ethers'
2
2
  import { ENSArgs } from '..'
3
- import { testable as fuseEnums } from '../utils/fuses'
3
+ import { fuseEnum } from '../utils/fuses'
4
4
  import { namehash } from '../utils/normalise'
5
5
 
6
- const NameSafety = [
7
- 'Safe',
8
- 'RegistrantNotWrapped',
9
- 'ControllerNotWrapped',
10
- 'SubdomainReplacementAllowed',
11
- 'Expired',
12
- ]
13
-
14
6
  const raw = async ({ contracts }: ENSArgs<'contracts'>, name: string) => {
15
7
  const nameWrapper = await contracts?.getNameWrapper()!
16
8
  return {
17
9
  to: nameWrapper.address,
18
- data: nameWrapper.interface.encodeFunctionData('getFuses', [
19
- namehash(name),
20
- ]),
10
+ data: nameWrapper.interface.encodeFunctionData('getData', [namehash(name)]),
21
11
  }
22
12
  }
23
13
 
24
14
  const decode = async (
25
15
  { contracts }: ENSArgs<'contracts'>,
26
16
  data: string,
27
- name: string,
28
17
  ) => {
29
18
  const nameWrapper = await contracts?.getNameWrapper()!
30
19
  try {
31
- const [_fuses, expiry] = nameWrapper.interface.decodeFunctionResult(
32
- 'getFuses',
33
- data,
34
- )
20
+ const {
21
+ owner,
22
+ fuses: _fuses,
23
+ expiry,
24
+ } = nameWrapper.interface.decodeFunctionResult('getData', data)
35
25
 
36
26
  const fuses = BigNumber.from(_fuses)
37
27
 
38
28
  const fuseObj = Object.fromEntries(
39
- Object.keys(fuseEnums).map((fuseEnum) => [
40
- fuseEnum
41
- .toLowerCase()
42
- .replace(/([-_][a-z])/g, (group: string) =>
43
- group.toUpperCase().replace('-', '').replace('_', ''),
44
- ),
45
- fuses.and(fuseEnums[fuseEnum as keyof typeof fuseEnums]).gt(0),
29
+ Object.keys(fuseEnum).map((fuse) => [
30
+ fuse,
31
+ fuses.and(fuseEnum[fuse as keyof typeof fuseEnum]).gt(0),
46
32
  ]),
47
33
  )
48
34
 
@@ -58,8 +44,10 @@ const decode = async (
58
44
  fuseObj,
59
45
  expiryDate,
60
46
  rawFuses: fuses,
47
+ owner,
61
48
  }
62
- } catch {
49
+ } catch (e) {
50
+ console.error('Error decoding fuses data: ', e)
63
51
  return
64
52
  }
65
53
  }
@@ -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,6 +10,7 @@ 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'
@@ -32,6 +33,8 @@ import type {
32
33
  _getText,
33
34
  } from './functions/getSpecificRecord'
34
35
  import type getSubnames from './functions/getSubnames'
36
+ import registerName from './functions/registerName'
37
+ import renewName from './functions/renewName'
35
38
  import type setName from './functions/setName'
36
39
  import type setRecord from './functions/setRecord'
37
40
  import type setRecords from './functions/setRecords'
@@ -43,6 +46,7 @@ import type wrapName from './functions/wrapName'
43
46
  import GqlManager from './GqlManager'
44
47
  import singleCall from './utils/singleCall'
45
48
  import writeTx from './utils/writeTx'
49
+ import fuseEnum from './utils/fuses'
46
50
 
47
51
  type ENSOptions = {
48
52
  graphURI?: string | null
@@ -92,7 +96,11 @@ type OptionalWriteOptions<F> = F extends (
92
96
  : never
93
97
 
94
98
  interface WriteFunction<F extends (...args: any) => any> extends Function {
95
- (...args: Parameters<OptionalWriteOptions<F>>): Promise<ContractTransaction>
99
+ (...args: Parameters<OptionalWriteOptions<F>>): Promise<
100
+ ContractTransaction & {
101
+ customData?: Record<string, any>
102
+ }
103
+ >
96
104
  populateTransaction: (
97
105
  ...args: Parameters<OptionalWriteOptions<F>>
98
106
  ) => Promise<PopulatedTransaction>
@@ -150,6 +158,7 @@ export class ENS {
150
158
  contracts?: ContractManager
151
159
  getContractAddress = _getContractAddress
152
160
  gqlInstance = new GqlManager()
161
+ fuses = fuseEnum
153
162
 
154
163
  constructor(options?: ENSOptions) {
155
164
  this.options = options
@@ -499,6 +508,11 @@ export class ENS {
499
508
  'getPrice',
500
509
  )
501
510
 
511
+ public getDNSOwner = this.generateFunction<typeof getDNSOwner>(
512
+ 'getDNSOwner',
513
+ [],
514
+ )
515
+
502
516
  public universalWrapper = this.generateRawFunction<typeof universalWrapper>(
503
517
  'initialGetters',
504
518
  ['contracts'],
@@ -569,8 +583,17 @@ export class ENS {
569
583
  ['contracts', 'getExpiry'],
570
584
  )
571
585
 
572
- public getDNSOwner = this.generateFunction<typeof getDNSOwner>(
573
- 'getDNSOwner',
574
- [],
586
+ public commitName = this.generateWriteFunction<typeof commitName>(
587
+ 'commitName',
588
+ ['contracts'],
589
+ )
590
+
591
+ public registerName = this.generateWriteFunction<typeof registerName>(
592
+ 'registerName',
593
+ ['contracts'],
575
594
  )
595
+
596
+ public renewName = this.generateWriteFunction<typeof renewName>('renewName', [
597
+ 'contracts',
598
+ ])
576
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
  }
@@ -1,6 +1,16 @@
1
1
  import { JsonRpcSigner } from '@ethersproject/providers'
2
2
  import type { PopulatedTransaction } from 'ethers'
3
3
 
4
+ type CustomData = Record<string, any>
5
+
6
+ const withCustomData = <T extends object>(
7
+ tx: T,
8
+ customData: CustomData | undefined,
9
+ ): (T & { customData: CustomData }) | T =>
10
+ customData ? { ...tx, customData } : tx
11
+
4
12
  export default (signer: JsonRpcSigner, populate: boolean) =>
5
- (tx: PopulatedTransaction) =>
6
- populate ? tx : signer.sendTransaction(tx)
13
+ ({ customData, ...tx }: PopulatedTransaction) =>
14
+ populate
15
+ ? withCustomData(tx, customData)
16
+ : signer.sendTransaction(tx).then((r) => withCustomData(r, customData))
@@ -1,40 +0,0 @@
1
- import { ethers } from 'ethers'
2
- import { ENS } from '..'
3
- import setup from '../tests/setup'
4
-
5
- let ENSInstance: ENS
6
- let revert: Awaited<ReturnType<typeof setup>>['revert']
7
- let provider: ethers.providers.JsonRpcProvider
8
- let accounts: string[]
9
-
10
- beforeAll(async () => {
11
- ;({ ENSInstance, revert, provider } = await setup())
12
- accounts = await provider.listAccounts()
13
- })
14
-
15
- afterAll(async () => {
16
- await revert()
17
- })
18
-
19
- jest.setTimeout(20000)
20
-
21
- describe('populateTransaction', () => {
22
- beforeEach(async () => {
23
- await revert()
24
- })
25
- it('should return a transaction successfully', async () => {
26
- const tx = await ENSInstance.setName('fleek.eth')
27
- expect(tx).toBeTruthy()
28
- if (tx) {
29
- await tx.wait()
30
- expect(tx.hash).toBeTruthy()
31
- }
32
- })
33
- it('should return a populated transaction successfully', async () => {
34
- const tx = await ENSInstance.setName.populateTransaction('fleek.eth')
35
- expect(tx).toBeTruthy()
36
- if (tx) {
37
- expect(tx).not.toHaveProperty('hash')
38
- }
39
- })
40
- })