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

Commit 4e43e82

Browse files
ylv-iospalladino
authored andcommitted
Eliminates ProxyAmdin code duplication; (#815)
Add Mixin class and showcase Mixin usage;
1 parent 920aed1 commit 4e43e82

File tree

4 files changed

+42
-23
lines changed

4 files changed

+42
-23
lines changed

packages/lib/src/project/AppProject.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import isEmpty from 'lodash.isempty';
55
import App from '../application/App';
66
import Package from '../application/Package';
77
import ProxyAdmin from '../proxy/ProxyAdmin';
8+
import ProxyAdminProjectMixin from './mixin/ProxyAdminProjectMixin';
89
import ImplementationDirectory from '../application/ImplementationDirectory';
910
import BasePackageProject from './BasePackageProject';
1011
import SimpleProject from './SimpleProject';
@@ -37,7 +38,7 @@ interface ExistingAddresses {
3738
proxyFactoryAddress?: string;
3839
}
3940

40-
export default class AppProject extends BasePackageProject {
41+
class BaseAppProject extends BasePackageProject {
4142
private name: string;
4243
private app: App;
4344
public proxyAdmin: ProxyAdmin;
@@ -68,7 +69,7 @@ export default class AppProject extends BasePackageProject {
6869
if (!await app.hasPackage(name, version)) await app.setPackage(name, thepackage.address, version);
6970
const proxyAdmin: ProxyAdmin | null = proxyAdminAddress ? await ProxyAdmin.fetch(proxyAdminAddress, txParams) : null;
7071
const proxyFactory = ProxyFactory.tryFetch(proxyFactoryAddress, txParams);
71-
const project: AppProject = new this(app, name, version, proxyAdmin, proxyFactory, txParams);
72+
const project: AppProject = new AppProject(app, name, version, proxyAdmin, proxyFactory, txParams);
7273
project.directory = directory;
7374
project.package = thepackage;
7475
return project;
@@ -130,11 +131,6 @@ export default class AppProject extends BasePackageProject {
130131
public getAdminAddress(): Promise<string> {
131132
return new Promise((resolve) => resolve(this.proxyAdmin ? this.proxyAdmin.address : null));
132133
}
133-
134-
public async transferAdminOwnership(newAdminOwner: string): Promise<void> {
135-
await this.proxyAdmin.transferOwnership(newAdminOwner);
136-
}
137-
138134
public getApp(): App {
139135
return this.app;
140136
}
@@ -237,10 +233,6 @@ export default class AppProject extends BasePackageProject {
237233
return this.proxyAdmin.upgradeProxy(proxyAddress, implementationAddress, contract, initMethod, initArgs);
238234
}
239235

240-
public async changeProxyAdmin(proxyAddress: string, newAdmin: string): Promise<void> {
241-
return this.proxyAdmin.changeProxyAdmin(proxyAddress, newAdmin);
242-
}
243-
244236
public async getDependencyPackage(name: string): Promise<Package> {
245237
const packageInfo = await this.app.getPackage(name);
246238
return packageInfo.package;
@@ -275,3 +267,6 @@ export default class AppProject extends BasePackageProject {
275267
}
276268
}
277269
}
270+
// Mixings produce value but not type
271+
// We have to export full class with type & callable
272+
export default class AppProject extends ProxyAdminProjectMixin(BaseAppProject) {};

packages/lib/src/project/ProxyAdminProject.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ import BaseSimpleProject from './BaseSimpleProject';
55
import { ContractInterface } from './AppProject';
66
import Contract from '../artifacts/Contract';
77
import ProxyFactory from '../proxy/ProxyFactory';
8+
import ProxyAdminProjectMixin from './mixin/ProxyAdminProjectMixin';
89

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

11-
export default class ProxyAdminProject extends BaseSimpleProject {
12+
class BaseProxyAdminProject extends BaseSimpleProject {
1213
public proxyAdmin: ProxyAdmin;
1314

14-
public static async fetch(name: string = 'main', txParams: any = {}, proxyAdminAddress?: string, proxyFactoryAddress?: string) {
15+
public static async fetch(name: string = 'main', txParams: any = {}, proxyAdminAddress?: string, proxyFactoryAddress?: string): Promise<ProxyAdminProject> {
1516
const proxyAdmin = proxyAdminAddress ? await ProxyAdmin.fetch(proxyAdminAddress, txParams) : null;
1617
const proxyFactory = proxyFactoryAddress ? await ProxyFactory.fetch(proxyFactoryAddress, txParams) : null;
17-
return new this(name, proxyAdmin, proxyFactory, txParams);
18+
return new ProxyAdminProject(name, proxyAdmin, proxyFactory, txParams);
1819
}
1920

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

43-
public async changeProxyAdmin(proxyAddress: string, newAdmin: string): Promise<void> {
44-
await this.proxyAdmin.changeProxyAdmin(proxyAddress, newAdmin);
45-
log.info(`Proxy ${proxyAddress} admin changed to ${newAdmin}`);
46-
}
47-
4844
public getAdminAddress(): Promise<string> {
4945
return new Promise((resolve) => resolve(this.proxyAdmin ? this.proxyAdmin.address : null));
5046
}
5147

52-
public async transferAdminOwnership(newAdminOwner: string): Promise<void> {
53-
await this.proxyAdmin.transferOwnership(newAdminOwner);
54-
}
55-
5648
public async ensureProxyAdmin(): Promise<ProxyAdmin> {
5749
if (!this.proxyAdmin) {
5850
this.proxyAdmin = await ProxyAdmin.deploy(this.txParams);
5951
}
6052
return this.proxyAdmin;
6153
}
6254
}
55+
56+
// Mixings produce value but not type
57+
// We have to export full class with type & callable
58+
export default class ProxyAdminProject extends ProxyAdminProjectMixin(BaseProxyAdminProject) {};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Constructable, { AbstractType, GetMixinType } from '../../utils/Mixin';
2+
import ProxyAdmin from '../../proxy/ProxyAdmin';
3+
4+
// A mixin that adds ProxyAdmin field and related ProxyAdminProject methods
5+
// Intented to as a building block for Project class
6+
// Can't extend contructor at that moment due to TypeScript limitations https://github.com/Microsoft/TypeScript/issues/14126
7+
function ProxyAdminProjectMixin<T extends Constructable>(Base: T) {
8+
return class extends Base {
9+
public proxyAdmin: ProxyAdmin;
10+
11+
public async transferAdminOwnership(newAdminOwner: string): Promise<void> {
12+
await this.proxyAdmin.transferOwnership(newAdminOwner);
13+
}
14+
15+
public async changeProxyAdmin(proxyAddress: string, newAdmin: string): Promise<void> {
16+
return this.proxyAdmin.changeProxyAdmin(proxyAddress, newAdmin);
17+
}
18+
};
19+
}
20+
21+
export default ProxyAdminProjectMixin;

packages/lib/src/utils/Mixin.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type Constructable<T = {}> = new (...args: any[]) => T;
2+
export type Callable<T = any> = (...args: any[]) => T;
3+
export type AbstractType<T = {}> = Function & { prototype: T };
4+
5+
export type GetMixinType<T extends Callable> = InstanceType<ReturnType<T>>;
6+
7+
export default Constructable;

0 commit comments

Comments
 (0)