Skip to content

Commit

Permalink
Support registering unwrapped, non-universal and non-Arc schemes (#341)
Browse files Browse the repository at this point in the history
  • Loading branch information
dkent600 authored Aug 30, 2018
1 parent 7ccf868 commit db38d89
Show file tree
Hide file tree
Showing 23 changed files with 416 additions and 218 deletions.
2 changes: 1 addition & 1 deletion docs/Wrappers.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ for (var wrapper in ContractWrappers) {

Arc contracts and associated Arc.js contract wrapper classes can be categorized as follows:

**Schemes**
**Universal Schemes**

* ContributionReward
* GenesisProtocol
Expand Down
4 changes: 0 additions & 4 deletions lib/commonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ export namespace SchemePermissions {
}
/*tslint:enable:no-namespace */

export interface HasContract {
contract: any;
}

export interface TruffleContract {
/**
* Migrate a new instance of the contract. Returns promise of being
Expand Down
33 changes: 7 additions & 26 deletions lib/contractWrapperBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ArcTransactionDataResult,
ArcTransactionResult,
GasPriceAdjustor,
IContractWrapperBase,
IContractWrapper,
IContractWrapperFactory,
StandardSchemeParams
} from "./iContractWrapperBase";
Expand All @@ -21,8 +21,9 @@ import {
} from "./transactionService";
import { Utils } from "./utils";
import { EventFetcherFactory, Web3EventService } from "./web3EventService";

/**
* Abstract base class for all Arc contract wrapper classes
* Abstract base class for all Arc contract wrapper classes.
*
* Example of how to define a wrapper:
*
Expand All @@ -40,7 +41,7 @@ import { EventFetcherFactory, Web3EventService } from "./web3EventService";
* new Web3EventService());
* ```
*/
export abstract class ContractWrapperBase implements IContractWrapperBase {
export abstract class ContractWrapperBase implements IContractWrapper {

/**
* The wrapper factor class providing static methods `at(someAddress)`, `new()` and `deployed()`.
Expand Down Expand Up @@ -77,7 +78,7 @@ export abstract class ContractWrapperBase implements IContractWrapperBase {
* This will migrate a new instance of the contract to the net.
* @returns this
*/
public async hydrateFromNew(...rest: Array<any>): Promise<IContractWrapperBase> {
public async hydrateFromNew(...rest: Array<any>): Promise<IContractWrapper> {
try {
// Note that because we are using `.then`, we are returning a true promise
// rather than the incomplete one returned by truffle.
Expand All @@ -96,7 +97,7 @@ export abstract class ContractWrapperBase implements IContractWrapperBase {
* @param address of the deployed contract
* @returns this or undefined if not found
*/
public async hydrateFromAt(address: string): Promise<IContractWrapperBase> {
public async hydrateFromAt(address: string): Promise<IContractWrapper> {
try {
// Note that because we are using `.then`, we are returning a true promise
// rather than the incomplete one returned by truffle.
Expand All @@ -114,7 +115,7 @@ export abstract class ContractWrapperBase implements IContractWrapperBase {
* Initialize as it was migrated by Arc.js on the current network.
* @returns this or undefined if not found
*/
public async hydrateFromDeployed(): Promise<IContractWrapperBase> {
public async hydrateFromDeployed(): Promise<IContractWrapper> {
try {
// Note that because we are using `.then`, we are returning a true promise
// rather than the incomplete one returned by truffle.
Expand All @@ -128,16 +129,6 @@ export abstract class ContractWrapperBase implements IContractWrapperBase {
return this;
}

/**
* Call setParameters on this.contract.
* Returns promise of ArcTransactionDataResult<Hash> where Result is the parameters hash.
*
* @param {any} params -- parameters as the contract.setParameters function expects them.
*/
public setParameters(...params: Array<any>): Promise<ArcTransactionDataResult<Hash>> {
throw new Error("setParameters has not been not implemented by the contract wrapper");
}

/**
* Given a hash, returns the associated parameters as an object.
* @param paramsHash
Expand All @@ -146,16 +137,6 @@ export abstract class ContractWrapperBase implements IContractWrapperBase {
throw new Error("getParameters has not been not implemented by the contract wrapper");
}

/**
* Given an object containing the contract's parameters, return the hash
* that would be used to represent them in Arc. Note this doesn't indicate
* whether the parameters have been registered with the contract.
* @param params
*/
public getParametersHash(params: any): Promise<Hash> {
throw new Error("getParametersHash has not been not implemented by the contract wrapper");
}

/**
* Given an avatar address, returns the schemes parameters hash
* @param avatarAddress
Expand Down
16 changes: 8 additions & 8 deletions lib/contractWrapperFactory.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { Address } from "./commonTypes";
import { IConfigService } from "./iConfigService";
import { IContractWrapperBase, IContractWrapperFactory } from "./iContractWrapperBase";
import { IContractWrapper, IContractWrapperFactory } from "./iContractWrapperBase";
import { LoggingService } from "./loggingService";
import { Utils } from "./utils";
import { Web3EventService } from "./web3EventService";

/**
* Generic class factory for all of the contract wrapper classes.
*/
export class ContractWrapperFactory<TWrapper extends IContractWrapperBase>
export class ContractWrapperFactory<TWrapper extends IContractWrapper>
implements IContractWrapperFactory<TWrapper> {

public static setConfigService(configService: IConfigService): void {
ContractWrapperFactory.configService = configService;
}

/**
* this is a Map keyed by contract name of a Map keyed by address to an `IContractWrapperBase`
* this is a Map keyed by contract name of a Map keyed by address to an `IContractWrapper`
*/
private static contractCache: Map<string, Map<Address, IContractWrapperBase>>
= new Map<string, Map<Address, IContractWrapperBase>>();
private static contractCache: Map<string, Map<Address, IContractWrapper>>
= new Map<string, Map<Address, IContractWrapper>>();

private static configService: IConfigService;

Expand Down Expand Up @@ -117,7 +117,7 @@ export class ContractWrapperFactory<TWrapper extends IContractWrapperBase>
return hydratedWrapper;
}

private getCachedContract(name: string, at: string): IContractWrapperBase | undefined {
private getCachedContract(name: string, at: string): IContractWrapper | undefined {
if (!at) {
return undefined;
}
Expand All @@ -130,12 +130,12 @@ export class ContractWrapperFactory<TWrapper extends IContractWrapperBase>

private setCachedContract(
name: string,
wrapper: IContractWrapperBase): void {
wrapper: IContractWrapper): void {

if (wrapper) {
let addressMap = ContractWrapperFactory.contractCache.get(name);
if (!addressMap) {
addressMap = new Map<Address, IContractWrapperBase>();
addressMap = new Map<Address, IContractWrapper>();
ContractWrapperFactory.contractCache.set(name, addressMap);
}
addressMap.set(wrapper.address, wrapper);
Expand Down
6 changes: 3 additions & 3 deletions lib/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import BigNumber from "bignumber.js";
import { AvatarService } from "./avatarService";
import { Address, fnVoid, Hash } from "./commonTypes";
import { DecodedLogEntryEvent, IContractWrapperBase } from "./iContractWrapperBase";
import { DecodedLogEntryEvent, IContractWrapper } from "./iContractWrapperBase";
import { TransactionService, TxGeneratingFunctionOptions } from "./transactionService";
import { Utils } from "./utils";
import { EntityFetcherFactory, EventFetcherFilterObject, Web3EventService } from "./web3EventService";
Expand Down Expand Up @@ -403,7 +403,7 @@ export interface DaoSchemeInfo {
/**
* Wrapper class for the scheme if it was deployed by the running version of Arc.js
*/
wrapper?: IContractWrapperBase;
wrapper?: IContractWrapper;
}

/********************************
Expand All @@ -417,7 +417,7 @@ export interface DaoGlobalConstraintInfo {
/**
* Wrapper class for the constraint if it was deployed by the running version of Arc.js
*/
wrapper: IContractWrapperBase;
wrapper: IContractWrapper;
/**
* hash of the constraint parameters
*/
Expand Down
46 changes: 31 additions & 15 deletions lib/iContractWrapperBase.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,53 @@
import BigNumber from "bignumber.js";
import { Address, HasContract, Hash, SchemePermissions } from "./commonTypes";
import { Address, Hash, SchemePermissions } from "./commonTypes";
import {
TransactionReceiptTruffle,
TransactionService,
TxGeneratingFunctionOptions
TransactionService
} from "./transactionService";
import { IIntVoteInterface } from "./wrappers/iIntVoteInterface";

export interface IContractWrapperBase extends HasContract {
export interface IContractWrapper {
factory: IContractWrapperFactory<any>;
name: string;
friendlyName: string;
address: Address;
contract: any;
hydrateFromNew(...rest: Array<any>): Promise<any>;
hydrateFromAt(address: string): Promise<any>;
hydrateFromDeployed(): Promise<any>;
setParameters(...params: Array<any>): Promise<ArcTransactionDataResult<Hash>>;
}

/**
* The minimum requirements for a scheme that can be registered with a DAO/controller.
*/
export interface ISchemeWrapper extends IContractWrapper {
getSchemePermissions(avatarAddress: Address): Promise<SchemePermissions>;
getDefaultPermissions(): SchemePermissions;
}

/**
* The minimum requirements for a universal scheme.
*/
export interface IUniversalSchemeWrapper extends ISchemeWrapper {
getParameters(paramsHash: Hash): Promise<any>;
getSchemeParametersHash(avatarAddress: Address): Promise<Hash>;
getParametersHash(params: any): Promise<Hash>;
setParameters(params: any): Promise<ArcTransactionDataResult<Hash>>;
getSchemeParameters(avatarAddress: Address): Promise<any>;
getParametersArray(paramsHash: Hash): Promise<Array<any>>;
getController(avatarAddress: Address): Promise<any>;
}

export interface IContractWrapperFactory<TWrapper extends IContractWrapperBase> {
/**
* The minimum requirements for a voting machine wrapper.
*/
export interface IVotingMachineWrapper extends IContractWrapper {
getParameters(paramsHash: Hash): Promise<any>;
getParametersHash(params: any): Promise<Hash>;
setParameters(params: any): Promise<ArcTransactionDataResult<Hash>>;
getParametersArray(paramsHash: Hash): Promise<Array<any>>;
}

export interface IContractWrapperFactory<TWrapper extends IContractWrapper> {
new: (...rest: Array<any>) => Promise<TWrapper>;
at: (address: string) => Promise<TWrapper>;
deployed: () => Promise<TWrapper>;
Expand Down Expand Up @@ -179,14 +203,6 @@ export interface StandardSchemeParams {
votingMachineAddress: Address;
}

export interface SchemeWrapper {
getParameters(paramsHash: Hash): Promise<any>;
setParameters(params: any): Promise<ArcTransactionDataResult<Hash>>;
getSchemeParameters(avatarAddress: Address): Promise<any>;
getDefaultPermissions(): SchemePermissions;
getSchemePermissions(avatarAddress: Address): Promise<SchemePermissions>;
}

export { DecodedLogEntryEvent, TransactionReceipt } from "web3";

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class Utils {
}
/* tslint:disable-next-line:max-line-length */
LoggingService.debug(`Utils.getWeb3: instantiating web3 with configured provider at ${url}`);
// No web3 is injected, look for a provider at providerUrl:providerPort (which defaults to localhost)
// No web3 is injected, look for a provider at providerUrl:providerPort (which defaults to http://127.0.0.1)
// This happens when running tests, or in a browser that is not running MetaMask
preWeb3 = new webConstructor(new Web3Providers.HttpProvider(url));
}
Expand Down
40 changes: 17 additions & 23 deletions lib/wrapperService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { promisify } from "es6-promisify";
import { Address } from "./commonTypes";
import { IContractWrapperBase, IContractWrapperFactory } from "./iContractWrapperBase";
import { IContractWrapper, IContractWrapperFactory, IUniversalSchemeWrapper } from "./iContractWrapperBase";
import { LoggingService } from "./loggingService";
import { Utils } from "./utils";
import {
Expand Down Expand Up @@ -117,27 +117,27 @@ export interface ArcWrappersByType {
/**
* All wrapped contracts
*/
allWrappers: Array<IContractWrapperBase>;
allWrappers: Array<IContractWrapper>;
/**
* All wrapped schemes
* All wrapped non-universal schemes
*/
schemes: Array<IContractWrapperBase>;
nonUniversalSchemes: Array<IContractWrapper>;
/**
* All wrapped schemes that can generate proposals
* All wrapped universal schemes
*/
proposalGeneratingSchemes: Array<IContractWrapperBase>;
universalSchemes: Array<IUniversalSchemeWrapper>;
/**
* All wrapped voting machines
*/
votingMachines: Array<IContractWrapperBase>;
votingMachines: Array<IContractWrapper>;
/**
* All wrapped global constraints
*/
globalConstraints: Array<IContractWrapperBase>;
globalConstraints: Array<IContractWrapper>;
/**
* Other types of wrappers
*/
other: Array<IContractWrapperBase>;
other: Array<IContractWrapper>;
}

/**
Expand Down Expand Up @@ -168,7 +168,7 @@ export class WrapperService {
* Currently only returns the wrappers for contracts that were deployed by the running
* version of Arc.js.
*/
public static wrappersByAddress: Map<Address, IContractWrapperBase> = new Map<Address, IContractWrapperBase>();
public static wrappersByAddress: Map<Address, IContractWrapper> = new Map<Address, IContractWrapper>();

/**
* initialize() must be called before any of the static properties will have values.
Expand Down Expand Up @@ -202,24 +202,18 @@ export class WrapperService {
/**
* Contract wrappers grouped by type
*/
WrapperService.wrappersByType.allWrappers = Object.values(WrapperService.wrappers) as Array<IContractWrapperBase>;
WrapperService.wrappersByType.allWrappers = Object.values(WrapperService.wrappers) as Array<IContractWrapper>;
WrapperService.wrappersByType.globalConstraints = [
WrapperService.wrappers.TokenCapGC,
];
WrapperService.wrappersByType.other = [
WrapperService.wrappers.DaoCreator,
WrapperService.wrappers.Redeemer,
];
WrapperService.wrappersByType.schemes = [
WrapperService.wrappers.ContributionReward,
WrapperService.wrappers.GenesisProtocol,
WrapperService.wrappers.GlobalConstraintRegistrar,
WrapperService.wrappers.SchemeRegistrar,
WrapperService.wrappers.UpgradeScheme,
WrapperService.wrappers.VestingScheme,
WrapperService.wrappers.VoteInOrganizationScheme,
WrapperService.wrappersByType.nonUniversalSchemes = [
];
WrapperService.wrappersByType.proposalGeneratingSchemes = [

WrapperService.wrappersByType.universalSchemes = [
WrapperService.wrappers.ContributionReward,
WrapperService.wrappers.GlobalConstraintRegistrar,
WrapperService.wrappers.SchemeRegistrar,
Expand Down Expand Up @@ -282,15 +276,15 @@ export class WrapperService {
* @param address - optional
*/
public static async getContractWrapper(contractName: string, address?: string)
: Promise<IContractWrapperBase | undefined> {
: Promise<IContractWrapper | undefined> {
const factories = await WrapperService.factories;
const factory = factories[contractName];
if (!factory) {
return undefined;
}
if (address) {
return factory.at(address)
.then((resultingContract: IContractWrapperBase) => resultingContract, () => undefined);
.then((resultingContract: IContractWrapper) => resultingContract, () => undefined);
} else {
return Promise.resolve(WrapperService.wrappers[contractName]);
}
Expand Down Expand Up @@ -389,4 +383,4 @@ export const ContractWrappersByType: ArcWrappersByType = WrapperService.wrappers
/**
* for quicker access to the contract wrappers by address
*/
export const ContractWrappersByAddress: Map<Address, IContractWrapperBase> = WrapperService.wrappersByAddress;
export const ContractWrappersByAddress: Map<Address, IContractWrapper> = WrapperService.wrappersByAddress;
Loading

0 comments on commit db38d89

Please sign in to comment.