@ensdomains/ensjs 3.0.0-alpha.12 → 3.0.0-alpha.13
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/functions/commitName.d.ts +26 -0
- package/dist/cjs/functions/commitName.js +24 -0
- package/dist/cjs/functions/getProfile.js +1 -1
- 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 +10 -2
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/utils/registerHelpers.d.ts +44 -16
- package/dist/cjs/utils/registerHelpers.js +43 -15
- package/dist/cjs/utils/writeTx.d.ts +18 -1
- package/dist/cjs/utils/writeTx.js +4 -1
- package/dist/esm/functions/commitName.d.ts +26 -0
- package/dist/esm/functions/commitName.js +21 -0
- package/dist/esm/functions/getProfile.js +1 -1
- 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 +10 -2
- package/dist/esm/index.js +6 -1
- package/dist/esm/utils/registerHelpers.d.ts +44 -16
- package/dist/esm/utils/registerHelpers.js +40 -14
- 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/commitName.test.ts +61 -0
- package/src/functions/commitName.ts +36 -0
- 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 +25 -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
|
@@ -7,37 +7,63 @@ export const randomSecret = () => {
|
|
|
7
7
|
const bytes = Buffer.allocUnsafe(32);
|
|
8
8
|
return '0x' + crypto.getRandomValues(bytes).toString('hex');
|
|
9
9
|
};
|
|
10
|
-
export const
|
|
10
|
+
export const makeCommitmentData = ({ name, owner, duration, resolver, records, reverseRecord, fuses, wrapperExpiry, secret, }) => {
|
|
11
11
|
const label = labelhash(name.split('.')[0]);
|
|
12
12
|
const hash = namehash(name);
|
|
13
13
|
const resolverAddress = resolver.address;
|
|
14
|
-
const data = records ? generateRecordCallArray(hash, records, resolver) : [];
|
|
15
|
-
const secret = randomSecret();
|
|
16
14
|
const fuseData = fuses ? generateFuseInput(fuses) : '0';
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
if (reverseRecord) {
|
|
16
|
+
if (!records) {
|
|
17
|
+
records = { coinTypes: [{ key: 'ETH', value: owner }] };
|
|
18
|
+
}
|
|
19
|
+
else if (!records.coinTypes?.find((c) => c.key === 'ETH')) {
|
|
20
|
+
if (!records.coinTypes)
|
|
21
|
+
records.coinTypes = [];
|
|
22
|
+
records.coinTypes.push({ key: 'ETH', value: owner });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const data = records ? generateRecordCallArray(hash, records, resolver) : [];
|
|
26
|
+
return [
|
|
27
|
+
label,
|
|
19
28
|
owner,
|
|
20
29
|
duration,
|
|
21
|
-
|
|
22
|
-
resolver: resolverAddress,
|
|
30
|
+
resolverAddress,
|
|
23
31
|
data,
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
secret,
|
|
33
|
+
!!reverseRecord,
|
|
34
|
+
fuseData,
|
|
35
|
+
wrapperExpiry || Math.floor(Date.now() / 1000) + duration,
|
|
36
|
+
];
|
|
37
|
+
};
|
|
38
|
+
export const makeRegistrationData = (params) => {
|
|
39
|
+
const commitmentData = makeCommitmentData(params);
|
|
40
|
+
commitmentData[0] = params.name.split('.')[0];
|
|
41
|
+
const secret = commitmentData.splice(5, 1)[0];
|
|
42
|
+
commitmentData.splice(3, 0, secret);
|
|
43
|
+
return commitmentData;
|
|
44
|
+
};
|
|
45
|
+
export const makeCommitment = ({ secret = randomSecret(), ...inputParams }) => {
|
|
46
|
+
const generatedParams = makeCommitmentData({
|
|
47
|
+
...inputParams,
|
|
48
|
+
secret,
|
|
26
49
|
});
|
|
50
|
+
const commitment = _makeCommitment(generatedParams);
|
|
27
51
|
return {
|
|
28
52
|
secret,
|
|
29
53
|
commitment,
|
|
54
|
+
wrapperExpiry: generatedParams[8],
|
|
30
55
|
};
|
|
31
56
|
};
|
|
32
|
-
export const _makeCommitment = (
|
|
33
|
-
return utils.
|
|
57
|
+
export const _makeCommitment = (params) => {
|
|
58
|
+
return utils.keccak256(utils.defaultAbiCoder.encode([
|
|
34
59
|
'bytes32',
|
|
35
60
|
'address',
|
|
36
61
|
'uint256',
|
|
37
|
-
'bytes32',
|
|
38
62
|
'address',
|
|
39
63
|
'bytes[]',
|
|
64
|
+
'bytes32',
|
|
40
65
|
'bool',
|
|
41
|
-
'
|
|
42
|
-
|
|
66
|
+
'uint32',
|
|
67
|
+
'uint64',
|
|
68
|
+
], params));
|
|
43
69
|
};
|
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
import { JsonRpcSigner } from '@ethersproject/providers';
|
|
2
2
|
import type { PopulatedTransaction } from 'ethers';
|
|
3
|
-
declare
|
|
3
|
+
declare type CustomData = Record<string, any>;
|
|
4
|
+
declare const _default: (signer: JsonRpcSigner, populate: boolean) => ({ customData, ...tx }: PopulatedTransaction) => {
|
|
5
|
+
to?: string | undefined;
|
|
6
|
+
from?: string | undefined;
|
|
7
|
+
nonce?: number | undefined;
|
|
8
|
+
gasLimit?: import("ethers").BigNumber | undefined;
|
|
9
|
+
gasPrice?: import("ethers").BigNumber | undefined;
|
|
10
|
+
data?: string | undefined;
|
|
11
|
+
value?: import("ethers").BigNumber | undefined;
|
|
12
|
+
chainId?: number | undefined;
|
|
13
|
+
type?: number | undefined;
|
|
14
|
+
accessList?: import("ethers/lib/utils").AccessList | undefined;
|
|
15
|
+
maxFeePerGas?: import("ethers").BigNumber | undefined;
|
|
16
|
+
maxPriorityFeePerGas?: import("ethers").BigNumber | undefined;
|
|
17
|
+
ccipReadEnabled?: boolean | undefined;
|
|
18
|
+
} | Promise<import("@ethersproject/providers").TransactionResponse | (import("@ethersproject/providers").TransactionResponse & {
|
|
19
|
+
customData: CustomData;
|
|
20
|
+
})>;
|
|
4
21
|
export default _default;
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
const withCustomData = (tx, customData) => customData ? { ...tx, customData } : tx;
|
|
2
|
+
export default (signer, populate) => ({ customData, ...tx }) => populate
|
|
3
|
+
? withCustomData(tx, customData)
|
|
4
|
+
: signer.sendTransaction(tx).then((r) => withCustomData(r, customData));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ensdomains/ensjs",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.13",
|
|
4
4
|
"description": "ENS javascript library for contract interaction",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"types": "./dist/cjs/index.d.ts",
|
|
@@ -22,26 +22,8 @@
|
|
|
22
22
|
"repository": "git@github.com:ensdomains/ensjs-v3.git",
|
|
23
23
|
"author": "TateB <yo@taytems.xyz>",
|
|
24
24
|
"license": "MIT",
|
|
25
|
-
"scripts": {
|
|
26
|
-
"env": "yarn ens-test-env",
|
|
27
|
-
"generate-types": "ts-node scripts/runTypechain.ts",
|
|
28
|
-
"generate-abis": "hardhat export-abi",
|
|
29
|
-
"start": "ts-node --files src/index.test.ts",
|
|
30
|
-
"test": "jest --run-in-band",
|
|
31
|
-
"test:watch": "jest --watch --run-in-band",
|
|
32
|
-
"test:specific": "ts-node --files ",
|
|
33
|
-
"clean": "rm -rf ./dist ./README.md ./LICENSE",
|
|
34
|
-
"build:esm": "tsc --project tsconfig.esm.json",
|
|
35
|
-
"build:cjs": "tsc --project tsconfig.cjs.json",
|
|
36
|
-
"build": "yarn clean && yarn build:esm && yarn build:cjs",
|
|
37
|
-
"prepublish": "yarn build && cp ../../{README.md,LICENSE} ./",
|
|
38
|
-
"remove-stableVersion": "ex -c '%s/,\\n\\s\\+\"stableVersion\".*\"//g' -cwq ./package.json",
|
|
39
|
-
"version:create": "yarn remove-stableVersion && yarn version",
|
|
40
|
-
"enode": "ganache --wallet.mnemonic=\"test test test test test test test test test test test junk\" --chain.chainId 1337 --chain.networkId 1337 --chain.time 1659500634000"
|
|
41
|
-
},
|
|
42
|
-
"packageManager": "yarn@3.2.0",
|
|
43
25
|
"dependencies": {
|
|
44
|
-
"@ensdomains/address-encoder": "
|
|
26
|
+
"@ensdomains/address-encoder": "0.2.16",
|
|
45
27
|
"@ensdomains/content-hash": "^2.5.7",
|
|
46
28
|
"dns-packet": "^5.3.1",
|
|
47
29
|
"ethers": "^5.6.1",
|
|
@@ -53,7 +35,7 @@
|
|
|
53
35
|
"devDependencies": {
|
|
54
36
|
"@ensdomains/buffer": "^0.0.13",
|
|
55
37
|
"@ensdomains/ens-contracts": "^0.0.12",
|
|
56
|
-
"@ensdomains/ens-test-env": "0.
|
|
38
|
+
"@ensdomains/ens-test-env": "0.2.2",
|
|
57
39
|
"@ethersproject/abi": "^5.6.0",
|
|
58
40
|
"@ethersproject/providers": "^5.6.2",
|
|
59
41
|
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
|
|
@@ -85,5 +67,20 @@
|
|
|
85
67
|
"peerDependencies": {
|
|
86
68
|
"ethers": "*"
|
|
87
69
|
},
|
|
88
|
-
"
|
|
70
|
+
"scripts": {
|
|
71
|
+
"tenv": "ens-test-env -a",
|
|
72
|
+
"generate-types": "ts-node scripts/runTypechain.ts",
|
|
73
|
+
"generate-abis": "hardhat export-abi",
|
|
74
|
+
"start": "ts-node --files src/index.test.ts",
|
|
75
|
+
"test": "jest --run-in-band",
|
|
76
|
+
"test:watch": "jest --watch --run-in-band",
|
|
77
|
+
"test:specific": "ts-node --files ",
|
|
78
|
+
"clean": "rm -rf ./dist ./README.md ./LICENSE",
|
|
79
|
+
"build:esm": "tsc --project tsconfig.esm.json",
|
|
80
|
+
"build:cjs": "tsc --project tsconfig.cjs.json",
|
|
81
|
+
"build": "pnpm clean && pnpm build:esm && pnpm build:cjs",
|
|
82
|
+
"prepublish": "pnpm build && cp ../../README.md ../../LICENSE ./",
|
|
83
|
+
"enode": "ganache --wallet.mnemonic=\"test test test test test test test test test test test junk\" --chain.chainId 1337 --chain.networkId 1337 --chain.time 1659500634000",
|
|
84
|
+
"ver": "pnpm version --no-workspaces-update"
|
|
85
|
+
}
|
|
89
86
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ethers } from 'ethers'
|
|
2
|
+
import { ENS } from '..'
|
|
3
|
+
import setup from '../tests/setup'
|
|
4
|
+
import { randomSecret } from '../utils/registerHelpers'
|
|
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('commitName', () => {
|
|
21
|
+
beforeEach(async () => {
|
|
22
|
+
await revert()
|
|
23
|
+
})
|
|
24
|
+
it('should return a populated commit transaction with extra data and succeed', async () => {
|
|
25
|
+
const { customData, ...popTx } =
|
|
26
|
+
await ENSInstance.commitName.populateTransaction('commitment.eth', {
|
|
27
|
+
duration: 31536000,
|
|
28
|
+
owner: accounts[1],
|
|
29
|
+
addressOrIndex: accounts[1],
|
|
30
|
+
})
|
|
31
|
+
expect(popTx).toBeTruthy()
|
|
32
|
+
expect(customData).toHaveProperty('secret')
|
|
33
|
+
expect(customData).toHaveProperty('commitment')
|
|
34
|
+
expect(customData).toHaveProperty('wrapperExpiry')
|
|
35
|
+
|
|
36
|
+
const tx = await provider.getSigner().sendTransaction(popTx)
|
|
37
|
+
await tx.wait()
|
|
38
|
+
|
|
39
|
+
const controller = await ENSInstance.contracts!.getEthRegistrarController()!
|
|
40
|
+
const commitment = await controller.commitments(customData!.commitment)
|
|
41
|
+
expect(commitment).toBeTruthy()
|
|
42
|
+
})
|
|
43
|
+
it('should return a customised commmit transaction and succeed', async () => {
|
|
44
|
+
const secret = randomSecret()
|
|
45
|
+
const tx = await ENSInstance.commitName('commitment.eth', {
|
|
46
|
+
duration: 31536000,
|
|
47
|
+
owner: accounts[1],
|
|
48
|
+
addressOrIndex: accounts[1],
|
|
49
|
+
secret,
|
|
50
|
+
wrapperExpiry: 100000,
|
|
51
|
+
})
|
|
52
|
+
await tx.wait()
|
|
53
|
+
expect(tx.customData).toBeTruthy()
|
|
54
|
+
expect(tx.customData!.wrapperExpiry).toBe(100000)
|
|
55
|
+
expect(tx.customData!.secret).toBe(secret)
|
|
56
|
+
|
|
57
|
+
const controller = await ENSInstance.contracts!.getEthRegistrarController()!
|
|
58
|
+
const commitment = await controller.commitments(tx.customData!.commitment)
|
|
59
|
+
expect(commitment).toBeTruthy()
|
|
60
|
+
})
|
|
61
|
+
})
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ENSArgs } from '..'
|
|
2
|
+
import { CommitmentParams, makeCommitment } from '../utils/registerHelpers'
|
|
3
|
+
|
|
4
|
+
type Params = Omit<CommitmentParams, 'resolver' | 'name'> & {
|
|
5
|
+
resolverAddress?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default async function (
|
|
9
|
+
{ contracts }: ENSArgs<'contracts'>,
|
|
10
|
+
name: string,
|
|
11
|
+
{ resolverAddress, ...params }: Params,
|
|
12
|
+
) {
|
|
13
|
+
const labels = name.split('.')
|
|
14
|
+
if (labels.length !== 2 || labels[1] !== 'eth')
|
|
15
|
+
throw new Error('Currently only .eth TLD registrations are supported')
|
|
16
|
+
|
|
17
|
+
const controller = await contracts!.getEthRegistrarController()
|
|
18
|
+
const resolver = await contracts!.getPublicResolver(
|
|
19
|
+
undefined,
|
|
20
|
+
resolverAddress,
|
|
21
|
+
)
|
|
22
|
+
const { secret, commitment, wrapperExpiry } = makeCommitment({
|
|
23
|
+
name,
|
|
24
|
+
resolver,
|
|
25
|
+
...params,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
...(await controller.populateTransaction.commit(commitment)),
|
|
30
|
+
customData: {
|
|
31
|
+
secret,
|
|
32
|
+
commitment,
|
|
33
|
+
wrapperExpiry,
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -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'
|
|
@@ -92,7 +95,11 @@ type OptionalWriteOptions<F> = F extends (
|
|
|
92
95
|
: never
|
|
93
96
|
|
|
94
97
|
interface WriteFunction<F extends (...args: any) => any> extends Function {
|
|
95
|
-
(...args: Parameters<OptionalWriteOptions<F>>): Promise<
|
|
98
|
+
(...args: Parameters<OptionalWriteOptions<F>>): Promise<
|
|
99
|
+
ContractTransaction & {
|
|
100
|
+
customData?: Record<string, any>
|
|
101
|
+
}
|
|
102
|
+
>
|
|
96
103
|
populateTransaction: (
|
|
97
104
|
...args: Parameters<OptionalWriteOptions<F>>
|
|
98
105
|
) => Promise<PopulatedTransaction>
|
|
@@ -499,6 +506,11 @@ export class ENS {
|
|
|
499
506
|
'getPrice',
|
|
500
507
|
)
|
|
501
508
|
|
|
509
|
+
public getDNSOwner = this.generateFunction<typeof getDNSOwner>(
|
|
510
|
+
'getDNSOwner',
|
|
511
|
+
[],
|
|
512
|
+
)
|
|
513
|
+
|
|
502
514
|
public universalWrapper = this.generateRawFunction<typeof universalWrapper>(
|
|
503
515
|
'initialGetters',
|
|
504
516
|
['contracts'],
|
|
@@ -569,8 +581,17 @@ export class ENS {
|
|
|
569
581
|
['contracts', 'getExpiry'],
|
|
570
582
|
)
|
|
571
583
|
|
|
572
|
-
public
|
|
573
|
-
'
|
|
574
|
-
[],
|
|
584
|
+
public commitName = this.generateWriteFunction<typeof commitName>(
|
|
585
|
+
'commitName',
|
|
586
|
+
['contracts'],
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
public registerName = this.generateWriteFunction<typeof registerName>(
|
|
590
|
+
'registerName',
|
|
591
|
+
['contracts'],
|
|
575
592
|
)
|
|
593
|
+
|
|
594
|
+
public renewName = this.generateWriteFunction<typeof renewName>('renewName', [
|
|
595
|
+
'contracts',
|
|
596
|
+
])
|
|
576
597
|
}
|