@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.
- 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/getHistory.d.ts +0 -30
- package/dist/cjs/functions/getHistory.js +3 -99
- package/dist/cjs/functions/getName.d.ts +2 -2
- package/dist/cjs/functions/getName.js +1 -1
- 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 +24 -35
- package/dist/cjs/index.js +8 -3
- 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/getHistory.d.ts +0 -30
- package/dist/esm/functions/getHistory.js +2 -96
- package/dist/esm/functions/getName.d.ts +2 -2
- package/dist/esm/functions/getName.js +1 -1
- 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 +24 -35
- package/dist/esm/index.js +8 -3
- 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/getHistory.test.ts +0 -84
- package/src/functions/getHistory.ts +2 -127
- package/src/functions/getName.test.ts +1 -1
- package/src/functions/getName.ts +1 -1
- 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 +28 -25
- 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 -58
- package/src/tests/signerInjection.test.ts +0 -46
- 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')
|
package/src/functions/getName.ts
CHANGED
|
@@ -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<
|
|
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
|
|
593
|
-
'
|
|
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
|
}
|
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
|
}
|