Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Commit

Permalink
Eliminates ProxyAmdin code duplication;
Browse files Browse the repository at this point in the history
Add Mixin class and showcase Mixin usage;
  • Loading branch information
ylv-io committed Apr 17, 2019
1 parent 96666ca commit 7fb3220
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 23 deletions.
17 changes: 6 additions & 11 deletions packages/lib/src/project/AppProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import isEmpty from 'lodash.isempty';
import App from '../application/App';
import Package from '../application/Package';
import ProxyAdmin from '../proxy/ProxyAdmin';
import ProxyAdminProjectMixin from './mixin/ProxyAdminProjectMixin';
import ImplementationDirectory from '../application/ImplementationDirectory';
import BasePackageProject from './BasePackageProject';
import SimpleProject from './SimpleProject';
Expand Down Expand Up @@ -37,7 +38,7 @@ interface ExistingAddresses {
proxyFactoryAddress?: string;
}

export default class AppProject extends BasePackageProject {
class BaseAppProject extends BasePackageProject {
private name: string;
private app: App;
public proxyAdmin: ProxyAdmin;
Expand Down Expand Up @@ -68,7 +69,7 @@ export default class AppProject extends BasePackageProject {
if (!await app.hasPackage(name, version)) await app.setPackage(name, thepackage.address, version);
const proxyAdmin: ProxyAdmin | null = proxyAdminAddress ? await ProxyAdmin.fetch(proxyAdminAddress, txParams) : null;
const proxyFactory = ProxyFactory.tryFetch(proxyFactoryAddress, txParams);
const project: AppProject = new this(app, name, version, proxyAdmin, proxyFactory, txParams);
const project: AppProject = new AppProject(app, name, version, proxyAdmin, proxyFactory, txParams);
project.directory = directory;
project.package = thepackage;
return project;
Expand Down Expand Up @@ -130,11 +131,6 @@ export default class AppProject extends BasePackageProject {
public getAdminAddress(): Promise<string> {
return new Promise((resolve) => resolve(this.proxyAdmin ? this.proxyAdmin.address : null));
}

public async transferAdminOwnership(newAdminOwner: string): Promise<void> {
await this.proxyAdmin.transferOwnership(newAdminOwner);
}

public getApp(): App {
return this.app;
}
Expand Down Expand Up @@ -237,10 +233,6 @@ export default class AppProject extends BasePackageProject {
return this.proxyAdmin.upgradeProxy(proxyAddress, implementationAddress, contract, initMethod, initArgs);
}

public async changeProxyAdmin(proxyAddress: string, newAdmin: string): Promise<void> {
return this.proxyAdmin.changeProxyAdmin(proxyAddress, newAdmin);
}

public async getDependencyPackage(name: string): Promise<Package> {
const packageInfo = await this.app.getPackage(name);
return packageInfo.package;
Expand Down Expand Up @@ -275,3 +267,6 @@ export default class AppProject extends BasePackageProject {
}
}
}
// Mixings produce value but not type
// We have to export full class with type & callable
export default class AppProject extends ProxyAdminProjectMixin(BaseAppProject) {};
20 changes: 8 additions & 12 deletions packages/lib/src/project/ProxyAdminProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import BaseSimpleProject from './BaseSimpleProject';
import { ContractInterface } from './AppProject';
import Contract from '../artifacts/Contract';
import ProxyFactory from '../proxy/ProxyFactory';
import ProxyAdminProjectMixin from './mixin/ProxyAdminProjectMixin';

const log: Logger = new Logger('ProxyAdminProject');

export default class ProxyAdminProject extends BaseSimpleProject {
class BaseProxyAdminProject extends BaseSimpleProject {
public proxyAdmin: ProxyAdmin;

public static async fetch(name: string = 'main', txParams: any = {}, proxyAdminAddress?: string, proxyFactoryAddress?: string) {
public static async fetch(name: string = 'main', txParams: any = {}, proxyAdminAddress?: string, proxyFactoryAddress?: string): Promise<ProxyAdminProject> {
const proxyAdmin = proxyAdminAddress ? await ProxyAdmin.fetch(proxyAdminAddress, txParams) : null;
const proxyFactory = proxyFactoryAddress ? await ProxyFactory.fetch(proxyFactoryAddress, txParams) : null;
return new this(name, proxyAdmin, proxyFactory, txParams);
return new ProxyAdminProject(name, proxyAdmin, proxyFactory, txParams);
}

constructor(name: string = 'main', proxyAdmin: ProxyAdmin, proxyFactory?: ProxyFactory, txParams: any = {}) {
Expand All @@ -40,23 +41,18 @@ export default class ProxyAdminProject extends BaseSimpleProject {
return contract.at(pAddress);
}

public async changeProxyAdmin(proxyAddress: string, newAdmin: string): Promise<void> {
await this.proxyAdmin.changeProxyAdmin(proxyAddress, newAdmin);
log.info(`Proxy ${proxyAddress} admin changed to ${newAdmin}`);
}

public getAdminAddress(): Promise<string> {
return new Promise((resolve) => resolve(this.proxyAdmin ? this.proxyAdmin.address : null));
}

public async transferAdminOwnership(newAdminOwner: string): Promise<void> {
await this.proxyAdmin.transferOwnership(newAdminOwner);
}

public async ensureProxyAdmin(): Promise<ProxyAdmin> {
if (!this.proxyAdmin) {
this.proxyAdmin = await ProxyAdmin.deploy(this.txParams);
}
return this.proxyAdmin;
}
}

// Mixings produce value but not type
// We have to export full class with type & callable
export default class ProxyAdminProject extends ProxyAdminProjectMixin(BaseProxyAdminProject) {};
21 changes: 21 additions & 0 deletions packages/lib/src/project/mixin/ProxyAdminProjectMixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Constructable, { AbstractType, GetMixinType } from '../../utils/Mixin';
import ProxyAdmin from '../../proxy/ProxyAdmin';

// A mixin that adds ProxyAdmin field and related ProxyAdminProject methods
// Intented to as a building block for Project class
// Can't extend contructor at that moment due to TypeScript limitations https://github.com/Microsoft/TypeScript/issues/14126
function ProxyAdminProjectMixin<T extends Constructable>(Base: T) {
return class extends Base {
public proxyAdmin: ProxyAdmin;

public async transferAdminOwnership(newAdminOwner: string): Promise<void> {
await this.proxyAdmin.transferOwnership(newAdminOwner);
}

public async changeProxyAdmin(proxyAddress: string, newAdmin: string): Promise<void> {
return this.proxyAdmin.changeProxyAdmin(proxyAddress, newAdmin);
}
};
}

export default ProxyAdminProjectMixin;
7 changes: 7 additions & 0 deletions packages/lib/src/utils/Mixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type Constructable<T = {}> = new (...args: any[]) => T;
export type Callable<T = any> = (...args: any[]) => T;
export type AbstractType<T = {}> = Function & { prototype: T };

export type GetMixinType<T extends Callable> = InstanceType<ReturnType<T>>;

export default Constructable;

0 comments on commit 7fb3220

Please sign in to comment.