diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 238f4993..1b3869e5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - run: pnpm install --frozen-lockfile - name: Run tests - run: pnpm -F @ensdomains/ensjs tenv start + run: pnpm -F @ensdomains/ensjs tenv start --extra-time 11368000 env: STATIC_ENS: ${{ matrix.type == 'static' }} lint: diff --git a/packages/ensjs/archive.tar.lz4 b/packages/ensjs/archive.tar.lz4 index 7ccff040..8ee6b070 100644 Binary files a/packages/ensjs/archive.tar.lz4 and b/packages/ensjs/archive.tar.lz4 differ diff --git a/packages/ensjs/deploy/00_register_legacy.ts b/packages/ensjs/deploy/00_register_legacy.ts index 73a54c30..d0ae9caf 100644 --- a/packages/ensjs/deploy/00_register_legacy.ts +++ b/packages/ensjs/deploy/00_register_legacy.ts @@ -152,6 +152,7 @@ const names: { data: object | string } } + duration?: number subnames?: Subname[] }[] = [ { @@ -287,6 +288,12 @@ const names: { }, }, }, + { + label: 'expired', + namedOwner: 'owner', + namedAddr: 'owner', + duration: 2419200, + }, ...Array.from({ length: 34 }, (_, i) => ({ label: `${i}-dummy`, namedOwner: 'owner2', @@ -303,13 +310,19 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await network.provider.send('anvil_setBlockTimestampInterval', [60]) - for (const { label, namedOwner, namedAddr, records, subnames } of names) { + for (const { + label, + namedOwner, + namedAddr, + records, + subnames, + duration = 31536000, + } of names) { const secret = '0x0000000000000000000000000000000000000000000000000000000000000000' const registrant = allNamedAccts[namedOwner] const resolver = publicResolver.address const addr = allNamedAccts[namedAddr] - const duration = 31536000 const commitment = await controller.makeCommitmentWithConfig( label, diff --git a/packages/ensjs/deploy/00_register_wrapped.ts b/packages/ensjs/deploy/00_register_wrapped.ts index 7bdfa021..4a86e67c 100644 --- a/packages/ensjs/deploy/00_register_wrapped.ts +++ b/packages/ensjs/deploy/00_register_wrapped.ts @@ -1,26 +1,39 @@ /* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable no-await-in-loop */ +import { BigNumber } from '@ethersproject/bignumber' import { ethers } from 'hardhat' import { DeployFunction } from 'hardhat-deploy/types' import { HardhatRuntimeEnvironment } from 'hardhat/types' import { namehash } from '../src/utils/normalise' -const names = [ +const names: { + label: string + namedOwner: string + data?: any[] + reverseRecord?: boolean + fuses?: number + subnames?: { + label: string + namedOwner: string + }[] + duration?: number +}[] = [ { label: 'wrapped', namedOwner: 'owner', - data: [], reverseRecord: true, - fuses: 0, }, { label: 'wrapped-with-subnames', namedOwner: 'owner', - data: [], - reverseRecord: false, - fuses: 0, subnames: [{ label: 'test', namedOwner: 'owner2' }], }, + { + label: 'expired-wrapped', + namedOwner: 'owner', + subnames: [{ label: 'test', namedOwner: 'owner2' }], + duration: 2419200, + }, ] const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { @@ -35,17 +48,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { for (const { label, namedOwner, - data, - reverseRecord, - fuses, + data = [], + reverseRecord = false, + fuses = 0, subnames, + duration = 31536000, } of names) { const secret = '0x0000000000000000000000000000000000000000000000000000000000000000' const owner = allNamedAccts[namedOwner] const resolver = publicResolver.address - const duration = 31536000 - const wrapperExpiry = 1659467455 + duration const commitment = await controller.makeCommitment( label, @@ -56,7 +68,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { data, reverseRecord, fuses, - wrapperExpiry, ) const _controller = controller.connect(await ethers.getSigner(owner)) @@ -79,7 +90,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { data, reverseRecord, fuses, - wrapperExpiry, { value: price, }, @@ -103,7 +113,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { resolver, '0', '0', - wrapperExpiry, + BigNumber.from(2).pow(64).sub(1), ) console.log(` - ${subnameLabel} (tx: ${setSubnameTx.hash})...`) await setSubnameTx.wait() diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index 9962f98c..3c523cc8 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -56,7 +56,7 @@ "license": "MIT", "scripts": { "tenv": "ens-test-env -a", - "denv": "pnpm tenv start -ns -nb --extra-time 11368000", + "denv": "pnpm tenv start -ns -nb --extra-time 11368000 --verbosity 1", "generate-types": "ts-node scripts/runTypechain.ts", "generate-abis": "hardhat export-abi", "start": "ts-node --files src/index.test.ts", @@ -86,9 +86,8 @@ "traverse": "^0.6.6" }, "devDependencies": { - "ethers": "^5.7.2", "@ensdomains/buffer": "^0.0.13", - "@ensdomains/ens-contracts": "^0.0.15", + "@ensdomains/ens-contracts": "^0.0.16", "@ensdomains/ens-test-env": "workspace:*", "@ethersproject/abi": "^5.6.4", "@ethersproject/abstract-provider": "^5.7.0", @@ -116,6 +115,7 @@ "dotenv": "^16.0.0", "esbuild": "^0.15.6", "eslint-plugin-jest": "^27.0.1", + "ethers": "^5.7.2", "ganache": "^7.4.0", "glob": "^8.0.3", "hardhat": "2.10.2", diff --git a/packages/ensjs/src/contracts/getContractAddress.ts b/packages/ensjs/src/contracts/getContractAddress.ts index 308f1ebf..8acb2525 100644 --- a/packages/ensjs/src/contracts/getContractAddress.ts +++ b/packages/ensjs/src/contracts/getContractAddress.ts @@ -20,19 +20,19 @@ const addresses: Record< '1': '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5', '3': '0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8', '4': '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5', - '5': '0x9C51161bA2FB02Cc0a403332B607117685f34831', + '5': '0xb7A1f9e633fdeaAa2ec44bE00a61a7Db9a733D70', }, Multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', NameWrapper: { '1': '0x0000000000000000000000000000000000000000', '3': '0xF82155e2a43Be0871821E9654Fc8Ae894FB8307C', '4': '0x0000000000000000000000000000000000000000', - '5': '0x582224b8d4534F4749EFA4f22eF7241E0C56D4B8', + '5': '0xEe1F756aCde7E81B2D8cC6aB3c8A1E2cE6db0F39', }, PublicResolver: { '1': '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41', '3': '0x13F0659Ee6bb7484C884FEeFb7F75C93951ef837', - '5': '0xE264d5bb84bA3b8061ADC38D3D76e6674aB91852', + '5': '0x2800Ec5BAB9CE9226d19E0ad5BC607e3cfC4347E', }, ENSRegistry: { '1': '0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e', @@ -43,7 +43,7 @@ const addresses: Record< ReverseRegistrar: { '1': '0x084b1c3C81545d370f3634392De611CaaBFf8148', '3': '0x806246b52f8cB61655d3038c58D2f63Aa55d4edE', - '5': '0xD5610A08E370051a01fdfe4bB3ddf5270af1aA48', + '5': '0x9a879320A9F7ad2BBb02063d67baF5551D6BD8B0', }, UniversalResolver: { '1': '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', diff --git a/packages/ensjs/src/functions/burnFuses.test.ts b/packages/ensjs/src/functions/burnFuses.test.ts deleted file mode 100644 index 2fe5b825..00000000 --- a/packages/ensjs/src/functions/burnFuses.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { ethers } from 'ethers' -import { ENS } from '..' -import setup from '../tests/setup' -import { namehash } from '../utils/normalise' - -let ensInstance: ENS -let revert: Awaited>['revert'] -let provider: ethers.providers.JsonRpcProvider -let accounts: string[] - -beforeAll(async () => { - ;({ ensInstance, revert, provider } = await setup()) - accounts = await provider.listAccounts() -}) - -afterAll(async () => { - await revert() -}) - -describe('burnFuses', () => { - beforeEach(async () => { - await revert() - }) - describe('Array', () => { - it('should return a burnFuses transaction from a named fuse array and succeed', async () => { - const tx = await ensInstance.burnFuses('wrapped.eth', { - namedFusesToBurn: [ - 'CANNOT_UNWRAP', - 'CANNOT_CREATE_SUBDOMAIN', - 'CANNOT_SET_TTL', - ], - addressOrIndex: accounts[1], - }) - expect(tx).toBeTruthy() - await tx.wait() - - const nameWrapper = await ensInstance.contracts!.getNameWrapper()! - const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) - expect(fuses).toBe(113) - }) - it('should return a burnFuses transaction from an unnamed fuse array and succeed', async () => { - const tx0 = await ensInstance.burnFuses('wrapped.eth', { - namedFusesToBurn: ['CANNOT_UNWRAP'], - addressOrIndex: accounts[1], - }) - expect(tx0).toBeTruthy() - await tx0.wait() - - const tx = await ensInstance.burnFuses('wrapped.eth', { - unnamedFusesToBurn: [128, 256, 512], - addressOrIndex: accounts[1], - }) - expect(tx).toBeTruthy() - await tx.wait() - - const nameWrapper = await ensInstance.contracts!.getNameWrapper()! - const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) - expect(fuses).toBe(961) - }) - it('should return a burnFuses transaction from both an unnamed and named fuse array and succeed', async () => { - const tx = await ensInstance.burnFuses('wrapped.eth', { - namedFusesToBurn: [ - 'CANNOT_UNWRAP', - 'CANNOT_CREATE_SUBDOMAIN', - 'CANNOT_SET_TTL', - ], - unnamedFusesToBurn: [128, 256, 512], - addressOrIndex: accounts[1], - }) - expect(tx).toBeTruthy() - await tx.wait() - - const nameWrapper = await ensInstance.contracts!.getNameWrapper()! - const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) - expect(fuses).toBe(1009) - }) - it('should throw an error when trying to burn a named fuse in an unnamed fuse array', async () => { - try { - await ensInstance.burnFuses('wrapped.eth', { - unnamedFusesToBurn: [64] as any, - }) - expect(false).toBeTruthy() - } catch (e: any) { - expect(e.message).toBe( - '64 is not a valid unnamed fuse. If you are trying to burn a named fuse, use the namedFusesToBurn property.', - ) - } - }) - it('should throw an error when trying to burn an unnamed fuse in a named fuse array', async () => { - try { - await ensInstance.burnFuses('wrapped.eth', { - namedFusesToBurn: ['COOL_SWAG_FUSE'] as any, - }) - expect(false).toBeTruthy() - } catch (e: any) { - expect(e.message).toBe('COOL_SWAG_FUSE is not a valid named fuse.') - } - }) - }) - describe('Number', () => { - it('should return a burnFuses transaction from a number and succeed', async () => { - const tx = await ensInstance.burnFuses('wrapped.eth', { - fuseNumberToBurn: 49, - addressOrIndex: accounts[1], - }) - expect(tx).toBeTruthy() - await tx.wait() - - const nameWrapper = await ensInstance.contracts!.getNameWrapper()! - const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) - expect(fuses).toBe(113) - }) - it('should throw an error if the number is too high', async () => { - try { - await ensInstance.burnFuses('wrapped.eth', { - fuseNumberToBurn: 4294967297, - }) - expect(false).toBeTruthy() - } catch (e: any) { - expect(e.message).toBe( - 'Fuse number must be limited to uint32, 4294967297 was too high.', - ) - } - }) - it('should throw an error if the number is too low', async () => { - try { - await ensInstance.burnFuses('wrapped.eth', { - fuseNumberToBurn: -1, - }) - expect(false).toBeTruthy() - } catch (e: any) { - expect(e.message).toBe( - 'Fuse number must be limited to uint32, -1 was too low.', - ) - } - }) - it('should throw an error if the number is not an integer', async () => { - try { - await ensInstance.burnFuses('wrapped.eth', { - fuseNumberToBurn: 7.5, - }) - expect(false).toBeTruthy() - } catch (e: any) { - expect(e.message).toBe('Fuse number must be an integer, 7.5 was not.') - } - }) - }) -}) diff --git a/packages/ensjs/src/functions/burnFuses.ts b/packages/ensjs/src/functions/burnFuses.ts deleted file mode 100644 index b1f668cf..00000000 --- a/packages/ensjs/src/functions/burnFuses.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ENSArgs } from '..' -import { FuseProps, validateFuses } from '../utils/fuses' -import { namehash } from '../utils/normalise' - -export default async function ( - { contracts, signer }: ENSArgs<'contracts' | 'signer'>, - name: string, - props: FuseProps, -) { - const encodedFuses = validateFuses(props) - - const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer) - const hash = namehash(name) - - return nameWrapper.populateTransaction.setFuses(hash, encodedFuses) -} diff --git a/packages/ensjs/src/functions/commitName.test.ts b/packages/ensjs/src/functions/commitName.test.ts index a9a05584..7b3d8e8f 100644 --- a/packages/ensjs/src/functions/commitName.test.ts +++ b/packages/ensjs/src/functions/commitName.test.ts @@ -31,7 +31,6 @@ describe('commitName', () => { expect(popTx).toBeTruthy() expect(customData).toHaveProperty('secret') expect(customData).toHaveProperty('commitment') - expect(customData).toHaveProperty('wrapperExpiry') const tx = await provider.getSigner().sendTransaction(popTx) await tx.wait() @@ -47,11 +46,9 @@ describe('commitName', () => { owner: accounts[1], addressOrIndex: accounts[1], secret, - wrapperExpiry: 100000, }) await tx.wait() expect(tx.customData).toBeTruthy() - expect(tx.customData!.wrapperExpiry).toBe(100000) expect(tx.customData!.secret).toBe(secret) const controller = await ensInstance.contracts!.getEthRegistrarController()! diff --git a/packages/ensjs/src/functions/commitName.ts b/packages/ensjs/src/functions/commitName.ts index 8817a90e..35d1fbb4 100644 --- a/packages/ensjs/src/functions/commitName.ts +++ b/packages/ensjs/src/functions/commitName.ts @@ -22,7 +22,7 @@ export default async function ( undefined, resolverAddress, ) - const { secret, commitment, wrapperExpiry } = makeCommitment({ + const { secret, commitment } = makeCommitment({ name, resolver, ...params, @@ -33,7 +33,6 @@ export default async function ( customData: { secret, commitment, - wrapperExpiry, }, } } diff --git a/packages/ensjs/src/functions/createSubname.ts b/packages/ensjs/src/functions/createSubname.ts index aefec2c6..a0851118 100644 --- a/packages/ensjs/src/functions/createSubname.ts +++ b/packages/ensjs/src/functions/createSubname.ts @@ -1,8 +1,7 @@ import { BigNumber } from '@ethersproject/bignumber/lib/bignumber' import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity' import { ENSArgs } from '..' -import { FuseOptions } from '../utils/fuses' -import generateFuseInput from '../utils/generateFuseInput' +import { CombinedFuseInput, encodeFuses } from '../utils/fuses' import { namehash } from '../utils/normalise' import { Expiry, makeExpiry, wrappedLabelLengthCheck } from '../utils/wrapper' @@ -14,7 +13,7 @@ type BaseArgs = { type NameWrapperArgs = { contract: 'nameWrapper' - fuses?: FuseOptions + fuses?: CombinedFuseInput expiry?: Expiry } & BaseArgs @@ -70,8 +69,8 @@ export default async function ( const generatedFuses = 'fuses' in wrapperArgs && wrapperArgs.fuses - ? generateFuseInput(wrapperArgs.fuses) - : '0' + ? encodeFuses(wrapperArgs.fuses) + : 0 return nameWrapper.populateTransaction.setSubnodeRecord( parentNodehash, diff --git a/packages/ensjs/src/functions/getHistory.ts b/packages/ensjs/src/functions/getHistory.ts index 12f35a74..6839e624 100644 --- a/packages/ensjs/src/functions/getHistory.ts +++ b/packages/ensjs/src/functions/getHistory.ts @@ -4,6 +4,30 @@ import { ENSArgs } from '..' import { decodeContenthash } from '../utils/contentHash' import { labelhash } from '../utils/labels' import { namehash } from '../utils/normalise' +import { + AbiChanged, + AddrChanged, + AuthorisationChanged, + ContenthashChanged, + ExpiryExtended, + FusesSet, + InterfaceChanged, + MulticoinAddrChanged, + NameChanged, + NameRegistered, + NameRenewed, + NameTransferred, + NameUnwrapped, + NameWrapped, + NewOwner, + NewResolver, + NewTtl, + PubkeyChanged, + TextChanged, + Transfer, + VersionChanged, + WrappedTransfer, +} from '../utils/subgraph-types' type DomainEvent = | 'NewOwner' @@ -14,6 +38,7 @@ type DomainEvent = | 'NameWrapped' | 'NameUnwrapped' | 'FusesSet' + | 'ExpiryExtended' type RegistrationEvent = 'NameRegistered' | 'NameRenewed' | 'NameTransferred' type ResolverEvent = | 'AddrChanged' @@ -38,30 +63,35 @@ const eventFormat: { [key in EventTypes]: { [n in EventFormat[key]]: (args: any) => object } } = { Domain: { - NewOwner: (args: any) => ({ owner: args.owner.id }), - NewResolver: (args: any) => ({ resolver: args.resolver.id.split('-')[0] }), - Transfer: (args: any) => ({ owner: args.owner.id }), - NewTTL: (args: any) => ({ ttl: args.ttl }), - WrappedTransfer: (args: any) => ({ owner: args.owner.id }), - NameWrapped: (args: any) => ({ + NewOwner: (args: NewOwner) => ({ owner: args.owner.id }), + NewResolver: (args: NewResolver) => ({ + resolver: args.resolver.id.split('-')[0], + }), + Transfer: (args: Transfer) => ({ owner: args.owner.id }), + NewTTL: (args: NewTtl) => ({ ttl: args.ttl }), + WrappedTransfer: (args: WrappedTransfer) => ({ owner: args.owner.id }), + NameWrapped: (args: NameWrapped) => ({ fuses: args.fuses, owner: args.owner.id, - expiry: args.expiry, + expiryDate: args.expiryDate, }), - NameUnwrapped: (args: any) => ({ owner: args.owner.id }), - FusesSet: (args: any) => ({ fuses: args.fuses, expiry: args.expiry }), + NameUnwrapped: (args: NameUnwrapped) => ({ owner: args.owner.id }), + FusesSet: (args: FusesSet) => ({ fuses: args.fuses }), + ExpiryExtended: (args: ExpiryExtended) => ({ expiryDate: args.expiryDate }), }, Registration: { - NameRegistered: (args: any) => ({ + NameRegistered: (args: NameRegistered) => ({ registrant: args.registrant.id, expiryDate: args.expiryDate, }), - NameRenewed: (args: any) => ({ expiryDate: args.expiryDate }), - NameTransferred: (args: any) => ({ owner: args.newOwner.id }), + NameRenewed: (args: NameRenewed) => ({ expiryDate: args.expiryDate }), + NameTransferred: (args: NameTransferred) => ({ owner: args.newOwner.id }), }, Resolver: { - AddrChanged: (args: any) => ({ addr: args.addr.id }), - MulticoinAddrChanged: (args: any) => { + AddrChanged: (args: AddrChanged) => ({ addr: args.addr.id }), + MulticoinAddrChanged: ( + args: Omit & { multiaddr: string }, + ) => { const format = formatsByCoinType[parseInt(args.coinType)] if (!format) { return { @@ -82,21 +112,23 @@ const eventFormat: { addr: format.encoder(Buffer.from(args.multiaddr.slice(2), 'hex')), } }, - NameChanged: (args: any) => ({ name: args.name }), - AbiChanged: (args: any) => ({ contentType: args.contentType }), - PubkeyChanged: (args: any) => ({ x: args.x, y: args.y }), - TextChanged: (args: any) => ({ key: args.key, value: args.value }), - ContenthashChanged: (args: any) => ({ hash: decodeContenthash(args.hash) }), - InterfaceChanged: (args: any) => ({ - interfaceId: args.interfaceId, + NameChanged: (args: NameChanged) => ({ name: args.name }), + AbiChanged: (args: AbiChanged) => ({ contentType: args.contentType }), + PubkeyChanged: (args: PubkeyChanged) => ({ x: args.x, y: args.y }), + TextChanged: (args: TextChanged) => ({ key: args.key, value: args.value }), + ContenthashChanged: (args: ContenthashChanged) => ({ + hash: decodeContenthash(args.hash), + }), + InterfaceChanged: (args: InterfaceChanged) => ({ + interfaceId: args.interfaceID, implementer: args.implementer, }), - AuthorisationChanged: (args: any) => ({ + AuthorisationChanged: (args: AuthorisationChanged) => ({ owner: args.owner, target: args.target, isAuthorized: args.isAuthorized, }), - VersionChanged: (args: any) => ({ version: args.version }), + VersionChanged: (args: VersionChanged) => ({ version: args.version }), }, } @@ -154,7 +186,7 @@ export async function getHistory( } ...on NameWrapped { fuses - expiry + expiryDate owner { id } @@ -166,7 +198,9 @@ export async function getHistory( } ...on FusesSet { fuses - expiry + } + ...on ExpiryExtended { + expiryDate } } registration { diff --git a/packages/ensjs/src/functions/getNames.test.ts b/packages/ensjs/src/functions/getNames.test.ts index d49d2a9c..e4469684 100644 --- a/packages/ensjs/src/functions/getNames.test.ts +++ b/packages/ensjs/src/functions/getNames.test.ts @@ -172,7 +172,7 @@ describe('getNames', () => { type: 'wrappedOwner', page: 0, }) - expect(pageOne).toHaveLength(1) + expect(pageOne).toHaveLength(2) }) describe('orderBy', () => { describe('registrations', () => { diff --git a/packages/ensjs/src/functions/getNames.ts b/packages/ensjs/src/functions/getNames.ts index 2520b102..8c781502 100644 --- a/packages/ensjs/src/functions/getNames.ts +++ b/packages/ensjs/src/functions/getNames.ts @@ -1,7 +1,8 @@ import { ENSArgs } from '..' import { truncateFormat } from '../utils/format' -import { CurrentFuses, decodeFuses } from '../utils/fuses' +import { AllCurrentFuses, decodeFuses } from '../utils/fuses' import { decryptName } from '../utils/labels' +import { Domain, Registration, WrappedDomain } from '../utils/subgraph-types' export type Name = { id: string @@ -16,7 +17,7 @@ export type Name = { createdAt?: Date registrationDate?: Date expiryDate?: Date - fuses?: CurrentFuses + fuses?: AllCurrentFuses registration?: { expiryDate: Date registrationDate: Date @@ -44,7 +45,7 @@ type OwnerParams = { type WrappedOwnerParams = { type: 'wrappedOwner' - orderBy?: 'expiryDate' | 'labelName' + orderBy?: 'expiryDate' | 'name' } type AllParams = { @@ -57,23 +58,35 @@ type AllParams = { type Params = BaseParams & (RegistrantParams | OwnerParams | WrappedOwnerParams | AllParams) -const mapDomain = (domain: any) => { - const decrypted = decryptName(domain.name) +const mapDomain = ({ name, ...domain }: Domain) => { + const decrypted = name ? decryptName(name) : undefined return { ...domain, name: decrypted, - truncatedName: truncateFormat(decrypted), + truncatedName: decrypted ? truncateFormat(decrypted) : undefined, createdAt: new Date(parseInt(domain.createdAt) * 1000), type: 'domain', } } -const mapWrappedDomain = (wrappedDomain: any) => { - const domain = mapDomain(wrappedDomain.domain) +const mapWrappedDomain = (wrappedDomain: WrappedDomain) => { + const domain = mapDomain(wrappedDomain.domain) as Omit< + ReturnType, + 'registration' + > & { + registration?: { + expiryDate: string | Date + registrationDate: string | Date + } + } if (domain.registration) { domain.registration = { - expiryDate: new Date(parseInt(domain.registration.expiryDate) * 1000), - registrationDate: new Date(domain.registration.registrationDate * 1000), + expiryDate: new Date( + parseInt(domain.registration.expiryDate as string) * 1000, + ), + registrationDate: new Date( + parseInt(domain.registration.registrationDate as string) * 1000, + ), } } return { @@ -84,8 +97,8 @@ const mapWrappedDomain = (wrappedDomain: any) => { } } -const mapRegistration = (registration: any) => { - const decrypted = decryptName(registration.domain.name) +const mapRegistration = (registration: Registration) => { + const decrypted = decryptName(registration.domain.name!) return { expiryDate: new Date(parseInt(registration.expiryDate) * 1000), registrationDate: new Date(parseInt(registration.registrationDate) * 1000), @@ -275,7 +288,7 @@ const getNames = async ( id: address, first: pageSize, skip: (page || 0) * pageSize, - orderBy, + orderBy: orderBy === 'labelName' ? 'name' : orderBy, orderDirection, } } diff --git a/packages/ensjs/src/functions/getOwner.test.ts b/packages/ensjs/src/functions/getOwner.test.ts index 6d98b8b2..bacb4680 100644 --- a/packages/ensjs/src/functions/getOwner.test.ts +++ b/packages/ensjs/src/functions/getOwner.test.ts @@ -1,11 +1,15 @@ +import { JsonRpcProvider } from '@ethersproject/providers' import { ENS } from '..' import setup from '../tests/setup' let ensInstance: ENS let revert: Awaited>['revert'] +let provider: JsonRpcProvider +let accounts: string[] beforeAll(async () => { - ;({ ensInstance, revert } = await setup()) + ;({ ensInstance, revert, provider } = await setup()) + accounts = await provider.listAccounts() }) afterAll(async () => { @@ -13,8 +17,63 @@ afterAll(async () => { }) describe('getOwner', () => { - it('should return nameWrapper as the ownership level for a wrapped name', async () => { + it('should return correct ownership level and values for a wrapped .eth name', async () => { const result = await ensInstance.getOwner('wrapped.eth') - expect(result?.ownershipLevel).toBe('nameWrapper') + expect(result).toEqual({ + ownershipLevel: 'nameWrapper', + owner: accounts[1], + expired: false, + }) + }) + it('should return correct ownership level and values for an expired wrapped .eth name', async () => { + const result = await ensInstance.getOwner('expired-wrapped.eth') + expect(result).toEqual({ + ownershipLevel: 'nameWrapper', + owner: '0x0000000000000000000000000000000000000000', + expired: true, + }) + }) + it('should return correct ownership level and values for an unwrapped .eth name', async () => { + const result = await ensInstance.getOwner('test123.eth') + expect(result).toEqual({ + ownershipLevel: 'registrar', + owner: accounts[1], + registrant: accounts[1], + expired: false, + }) + }) + it('should return correct ownership level and values for an expired unwrapped .eth name', async () => { + const result = await ensInstance.getOwner('expired.eth') + expect(result).toEqual({ + ownershipLevel: 'registrar', + owner: accounts[1], + registrant: accounts[1].toLowerCase(), + expired: true, + }) + }) + describe('subname', () => { + it('should return correct ownership level and values for a unwrapped name', async () => { + const result = await ensInstance.getOwner('test.with-subnames.eth') + expect(result).toEqual({ + ownershipLevel: 'registry', + owner: accounts[2], + }) + }) + it('should return correct ownership level and values for a wrapped name', async () => { + const result = await ensInstance.getOwner( + 'test.wrapped-with-subnames.eth', + ) + expect(result).toEqual({ + ownershipLevel: 'nameWrapper', + owner: accounts[2], + }) + }) + it('should return correct ownership level and values for an expired wrapped name', async () => { + const result = await ensInstance.getOwner('test.expired-wrapped.eth') + expect(result).toEqual({ + ownershipLevel: 'nameWrapper', + owner: accounts[2], + }) + }) }) }) diff --git a/packages/ensjs/src/functions/getOwner.ts b/packages/ensjs/src/functions/getOwner.ts index 7c514efd..be2cd308 100644 --- a/packages/ensjs/src/functions/getOwner.ts +++ b/packages/ensjs/src/functions/getOwner.ts @@ -9,6 +9,7 @@ type Owner = { registrant?: string owner?: string ownershipLevel: 'nameWrapper' | 'registry' | 'registrar' + expired?: boolean } const singleContractOwnerRaw = async ( @@ -146,26 +147,43 @@ const decode = async ( const registryOwner = (decodedData[0] as Result)[0] const nameWrapperOwner = (decodedData[1] as Result)[0] - let registrarOwner = (decodedData[2] as Result | undefined)?.[0] + let registrarOwner: string | undefined = ( + decodedData[2] as Result | undefined + )?.[0] + let baseReturnObject: { + expired?: boolean + } = {} // check for only .eth names if (labels[labels.length - 1] === 'eth') { - if (!registrarOwner && labels.length === 2) { - const graphRegistrantResult = await gqlInstance.client.request( - registrantQuery, - { - namehash: makeNamehash(name), - }, - ) - registrarOwner = - graphRegistrantResult.domain?.registration?.registrant?.id + // if there is no registrar owner, the name is expired + // but we still want to get the registrar owner prior to expiry + if (labels.length === 2) { + if (!registrarOwner) { + const graphRegistrantResult = await gqlInstance.client.request( + registrantQuery, + { + namehash: makeNamehash(name), + }, + ) + registrarOwner = + graphRegistrantResult.domain?.registration?.registrant?.id + baseReturnObject = { + expired: true, + } + } else { + baseReturnObject = { + expired: false, + } + } } // if the owner on the registrar is the namewrapper, then the namewrapper owner is the owner // there is no "registrant" for wrapped names - if (registrarOwner === nameWrapper.address) { + if (registrarOwner?.toLowerCase() === nameWrapper.address.toLowerCase()) { return { owner: nameWrapperOwner, ownershipLevel: 'nameWrapper', + ...baseReturnObject, } } // if there is a registrar owner, then it's not a subdomain but we have also passed the namewrapper clause @@ -177,6 +195,7 @@ const decode = async ( registrant: registrarOwner, owner: registryOwner, ownershipLevel: 'registrar', + ...baseReturnObject, } } if (hexStripZeros(registryOwner) !== '0x') { @@ -187,6 +206,7 @@ const decode = async ( registrant: undefined, owner: registryOwner, ownershipLevel: 'registrar', + expired: true, } } // this means that the subname is wrapped diff --git a/packages/ensjs/src/functions/getWrapperData.test.ts b/packages/ensjs/src/functions/getWrapperData.test.ts index 31f96af9..119bf576 100644 --- a/packages/ensjs/src/functions/getWrapperData.test.ts +++ b/packages/ensjs/src/functions/getWrapperData.test.ts @@ -1,4 +1,3 @@ -import { BigNumber } from 'ethers' import { ENS } from '../index' import setup from '../tests/setup' @@ -7,22 +6,6 @@ let revert: Awaited>['revert'] let createSnapshot: Awaited>['createSnapshot'] let withWrappedSnapshot: any -const unwrappedNameDefault = { - expiryDate: new Date(0).toString(), - fuseObj: { - CANNOT_BURN_FUSES: false, - CANNOT_CREATE_SUBDOMAIN: false, - CANNOT_SET_RESOLVER: false, - CANNOT_SET_TTL: false, - CANNOT_TRANSFER: false, - CANNOT_UNWRAP: false, - PARENT_CANNOT_CONTROL: false, - CAN_DO_EVERYTHING: true, - }, - owner: '0x0000000000000000000000000000000000000000', - rawFuses: BigNumber.from(0), -} - beforeAll(async () => { ;({ ensInstance, revert, createSnapshot } = await setup()) @@ -41,9 +24,9 @@ afterAll(async () => { describe('getWrapperData', () => { it('should return default data for an unwrapped name', async () => { const result = await ensInstance.getWrapperData('with-profile.eth') - expect({ ...result, expiryDate: result?.expiryDate.toString() }).toEqual( - unwrappedNameDefault, - ) + expect(result?.expiryDate).toBeUndefined() + expect(result?.rawFuses).toEqual(0) + expect(result?.child.CAN_DO_EVERYTHING).toBeTruthy() }) it('should return with CAN_DO_EVERYTHING set to true for a name with no fuses burned', async () => { const result = await ensInstance.getWrapperData( @@ -51,23 +34,13 @@ describe('getWrapperData', () => { ) expect(result).toBeTruthy() if (result) { - expect(result.fuseObj.CAN_DO_EVERYTHING).toBe(true) - expect( - Object.values(result.fuseObj).reduce( - (prev, curr) => (curr ? prev + 1 : prev), - 0, - ), - ).toBe(1) - expect(result.rawFuses.toHexString()).toBe('0x00') + expect(result.child.CAN_DO_EVERYTHING).toBe(true) + expect(result.rawFuses).toBe(0) } }) it('should return with other correct fuses', async () => { - const tx = await ensInstance.burnFuses('wrapped.eth', { - namedFusesToBurn: [ - 'CANNOT_UNWRAP', - 'CANNOT_CREATE_SUBDOMAIN', - 'CANNOT_SET_TTL', - ], + const tx = await ensInstance.setFuses('wrapped.eth', { + named: ['CANNOT_UNWRAP', 'CANNOT_CREATE_SUBDOMAIN', 'CANNOT_SET_TTL'], addressOrIndex: 1, }) await tx.wait() @@ -75,17 +48,10 @@ describe('getWrapperData', () => { const result = await ensInstance.getWrapperData('wrapped.eth') expect(result).toBeTruthy() if (result) { - expect(result.fuseObj).toMatchObject({ - CANNOT_UNWRAP: true, - CANNOT_BURN_FUSES: false, - CANNOT_TRANSFER: false, - CANNOT_SET_RESOLVER: false, - CANNOT_SET_TTL: true, - CANNOT_CREATE_SUBDOMAIN: true, - PARENT_CANNOT_CONTROL: true, - CAN_DO_EVERYTHING: false, - }) - expect(result.rawFuses.toHexString()).toBe('0x71') + expect(result.child.CAN_DO_EVERYTHING).toBe(false) + expect(result.child.CANNOT_UNWRAP).toBe(true) + expect(result.child.CANNOT_CREATE_SUBDOMAIN).toBe(true) + expect(result.child.CANNOT_SET_TTL).toBe(true) } }) it('should return correct expiry', async () => { diff --git a/packages/ensjs/src/functions/getWrapperData.ts b/packages/ensjs/src/functions/getWrapperData.ts index 81511f26..d68e5977 100644 --- a/packages/ensjs/src/functions/getWrapperData.ts +++ b/packages/ensjs/src/functions/getWrapperData.ts @@ -14,18 +14,20 @@ const raw = async ({ contracts }: ENSArgs<'contracts'>, name: string) => { const decode = async ({ contracts }: ENSArgs<'contracts'>, data: string) => { const nameWrapper = await contracts?.getNameWrapper()! try { - const [owner, _fuses, expiry] = nameWrapper.interface.decodeFunctionResult( + const [owner, fuses, expiry] = nameWrapper.interface.decodeFunctionResult( 'getData', data, - ) + ) as [string, number, BigNumber] - const fuses = BigNumber.from(_fuses) const fuseObj = decodeFuses(fuses) - const expiryDate = new Date(expiry * 1000) + const expiryDate = + expiry.gt(0) && expiry.lt(BigNumber.from(2).pow(32)) + ? new Date(expiry.mul(1000).toString()) + : undefined return { - fuseObj, + ...fuseObj, expiryDate, rawFuses: fuses, owner, diff --git a/packages/ensjs/src/functions/registerName.test.ts b/packages/ensjs/src/functions/registerName.test.ts index cbd88f22..2c7073ef 100644 --- a/packages/ensjs/src/functions/registerName.test.ts +++ b/packages/ensjs/src/functions/registerName.test.ts @@ -23,6 +23,8 @@ describe('registerName', () => { await revert() }) it('should return a registration transaction and succeed', async () => { + const controller = await ensInstance.contracts!.getEthRegistrarController()! + const name = 'cool-swag.eth' const duration = 31536000 const { customData, ...commitPopTx } = @@ -37,14 +39,12 @@ describe('registerName', () => { await provider.send('evm_increaseTime', [60]) await provider.send('evm_mine', []) - const { secret, wrapperExpiry } = customData! + const { secret } = customData! - const controller = await ensInstance.contracts!.getEthRegistrarController()! const [price] = await controller.rentPrice(name, duration) const tx = await ensInstance.registerName(name, { secret, - wrapperExpiry, duration, owner: accounts[1], addressOrIndex: accounts[1], diff --git a/packages/ensjs/src/functions/renewNames.ts b/packages/ensjs/src/functions/renewNames.ts index a1933ae6..fea3416c 100644 --- a/packages/ensjs/src/functions/renewNames.ts +++ b/packages/ensjs/src/functions/renewNames.ts @@ -1,39 +1,33 @@ import { BigNumber, BigNumberish } from '@ethersproject/bignumber/lib/bignumber' import { ENSArgs } from '..' -import { FuseProps, validateFuses } from '../utils/fuses' -import { MAX_INT_64 } from '../utils/registerHelpers' +import { MAX_INT_64 } from '../utils/consts' +import { labelhash } from '../utils/labels' +import { namehash } from '../utils/normalise' type BaseProps = { duration: number value: BigNumber } -export async function renewNameWithData( +type WrappedProps = { + duration: BigNumberish +} + +export async function extendWrappedName( { contracts }: ENSArgs<'contracts'>, name: string, - { - duration, - value, - fuses, - wrapperExpiry = MAX_INT_64, - }: BaseProps & { - fuses?: FuseProps - wrapperExpiry?: BigNumberish - }, + options?: WrappedProps, ) { + const expiry = options?.duration || MAX_INT_64 const labels = name.split('.') - if (labels.length !== 2 || labels[1] !== 'eth') { - throw new Error('Currently only .eth TLD renewals are supported') - } + const labelHash = labelhash(labels.shift()!) + const parentNode = namehash(labels.join('.')) - const encodedFuses = fuses ? validateFuses(fuses) : 0 - const controller = await contracts!.getEthRegistrarController() - return controller.populateTransaction.renewWithFuses( - labels[0], - duration, - encodedFuses, - wrapperExpiry, - { value }, + const nameWrapper = await contracts!.getNameWrapper() + return nameWrapper.populateTransaction.extendExpiry( + parentNode, + labelHash, + expiry, ) } diff --git a/packages/ensjs/src/functions/setFuses.test.ts b/packages/ensjs/src/functions/setFuses.test.ts new file mode 100644 index 00000000..8a07b217 --- /dev/null +++ b/packages/ensjs/src/functions/setFuses.test.ts @@ -0,0 +1,240 @@ +import { ethers } from 'ethers' +import { ENS } from '../index' +import setup from '../tests/setup' +import { unnamedUserSettableFuses, userSettableFuseEnum } from '../utils/fuses' +import { namehash } from '../utils/normalise' + +let ensInstance: ENS +let revert: Awaited>['revert'] +let provider: ethers.providers.JsonRpcProvider +let accounts: string[] + +beforeAll(async () => { + ;({ ensInstance, revert, provider } = await setup()) + accounts = await provider.listAccounts() +}) + +afterAll(async () => { + await revert() +}) + +const checkFuses = ( + fuses: number, + expected: (keyof typeof userSettableFuseEnum)[], +) => { + // eslint-disable-next-line guard-for-in + for (const fuse in userSettableFuseEnum) { + const active = + (fuses & + userSettableFuseEnum[fuse as keyof typeof userSettableFuseEnum]) > + 0 + if (expected.includes(fuse as keyof typeof userSettableFuseEnum)) { + try { + expect(active).toBeTruthy() + } catch { + throw new Error(`${fuse} should be true but is false`) + } + } else if (active) { + try { + expect(active).toBeFalsy() + } catch { + throw new Error(`${fuse} should be false but is true`) + } + } + } +} + +const checkUnnamedFuses = ( + fuses: number, + expected: (keyof typeof unnamedUserSettableFuses)[], +) => { + // eslint-disable-next-line guard-for-in + for (const fuse of unnamedUserSettableFuses) { + const active = (fuses & fuse) > 0 + if (expected.includes(fuse as keyof typeof unnamedUserSettableFuses)) { + try { + expect(active).toBeTruthy() + } catch { + throw new Error(`${fuse} should be true but is false`) + } + } else if (active) { + try { + expect(active).toBeFalsy() + } catch { + throw new Error(`${fuse} should be false but is true`) + } + } + } +} + +describe('setFuses', () => { + beforeEach(async () => { + await revert() + }) + describe('Array', () => { + it('should return a setFuses transaction from a named fuse array and succeed', async () => { + const tx = await ensInstance.setFuses('wrapped.eth', { + named: ['CANNOT_UNWRAP', 'CANNOT_CREATE_SUBDOMAIN', 'CANNOT_SET_TTL'], + addressOrIndex: accounts[1], + }) + expect(tx).toBeTruthy() + await tx.wait() + + const nameWrapper = await ensInstance.contracts!.getNameWrapper()! + const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) + checkFuses(fuses, [ + 'CANNOT_UNWRAP', + 'CANNOT_CREATE_SUBDOMAIN', + 'CANNOT_SET_TTL', + 'PARENT_CANNOT_CONTROL', + ]) + }) + it('should return a setFuses transaction from an unnamed fuse array and succeed', async () => { + const tx0 = await ensInstance.setFuses('wrapped.eth', { + named: ['CANNOT_UNWRAP'], + addressOrIndex: accounts[1], + }) + expect(tx0).toBeTruthy() + await tx0.wait() + + const tx = await ensInstance.setFuses('wrapped.eth', { + unnamed: [128, 256, 512], + addressOrIndex: accounts[1], + }) + expect(tx).toBeTruthy() + await tx.wait() + + const nameWrapper = await ensInstance.contracts!.getNameWrapper()! + const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) + checkUnnamedFuses(fuses, [128, 256, 512]) + }) + it('should return a setFuses transaction from both an unnamed and named fuse array and succeed', async () => { + const tx = await ensInstance.setFuses('wrapped.eth', { + named: ['CANNOT_UNWRAP', 'CANNOT_CREATE_SUBDOMAIN', 'CANNOT_SET_TTL'], + unnamed: [128, 256, 512], + addressOrIndex: accounts[1], + }) + expect(tx).toBeTruthy() + await tx.wait() + + const nameWrapper = await ensInstance.contracts!.getNameWrapper()! + const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) + checkFuses(fuses, [ + 'CANNOT_UNWRAP', + 'CANNOT_CREATE_SUBDOMAIN', + 'CANNOT_SET_TTL', + 'PARENT_CANNOT_CONTROL', + ]) + checkUnnamedFuses(fuses, [128, 256, 512]) + }) + it('should throw an error when trying to burn a named fuse in an unnamed fuse array', async () => { + try { + await ensInstance.setFuses('wrapped.eth', { + unnamed: [32] as any, + addressOrIndex: accounts[1], + }) + expect(false).toBeTruthy() + } catch (e: any) { + expect(e.message).toBe( + '32 is not a valid unnamed fuse. If you are trying to set a named fuse, use the named property.', + ) + } + }) + it('should throw an error when trying to burn an unnamed fuse in a named fuse array', async () => { + try { + await ensInstance.setFuses('wrapped.eth', { + named: ['COOL_SWAG_FUSE'] as any, + }) + expect(false).toBeTruthy() + } catch (e: any) { + expect(e.message).toBe('COOL_SWAG_FUSE is not a valid named fuse.') + } + }) + }) + describe('Number', () => { + it('should return a setFuses transaction from a number and succeed', async () => { + const tx = await ensInstance.setFuses('wrapped.eth', { + number: 49, + addressOrIndex: accounts[1], + }) + expect(tx).toBeTruthy() + await tx.wait() + + const nameWrapper = await ensInstance.contracts!.getNameWrapper()! + const [, fuses] = await nameWrapper.getData(namehash('wrapped.eth')) + checkFuses(fuses, [ + 'CANNOT_UNWRAP', + 'CANNOT_CREATE_SUBDOMAIN', + 'CANNOT_SET_TTL', + 'PARENT_CANNOT_CONTROL', + ]) + }) + it('should throw an error if the number is too high', async () => { + try { + await ensInstance.setFuses('wrapped.eth', { + number: 4294967297, + addressOrIndex: accounts[1], + }) + expect(false).toBeTruthy() + } catch (e: any) { + expect(e.message).toBe( + 'Fuse number must be limited to uint32, 4294967297 was too high.', + ) + } + }) + it('should throw an error if the number is too low', async () => { + try { + await ensInstance.setFuses('wrapped.eth', { + number: -1, + addressOrIndex: accounts[1], + }) + expect(false).toBeTruthy() + } catch (e: any) { + expect(e.message).toBe( + 'Fuse number must be limited to uint32, -1 was too low.', + ) + } + }) + it('should throw an error if the number is not an integer', async () => { + try { + await ensInstance.setFuses('wrapped.eth', { + number: 7.5, + }) + expect(false).toBeTruthy() + } catch (e: any) { + expect(e.message).toBe('Fuse number must be an integer, 7.5 was not.') + } + }) + }) +}) + +describe('setChildFuses', () => { + it('should return a setChildFuses transaction and succeed', async () => { + const nameWrapper = await ensInstance.contracts!.getNameWrapper()! + const setParentTx = await ensInstance.setFuses( + 'wrapped-with-subnames.eth', + { + named: ['CANNOT_UNWRAP'], + addressOrIndex: accounts[1], + }, + ) + expect(setParentTx).toBeTruthy() + await setParentTx.wait() + + const tx = await ensInstance.setChildFuses( + 'test.wrapped-with-subnames.eth', + { + fuses: 65537, + addressOrIndex: accounts[1], + }, + ) + expect(tx).toBeTruthy() + await tx.wait() + + const [, fuses] = await nameWrapper.getData( + namehash('test.wrapped-with-subnames.eth'), + ) + + checkFuses(fuses, ['CANNOT_UNWRAP', 'PARENT_CANNOT_CONTROL']) + }) +}) diff --git a/packages/ensjs/src/functions/setFuses.ts b/packages/ensjs/src/functions/setFuses.ts new file mode 100644 index 00000000..4000f60e --- /dev/null +++ b/packages/ensjs/src/functions/setFuses.ts @@ -0,0 +1,44 @@ +import { ENSArgs } from '../index' +import { CombinedFuseInput, encodeFuses } from '../utils/fuses' +import { labelhash } from '../utils/labels' +import { namehash } from '../utils/normalise' + +export async function setChildFuses( + { contracts, signer }: ENSArgs<'contracts' | 'signer'>, + name: string, + { + fuses, + expiry = 0, + }: { + fuses: Partial | number + expiry?: number + }, +) { + const encodedFuses = encodeFuses(fuses) + + const labels = name.split('.') + const labelHash = labelhash(labels.shift()!) + const parentNode = namehash(labels.join('.')) + + const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer) + + return nameWrapper.populateTransaction.setChildFuses( + parentNode, + labelHash, + encodedFuses, + expiry, + ) +} + +export default async function ( + { contracts, signer }: ENSArgs<'contracts' | 'signer'>, + name: string, + props: CombinedFuseInput['child'], +) { + const encodedFuses = encodeFuses(props, 'child') + + const nameWrapper = (await contracts!.getNameWrapper()!).connect(signer) + const hash = namehash(name) + + return nameWrapper.populateTransaction.setFuses(hash, encodedFuses) +} diff --git a/packages/ensjs/src/functions/types.ts b/packages/ensjs/src/functions/types.ts index e32607ba..ce308755 100644 --- a/packages/ensjs/src/functions/types.ts +++ b/packages/ensjs/src/functions/types.ts @@ -4,7 +4,6 @@ import type { resolverMulticallWrapper, universalWrapper, } from './batchWrappers' -import type burnFuses from './burnFuses' import type commitName from './commitName' import type createSubname from './createSubname' import type deleteSubname from './deleteSubname' @@ -36,8 +35,10 @@ import type registerName from './registerName' import type { // eslint-disable-next-line import/no-named-default default as renewNames, - renewNameWithData, + extendWrappedName, } from './renewNames' +import type setFuses from './setFuses' +import type { setChildFuses } from './setFuses' import type setName from './setName' import type setRecord from './setRecord' import type setRecords from './setRecords' @@ -54,7 +55,8 @@ type Function = { multicallWrapper: typeof multicallWrapper resolverMulticallWrapper: typeof resolverMulticallWrapper universalWrapper: typeof universalWrapper - burnFuses: typeof burnFuses + setFuses: typeof setFuses + setChildFuses: typeof setChildFuses commitName: typeof commitName createSubname: typeof createSubname deleteSubname: typeof deleteSubname @@ -82,7 +84,7 @@ type Function = { importDNSSECName: typeof importDNSSECName registerName: typeof registerName renewNames: typeof renewNames - renewNameWithData: typeof renewNameWithData + extendWrappedName: typeof extendWrappedName setName: typeof setName setRecord: typeof setRecord setRecords: typeof setRecords diff --git a/packages/ensjs/src/functions/wrapName.test.ts b/packages/ensjs/src/functions/wrapName.test.ts index 6de61d97..d694da07 100644 --- a/packages/ensjs/src/functions/wrapName.test.ts +++ b/packages/ensjs/src/functions/wrapName.test.ts @@ -46,15 +46,15 @@ describe('wrapName', () => { const nameWrapper = await ensInstance.contracts!.getNameWrapper()! const [, fuses] = await nameWrapper.getData(namehash('test123.eth')) - // parent cannot control - expect(fuses).toBe(64) + expect(fuses).toBe(196608) }) it('should allow initial fuses', async () => { const tx = await ensInstance.wrapName('test123.eth', { wrappedOwner: accounts[2], fuseOptions: { - CANNOT_UNWRAP: true, - CANNOT_SET_TTL: true, + child: { + named: ['CANNOT_UNWRAP', 'CANNOT_SET_TTL'], + }, }, addressOrIndex: 1, }) @@ -63,7 +63,7 @@ describe('wrapName', () => { const nameWrapper = await ensInstance.contracts!.getNameWrapper()! const [, fuses] = await nameWrapper.getData(namehash('test123.eth')) - expect(fuses).toBe(81) + expect(fuses).toBe(196625) }) it('should allow an initial resolver address', async () => { const tx = await ensInstance.wrapName('test123.eth', { @@ -139,8 +139,9 @@ describe('wrapName', () => { ensInstance.wrapName('test.with-subnames.eth', { wrappedOwner: accounts[2], fuseOptions: { - cannotUnwrap: true, - cannotSetTtl: true, + child: { + named: ['CANNOT_UNWRAP', 'CANNOT_SET_TTL'], + }, }, addressOrIndex: 1, }), diff --git a/packages/ensjs/src/functions/wrapName.ts b/packages/ensjs/src/functions/wrapName.ts index 90d14bc2..16a1ae74 100644 --- a/packages/ensjs/src/functions/wrapName.ts +++ b/packages/ensjs/src/functions/wrapName.ts @@ -1,19 +1,16 @@ import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder' import { Signer } from '@ethersproject/abstract-signer' -import { BigNumber } from '@ethersproject/bignumber/lib/bignumber' import { keccak256 as solidityKeccak256 } from '@ethersproject/solidity' import { ENSArgs } from '..' -import { FuseOptions } from '../utils/fuses' -import generateFuseInput from '../utils/generateFuseInput' +import { CombinedFuseInput, encodeFuses } from '../utils/fuses' import { hexEncodeName } from '../utils/hexEncodedName' -import { Expiry, makeExpiry, wrappedLabelLengthCheck } from '../utils/wrapper' +import { Expiry, wrappedLabelLengthCheck } from '../utils/wrapper' async function wrapETH( { contracts }: ENSArgs<'contracts'>, labels: string[], wrappedOwner: string, - expiry: BigNumber, - decodedFuses: string, + decodedFuses: number, resolverAddress: string, signer: Signer, address: string, @@ -24,8 +21,8 @@ async function wrapETH( const labelhash = solidityKeccak256(['string'], [labels[0]]) const data = defaultAbiCoder.encode( - ['string', 'address', 'uint32', 'uint64', 'address'], - [labels[0], wrappedOwner, decodedFuses, expiry, resolverAddress], + ['string', 'address', 'uint16', 'address'], + [labels[0], wrappedOwner, decodedFuses, resolverAddress], ) return baseRegistrar.populateTransaction[ @@ -63,11 +60,7 @@ async function wrapOther( } export default async function ( - { - contracts, - signer, - getExpiry, - }: ENSArgs<'contracts' | 'signer' | 'getExpiry'>, + { contracts, signer }: ENSArgs<'contracts' | 'signer'>, name: string, { wrappedOwner, @@ -76,14 +69,14 @@ export default async function ( resolverAddress, }: { wrappedOwner: string - fuseOptions?: FuseOptions | string | number + fuseOptions?: Partial | number expiry?: Expiry resolverAddress?: string }, ) { const address = await signer.getAddress() - let decodedFuses: string + let decodedFuses: number const publicResolver = await contracts?.getPublicResolver()! if (!resolverAddress) resolverAddress = publicResolver.address @@ -94,19 +87,15 @@ export default async function ( if (labels.length === 2 && labels[1] === 'eth') { switch (typeof fuseOptions) { case 'object': { - decodedFuses = generateFuseInput(fuseOptions) + decodedFuses = encodeFuses(fuseOptions) break } case 'number': { - decodedFuses = fuseOptions.toString(16) - break - } - case 'string': { decodedFuses = fuseOptions break } case 'undefined': { - decodedFuses = '0' + decodedFuses = 0 break } default: { @@ -114,13 +103,10 @@ export default async function ( } } - const expiryToUse = await makeExpiry({ getExpiry }, name, expiry) - return wrapETH( { contracts }, labels, wrappedOwner, - expiryToUse, decodedFuses, resolverAddress, signer, diff --git a/packages/ensjs/src/generated/ETHRegistrarController.ts b/packages/ensjs/src/generated/ETHRegistrarController.ts index 6a5bf7e2..deb019c6 100644 --- a/packages/ensjs/src/generated/ETHRegistrarController.ts +++ b/packages/ensjs/src/generated/ETHRegistrarController.ts @@ -45,16 +45,15 @@ export interface ETHRegistrarControllerInterface extends Interface { 'available(string)': FunctionFragment 'commit(bytes32)': FunctionFragment 'commitments(bytes32)': FunctionFragment - 'makeCommitment(string,address,uint256,bytes32,address,bytes[],bool,uint32,uint64)': FunctionFragment + 'makeCommitment(string,address,uint256,bytes32,address,bytes[],bool,uint16)': FunctionFragment 'maxCommitmentAge()': FunctionFragment 'minCommitmentAge()': FunctionFragment 'nameWrapper()': FunctionFragment 'owner()': FunctionFragment 'prices()': FunctionFragment 'recoverFunds(address,address,uint256)': FunctionFragment - 'register(string,address,uint256,bytes32,address,bytes[],bool,uint32,uint64)': FunctionFragment + 'register(string,address,uint256,bytes32,address,bytes[],bool,uint16)': FunctionFragment 'renew(string,uint256)': FunctionFragment - 'renewWithFuses(string,uint256,uint32,uint64)': FunctionFragment 'renounceOwnership()': FunctionFragment 'rentPrice(string,uint256)': FunctionFragment 'reverseRegistrar()': FunctionFragment @@ -79,7 +78,6 @@ export interface ETHRegistrarControllerInterface extends Interface { | 'recoverFunds' | 'register' | 'renew' - | 'renewWithFuses' | 'renounceOwnership' | 'rentPrice' | 'reverseRegistrar' @@ -116,7 +114,6 @@ export interface ETHRegistrarControllerInterface extends Interface { PromiseOrValue[], PromiseOrValue, PromiseOrValue, - PromiseOrValue, ], ): string encodeFunctionData( @@ -152,22 +149,12 @@ export interface ETHRegistrarControllerInterface extends Interface { PromiseOrValue[], PromiseOrValue, PromiseOrValue, - PromiseOrValue, ], ): string encodeFunctionData( functionFragment: 'renew', values: [PromiseOrValue, PromiseOrValue], ): string - encodeFunctionData( - functionFragment: 'renewWithFuses', - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - ], - ): string encodeFunctionData( functionFragment: 'renounceOwnership', values?: undefined, @@ -222,10 +209,6 @@ export interface ETHRegistrarControllerInterface extends Interface { ): Result decodeFunctionResult(functionFragment: 'register', data: BytesLike): Result decodeFunctionResult(functionFragment: 'renew', data: BytesLike): Result - decodeFunctionResult( - functionFragment: 'renewWithFuses', - data: BytesLike, - ): Result decodeFunctionResult( functionFragment: 'renounceOwnership', data: BytesLike, @@ -349,8 +332,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise<[string]> @@ -379,8 +361,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise @@ -390,14 +371,6 @@ export interface ETHRegistrarController extends BaseContract { overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise - renewWithFuses( - name: PromiseOrValue, - duration: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue }, - ): Promise - renounceOwnership( overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -459,8 +432,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -489,8 +461,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise @@ -500,14 +471,6 @@ export interface ETHRegistrarController extends BaseContract { overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise - renewWithFuses( - name: PromiseOrValue, - duration: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue }, - ): Promise - renounceOwnership( overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -565,8 +528,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -595,8 +557,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -606,14 +567,6 @@ export interface ETHRegistrarController extends BaseContract { overrides?: CallOverrides, ): Promise - renewWithFuses( - name: PromiseOrValue, - duration: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, - overrides?: CallOverrides, - ): Promise - renounceOwnership(overrides?: CallOverrides): Promise rentPrice( @@ -709,8 +662,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -739,8 +691,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise @@ -750,14 +701,6 @@ export interface ETHRegistrarController extends BaseContract { overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise - renewWithFuses( - name: PromiseOrValue, - duration: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue }, - ): Promise - renounceOwnership( overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -818,8 +761,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -848,8 +790,7 @@ export interface ETHRegistrarController extends BaseContract { resolver: PromiseOrValue, data: PromiseOrValue[], reverseRecord: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise @@ -859,14 +800,6 @@ export interface ETHRegistrarController extends BaseContract { overrides?: PayableOverrides & { from?: PromiseOrValue }, ): Promise - renewWithFuses( - name: PromiseOrValue, - duration: PromiseOrValue, - fuses: PromiseOrValue, - wrapperExpiry: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue }, - ): Promise - renounceOwnership( overrides?: Overrides & { from?: PromiseOrValue }, ): Promise diff --git a/packages/ensjs/src/generated/NameWrapper.ts b/packages/ensjs/src/generated/NameWrapper.ts index b2633173..e156380d 100644 --- a/packages/ensjs/src/generated/NameWrapper.ts +++ b/packages/ensjs/src/generated/NameWrapper.ts @@ -32,11 +32,12 @@ export interface NameWrapperInterface extends Interface { 'allFusesBurned(bytes32,uint32)': FunctionFragment 'balanceOf(address,uint256)': FunctionFragment 'balanceOfBatch(address[],uint256[])': FunctionFragment + 'canModifyName(bytes32,address)': FunctionFragment 'controllers(address)': FunctionFragment 'ens()': FunctionFragment + 'extendExpiry(bytes32,bytes32,uint64)': FunctionFragment 'getData(uint256)': FunctionFragment 'isApprovedForAll(address,address)': FunctionFragment - 'isTokenOwnerOrApproved(bytes32,address)': FunctionFragment 'isWrapped(bytes32)': FunctionFragment 'metadataService()': FunctionFragment 'name()': FunctionFragment @@ -45,16 +46,16 @@ export interface NameWrapperInterface extends Interface { 'owner()': FunctionFragment 'ownerOf(uint256)': FunctionFragment 'recoverFunds(address,address,uint256)': FunctionFragment - 'registerAndWrapETH2LD(string,address,uint256,address,uint32,uint64)': FunctionFragment + 'registerAndWrapETH2LD(string,address,uint256,address,uint16)': FunctionFragment 'registrar()': FunctionFragment - 'renew(uint256,uint256,uint32,uint64)': FunctionFragment + 'renew(uint256,uint256)': FunctionFragment 'renounceOwnership()': FunctionFragment 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)': FunctionFragment 'safeTransferFrom(address,address,uint256,uint256,bytes)': FunctionFragment 'setApprovalForAll(address,bool)': FunctionFragment 'setChildFuses(bytes32,bytes32,uint32,uint64)': FunctionFragment 'setController(address,bool)': FunctionFragment - 'setFuses(bytes32,uint32)': FunctionFragment + 'setFuses(bytes32,uint16)': FunctionFragment 'setMetadataService(address)': FunctionFragment 'setRecord(bytes32,address,address,uint64)': FunctionFragment 'setResolver(bytes32,address)': FunctionFragment @@ -71,7 +72,7 @@ export interface NameWrapperInterface extends Interface { 'upgradeETH2LD(string,address,address)': FunctionFragment 'uri(uint256)': FunctionFragment 'wrap(bytes,address,address)': FunctionFragment - 'wrapETH2LD(string,address,uint32,uint64,address)': FunctionFragment + 'wrapETH2LD(string,address,uint16,address)': FunctionFragment } getFunction( @@ -80,11 +81,12 @@ export interface NameWrapperInterface extends Interface { | 'allFusesBurned' | 'balanceOf' | 'balanceOfBatch' + | 'canModifyName' | 'controllers' | 'ens' + | 'extendExpiry' | 'getData' | 'isApprovedForAll' - | 'isTokenOwnerOrApproved' | 'isWrapped' | 'metadataService' | 'name' @@ -138,11 +140,23 @@ export interface NameWrapperInterface extends Interface { functionFragment: 'balanceOfBatch', values: [PromiseOrValue[], PromiseOrValue[]], ): string + encodeFunctionData( + functionFragment: 'canModifyName', + values: [PromiseOrValue, PromiseOrValue], + ): string encodeFunctionData( functionFragment: 'controllers', values: [PromiseOrValue], ): string encodeFunctionData(functionFragment: 'ens', values?: undefined): string + encodeFunctionData( + functionFragment: 'extendExpiry', + values: [ + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + ], + ): string encodeFunctionData( functionFragment: 'getData', values: [PromiseOrValue], @@ -151,10 +165,6 @@ export interface NameWrapperInterface extends Interface { functionFragment: 'isApprovedForAll', values: [PromiseOrValue, PromiseOrValue], ): string - encodeFunctionData( - functionFragment: 'isTokenOwnerOrApproved', - values: [PromiseOrValue, PromiseOrValue], - ): string encodeFunctionData( functionFragment: 'isWrapped', values: [PromiseOrValue], @@ -198,18 +208,12 @@ export interface NameWrapperInterface extends Interface { PromiseOrValue, PromiseOrValue, PromiseOrValue, - PromiseOrValue, ], ): string encodeFunctionData(functionFragment: 'registrar', values?: undefined): string encodeFunctionData( functionFragment: 'renew', - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - ], + values: [PromiseOrValue, PromiseOrValue], ): string encodeFunctionData( functionFragment: 'renounceOwnership', @@ -366,7 +370,6 @@ export interface NameWrapperInterface extends Interface { PromiseOrValue, PromiseOrValue, PromiseOrValue, - PromiseOrValue, PromiseOrValue, ], ): string @@ -381,15 +384,19 @@ export interface NameWrapperInterface extends Interface { functionFragment: 'balanceOfBatch', data: BytesLike, ): Result + decodeFunctionResult( + functionFragment: 'canModifyName', + data: BytesLike, + ): Result decodeFunctionResult(functionFragment: 'controllers', data: BytesLike): Result decodeFunctionResult(functionFragment: 'ens', data: BytesLike): Result - decodeFunctionResult(functionFragment: 'getData', data: BytesLike): Result decodeFunctionResult( - functionFragment: 'isApprovedForAll', + functionFragment: 'extendExpiry', data: BytesLike, ): Result + decodeFunctionResult(functionFragment: 'getData', data: BytesLike): Result decodeFunctionResult( - functionFragment: 'isTokenOwnerOrApproved', + functionFragment: 'isApprovedForAll', data: BytesLike, ): Result decodeFunctionResult(functionFragment: 'isWrapped', data: BytesLike): Result @@ -488,7 +495,8 @@ export interface NameWrapperInterface extends Interface { events: { 'ApprovalForAll(address,address,bool)': EventFragment 'ControllerChanged(address,bool)': EventFragment - 'FusesSet(bytes32,uint32,uint64)': EventFragment + 'ExpiryExtended(bytes32,uint64)': EventFragment + 'FusesSet(bytes32,uint32)': EventFragment 'NameUnwrapped(bytes32,address)': EventFragment 'NameWrapped(bytes32,bytes,address,uint32,uint64)': EventFragment 'OwnershipTransferred(address,address)': EventFragment @@ -499,6 +507,7 @@ export interface NameWrapperInterface extends Interface { getEvent(nameOrSignatureOrTopic: 'ApprovalForAll'): EventFragment getEvent(nameOrSignatureOrTopic: 'ControllerChanged'): EventFragment + getEvent(nameOrSignatureOrTopic: 'ExpiryExtended'): EventFragment getEvent(nameOrSignatureOrTopic: 'FusesSet'): EventFragment getEvent(nameOrSignatureOrTopic: 'NameUnwrapped'): EventFragment getEvent(nameOrSignatureOrTopic: 'NameWrapped'): EventFragment @@ -532,16 +541,23 @@ export type ControllerChangedEvent = TypedEvent< export type ControllerChangedEventFilter = TypedEventFilter -export interface FusesSetEventObject { +export interface ExpiryExtendedEventObject { node: string - fuses: number expiry: BigNumber } -export type FusesSetEvent = TypedEvent< - [string, number, BigNumber], - FusesSetEventObject +export type ExpiryExtendedEvent = TypedEvent< + [string, BigNumber], + ExpiryExtendedEventObject > +export type ExpiryExtendedEventFilter = TypedEventFilter + +export interface FusesSetEventObject { + node: string + fuses: number +} +export type FusesSetEvent = TypedEvent<[string, number], FusesSetEventObject> + export type FusesSetEventFilter = TypedEventFilter export interface NameUnwrappedEventObject { @@ -667,6 +683,12 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise<[BigNumber[]]> + canModifyName( + node: PromiseOrValue, + addr: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[boolean]> + controllers( arg0: PromiseOrValue, overrides?: CallOverrides, @@ -674,10 +696,23 @@ export interface NameWrapper extends BaseContract { ens(overrides?: CallOverrides): Promise<[string]> + extendExpiry( + parentNode: PromiseOrValue, + labelhash: PromiseOrValue, + expiry: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + getData( id: PromiseOrValue, overrides?: CallOverrides, - ): Promise<[string, number, BigNumber]> + ): Promise< + [string, number, BigNumber] & { + owner: string + fuses: number + expiry: BigNumber + } + > isApprovedForAll( account: PromiseOrValue, @@ -685,12 +720,6 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise<[boolean]> - isTokenOwnerOrApproved( - node: PromiseOrValue, - addr: PromiseOrValue, - overrides?: CallOverrides, - ): Promise<[boolean]> - isWrapped( node: PromiseOrValue, overrides?: CallOverrides, @@ -732,8 +761,7 @@ export interface NameWrapper extends BaseContract { wrappedOwner: PromiseOrValue, duration: PromiseOrValue, resolver: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -742,8 +770,6 @@ export interface NameWrapper extends BaseContract { renew( tokenId: PromiseOrValue, duration: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -791,7 +817,7 @@ export interface NameWrapper extends BaseContract { setFuses( node: PromiseOrValue, - fuses: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -901,8 +927,7 @@ export interface NameWrapper extends BaseContract { wrapETH2LD( label: PromiseOrValue, wrappedOwner: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, resolver: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -931,6 +956,12 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise + canModifyName( + node: PromiseOrValue, + addr: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + controllers( arg0: PromiseOrValue, overrides?: CallOverrides, @@ -938,10 +969,23 @@ export interface NameWrapper extends BaseContract { ens(overrides?: CallOverrides): Promise + extendExpiry( + parentNode: PromiseOrValue, + labelhash: PromiseOrValue, + expiry: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + getData( id: PromiseOrValue, overrides?: CallOverrides, - ): Promise<[string, number, BigNumber]> + ): Promise< + [string, number, BigNumber] & { + owner: string + fuses: number + expiry: BigNumber + } + > isApprovedForAll( account: PromiseOrValue, @@ -949,12 +993,6 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise - isTokenOwnerOrApproved( - node: PromiseOrValue, - addr: PromiseOrValue, - overrides?: CallOverrides, - ): Promise - isWrapped( node: PromiseOrValue, overrides?: CallOverrides, @@ -996,8 +1034,7 @@ export interface NameWrapper extends BaseContract { wrappedOwner: PromiseOrValue, duration: PromiseOrValue, resolver: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1006,8 +1043,6 @@ export interface NameWrapper extends BaseContract { renew( tokenId: PromiseOrValue, duration: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1055,7 +1090,7 @@ export interface NameWrapper extends BaseContract { setFuses( node: PromiseOrValue, - fuses: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1165,8 +1200,7 @@ export interface NameWrapper extends BaseContract { wrapETH2LD( label: PromiseOrValue, wrappedOwner: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, resolver: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1195,6 +1229,12 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise + canModifyName( + node: PromiseOrValue, + addr: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + controllers( arg0: PromiseOrValue, overrides?: CallOverrides, @@ -1202,10 +1242,23 @@ export interface NameWrapper extends BaseContract { ens(overrides?: CallOverrides): Promise + extendExpiry( + parentNode: PromiseOrValue, + labelhash: PromiseOrValue, + expiry: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + getData( id: PromiseOrValue, overrides?: CallOverrides, - ): Promise<[string, number, BigNumber]> + ): Promise< + [string, number, BigNumber] & { + owner: string + fuses: number + expiry: BigNumber + } + > isApprovedForAll( account: PromiseOrValue, @@ -1213,12 +1266,6 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise - isTokenOwnerOrApproved( - node: PromiseOrValue, - addr: PromiseOrValue, - overrides?: CallOverrides, - ): Promise - isWrapped( node: PromiseOrValue, overrides?: CallOverrides, @@ -1260,8 +1307,7 @@ export interface NameWrapper extends BaseContract { wrappedOwner: PromiseOrValue, duration: PromiseOrValue, resolver: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -1270,8 +1316,6 @@ export interface NameWrapper extends BaseContract { renew( tokenId: PromiseOrValue, duration: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -1317,7 +1361,7 @@ export interface NameWrapper extends BaseContract { setFuses( node: PromiseOrValue, - fuses: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: CallOverrides, ): Promise @@ -1427,11 +1471,10 @@ export interface NameWrapper extends BaseContract { wrapETH2LD( label: PromiseOrValue, wrappedOwner: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, resolver: PromiseOrValue, overrides?: CallOverrides, - ): Promise + ): Promise } filters: { @@ -1455,15 +1498,22 @@ export interface NameWrapper extends BaseContract { active?: null, ): ControllerChangedEventFilter - 'FusesSet(bytes32,uint32,uint64)'( + 'ExpiryExtended(bytes32,uint64)'( + node?: PromiseOrValue | null, + expiry?: null, + ): ExpiryExtendedEventFilter + ExpiryExtended( node?: PromiseOrValue | null, - fuses?: null, expiry?: null, + ): ExpiryExtendedEventFilter + + 'FusesSet(bytes32,uint32)'( + node?: PromiseOrValue | null, + fuses?: null, ): FusesSetEventFilter FusesSet( node?: PromiseOrValue | null, fuses?: null, - expiry?: null, ): FusesSetEventFilter 'NameUnwrapped(bytes32,address)'( @@ -1560,6 +1610,12 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise + canModifyName( + node: PromiseOrValue, + addr: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + controllers( arg0: PromiseOrValue, overrides?: CallOverrides, @@ -1567,6 +1623,13 @@ export interface NameWrapper extends BaseContract { ens(overrides?: CallOverrides): Promise + extendExpiry( + parentNode: PromiseOrValue, + labelhash: PromiseOrValue, + expiry: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + getData( id: PromiseOrValue, overrides?: CallOverrides, @@ -1578,12 +1641,6 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise - isTokenOwnerOrApproved( - node: PromiseOrValue, - addr: PromiseOrValue, - overrides?: CallOverrides, - ): Promise - isWrapped( node: PromiseOrValue, overrides?: CallOverrides, @@ -1625,8 +1682,7 @@ export interface NameWrapper extends BaseContract { wrappedOwner: PromiseOrValue, duration: PromiseOrValue, resolver: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1635,8 +1691,6 @@ export interface NameWrapper extends BaseContract { renew( tokenId: PromiseOrValue, duration: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1684,7 +1738,7 @@ export interface NameWrapper extends BaseContract { setFuses( node: PromiseOrValue, - fuses: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1794,8 +1848,7 @@ export interface NameWrapper extends BaseContract { wrapETH2LD( label: PromiseOrValue, wrappedOwner: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, resolver: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1825,6 +1878,12 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise + canModifyName( + node: PromiseOrValue, + addr: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + controllers( arg0: PromiseOrValue, overrides?: CallOverrides, @@ -1832,6 +1891,13 @@ export interface NameWrapper extends BaseContract { ens(overrides?: CallOverrides): Promise + extendExpiry( + parentNode: PromiseOrValue, + labelhash: PromiseOrValue, + expiry: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + getData( id: PromiseOrValue, overrides?: CallOverrides, @@ -1843,12 +1909,6 @@ export interface NameWrapper extends BaseContract { overrides?: CallOverrides, ): Promise - isTokenOwnerOrApproved( - node: PromiseOrValue, - addr: PromiseOrValue, - overrides?: CallOverrides, - ): Promise - isWrapped( node: PromiseOrValue, overrides?: CallOverrides, @@ -1890,8 +1950,7 @@ export interface NameWrapper extends BaseContract { wrappedOwner: PromiseOrValue, duration: PromiseOrValue, resolver: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1900,8 +1959,6 @@ export interface NameWrapper extends BaseContract { renew( tokenId: PromiseOrValue, duration: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -1949,7 +2006,7 @@ export interface NameWrapper extends BaseContract { setFuses( node: PromiseOrValue, - fuses: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -2059,8 +2116,7 @@ export interface NameWrapper extends BaseContract { wrapETH2LD( label: PromiseOrValue, wrappedOwner: PromiseOrValue, - fuses: PromiseOrValue, - expiry: PromiseOrValue, + ownerControlledFuses: PromiseOrValue, resolver: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, ): Promise diff --git a/packages/ensjs/src/generated/PublicResolver.ts b/packages/ensjs/src/generated/PublicResolver.ts index 9ec880a4..f7664623 100644 --- a/packages/ensjs/src/generated/PublicResolver.ts +++ b/packages/ensjs/src/generated/PublicResolver.ts @@ -31,11 +31,13 @@ export interface PublicResolverInterface extends Interface { 'ABI(bytes32,uint256)': FunctionFragment 'addr(bytes32)': FunctionFragment 'addr(bytes32,uint256)': FunctionFragment + 'approve(bytes32,address,bool)': FunctionFragment 'clearRecords(bytes32)': FunctionFragment 'contenthash(bytes32)': FunctionFragment 'dnsRecord(bytes32,bytes32,uint16)': FunctionFragment 'hasDNSRecords(bytes32,bytes32)': FunctionFragment 'interfaceImplementer(bytes32,bytes4)': FunctionFragment + 'isApprovedFor(address,bytes32,address)': FunctionFragment 'isApprovedForAll(address,address)': FunctionFragment 'multicall(bytes[])': FunctionFragment 'multicallWithNodeCheck(bytes32,bytes[])': FunctionFragment @@ -63,11 +65,13 @@ export interface PublicResolverInterface extends Interface { | 'ABI' | 'addr(bytes32)' | 'addr(bytes32,uint256)' + | 'approve' | 'clearRecords' | 'contenthash' | 'dnsRecord' | 'hasDNSRecords' | 'interfaceImplementer' + | 'isApprovedFor' | 'isApprovedForAll' | 'multicall' | 'multicallWithNodeCheck' @@ -102,6 +106,14 @@ export interface PublicResolverInterface extends Interface { functionFragment: 'addr(bytes32,uint256)', values: [PromiseOrValue, PromiseOrValue], ): string + encodeFunctionData( + functionFragment: 'approve', + values: [ + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + ], + ): string encodeFunctionData( functionFragment: 'clearRecords', values: [PromiseOrValue], @@ -126,6 +138,14 @@ export interface PublicResolverInterface extends Interface { functionFragment: 'interfaceImplementer', values: [PromiseOrValue, PromiseOrValue], ): string + encodeFunctionData( + functionFragment: 'isApprovedFor', + values: [ + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + ], + ): string encodeFunctionData( functionFragment: 'isApprovedForAll', values: [PromiseOrValue, PromiseOrValue], @@ -236,6 +256,7 @@ export interface PublicResolverInterface extends Interface { functionFragment: 'addr(bytes32,uint256)', data: BytesLike, ): Result + decodeFunctionResult(functionFragment: 'approve', data: BytesLike): Result decodeFunctionResult( functionFragment: 'clearRecords', data: BytesLike, @@ -250,6 +271,10 @@ export interface PublicResolverInterface extends Interface { functionFragment: 'interfaceImplementer', data: BytesLike, ): Result + decodeFunctionResult( + functionFragment: 'isApprovedFor', + data: BytesLike, + ): Result decodeFunctionResult( functionFragment: 'isApprovedForAll', data: BytesLike, @@ -306,6 +331,7 @@ export interface PublicResolverInterface extends Interface { 'AddrChanged(bytes32,address)': EventFragment 'AddressChanged(bytes32,uint256,bytes)': EventFragment 'ApprovalForAll(address,address,bool)': EventFragment + 'Approved(address,bytes32,address,bool)': EventFragment 'ContenthashChanged(bytes32,bytes)': EventFragment 'DNSRecordChanged(bytes32,bytes,uint16,bytes)': EventFragment 'DNSRecordDeleted(bytes32,bytes,uint16)': EventFragment @@ -321,6 +347,7 @@ export interface PublicResolverInterface extends Interface { getEvent(nameOrSignatureOrTopic: 'AddrChanged'): EventFragment getEvent(nameOrSignatureOrTopic: 'AddressChanged'): EventFragment getEvent(nameOrSignatureOrTopic: 'ApprovalForAll'): EventFragment + getEvent(nameOrSignatureOrTopic: 'Approved'): EventFragment getEvent(nameOrSignatureOrTopic: 'ContenthashChanged'): EventFragment getEvent(nameOrSignatureOrTopic: 'DNSRecordChanged'): EventFragment getEvent(nameOrSignatureOrTopic: 'DNSRecordDeleted'): EventFragment @@ -378,6 +405,19 @@ export type ApprovalForAllEvent = TypedEvent< export type ApprovalForAllEventFilter = TypedEventFilter +export interface ApprovedEventObject { + owner: string + node: string + delegate: string + approved: boolean +} +export type ApprovedEvent = TypedEvent< + [string, string, string, boolean], + ApprovedEventObject +> + +export type ApprovedEventFilter = TypedEventFilter + export interface ContenthashChangedEventObject { node: string hash: string @@ -534,6 +574,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise<[string]> + approve( + node: PromiseOrValue, + delegate: PromiseOrValue, + approved: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + clearRecords( node: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, @@ -563,6 +610,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise<[string]> + isApprovedFor( + owner: PromiseOrValue, + node: PromiseOrValue, + delegate: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[boolean]> + isApprovedForAll( account: PromiseOrValue, operator: PromiseOrValue, @@ -700,6 +754,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + approve( + node: PromiseOrValue, + delegate: PromiseOrValue, + approved: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + clearRecords( node: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, @@ -729,6 +790,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + isApprovedFor( + owner: PromiseOrValue, + node: PromiseOrValue, + delegate: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + isApprovedForAll( account: PromiseOrValue, operator: PromiseOrValue, @@ -866,6 +934,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + approve( + node: PromiseOrValue, + delegate: PromiseOrValue, + approved: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + clearRecords( node: PromiseOrValue, overrides?: CallOverrides, @@ -895,6 +970,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + isApprovedFor( + owner: PromiseOrValue, + node: PromiseOrValue, + delegate: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + isApprovedForAll( account: PromiseOrValue, operator: PromiseOrValue, @@ -1056,6 +1138,19 @@ export interface PublicResolver extends BaseContract { approved?: null, ): ApprovalForAllEventFilter + 'Approved(address,bytes32,address,bool)'( + owner?: null, + node?: PromiseOrValue | null, + delegate?: PromiseOrValue | null, + approved?: PromiseOrValue | null, + ): ApprovedEventFilter + Approved( + owner?: null, + node?: PromiseOrValue | null, + delegate?: PromiseOrValue | null, + approved?: PromiseOrValue | null, + ): ApprovedEventFilter + 'ContenthashChanged(bytes32,bytes)'( node?: PromiseOrValue | null, hash?: null, @@ -1172,6 +1267,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + approve( + node: PromiseOrValue, + delegate: PromiseOrValue, + approved: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + clearRecords( node: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, @@ -1201,6 +1303,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + isApprovedFor( + owner: PromiseOrValue, + node: PromiseOrValue, + delegate: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + isApprovedForAll( account: PromiseOrValue, operator: PromiseOrValue, @@ -1339,6 +1448,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + approve( + node: PromiseOrValue, + delegate: PromiseOrValue, + approved: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + clearRecords( node: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue }, @@ -1368,6 +1484,13 @@ export interface PublicResolver extends BaseContract { overrides?: CallOverrides, ): Promise + isApprovedFor( + owner: PromiseOrValue, + node: PromiseOrValue, + delegate: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + isApprovedForAll( account: PromiseOrValue, operator: PromiseOrValue, diff --git a/packages/ensjs/src/generated/UniversalResolver.ts b/packages/ensjs/src/generated/UniversalResolver.ts index 4dae31a2..2b3a4536 100644 --- a/packages/ensjs/src/generated/UniversalResolver.ts +++ b/packages/ensjs/src/generated/UniversalResolver.ts @@ -1,7 +1,11 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ -import type { FunctionFragment, Result } from '@ethersproject/abi' +import type { + EventFragment, + FunctionFragment, + Result, +} from '@ethersproject/abi' import { Interface } from '@ethersproject/abi' import type { Listener, Provider } from '@ethersproject/abstract-provider' import type { Signer } from '@ethersproject/abstract-signer' @@ -27,7 +31,9 @@ export interface UniversalResolverInterface extends Interface { '_resolveSingle(bytes,bytes,string[],bytes4,bytes)': FunctionFragment 'batchGatewayURLs(uint256)': FunctionFragment 'findResolver(bytes)': FunctionFragment + 'owner()': FunctionFragment 'registry()': FunctionFragment + 'renounceOwnership()': FunctionFragment 'resolve(bytes,bytes,string[])': FunctionFragment 'resolve(bytes,bytes[])': FunctionFragment 'resolve(bytes,bytes[],string[])': FunctionFragment @@ -37,7 +43,9 @@ export interface UniversalResolverInterface extends Interface { 'reverse(bytes,string[])': FunctionFragment 'reverse(bytes)': FunctionFragment 'reverseCallback(bytes,bytes)': FunctionFragment + 'setGatewayURLs(string[])': FunctionFragment 'supportsInterface(bytes4)': FunctionFragment + 'transferOwnership(address)': FunctionFragment } getFunction( @@ -45,7 +53,9 @@ export interface UniversalResolverInterface extends Interface { | '_resolveSingle' | 'batchGatewayURLs' | 'findResolver' + | 'owner' | 'registry' + | 'renounceOwnership' | 'resolve(bytes,bytes,string[])' | 'resolve(bytes,bytes[])' | 'resolve(bytes,bytes[],string[])' @@ -55,7 +65,9 @@ export interface UniversalResolverInterface extends Interface { | 'reverse(bytes,string[])' | 'reverse(bytes)' | 'reverseCallback' - | 'supportsInterface', + | 'setGatewayURLs' + | 'supportsInterface' + | 'transferOwnership', ): FunctionFragment encodeFunctionData( @@ -76,7 +88,12 @@ export interface UniversalResolverInterface extends Interface { functionFragment: 'findResolver', values: [PromiseOrValue], ): string + encodeFunctionData(functionFragment: 'owner', values?: undefined): string encodeFunctionData(functionFragment: 'registry', values?: undefined): string + encodeFunctionData( + functionFragment: 'renounceOwnership', + values?: undefined, + ): string encodeFunctionData( functionFragment: 'resolve(bytes,bytes,string[])', values: [ @@ -121,10 +138,18 @@ export interface UniversalResolverInterface extends Interface { functionFragment: 'reverseCallback', values: [PromiseOrValue, PromiseOrValue], ): string + encodeFunctionData( + functionFragment: 'setGatewayURLs', + values: [PromiseOrValue[]], + ): string encodeFunctionData( functionFragment: 'supportsInterface', values: [PromiseOrValue], ): string + encodeFunctionData( + functionFragment: 'transferOwnership', + values: [PromiseOrValue], + ): string decodeFunctionResult( functionFragment: '_resolveSingle', @@ -138,7 +163,12 @@ export interface UniversalResolverInterface extends Interface { functionFragment: 'findResolver', data: BytesLike, ): Result + decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result decodeFunctionResult(functionFragment: 'registry', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'renounceOwnership', + data: BytesLike, + ): Result decodeFunctionResult( functionFragment: 'resolve(bytes,bytes,string[])', data: BytesLike, @@ -175,14 +205,38 @@ export interface UniversalResolverInterface extends Interface { functionFragment: 'reverseCallback', data: BytesLike, ): Result + decodeFunctionResult( + functionFragment: 'setGatewayURLs', + data: BytesLike, + ): Result decodeFunctionResult( functionFragment: 'supportsInterface', data: BytesLike, ): Result + decodeFunctionResult( + functionFragment: 'transferOwnership', + data: BytesLike, + ): Result + + events: { + 'OwnershipTransferred(address,address)': EventFragment + } - events: {} + getEvent(nameOrSignatureOrTopic: 'OwnershipTransferred'): EventFragment } +export interface OwnershipTransferredEventObject { + previousOwner: string + newOwner: string +} +export type OwnershipTransferredEvent = TypedEvent< + [string, string], + OwnershipTransferredEventObject +> + +export type OwnershipTransferredEventFilter = + TypedEventFilter + export interface UniversalResolver extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this attach(addressOrName: string): this @@ -229,8 +283,14 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise<[string, string]> + owner(overrides?: CallOverrides): Promise<[string]> + registry(overrides?: CallOverrides): Promise<[string]> + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + 'resolve(bytes,bytes,string[])'( name: PromiseOrValue, data: PromiseOrValue, @@ -260,14 +320,14 @@ export interface UniversalResolver extends BaseContract { resolveCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, - ): Promise + overrides?: CallOverrides, + ): Promise<[string[], string]> resolveSingleCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, - ): Promise + overrides?: CallOverrides, + ): Promise<[string, string]> 'reverse(bytes,string[])'( reverseName: PromiseOrValue, @@ -283,6 +343,11 @@ export interface UniversalResolver extends BaseContract { reverseCallback( response: PromiseOrValue, extraData: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[string, string, string, string]> + + setGatewayURLs( + _urls: PromiseOrValue[], overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -290,6 +355,11 @@ export interface UniversalResolver extends BaseContract { interfaceId: PromiseOrValue, overrides?: CallOverrides, ): Promise<[boolean]> + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise } _resolveSingle( @@ -311,8 +381,14 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise<[string, string]> + owner(overrides?: CallOverrides): Promise + registry(overrides?: CallOverrides): Promise + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + 'resolve(bytes,bytes,string[])'( name: PromiseOrValue, data: PromiseOrValue, @@ -342,14 +418,14 @@ export interface UniversalResolver extends BaseContract { resolveCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, - ): Promise + overrides?: CallOverrides, + ): Promise<[string[], string]> resolveSingleCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, - ): Promise + overrides?: CallOverrides, + ): Promise<[string, string]> 'reverse(bytes,string[])'( reverseName: PromiseOrValue, @@ -365,6 +441,11 @@ export interface UniversalResolver extends BaseContract { reverseCallback( response: PromiseOrValue, extraData: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[string, string, string, string]> + + setGatewayURLs( + _urls: PromiseOrValue[], overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -373,6 +454,11 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + callStatic: { _resolveSingle( name: PromiseOrValue, @@ -393,8 +479,12 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise<[string, string]> + owner(overrides?: CallOverrides): Promise + registry(overrides?: CallOverrides): Promise + renounceOwnership(overrides?: CallOverrides): Promise + 'resolve(bytes,bytes,string[])'( name: PromiseOrValue, data: PromiseOrValue, @@ -450,13 +540,32 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise<[string, string, string, string]> + setGatewayURLs( + _urls: PromiseOrValue[], + overrides?: CallOverrides, + ): Promise + supportsInterface( interfaceId: PromiseOrValue, overrides?: CallOverrides, ): Promise + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: CallOverrides, + ): Promise } - filters: {} + filters: { + 'OwnershipTransferred(address,address)'( + previousOwner?: PromiseOrValue | null, + newOwner?: PromiseOrValue | null, + ): OwnershipTransferredEventFilter + OwnershipTransferred( + previousOwner?: PromiseOrValue | null, + newOwner?: PromiseOrValue | null, + ): OwnershipTransferredEventFilter + } estimateGas: { _resolveSingle( @@ -478,8 +587,14 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise + owner(overrides?: CallOverrides): Promise + registry(overrides?: CallOverrides): Promise + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + 'resolve(bytes,bytes,string[])'( name: PromiseOrValue, data: PromiseOrValue, @@ -509,13 +624,13 @@ export interface UniversalResolver extends BaseContract { resolveCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, + overrides?: CallOverrides, ): Promise resolveSingleCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, + overrides?: CallOverrides, ): Promise 'reverse(bytes,string[])'( @@ -532,6 +647,11 @@ export interface UniversalResolver extends BaseContract { reverseCallback( response: PromiseOrValue, extraData: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + + setGatewayURLs( + _urls: PromiseOrValue[], overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -539,6 +659,11 @@ export interface UniversalResolver extends BaseContract { interfaceId: PromiseOrValue, overrides?: CallOverrides, ): Promise + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise } populateTransaction: { @@ -561,8 +686,14 @@ export interface UniversalResolver extends BaseContract { overrides?: CallOverrides, ): Promise + owner(overrides?: CallOverrides): Promise + registry(overrides?: CallOverrides): Promise + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise + 'resolve(bytes,bytes,string[])'( name: PromiseOrValue, data: PromiseOrValue, @@ -592,13 +723,13 @@ export interface UniversalResolver extends BaseContract { resolveCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, + overrides?: CallOverrides, ): Promise resolveSingleCallback( response: PromiseOrValue, extraData: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue }, + overrides?: CallOverrides, ): Promise 'reverse(bytes,string[])'( @@ -615,6 +746,11 @@ export interface UniversalResolver extends BaseContract { reverseCallback( response: PromiseOrValue, extraData: PromiseOrValue, + overrides?: CallOverrides, + ): Promise + + setGatewayURLs( + _urls: PromiseOrValue[], overrides?: Overrides & { from?: PromiseOrValue }, ): Promise @@ -622,5 +758,10 @@ export interface UniversalResolver extends BaseContract { interfaceId: PromiseOrValue, overrides?: CallOverrides, ): Promise + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise } } diff --git a/packages/ensjs/src/generated/factories/ETHRegistrarController__factory.ts b/packages/ensjs/src/generated/factories/ETHRegistrarController__factory.ts index 8bf590fe..a66aa03c 100644 --- a/packages/ensjs/src/generated/factories/ETHRegistrarController__factory.ts +++ b/packages/ensjs/src/generated/factories/ETHRegistrarController__factory.ts @@ -112,17 +112,6 @@ const _abi = [ name: 'ResolverRequiredWhenDataSupplied', type: 'error', }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'node', - type: 'bytes32', - }, - ], - name: 'Unauthorised', - type: 'error', - }, { inputs: [ { @@ -329,14 +318,9 @@ const _abi = [ type: 'bool', }, { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'wrapperExpiry', - type: 'uint64', + internalType: 'uint16', + name: 'ownerControlledFuses', + type: 'uint16', }, ], name: 'makeCommitment', @@ -476,14 +460,9 @@ const _abi = [ type: 'bool', }, { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'wrapperExpiry', - type: 'uint64', + internalType: 'uint16', + name: 'ownerControlledFuses', + type: 'uint16', }, ], name: 'register', @@ -509,34 +488,6 @@ const _abi = [ stateMutability: 'payable', type: 'function', }, - { - inputs: [ - { - internalType: 'string', - name: 'name', - type: 'string', - }, - { - internalType: 'uint256', - name: 'duration', - type: 'uint256', - }, - { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'wrapperExpiry', - type: 'uint64', - }, - ], - name: 'renewWithFuses', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, { inputs: [], name: 'renounceOwnership', diff --git a/packages/ensjs/src/generated/factories/NameWrapper__factory.ts b/packages/ensjs/src/generated/factories/NameWrapper__factory.ts index 9c49223b..b4b3d3dd 100644 --- a/packages/ensjs/src/generated/factories/NameWrapper__factory.ts +++ b/packages/ensjs/src/generated/factories/NameWrapper__factory.ts @@ -88,6 +88,11 @@ const _abi = [ name: 'LabelTooShort', type: 'error', }, + { + inputs: [], + name: 'NameIsNotWrapped', + type: 'error', + }, { inputs: [ { @@ -168,12 +173,6 @@ const _abi = [ name: 'node', type: 'bytes32', }, - { - indexed: false, - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, { indexed: false, internalType: 'uint64', @@ -181,6 +180,25 @@ const _abi = [ type: 'uint64', }, ], + name: 'ExpiryExtended', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'node', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint32', + name: 'fuses', + type: 'uint32', + }, + ], name: 'FusesSet', type: 'event', }, @@ -443,6 +461,30 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'node', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'addr', + type: 'address', + }, + ], + name: 'canModifyName', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [ { @@ -475,6 +517,35 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'parentNode', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'labelhash', + type: 'bytes32', + }, + { + internalType: 'uint64', + name: 'expiry', + type: 'uint64', + }, + ], + name: 'extendExpiry', + outputs: [ + { + internalType: 'uint64', + name: '', + type: 'uint64', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, { inputs: [ { @@ -487,17 +558,17 @@ const _abi = [ outputs: [ { internalType: 'address', - name: '', + name: 'owner', type: 'address', }, { internalType: 'uint32', - name: '', + name: 'fuses', type: 'uint32', }, { internalType: 'uint64', - name: '', + name: 'expiry', type: 'uint64', }, ], @@ -528,30 +599,6 @@ const _abi = [ stateMutability: 'view', type: 'function', }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'node', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'addr', - type: 'address', - }, - ], - name: 'isTokenOwnerOrApproved', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, { inputs: [ { @@ -728,14 +775,9 @@ const _abi = [ type: 'address', }, { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'expiry', - type: 'uint64', + internalType: 'uint16', + name: 'ownerControlledFuses', + type: 'uint16', }, ], name: 'registerAndWrapETH2LD', @@ -774,16 +816,6 @@ const _abi = [ name: 'duration', type: 'uint256', }, - { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'expiry', - type: 'uint64', - }, ], name: 'renew', outputs: [ @@ -941,9 +973,9 @@ const _abi = [ type: 'bytes32', }, { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', + internalType: 'uint16', + name: 'ownerControlledFuses', + type: 'uint16', }, ], name: 'setFuses', @@ -1332,14 +1364,9 @@ const _abi = [ type: 'address', }, { - internalType: 'uint32', - name: 'fuses', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'expiry', - type: 'uint64', + internalType: 'uint16', + name: 'ownerControlledFuses', + type: 'uint16', }, { internalType: 'address', @@ -1348,13 +1375,7 @@ const _abi = [ }, ], name: 'wrapETH2LD', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], + outputs: [], stateMutability: 'nonpayable', type: 'function', }, diff --git a/packages/ensjs/src/generated/factories/PublicResolver__factory.ts b/packages/ensjs/src/generated/factories/PublicResolver__factory.ts index a47f04b8..56a47cb9 100644 --- a/packages/ensjs/src/generated/factories/PublicResolver__factory.ts +++ b/packages/ensjs/src/generated/factories/PublicResolver__factory.ts @@ -123,6 +123,37 @@ const _abi = [ name: 'ApprovalForAll', type: 'event', }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'node', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'delegate', + type: 'address', + }, + { + indexed: true, + internalType: 'bool', + name: 'approved', + type: 'bool', + }, + ], + name: 'Approved', + type: 'event', + }, { anonymous: false, inputs: [ @@ -414,6 +445,29 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'node', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'delegate', + type: 'address', + }, + { + internalType: 'bool', + name: 'approved', + type: 'bool', + }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, { inputs: [ { @@ -523,6 +577,35 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'node', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'delegate', + type: 'address', + }, + ], + name: 'isApprovedFor', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [ { diff --git a/packages/ensjs/src/generated/factories/UniversalResolver__factory.ts b/packages/ensjs/src/generated/factories/UniversalResolver__factory.ts index 3422e5b6..213a5923 100644 --- a/packages/ensjs/src/generated/factories/UniversalResolver__factory.ts +++ b/packages/ensjs/src/generated/factories/UniversalResolver__factory.ts @@ -59,6 +59,25 @@ const _abi = [ name: 'OffchainLookup', type: 'error', }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, { inputs: [ { @@ -146,6 +165,19 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [], name: 'registry', @@ -159,6 +191,13 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, { inputs: [ { @@ -311,7 +350,7 @@ const _abi = [ type: 'address', }, ], - stateMutability: 'nonpayable', + stateMutability: 'view', type: 'function', }, { @@ -340,7 +379,7 @@ const _abi = [ type: 'address', }, ], - stateMutability: 'nonpayable', + stateMutability: 'view', type: 'function', }, { @@ -452,6 +491,19 @@ const _abi = [ type: 'address', }, ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'string[]', + name: '_urls', + type: 'string[]', + }, + ], + name: 'setGatewayURLs', + outputs: [], stateMutability: 'nonpayable', type: 'function', }, @@ -474,6 +526,19 @@ const _abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, ] export class UniversalResolver__factory { diff --git a/packages/ensjs/src/index.ts b/packages/ensjs/src/index.ts index 9c1a684d..44cc4357 100644 --- a/packages/ensjs/src/index.ts +++ b/packages/ensjs/src/index.ts @@ -15,14 +15,7 @@ import GqlManager from './GqlManager' import singleCall from './utils/singleCall' import writeTx from './utils/writeTx' -export type { - Fuse, - FuseArrayPossibilities, - FuseObj, - NamedFusesToBurn, - UnnamedFuseType, - UnnamedFuseValues, -} from './utils/fuses' +export type { ChildFuses, ParentFuses } from './utils/fuses' type ENSOptions = { graphURI?: string | null @@ -597,7 +590,7 @@ export class ENS { public wrapName = this.generateWriteFunction( 'wrapName', - ['contracts', 'getExpiry'], + ['contracts'], ) public unwrapName = this.generateWriteFunction( @@ -605,11 +598,15 @@ export class ENS { ['contracts'], ) - public burnFuses = this.generateWriteFunction( - 'burnFuses', + public setFuses = this.generateWriteFunction( + 'setFuses', ['contracts'], ) + public setChildFuses = this.generateWriteFunction< + FunctionTypes['setChildFuses'] + >('setFuses', ['contracts'], 'setChildFuses') + public importDNSSECName = this.generateWriteFunction< FunctionTypes['importDNSSECName'] >('importDNSSECName', ['contracts', 'provider', 'signer']) @@ -640,7 +637,7 @@ export class ENS { ['contracts'], ) - public renewNameWithData = this.generateWriteFunction< - FunctionTypes['renewNameWithData'] - >('renewNames', ['contracts'], 'renewNameWithData') + public extendWrappedName = this.generateWriteFunction< + FunctionTypes['extendWrappedName'] + >('renewNames', ['contracts'], 'extendWrappedName') } diff --git a/packages/ensjs/src/tests/func-imports.ts b/packages/ensjs/src/tests/func-imports.ts index 48ce6ca8..9a869a1a 100644 --- a/packages/ensjs/src/tests/func-imports.ts +++ b/packages/ensjs/src/tests/func-imports.ts @@ -4,7 +4,6 @@ import { resolverMulticallWrapper, universalWrapper, } from '../functions/batchWrappers' -import burnFuses from '../functions/burnFuses' import commitName from '../functions/commitName' import createSubname from '../functions/createSubname' import deleteSubname from '../functions/deleteSubname' @@ -36,8 +35,9 @@ import registerName from '../functions/registerName' import { // eslint-disable-next-line import/no-named-default default as renewNames, - renewNameWithData, + extendWrappedName, } from '../functions/renewNames' +import setFuses, { setChildFuses } from '../functions/setFuses' import setName from '../functions/setName' import setRecord from '../functions/setRecord' import setRecords from '../functions/setRecords' @@ -54,7 +54,8 @@ export default { multicallWrapper, resolverMulticallWrapper, universalWrapper, - burnFuses, + setFuses, + setChildFuses, commitName, createSubname, deleteSubname, @@ -82,7 +83,7 @@ export default { importDNSSECName, registerName, renewNames, - renewNameWithData, + extendWrappedName, setName, setRecord, setRecords, diff --git a/packages/ensjs/src/tests/registerHelpers.test.ts b/packages/ensjs/src/tests/registerHelpers.test.ts index 10119bf6..3fa25a98 100644 --- a/packages/ensjs/src/tests/registerHelpers.test.ts +++ b/packages/ensjs/src/tests/registerHelpers.test.ts @@ -37,7 +37,6 @@ describe('registerHelpers', () => { const result = makeCommitment({ ...baseData, secret, - wrapperExpiry: 100000, } as any) const fetched = await controller.makeCommitment( baseData.name!.split('.')[0], @@ -48,7 +47,6 @@ describe('registerHelpers', () => { [], false, 0, - 100000, ) expect(fetched).toBe(result.commitment) }) @@ -56,7 +54,6 @@ describe('registerHelpers', () => { const result = makeCommitment(baseData as any) expect(result).toHaveProperty('secret') expect(result).toHaveProperty('commitment') - expect(result).toHaveProperty('wrapperExpiry') }) it('should allow a custom secret', () => { const result = makeCommitment({ @@ -75,20 +72,12 @@ describe('registerHelpers', () => { } as any) expect(result[4]).not.toStrictEqual([]) }) - it('should allow custom wrapper expiry', () => { - const result = makeCommitmentData({ - ...baseData, - secret, - wrapperExpiry: 100, - } as any) - expect(result[8]).toBe(100) - }) it('should return empty data if no reverse record and no records', () => { const result = makeCommitmentData({ ...baseData, secret, } as any) - expect(result[4]).toStrictEqual([]) + expect(result[5]).toStrictEqual([]) }) }) describe('makeRegistrationData', () => { @@ -96,7 +85,6 @@ describe('registerHelpers', () => { const result = makeRegistrationData({ ...baseData, secret, - wrapperExpiry: 1000, duration: 1000, } as any) expect(result[0]).toBe('test') diff --git a/packages/ensjs/src/utils/consts.ts b/packages/ensjs/src/utils/consts.ts index b4908768..ddebe3e2 100644 --- a/packages/ensjs/src/utils/consts.ts +++ b/packages/ensjs/src/utils/consts.ts @@ -1 +1,2 @@ export const EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000' +export const MAX_INT_64 = 2n ** 64n - 1n diff --git a/packages/ensjs/src/utils/fuses.ts b/packages/ensjs/src/utils/fuses.ts index 375d2c77..82350da2 100644 --- a/packages/ensjs/src/utils/fuses.ts +++ b/packages/ensjs/src/utils/fuses.ts @@ -1,160 +1,357 @@ -import { BigNumber, BigNumberish } from '@ethersproject/bignumber/lib/bignumber' - +// child named fuses const CANNOT_UNWRAP = 1 const CANNOT_BURN_FUSES = 2 const CANNOT_TRANSFER = 4 const CANNOT_SET_RESOLVER = 8 const CANNOT_SET_TTL = 16 const CANNOT_CREATE_SUBDOMAIN = 32 -const PARENT_CANNOT_CONTROL = 64 + +// parent named fuses +const PARENT_CANNOT_CONTROL = 0x10000 +const IS_DOT_ETH = 0x20000 +const CAN_EXTEND_EXPIRY = 0x40000 + +// fuse ranges +export const CHILD_CONTROLLED_FUSES = 0x0000ffff +export const PARENT_CONTROLLED_FUSES = 0xffff0000 +export const USER_SETTABLE_FUSES = 0xfffdffff + +// empty fuse const CAN_DO_EVERYTHING = 0 -export const fuseEnum = { +export const childFuseEnum = { CANNOT_UNWRAP, CANNOT_BURN_FUSES, CANNOT_TRANSFER, CANNOT_SET_RESOLVER, CANNOT_SET_TTL, CANNOT_CREATE_SUBDOMAIN, - PARENT_CANNOT_CONTROL, } as const -export type FuseOptions = { -readonly [K in keyof typeof fuseEnum]?: boolean } +export const parentFuseEnum = { + PARENT_CANNOT_CONTROL, + CAN_EXTEND_EXPIRY, +} -export const unnamedFuses = [ - 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, - 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, - 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, -] as const +export const fullParentFuseEnum = { + ...parentFuseEnum, + IS_DOT_ETH, +} as const + +export const userSettableFuseEnum = { + ...childFuseEnum, + ...parentFuseEnum, +} as const -const fullFuseEnum = { - ...fuseEnum, +export const fullFuseEnum = { + ...userSettableFuseEnum, CAN_DO_EVERYTHING, } -export type FuseObj = typeof fuseEnum -export type CurrentFuses = { [f in keyof FuseObj]: boolean } & { - CAN_DO_EVERYTHING: boolean +export const unnamedChildFuses = [ + 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, +] as const + +export const unnamedParentFuses = [ + 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, + 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, +] as const + +export const unnamedUserSettableFuses = [ + ...unnamedChildFuses, + ...unnamedParentFuses, +] as const + +export const childFuseKeys = Object.keys( + childFuseEnum, +) as (keyof typeof childFuseEnum)[] +export const parentFuseKeys = Object.keys( + parentFuseEnum, +) as (keyof typeof parentFuseEnum)[] +export const fullParentFuseKeys = Object.keys( + fullParentFuseEnum, +) as (keyof typeof fullParentFuseEnum)[] +export const userSettableFuseKeys = Object.keys( + userSettableFuseEnum, +) as (keyof typeof userSettableFuseEnum)[] + +type FuseType< + Enum extends Record, + UnnamedTuple extends readonly number[], + CustomFuses extends string = never, +> = { + fuse: keyof Enum + options: { -readonly [K in keyof Enum]?: boolean } + current: { [K in keyof Enum]: boolean } & { + readonly [K in CustomFuses]: boolean + } + unnamed: UnnamedTuple + unnamedValues: UnnamedTuple[number] + unnamedObject: { [K in UnnamedTuple[number]]: boolean } } -export type UnnamedFuseType = typeof unnamedFuses -export type Fuse = keyof FuseObj -export type UnnamedFuseValues = UnnamedFuseType[number] - -// We need this type so that the following type isn't infinite. This type limits the max length of the fuse array to 7. -export type FuseArrayPossibilities = - | [Fuse] - | [Fuse, Fuse] - | [Fuse, Fuse, Fuse] - | [Fuse, Fuse, Fuse, Fuse] - | [Fuse, Fuse, Fuse, Fuse, Fuse] - | [Fuse, Fuse, Fuse, Fuse, Fuse, Fuse] - | [Fuse, Fuse, Fuse, Fuse, Fuse, Fuse, Fuse] - -/** - * This type creates a type error if there are any duplicate fuses. - * It effectively works like a reduce function, starting with 0 included types, adding a type each time, and then checking for duplicates. - * - * @template A The array to check for duplicates. - * @template B The union of all checked existing types. - */ -// CLAUSE A: This extension unwraps the type as a fuse tuple. -type FusesWithoutDuplicates = A extends FuseArrayPossibilities - ? // CLAUSE A > TRUE: CLAUSE B: Pick out the first item in the current array, separating the current item from the rest. - A extends [infer Head, ...infer Tail] - ? // CLAUSE B > TRUE: CLAUSE C: Check if the current item is a duplicate based on the input union. - Head extends B - ? // CLAUSE C > TRUE: Duplicate found, return an empty array to throw a type error. - [] - : // CLAUSE C > FALSE: Return a new array to continue the recursion, adds the current item type to the union. - [Head, ...FusesWithoutDuplicates] - : // CLAUSE B > FALSE: Return the input array as there is no more array elements to check. - A - : // CLAUSE A > FALSE: Return an empty array as it isn't a fuse tuple. - [] - -export type NamedFusesToBurn = FusesWithoutDuplicates - -export type FusePropsNamedArray = { - namedFusesToBurn: NamedFusesToBurn + +export type ChildFuses = FuseType< + typeof childFuseEnum, + typeof unnamedChildFuses, + 'CAN_DO_EVERYTHING' +> +export type ParentFuses = FuseType< + typeof parentFuseEnum, + typeof unnamedParentFuses +> +export type FullParentFuses = FuseType< + typeof fullParentFuseEnum, + typeof unnamedParentFuses +> +export type UserSettableFuses = FuseType< + typeof userSettableFuseEnum, + typeof unnamedUserSettableFuses +> + +type InputFuses = + | { + named: readonly NamedFuse[] + } + | { + unnamed: readonly UnnamedFuse[] + } + | { + named: readonly NamedFuse[] + unnamed: readonly UnnamedFuse[] + } + | { + number: number + } + +export type CombinedFuseInput = { + child: InputFuses + parent: InputFuses } -export type FusePropsUnnamedArray = { - unnamedFusesToBurn: UnnamedFuseValues[] +type FuseRestriction = 'parent' | 'child' + +const checkNumber = (fuses: number) => { + if (fuses > 2 ** 32 || fuses < 1) { + throw new Error( + `Fuse number must be limited to uint32, ${fuses} was too ${ + fuses < 1 ? 'low' : 'high' + }.`, + ) + } else if (fuses % 1 !== 0) { + throw new Error(`Fuse number must be an integer, ${fuses} was not.`) + } else if ((fuses & USER_SETTABLE_FUSES) !== fuses) { + throw new Error( + `Fuse number must be limited to user settable fuses, ${fuses} was not.`, + ) + } } -export type FusePropsNumber = { - fuseNumberToBurn: number +const testFuses = (fuses: any) => { + if ('named' in fuses && fuses.named.length > 0) { + return true + } + if ('unnamed' in fuses && fuses.unnamed.length > 0) { + return true + } + if ('number' in fuses && fuses.number !== 0) { + return true + } + return false } -export type FuseProps = - | (Partial & FusePropsUnnamedArray) - | (FusePropsNamedArray & Partial) - | FusePropsNumber +export const hasFuses = (fuses: any) => { + if (typeof fuses === 'number') { + return fuses !== 0 + } -export const validateFuses = (fuses: FuseProps) => { - const isNumber = 'fuseNumberToBurn' in fuses - const hasNamedArray = 'namedFusesToBurn' in fuses - const hasUnnamedArray = 'unnamedFusesToBurn' in fuses + if (typeof fuses === 'object') { + if ('child' in fuses && testFuses(fuses.child)) { + return true + } + if ('parent' in fuses && testFuses(fuses.parent)) { + return true + } + if (testFuses(fuses)) { + return true + } + } + return false +} +export function encodeFuses(fuses: Partial | number): number +export function encodeFuses( + fuses: CombinedFuseInput['child'], + restrictTo: 'child', +): number +export function encodeFuses( + fuses: CombinedFuseInput['parent'], + restrictTo: 'parent', +): number +export function encodeFuses( + fuses: CombinedFuseInput[T], + restrictTo?: T, +) { let encodedFuses: number = 0 - if (isNumber) { - if (fuses.fuseNumberToBurn > 2 ** 32 || fuses.fuseNumberToBurn < 1) { - throw new Error( - `Fuse number must be limited to uint32, ${ - fuses.fuseNumberToBurn - } was too ${fuses.fuseNumberToBurn < 1 ? 'low' : 'high'}.`, - ) - } else if (fuses.fuseNumberToBurn % 1 !== 0) { - throw new Error( - `Fuse number must be an integer, ${fuses.fuseNumberToBurn} was not.`, - ) + if (typeof fuses === 'number') { + if (restrictTo) { + throw new Error('Cannot specify an exact fuse value when restricted.') } - encodedFuses = fuses.fuseNumberToBurn + checkNumber(fuses) + + encodedFuses = fuses } else { - if (!hasNamedArray && !hasUnnamedArray) { - throw new Error('Please provide fuses to burn') + let fusesRef = fuses as unknown as CombinedFuseInput + let allowedNamed: readonly UserSettableFuses['fuse'][] = [] + let allowedUnnamed: readonly UserSettableFuses['unnamedValues'][] = [] + + let namedArray: readonly UserSettableFuses['fuse'][] = [] + let unnamedArray: readonly UserSettableFuses['unnamedValues'][] = [] + + if (restrictTo) { + if ('parent' in fuses || 'child' in fuses) { + throw new Error("Can't specify fuse category when restricted.") + } + allowedNamed = restrictTo === 'child' ? childFuseKeys : parentFuseKeys + allowedUnnamed = + restrictTo === 'child' ? unnamedChildFuses : unnamedParentFuses + + fusesRef = { [restrictTo]: fuses } as unknown as CombinedFuseInput + } else { + allowedNamed = userSettableFuseKeys + allowedUnnamed = unnamedUserSettableFuses + } + if ('parent' in fusesRef) { + if ('named' in fusesRef.parent) namedArray = fusesRef.parent.named + if ('unnamed' in fusesRef.parent) unnamedArray = fusesRef.parent.unnamed + if ('number' in fusesRef.parent) { + if ('named' in fusesRef.parent || 'unnamed' in fusesRef.parent) { + throw new Error( + 'Cannot specify both a fuse number and named/unnamed fuses.', + ) + } + checkNumber(fusesRef.parent.number) + + if ( + (fusesRef.parent.number & PARENT_CONTROLLED_FUSES) !== + fusesRef.parent.number + ) { + throw new Error( + "Cannot specify a fuse value to set that is outside of the parent's control.", + ) + } + + encodedFuses |= fusesRef.parent.number + } } - if (hasNamedArray) { - for (const fuse of fuses.namedFusesToBurn!) { - if (!(fuse in fuseEnum)) { + if ('child' in fusesRef) { + if ('named' in fusesRef.child) + namedArray = [...namedArray, ...fusesRef.child.named] + if ('unnamed' in fusesRef.child) + unnamedArray = [...unnamedArray, ...fusesRef.child.unnamed] + if ('number' in fusesRef.child) { + if ('named' in fusesRef.child || 'unnamed' in fusesRef.child) { + throw new Error( + 'Cannot specify both a fuse number and named/unnamed fuses.', + ) + } + checkNumber(fusesRef.child.number) + + if ( + (fusesRef.child.number & CHILD_CONTROLLED_FUSES) !== + fusesRef.child.number + ) { + throw new Error( + "Cannot specify a fuse value to set that is outside of the owner's control.", + ) + } + + encodedFuses |= fusesRef.child.number + } + } + + if (!namedArray.length && !unnamedArray.length && !encodedFuses) { + throw new Error('Must specify at least one fuse.') + } + + for (const fuse of namedArray) { + if (!allowedNamed.includes(fuse)) { + if (!userSettableFuseKeys.includes(fuse)) { throw new Error(`${fuse} is not a valid named fuse.`) } - encodedFuses |= fuseEnum[fuse] + throw new Error(`Fuse ${fuse} is not allowed for this operation.`) } + encodedFuses |= userSettableFuseEnum[fuse] } - if (hasUnnamedArray) { - for (const fuse of fuses.unnamedFusesToBurn!) { - if (!unnamedFuses.includes(fuse)) { + for (const fuse of unnamedArray) { + if (!allowedUnnamed.includes(fuse)) { + if (!unnamedUserSettableFuses.includes(fuse)) { throw new Error( - `${fuse} is not a valid unnamed fuse. If you are trying to burn a named fuse, use the namedFusesToBurn property.`, + `${fuse} is not a valid unnamed fuse. If you are trying to set a named fuse, use the named property.`, ) } - encodedFuses |= fuse + throw new Error(`Fuse ${fuse} is not allowed for this operation.`) } + encodedFuses |= fuse } } return encodedFuses } -export const decodeFuses = (fuses: BigNumberish) => { - const bnFuses = BigNumber.from(fuses) - +const decodeNamedFuses = (fuses: number, arr: readonly string[]) => { const fuseObj = Object.fromEntries( - Object.keys(fuseEnum).map((fuse) => [ + arr.map((fuse) => [ fuse, - bnFuses.and(fuseEnum[fuse as keyof typeof fuseEnum]).gt(0), + (fuses & + userSettableFuseEnum[fuse as keyof typeof userSettableFuseEnum]) > + 0, ]), ) - if (bnFuses.eq(0)) { - fuseObj.CAN_DO_EVERYTHING = true - } else { - fuseObj.CAN_DO_EVERYTHING = false - } + return fuseObj +} - return fuseObj as CurrentFuses +const decodeUnnamedFuses = (fuses: number, arr: readonly number[]) => { + const fuseObj = Object.fromEntries( + arr.map((fuse) => [fuse, (fuses & fuse) > 0]), + ) + + return fuseObj } +export const decodeFuses = (fuses: number) => { + const parentNamedFuses = decodeNamedFuses( + fuses, + fullParentFuseKeys, + ) as FullParentFuses['current'] + const parentUnnamedFuses = decodeUnnamedFuses( + fuses, + unnamedParentFuses, + ) as ParentFuses['unnamedObject'] + + const childNamedFuses = decodeNamedFuses( + fuses, + childFuseKeys, + ) as ChildFuses['current'] + const childUnnamedFuses = decodeUnnamedFuses( + fuses, + unnamedChildFuses, + ) as ChildFuses['unnamedObject'] + + return { + parent: { + ...parentNamedFuses, + unnamed: parentUnnamedFuses, + }, + child: { + ...childNamedFuses, + CAN_DO_EVERYTHING: (fuses & CHILD_CONTROLLED_FUSES) === 0, + unnamed: childUnnamedFuses, + }, + } +} + +export type AllCurrentFuses = ReturnType + export default fullFuseEnum diff --git a/packages/ensjs/src/utils/generateFuseInput.ts b/packages/ensjs/src/utils/generateFuseInput.ts deleted file mode 100644 index e26ca752..00000000 --- a/packages/ensjs/src/utils/generateFuseInput.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BigNumber } from '@ethersproject/bignumber/lib/bignumber' -import fuses, { FuseOptions } from './fuses' - -export default (fuseOptions: FuseOptions) => { - const fuseKeys = Object.keys(fuseOptions).filter( - (opt) => fuseOptions[opt as keyof FuseOptions] === true, - ) - - const bigNumberFuses = fuseKeys.reduce((prev, curr) => { - return prev.or(fuses[curr as keyof typeof fuses]) - }, BigNumber.from(0)) - return bigNumberFuses.toHexString() -} diff --git a/packages/ensjs/src/utils/normalise.ts b/packages/ensjs/src/utils/normalise.ts index 8d512670..57a42ca5 100644 --- a/packages/ensjs/src/utils/normalise.ts +++ b/packages/ensjs/src/utils/normalise.ts @@ -1,6 +1,6 @@ import { concat, hexlify } from '@ethersproject/bytes' import { keccak256 } from '@ethersproject/keccak256' -import { toUtf8Bytes } from '@ethersproject/strings/lib/utf8' +import { toUtf8Bytes } from '@ethersproject/strings' import uts46 from 'idna-uts46-hx/uts46bundle.js' import { decodeLabelhash, isEncodedLabelhash } from './labels' diff --git a/packages/ensjs/src/utils/recordHelpers.ts b/packages/ensjs/src/utils/recordHelpers.ts index ac935131..5a3740ed 100644 --- a/packages/ensjs/src/utils/recordHelpers.ts +++ b/packages/ensjs/src/utils/recordHelpers.ts @@ -1,6 +1,7 @@ import { formatsByCoinType, formatsByName } from '@ensdomains/address-encoder' +import { isBytesLike } from '@ethersproject/bytes' +import { toUtf8Bytes } from '@ethersproject/strings' import type { BigNumberish } from 'ethers' -import { isBytesLike, toUtf8Bytes } from 'ethers/lib/utils' import type { PublicResolver } from '../generated' import { encodeContenthash } from './contentHash' diff --git a/packages/ensjs/src/utils/registerHelpers.ts b/packages/ensjs/src/utils/registerHelpers.ts index 6553d8f7..3d0dbdd5 100644 --- a/packages/ensjs/src/utils/registerHelpers.ts +++ b/packages/ensjs/src/utils/registerHelpers.ts @@ -1,15 +1,11 @@ import { defaultAbiCoder } from '@ethersproject/abi/lib/abi-coder' -import { BigNumberish } from '@ethersproject/bignumber/lib/bignumber' import { keccak256 } from '@ethersproject/keccak256' import type { PublicResolver } from '../generated' -import { FuseOptions } from './fuses' -import generateFuseInput from './generateFuseInput' +import { CombinedFuseInput, encodeFuses, hasFuses } from './fuses' import { labelhash } from './labels' import { namehash } from './normalise' import { generateRecordCallArray, RecordOptions } from './recordHelpers' -export const MAX_INT_64 = 2n ** 64n - 1n - export type BaseRegistrationParams = { owner: string duration: number @@ -17,8 +13,7 @@ export type BaseRegistrationParams = { resolverAddress?: string records?: RecordOptions reverseRecord?: boolean - fuses?: FuseOptions - wrapperExpiry?: BigNumberish + fuses?: CombinedFuseInput['child'] } export type RegistrationParams = Omit< @@ -29,12 +24,8 @@ export type RegistrationParams = Omit< resolver: PublicResolver } -export type CommitmentParams = Omit< - RegistrationParams, - 'secret' | 'wrapperExpiry' -> & { +export type CommitmentParams = Omit & { secret?: string - wrapperExpiry?: BigNumberish } export type RegistrationTuple = [ @@ -45,20 +36,7 @@ export type RegistrationTuple = [ resolver: string, data: string[], reverseRecord: boolean, - fuses: string, - wrapperExpiry: BigNumberish, -] - -export type CommitmentTuple = [ - labelhash: string, - owner: string, - duration: number, - resolver: string, - data: string[], - secret: string, - reverseRecord: boolean, - fuses: string, - wrapperExpiry: BigNumberish, + ownerControlledFuses: number, ] export const randomSecret = () => { @@ -74,15 +52,14 @@ export const makeCommitmentData = ({ records, reverseRecord, fuses, - wrapperExpiry, secret, }: CommitmentParams & { secret: string -}): CommitmentTuple => { - const label = labelhash(name.split('.')[0]) +}): RegistrationTuple => { + const labelHash = labelhash(name.split('.')[0]) const hash = namehash(name) const resolverAddress = resolver.address - const fuseData = fuses ? generateFuseInput(fuses) : '0' + const fuseData = hasFuses(fuses) ? encodeFuses(fuses!, 'child') : 0 if (reverseRecord) { if (!records) { @@ -96,15 +73,14 @@ export const makeCommitmentData = ({ const data = records ? generateRecordCallArray(hash, records, resolver) : [] return [ - label, + labelHash, owner, duration, + secret, resolverAddress, data, - secret, !!reverseRecord, fuseData, - wrapperExpiry || MAX_INT_64, ] } @@ -114,24 +90,21 @@ export const makeRegistrationData = ( const commitmentData = makeCommitmentData(params) const label = params.name.split('.')[0] commitmentData[0] = label - const secret = commitmentData.splice(5, 1)[0] - commitmentData.splice(3, 0, secret) - return commitmentData as unknown as RegistrationTuple + return commitmentData } -export const _makeCommitment = (params: CommitmentTuple) => { +export const _makeCommitment = (params: RegistrationTuple) => { return keccak256( defaultAbiCoder.encode( [ 'bytes32', 'address', 'uint256', + 'bytes32', 'address', 'bytes[]', - 'bytes32', 'bool', - 'uint32', - 'uint64', + 'uint16', ], params, ), @@ -152,6 +125,5 @@ export const makeCommitment = ({ return { secret, commitment, - wrapperExpiry: generatedParams[8], } } diff --git a/packages/ensjs/src/utils/subgraph-types.ts b/packages/ensjs/src/utils/subgraph-types.ts new file mode 100644 index 00000000..b875cc55 --- /dev/null +++ b/packages/ensjs/src/utils/subgraph-types.ts @@ -0,0 +1,312 @@ +export type Maybe = T | null +export type Exact = { + [K in keyof T]: T[K] +} +export type MakeOptional = Omit & { + [SubKey in K]?: Maybe +} +export type MakeMaybe = Omit & { + [SubKey in K]: Maybe +} +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string + String: string + Boolean: boolean + Int: number + Float: number + Bytes: string + BigInt: string +} + +export type Domain = { + __typename?: 'Domain' + id: Scalars['ID'] + name?: Maybe + labelName?: Maybe + labelhash?: Maybe + parent?: Maybe + subdomains: Array + subdomainCount: Scalars['Int'] + resolvedAddress?: Maybe + owner: Account + resolver?: Maybe + ttl?: Maybe + isMigrated: Scalars['Boolean'] + createdAt: Scalars['BigInt'] + events: Array + registration?: Maybe + wrappedDomain?: Maybe +} + +export type DomainEvent = { + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] +} + +export type Transfer = DomainEvent & { + __typename?: 'Transfer' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + owner: Account +} + +export type NewOwner = DomainEvent & { + __typename?: 'NewOwner' + id: Scalars['ID'] + parentDomain: Domain + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + owner: Account +} + +export type NewResolver = DomainEvent & { + __typename?: 'NewResolver' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + resolver: Resolver +} + +export type NewTtl = DomainEvent & { + __typename?: 'NewTTL' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + ttl: Scalars['BigInt'] +} + +export type WrappedTransfer = DomainEvent & { + __typename?: 'WrappedTransfer' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + owner: Account +} + +export type NameWrapped = DomainEvent & { + __typename?: 'NameWrapped' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + name: Scalars['String'] + fuses: Scalars['Int'] + owner: Account + expiryDate: Scalars['BigInt'] +} + +export type NameUnwrapped = DomainEvent & { + __typename?: 'NameUnwrapped' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + owner: Account +} + +export type FusesSet = DomainEvent & { + __typename?: 'FusesSet' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + fuses: Scalars['Int'] +} + +export type ExpiryExtended = DomainEvent & { + __typename?: 'ExpiryExtended' + id: Scalars['ID'] + domain: Domain + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + expiryDate: Scalars['BigInt'] +} + +export type Registration = { + __typename?: 'Registration' + id: Scalars['ID'] + domain: Domain + registrationDate: Scalars['BigInt'] + expiryDate: Scalars['BigInt'] + cost?: Maybe + registrant: Account + labelName?: Maybe + events: Array +} + +export type RegistrationEvent = { + id: Scalars['ID'] + registration: Registration + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] +} + +export type NameRegistered = RegistrationEvent & { + __typename?: 'NameRegistered' + id: Scalars['ID'] + registration: Registration + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + registrant: Account + expiryDate: Scalars['BigInt'] +} + +export type NameRenewed = RegistrationEvent & { + __typename?: 'NameRenewed' + id: Scalars['ID'] + registration: Registration + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + expiryDate: Scalars['BigInt'] +} + +export type NameTransferred = RegistrationEvent & { + __typename?: 'NameTransferred' + id: Scalars['ID'] + registration: Registration + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + newOwner: Account +} + +export type WrappedDomain = { + __typename?: 'WrappedDomain' + id: Scalars['ID'] + domain: Domain + expiryDate: Scalars['BigInt'] + fuses: Scalars['Int'] + owner: Account + name?: Maybe +} + +export type Account = { + __typename?: 'Account' + id: Scalars['ID'] + domains: Array + wrappedDomains?: Maybe> + registrations?: Maybe> +} + +export type Resolver = { + __typename?: 'Resolver' + id: Scalars['ID'] + domain?: Maybe + address: Scalars['Bytes'] + addr?: Maybe + contentHash?: Maybe + texts?: Maybe> + coinTypes?: Maybe> + events: Array +} + +export type ResolverEvent = { + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] +} + +export type AddrChanged = ResolverEvent & { + __typename?: 'AddrChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + addr: Account +} + +export type MulticoinAddrChanged = ResolverEvent & { + __typename?: 'MulticoinAddrChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + coinType: Scalars['BigInt'] + addr: Scalars['Bytes'] +} + +export type NameChanged = ResolverEvent & { + __typename?: 'NameChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + name: Scalars['String'] +} + +export type AbiChanged = ResolverEvent & { + __typename?: 'AbiChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + contentType: Scalars['BigInt'] +} + +export type PubkeyChanged = ResolverEvent & { + __typename?: 'PubkeyChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + x: Scalars['Bytes'] + y: Scalars['Bytes'] +} + +export type TextChanged = ResolverEvent & { + __typename?: 'TextChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + key: Scalars['String'] + value?: Maybe +} + +export type ContenthashChanged = ResolverEvent & { + __typename?: 'ContenthashChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + hash: Scalars['Bytes'] +} + +export type InterfaceChanged = ResolverEvent & { + __typename?: 'InterfaceChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + interfaceID: Scalars['Bytes'] + implementer: Scalars['Bytes'] +} + +export type AuthorisationChanged = ResolverEvent & { + __typename?: 'AuthorisationChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + owner: Scalars['Bytes'] + target: Scalars['Bytes'] + isAuthorized: Scalars['Boolean'] +} + +export type VersionChanged = ResolverEvent & { + __typename?: 'VersionChanged' + id: Scalars['ID'] + resolver: Resolver + blockNumber: Scalars['Int'] + transactionID: Scalars['Bytes'] + version: Scalars['BigInt'] +} diff --git a/packages/ensjs/src/utils/wrapper.ts b/packages/ensjs/src/utils/wrapper.ts index cb0e9b59..36fb2bf6 100644 --- a/packages/ensjs/src/utils/wrapper.ts +++ b/packages/ensjs/src/utils/wrapper.ts @@ -1,5 +1,5 @@ import { BigNumber } from '@ethersproject/bignumber/lib/bignumber' -import { toUtf8Bytes } from '@ethersproject/strings/lib/utf8' +import { toUtf8Bytes } from '@ethersproject/strings' import { ENSArgs } from '../index' export type Expiry = string | number | Date | BigNumber diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9bb712be..56d5a392 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,7 +80,7 @@ importers: '@ensdomains/content-hash': ^2.5.7 '@ensdomains/dnsprovejs': ^0.4.1 '@ensdomains/dnssecoraclejs': ^0.2.7 - '@ensdomains/ens-contracts': ^0.0.15 + '@ensdomains/ens-contracts': ^0.0.16 '@ensdomains/ens-test-env': workspace:* '@ethersproject/abi': ^5.6.4 '@ethersproject/abstract-provider': ^5.7.0 @@ -147,7 +147,7 @@ importers: traverse: 0.6.6 devDependencies: '@ensdomains/buffer': 0.0.13_hardhat@2.10.2 - '@ensdomains/ens-contracts': 0.0.15_hardhat@2.10.2 + '@ensdomains/ens-contracts': 0.0.16_hardhat@2.10.2 '@ensdomains/ens-test-env': link:../ens-test-env '@ethersproject/abi': 5.6.4 '@ethersproject/abstract-provider': 5.7.0 @@ -627,8 +627,8 @@ packages: - web3-utils dev: false - /@ensdomains/ens-contracts/0.0.15_hardhat@2.10.2: - resolution: {integrity: sha512-fOmGylPbsHWjhD3iXz1pyi5VuyW25ahbjjUIjaKwC5MBULJYJDFb2sHlK8P4bxVep2pTGfV3XUhdFVMiEE4LLQ==} + /@ensdomains/ens-contracts/0.0.16_hardhat@2.10.2: + resolution: {integrity: sha512-pssd2nrzHoFJOvzANoBVNMdb9H9tpyMPSyb9JaTFmS6HDo7RRcsyWL8FYCGkUmsnAqzz8dz3OwxiH03s8cLG2A==} dependencies: '@ensdomains/buffer': 0.0.13_hardhat@2.10.2 '@ensdomains/solsha1': 0.0.3