diff --git a/packages/abi/src.ts/interface.ts b/packages/abi/src.ts/interface.ts index d4a5c72bd8..05f79c7215 100644 --- a/packages/abi/src.ts/interface.ts +++ b/packages/abi/src.ts/interface.ts @@ -6,7 +6,7 @@ import { arrayify, BytesLike, concat, hexDataSlice, hexlify, hexZeroPad, isHexSt import { id } from "@ethersproject/hash"; import { keccak256 } from "@ethersproject/keccak256" import * as errors from "@ethersproject/errors"; -import { defineReadOnly, Description } from "@ethersproject/properties"; +import { defineReadOnly, Description, getStatic } from "@ethersproject/properties"; import { AbiCoder, defaultAbiCoder } from "./abi-coder"; import { ConstructorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments"; @@ -71,7 +71,7 @@ export class Interface { return Fragment.from(fragment); }).filter((fragment) => (fragment != null))); - defineReadOnly(this, "_abiCoder", new.target.getAbiCoder()); + defineReadOnly(this, "_abiCoder", getStatic<() => AbiCoder>(new.target, "getAbiCoder")()); defineReadOnly(this, "functions", { }); defineReadOnly(this, "errors", { }); diff --git a/packages/contracts/src.ts/index.ts b/packages/contracts/src.ts/index.ts index a7b40b5575..3b8eb43618 100644 --- a/packages/contracts/src.ts/index.ts +++ b/packages/contracts/src.ts/index.ts @@ -8,7 +8,7 @@ import { BigNumber, BigNumberish } from "@ethersproject/bignumber"; import { BytesLike, concat, hexlify, isBytes, isHexString } from "@ethersproject/bytes"; import { Zero } from "@ethersproject/constants"; import * as errors from "@ethersproject/errors"; -import { defineReadOnly, deepCopy, resolveProperties, shallowCopy } from "@ethersproject/properties"; +import { defineReadOnly, deepCopy, getStatic, resolveProperties, shallowCopy } from "@ethersproject/properties"; import { UnsignedTransaction } from "@ethersproject/transactions"; @@ -402,6 +402,8 @@ class WildcardRunningEvent extends RunningEvent { export type ContractInterface = string | Array | Interface; +type InterfaceFunc = (contractInterface: ContractInterface) => Interface; + export class Contract { readonly address: string; readonly interface: Interface; @@ -437,8 +439,8 @@ export class Contract { // @TODO: Maybe still check the addressOrName looks like a valid address or name? //address = getAddress(address); - - defineReadOnly(this, "interface", new.target.getInterface(contractInterface)); +console.log(getStatic(new.target, "getInterface")); + defineReadOnly(this, "interface", getStatic(new.target, "getInterface")(contractInterface)); if (Signer.isSigner(signerOrProvider)) { defineReadOnly(this, "provider", signerOrProvider.provider || null); @@ -850,7 +852,7 @@ export class ContractFactory { } defineReadOnly(this, "bytecode", bytecodeHex); - defineReadOnly(this, "interface", new.target.getInterface(contractInterface)); + defineReadOnly(this, "interface", getStatic(new.target, "getInterface")(contractInterface)); defineReadOnly(this, "signer", signer || null); } diff --git a/packages/properties/src.ts/index.ts b/packages/properties/src.ts/index.ts index 3f618a20d5..8466964d00 100644 --- a/packages/properties/src.ts/index.ts +++ b/packages/properties/src.ts/index.ts @@ -10,6 +10,16 @@ export function defineReadOnly(object: any, name: string, value: any): void { }); } +// Crawl up the constructor chain to find a static method +export function getStatic(ctor: any, key: string): T { + for (let i = 0; i < 32; i++) { + if (ctor[key]) { return ctor[key]; } + if (!ctor.prototype || typeof(ctor.prototype) !== "object") { break; } + ctor = Object.getPrototypeOf(ctor.prototype).constructor; + } + return null; +} + export function resolveProperties(object: any): Promise { let result: any = {};