@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.
- package/dist/cjs/contracts/index.d.ts +8 -8
- package/dist/cjs/functions/burnFuses.d.ts +31 -4
- package/dist/cjs/functions/burnFuses.js +36 -6
- package/dist/cjs/functions/commitName.d.ts +26 -0
- package/dist/cjs/functions/commitName.js +24 -0
- package/dist/cjs/functions/getFuses.d.ts +2 -1
- package/dist/cjs/functions/getFuses.js +9 -18
- package/dist/cjs/functions/getProfile.js +1 -1
- package/dist/cjs/functions/getSpecificRecord.d.ts +4 -4
- package/dist/cjs/functions/registerName.d.ts +11 -0
- package/dist/cjs/functions/registerName.js +19 -0
- package/dist/cjs/functions/renewName.d.ts +6 -0
- package/dist/cjs/functions/renewName.js +10 -0
- package/dist/cjs/index.d.ts +22 -3
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/utils/fuses.d.ts +18 -17
- package/dist/cjs/utils/fuses.js +10 -4
- package/dist/cjs/utils/registerHelpers.d.ts +44 -16
- package/dist/cjs/utils/registerHelpers.js +43 -15
- package/dist/cjs/utils/wrapperExpiry.d.ts +1 -1
- package/dist/cjs/utils/writeTx.d.ts +18 -1
- package/dist/cjs/utils/writeTx.js +4 -1
- package/dist/esm/contracts/index.d.ts +8 -8
- package/dist/esm/functions/burnFuses.d.ts +31 -4
- package/dist/esm/functions/burnFuses.js +36 -3
- package/dist/esm/functions/commitName.d.ts +26 -0
- package/dist/esm/functions/commitName.js +21 -0
- package/dist/esm/functions/getFuses.d.ts +2 -1
- package/dist/esm/functions/getFuses.js +10 -19
- package/dist/esm/functions/getProfile.js +1 -1
- package/dist/esm/functions/getSpecificRecord.d.ts +4 -4
- package/dist/esm/functions/registerName.d.ts +11 -0
- package/dist/esm/functions/registerName.js +16 -0
- package/dist/esm/functions/renewName.d.ts +6 -0
- package/dist/esm/functions/renewName.js +7 -0
- package/dist/esm/index.d.ts +22 -3
- package/dist/esm/index.js +8 -1
- package/dist/esm/utils/fuses.d.ts +18 -17
- package/dist/esm/utils/fuses.js +9 -3
- package/dist/esm/utils/registerHelpers.d.ts +44 -16
- package/dist/esm/utils/registerHelpers.js +40 -14
- package/dist/esm/utils/wrapperExpiry.d.ts +1 -1
- package/dist/esm/utils/writeTx.d.ts +18 -1
- package/dist/esm/utils/writeTx.js +4 -1
- package/package.json +19 -22
- package/src/functions/burnFuses.test.ts +123 -15
- package/src/functions/burnFuses.ts +101 -10
- package/src/functions/commitName.test.ts +61 -0
- package/src/functions/commitName.ts +36 -0
- package/src/functions/getFuses.test.ts +33 -15
- package/src/functions/getFuses.ts +13 -25
- package/src/functions/getProfile.ts +1 -1
- package/src/functions/registerName.test.ts +59 -0
- package/src/functions/registerName.ts +38 -0
- package/src/functions/renewName.test.ts +44 -0
- package/src/functions/renewName.ts +22 -0
- package/src/index.ts +27 -4
- package/src/utils/fuses.ts +12 -4
- package/src/utils/registerHelpers.ts +107 -49
- package/src/utils/writeTx.ts +12 -2
- package/src/tests/populateTransaction.test.ts +0 -40
- package/src/tests/setup.ts +0 -57
- package/src/tests/signerInjection.test.ts +0 -46
- 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
|
|
45
|
+
it('should return default data for an unwrapped name', async () => {
|
|
30
46
|
const result = await ENSInstance.getFuses('with-profile.eth')
|
|
31
|
-
expect(result).
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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 {
|
|
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('
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
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(
|
|
40
|
-
|
|
41
|
-
|
|
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<
|
|
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
|
|
573
|
-
'
|
|
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
|
}
|
package/src/utils/fuses.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
21
|
-
...
|
|
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
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
43
|
-
resolver: resolverAddress,
|
|
91
|
+
resolverAddress,
|
|
44
92
|
data,
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
}
|
package/src/utils/writeTx.ts
CHANGED
|
@@ -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
|
|
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
|
-
})
|