Skip to content

Commit

Permalink
feat: upgrade resolver to v2
Browse files Browse the repository at this point in the history
  • Loading branch information
JGiter committed Feb 28, 2022
1 parent b1dde46 commit f708e40
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 26 deletions.
10 changes: 9 additions & 1 deletion e2e/utils/setup_contracts.ts
Expand Up @@ -4,6 +4,7 @@ import { Chain } from '@ew-did-registry/did';
import { DomainNotifier__factory } from '../../ethers/factories/DomainNotifier__factory';
import type { DomainNotifier } from '../../ethers/DomainNotifier';
import { RoleDefinitionResolver__factory } from '../../ethers/factories/RoleDefinitionResolver__factory';
import { RoleDefinitionResolverV2__factory } from '../../ethers/factories/RoleDefinitionResolverV2__factory';
import type { RoleDefinitionResolver } from '../../ethers/RoleDefinitionResolver';
import { ENSRegistry } from '../../ethers/ENSRegistry';
import { ENSRegistry__factory } from '../../ethers/factories/ENSRegistry__factory';
Expand All @@ -14,6 +15,7 @@ import { ClaimManager__factory } from '../../ethers/factories/ClaimManager__fact
import { ClaimManager } from '../../ethers/ClaimManager';
import { setChainConfig } from '../../src/config/chain.config';
import { labelhash } from '../../src/utils/ensHash';
import { RoleDefinitionResolverV2 } from '../../ethers/RoleDefinitionResolverV2';

const { JsonRpcProvider } = providers;
const { parseEther, namehash } = utils;
Expand All @@ -27,6 +29,7 @@ const provider = new JsonRpcProvider(rpcUrl);
let didRegistry: Contract;
let ensRegistry: ENSRegistry;
let ensResolver: RoleDefinitionResolver;
let ensResolverV2: RoleDefinitionResolverV2;
let domainNotifer: DomainNotifier;
let assetsManager: IdentityManager;
let claimManager: ClaimManager;
Expand All @@ -51,6 +54,10 @@ const deployEns = async () => {
ensRegistry.address,
domainNotifer.address
);
ensResolverV2 = await new RoleDefinitionResolverV2__factory(deployer).deploy(
ensRegistry.address,
domainNotifer.address
);
};

const deployIdentityManager = async (): Promise<void> => {
Expand Down Expand Up @@ -93,6 +100,7 @@ export const setupENS = async (rootOwner: string) => {
rpcUrl,
chainName: Chain.VOLTA,
ensRegistryAddress: ensRegistry.address,
ensResolverV2Address: ensResolverV2.address,
ensResolverAddress: ensResolver.address,
didRegistryAddress: didRegistry.address,
assetManagerAddress: assetsManager.address,
Expand All @@ -103,7 +111,7 @@ export const setupENS = async (rootOwner: string) => {
namehash(''),
labelhash(root),
rootOwner,
ensResolver.address,
ensResolverV2.address,
BigNumber.from(0)
);
await tx.wait();
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -20,12 +20,13 @@
"build:contracts": "npm run build:typechain:ens && npm run build:typechain:did && npm run build:typechain:roles && npm run build:typechain:staking",
"build:typechain:ens": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@ensdomains/ens/build/contracts/ENSRegistry.json\"",
"build:typechain:did": "npm run build:typechain:offerableIdentity && npm run build:typechain:identityManager",
"build:typechain:roles": " npm run build:typechain:claimManager && npm run build:typechain:roledefinitionresolver && npm run build:typechain:domainnotifier && npm run build:typechain:publicresolver",
"build:typechain:roles": " npm run build:typechain:claimManager && npm run build:typechain:roledefinitionresolver && npm run build:typechain:domainnotifier && npm run build:typechain:publicresolver && npm run build:typechain:roledefinitionresolverv2",
"build:typechain:staking": "npm run build:typechain:staking-pool",
"build:typechain:offerableIdentity": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@ew-did-registry/proxyidentity/build/contracts/OfferableIdentity.json\"",
"build:typechain:identityManager": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@ew-did-registry/proxyidentity/build/contracts/IdentityManager.json\"",
"build:typechain:claimManager": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@energyweb/iam-contracts/dist/contracts/ClaimManager.json\"",
"build:typechain:roledefinitionresolver": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@energyweb/iam-contracts/dist/contracts/RoleDefinitionResolver.json\"",
"build:typechain:roledefinitionresolverv2": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@energyweb/iam-contracts/dist/contracts/RoleDefinitionResolverV2.json\"",
"build:typechain:domainnotifier": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@energyweb/iam-contracts/dist/contracts/DomainNotifier.json\"",
"build:typechain:publicresolver": "typechain --target ethers-v5 --out-dir ethers \"./node_modules/@energyweb/iam-contracts/dist/contracts/PublicResolver.json\"",
"build:typechain:staking-pool": "typechain --target ethers-v5 --out-dir ethers-staking \"./node_modules/@energyweb/staking-pool/dist/contracts/StakingPool.sol/StakingPool.json\"",
Expand Down
5 changes: 5 additions & 0 deletions src/errors/UnregisteredResolverError.ts
@@ -0,0 +1,5 @@
export class UnregisteredResolverError extends Error {
constructor(domain: string, resolver: string) {
super(`Domain ${domain} is defined on unregistered resolver ${resolver}`);
}
}
73 changes: 50 additions & 23 deletions src/modules/domains/domains.service.ts
Expand Up @@ -3,11 +3,13 @@ import {
IAppDefinition,
IOrganizationDefinition,
IRoleDefinition,
IRoleDefinitionV2,
EncodedCall,
DomainReader,
DomainTransactionFactory,
ResolverContractType,
DomainHierarchy,
VOLTA_CHAIN_ID,
DomainTransactionFactoryV2,
} from '@energyweb/iam-contracts';
import { ENSRegistry } from '../../../ethers/ENSRegistry';
import { ENSRegistry__factory } from '../../../ethers/factories/ENSRegistry__factory';
Expand All @@ -27,17 +29,21 @@ import { SignerService } from '../signer/signer.service';
import { NamespaceType, IOrganization } from './domains.types';
import { SearchType } from '../cacheClient/cacheClient.types';
import { validateAddress } from '../../utils/address';
import { UnregisteredResolverError } from '../../errors/UnregisteredResolverError';
import { castToV2 } from './domains.types';

const { namehash } = utils;

export class DomainsService {
private chainId: number;
private _ensRegistry: ENSRegistry;
private _domainDefinitionReader: DomainReader;
private _domainDefinitionTransactionFactory: DomainTransactionFactory;
private _domainDefinitionTransactionFactory: DomainTransactionFactoryV2;
private _domainHierarchy: DomainHierarchy;
private _owner: string;
private _ensRegistryAddress: string;
private _ensResolver: string;
private _ensResolverV2Address: string;
private _ensResolverAddress: string;
private _ensPublicResolverAddress: string;
private _ttl = BigNumber.from(0);
Expand All @@ -61,11 +67,14 @@ export class DomainsService {
const provider = this._signerService.provider;
const {
ensRegistryAddress,
ensResolverV2Address,
ensResolverAddress,
ensPublicResolverAddress,
domainNotifierAddress,
} = chainConfigs()[this.chainId];
this._ensRegistryAddress = ensRegistryAddress;
this._ensResolver = ensResolverV2Address;
this._ensResolverV2Address = ensResolverV2Address;
this._ensResolverAddress = ensResolverAddress;
this._ensPublicResolverAddress = ensPublicResolverAddress;
this._ensRegistry = new ENSRegistry__factory(
Expand All @@ -78,28 +87,37 @@ export class DomainsService {
ensRegistryAddress,
provider,
});
ensPublicResolverAddress &&

this._domainDefinitionReader.addKnownResolver({
chainId,
address: ensResolverV2Address,
type: ResolverContractType.RoleDefinitionResolver_v2,
});

// until role definitions are migrated to resolver_v2
if (chainId === VOLTA_CHAIN_ID) {
this._domainDefinitionReader.addKnownResolver({
chainId,
address: ensPublicResolverAddress,
type: ResolverContractType.PublicResolver,
address: ensResolverAddress,
type: ResolverContractType.RoleDefinitionResolver_v1,
});
ensResolverAddress &&
this._domainDefinitionReader.addKnownResolver({
chainId,
address: ensResolverAddress,
type: ResolverContractType.RoleDefinitionResolver_v1,
address: ensPublicResolverAddress,
type: ResolverContractType.PublicResolver,
});
this._domainDefinitionTransactionFactory = new DomainTransactionFactory({
domainResolverAddress: ensResolverAddress,
}
this._domainDefinitionTransactionFactory = new DomainTransactionFactoryV2({
domainResolverAddress: ensResolverV2Address,
});
this._domainHierarchy = new DomainHierarchy({
domainReader: this._domainDefinitionReader,
ensRegistryAddress: this._ensRegistryAddress,
ensRegistryAddress: ensRegistryAddress,
provider,
domainNotifierAddress: domainNotifierAddress,
publicResolverAddress: ensPublicResolverAddress,
});

this._owner = this._signerService.address;
}

Expand All @@ -115,7 +133,7 @@ export class DomainsService {
data,
}: {
domain: string;
data: IAppDefinition | IOrganizationDefinition | IRoleDefinition;
data: IAppDefinition | IOrganizationDefinition | IRoleDefinitionV2;
}) {
// Special case of updating legacy PublicResolver definitions
if (await this.updateLegacyDefinition(domain, data)) {
Expand Down Expand Up @@ -290,9 +308,10 @@ export class DomainsService {
}: {
roleName: string;
namespace: string;
data: IRoleDefinition;
data: IRoleDefinition | IRoleDefinitionV2;
returnSteps?: boolean;
}) {
const dataV2 = castToV2(data);
const newDomain = `${roleName}.${namespace}`;
const from = await this.getOwner({ namespace });
const steps = [
Expand All @@ -307,7 +326,7 @@ export class DomainsService {
{
tx: this._domainDefinitionTransactionFactory.newRole({
domain: newDomain,
roleDefinition: data,
roleDefinition: dataV2,
}),
info: 'Set name and definition for role',
},
Expand Down Expand Up @@ -368,8 +387,6 @@ export class DomainsService {
}

const apps = await this.getAppsOfOrg(namespace);
// @todo fix /org/namespace/suborgs and transfer suborganizations
// https://energyweb.atlassian.net/browse/ICS-135
if (apps && apps.length > 0) {
if (!withSubdomains) {
throw new Error(
Expand Down Expand Up @@ -965,26 +982,30 @@ export class DomainsService {
*/
async updateLegacyDefinition(
domain: string,
data: IAppDefinition | IOrganizationDefinition | IRoleDefinition
data:
| IAppDefinition
| IOrganizationDefinition
| IRoleDefinition
| IRoleDefinitionV2
): Promise<boolean> {
const node = namehash(domain);
const currentResolverAddress = await this._ensRegistry.resolver(node);
const { ensPublicResolverAddress, ensResolverAddress, ensRegistryAddress } =
const { ensResolverV2Address, ensRegistryAddress } =
chainConfigs()[this.chainId];
if (currentResolverAddress === ensPublicResolverAddress) {
if (currentResolverAddress !== ensResolverV2Address) {
const updateResolverTransaction: EncodedCall = {
to: ensRegistryAddress,
data: this._ensRegistry.interface.encodeFunctionData('setResolver', [
node,
ensResolverAddress,
ensResolverV2Address,
]),
};
// Need to use newRole/newDomain as need to set reverse domain name
const updateDomain = DomainReader.isRoleDefinition(data)
? this._domainDefinitionTransactionFactory.newRole({
domain,
roleDefinition: {
...data,
...castToV2(data),
version: parseInt(data.version.toString(), 10),
},
})
Expand Down Expand Up @@ -1015,11 +1036,17 @@ export class DomainsService {
continue;
}
const resolver = await this._ensRegistry.resolver(namehash(role));
if (resolver === this._ensResolverAddress) {
if (
[this._ensResolverAddress, this._ensResolverV2Address].includes(
resolver
)
) {
types[role].add(RegistrationTypes.OnChain);
types[role].add(RegistrationTypes.OffChain);
} else if (resolver === this._ensPublicResolverAddress) {
types[role].add(RegistrationTypes.OffChain);
} else {
throw new UnregisteredResolverError(role, resolver);
}
}
return types;
Expand All @@ -1045,7 +1072,7 @@ export class DomainsService {
namehash(domain),
labelhash(nodeName),
owner,
this._ensResolverAddress,
this._ensResolver,
this._ttl,
]),
};
Expand Down
23 changes: 22 additions & 1 deletion src/modules/domains/domains.types.ts
@@ -1,4 +1,10 @@
import { IAppDefinition, IOrganizationDefinition, IRoleDefinition } from '@energyweb/iam-contracts';
import {
IAppDefinition,
IOrganizationDefinition,
IRevokerDefinition,
IRoleDefinition,
IRoleDefinitionV2,
} from '@energyweb/iam-contracts';

export enum NamespaceType {
Role = 'roles',
Expand Down Expand Up @@ -38,3 +44,18 @@ export interface IApp {
}

export const NODE_FIELDS_KEY = 'metadata';

export function castToV2(
roleDef: IRoleDefinition | IRoleDefinitionV2
): IRoleDefinitionV2 {
if (!Object.keys(roleDef).includes('revoker')) {
const revoker: IRevokerDefinition = {
did: roleDef.issuer.did,
revokerType: roleDef.issuer.issuerType,
roleName: roleDef.issuer.roleName,
};
return { ...roleDef, revoker };
} else {
return <IRoleDefinitionV2>roleDef;
}
}

0 comments on commit f708e40

Please sign in to comment.