No longer using instanceof which conflicts with npm link.

This commit is contained in:
Richard Moore 2018-07-25 21:15:43 -04:00
parent 7cf8596906
commit 00bb20546b
No known key found for this signature in database
GPG Key ID: 525F70A6FCABC295
9 changed files with 83 additions and 28 deletions

@ -236,16 +236,17 @@ export class Contract {
// @TODO: Maybe still check the addressOrName looks like a valid address or name? // @TODO: Maybe still check the addressOrName looks like a valid address or name?
//address = getAddress(address); //address = getAddress(address);
if (contractInterface instanceof Interface) {
if (Interface.isInterface(contractInterface)) {
defineReadOnly(this, 'interface', contractInterface); defineReadOnly(this, 'interface', contractInterface);
} else { } else {
defineReadOnly(this, 'interface', new Interface(contractInterface)); defineReadOnly(this, 'interface', new Interface(contractInterface));
} }
if (signerOrProvider instanceof Signer) { if (Signer.isSigner(signerOrProvider)) {
defineReadOnly(this, 'provider', signerOrProvider.provider); defineReadOnly(this, 'provider', signerOrProvider.provider);
defineReadOnly(this, 'signer', signerOrProvider); defineReadOnly(this, 'signer', signerOrProvider);
} else if (signerOrProvider instanceof MinimalProvider) { } else if (MinimalProvider.isProvider(signerOrProvider)) {
defineReadOnly(this, 'provider', signerOrProvider); defineReadOnly(this, 'provider', signerOrProvider);
defineReadOnly(this, 'signer', null); defineReadOnly(this, 'signer', null);
} else { } else {

@ -8,7 +8,7 @@ import { bigNumberify } from '../utils/bignumber';
import { arrayify, concat, hexlify, hexZeroPad, isHexString } from '../utils/bytes'; import { arrayify, concat, hexlify, hexZeroPad, isHexString } from '../utils/bytes';
import { id } from '../utils/hash'; import { id } from '../utils/hash';
import { keccak256 } from '../utils/keccak256'; import { keccak256 } from '../utils/keccak256';
import { defineReadOnly, defineFrozen } from '../utils/properties'; import { defineReadOnly, defineFrozen, isType, setType } from '../utils/properties';
import { import {
BigNumber, BigNumberish, BigNumber, BigNumberish,
@ -361,6 +361,8 @@ export class Interface {
if (!this.deployFunction) { if (!this.deployFunction) {
addMethod.call(this, {type: 'constructor', inputs: []}); addMethod.call(this, {type: 'constructor', inputs: []});
} }
setType(this, 'Interface');
} }
parseTransaction(tx: { data: string, value?: BigNumberish }): _TransactionDescription { parseTransaction(tx: { data: string, value?: BigNumberish }): _TransactionDescription {
@ -403,4 +405,8 @@ export class Interface {
return null; return null;
} }
static isInterface(value: any): value is Interface {
return isType(value, 'Interface');
}
} }

@ -176,7 +176,7 @@ class BigNumber extends _BigNumber {
} }
export function bigNumberify(value: BigNumberish): _BigNumber { export function bigNumberify(value: BigNumberish): _BigNumber {
if (value instanceof BigNumber) { return value; } if (BigNumber.isBigNumber(value)) { return value; }
return new BigNumber(value); return new BigNumber(value);
} }

@ -12,10 +12,6 @@ export const AddressZero = '0x0000000000000000000000000000000000000000';
export const HashZero = '0x0000000000000000000000000000000000000000000000000000000000000000'; export const HashZero = '0x0000000000000000000000000000000000000000000000000000000000000000';
function isBigNumber(value: any): value is BigNumber {
return (value instanceof BigNumber);
}
function addSlice(array: Uint8Array): Uint8Array { function addSlice(array: Uint8Array): Uint8Array {
if (array.slice) { return array; } if (array.slice) { return array; }
@ -47,7 +43,7 @@ export function arrayify(value: Arrayish | BigNumber): Uint8Array {
errors.throwError('cannot convert null value to array', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); errors.throwError('cannot convert null value to array', errors.INVALID_ARGUMENT, { arg: 'value', value: value });
} }
if (isBigNumber(value)) { if (BigNumber.isBigNumber(value)) {
value = value.toHexString(); value = value.toHexString();
} }
@ -142,7 +138,7 @@ const HexCharacters: string = '0123456789abcdef';
export function hexlify(value: Arrayish | BigNumber | number): string { export function hexlify(value: Arrayish | BigNumber | number): string {
if (isBigNumber(value)) { if (BigNumber.isBigNumber(value)) {
return value.toHexString(); return value.toHexString();
} }

@ -16,6 +16,17 @@ export function defineFrozen(object: any, name: string, value: any): void {
}); });
} }
// There are some issues with instanceof with npm link, so we use this
// to ensure types are what we expect.
export function setType(object: any, type: string): void {
Object.defineProperty(object, '_ethersType', { configurable: false, value: type, writable: false });
}
export function isType(object: any, type: string): boolean {
return (object._ethersType === type);
}
export function resolveProperties(object: any): Promise<any> { export function resolveProperties(object: any): Promise<any> {
let result: any = {}; let result: any = {};

@ -5,6 +5,13 @@
export type Arrayish = string | ArrayLike<number>; export type Arrayish = string | ArrayLike<number>;
function setType(object: any, type: string): void {
Object.defineProperty(object, '_ethersType', { configurable: false, value: type, writable: false });
}
function isType(object: any, type: string): boolean {
return (object._ethersType === type);
}
/////////////////////////////// ///////////////////////////////
// BigNumber // BigNumber
@ -28,6 +35,14 @@ export abstract class BigNumber {
abstract toNumber(): number; abstract toNumber(): number;
abstract toString(): string; abstract toString(): string;
abstract toHexString(): string; abstract toHexString(): string;
constructor() {
setType(this, 'BigNumber');
}
static isBigNumber(value: any): value is BigNumber {
return isType(value, 'BigNumber');
}
}; };
export type BigNumberish = BigNumber | string | number | Arrayish; export type BigNumberish = BigNumber | string | number | Arrayish;
@ -254,6 +269,14 @@ export interface TransactionResponse extends Transaction {
export abstract class Indexed { export abstract class Indexed {
readonly hash: string; readonly hash: string;
constructor() {
setType(this, 'Indexed');
}
static isIndexed(value: any): value is Indexed {
return isType(value, 'Indexed');
}
} }
export interface DeployDescription { export interface DeployDescription {
@ -335,12 +358,6 @@ export type EventType = string | Array<string> | Filter;
export type Listener = (...args: Array<any>) => void; export type Listener = (...args: Array<any>) => void;
/**
* Provider
*
* Note: We use an abstract class so we can use instanceof to determine if an
* object is a Provider.
*/
export abstract class MinimalProvider implements OnceBlockable { export abstract class MinimalProvider implements OnceBlockable {
abstract getNetwork(): Promise<Network>; abstract getNetwork(): Promise<Network>;
@ -374,6 +391,14 @@ export abstract class MinimalProvider implements OnceBlockable {
// @TODO: This *could* be implemented here, but would pull in events... // @TODO: This *could* be implemented here, but would pull in events...
abstract waitForTransaction(transactionHash: string, timeout?: number): Promise<TransactionReceipt>; abstract waitForTransaction(transactionHash: string, timeout?: number): Promise<TransactionReceipt>;
constructor() {
setType(this, 'Provider');
}
static isProvider(value: any): value is MinimalProvider {
return isType(value, 'Provider');
}
} }
export type AsyncProvider = { export type AsyncProvider = {
@ -403,12 +428,6 @@ export type EncryptOptions = {
} }
} }
/**
* Signer
*
* Note: We use an abstract class so we can use instanceof to determine if an
* object is a Signer.
*/
export abstract class Signer { export abstract class Signer {
provider?: MinimalProvider; provider?: MinimalProvider;
@ -416,6 +435,14 @@ export abstract class Signer {
abstract signMessage(message: Arrayish | string): Promise<string>; abstract signMessage(message: Arrayish | string): Promise<string>;
abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>; abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
constructor() {
setType(this, 'Signer');
}
static isSigner(value: any): value is Signer {
return isType(value, 'Signer');
}
} }
/////////////////////////////// ///////////////////////////////
@ -434,6 +461,14 @@ export abstract class HDNode {
readonly depth: number; readonly depth: number;
abstract derivePath(path: string): HDNode; abstract derivePath(path: string): HDNode;
constructor() {
setType(this, 'HDNode');
}
static isHDNode(value: any): value is HDNode {
return isType(value, 'HDNode');
}
} }
/////////////////////////////// ///////////////////////////////

@ -276,7 +276,7 @@ export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish |
// Check the private key // Check the private key
let privateKeyBytes: Uint8Array = null; let privateKeyBytes: Uint8Array = null;
if (privateKey instanceof SigningKey) { if (SigningKey.isSigningKey(privateKey)) {
privateKeyBytes = arrayify(privateKey.privateKey); privateKeyBytes = arrayify(privateKey.privateKey);
} else { } else {
privateKeyBytes = arrayify(privateKey); privateKeyBytes = arrayify(privateKey);

@ -7,7 +7,7 @@
*/ */
import { arrayify, hexlify } from '../utils/bytes'; import { arrayify, hexlify } from '../utils/bytes';
import { defineReadOnly } from '../utils/properties'; import { defineReadOnly, isType, setType } from '../utils/properties';
import { computeAddress, KeyPair } from '../utils/secp256k1'; import { computeAddress, KeyPair } from '../utils/secp256k1';
import { Arrayish, HDNode, Signature } from '../utils/types'; import { Arrayish, HDNode, Signature } from '../utils/types';
@ -30,7 +30,7 @@ export class SigningKey {
let privateKeyBytes = null; let privateKeyBytes = null;
if (privateKey instanceof HDNode) { if (HDNode.isHDNode(privateKey)) {
defineReadOnly(this, 'mnemonic', privateKey.mnemonic); defineReadOnly(this, 'mnemonic', privateKey.mnemonic);
defineReadOnly(this, 'path', privateKey.path); defineReadOnly(this, 'path', privateKey.path);
privateKeyBytes = arrayify(privateKey.privateKey); privateKeyBytes = arrayify(privateKey.privateKey);
@ -61,9 +61,15 @@ export class SigningKey {
defineReadOnly(this, 'keyPair', new KeyPair(privateKeyBytes)); defineReadOnly(this, 'keyPair', new KeyPair(privateKeyBytes));
defineReadOnly(this, 'publicKey', this.keyPair.publicKey); defineReadOnly(this, 'publicKey', this.keyPair.publicKey);
defineReadOnly(this, 'address', computeAddress(this.keyPair.publicKey)); defineReadOnly(this, 'address', computeAddress(this.keyPair.publicKey));
setType(this, 'SigningKey');
} }
signDigest(digest: Arrayish): Signature { signDigest(digest: Arrayish): Signature {
return this.keyPair.sign(digest); return this.keyPair.sign(digest);
} }
static isSigningKey(value: any): value is SigningKey {
return isType(value, 'SigningKey');
}
} }

@ -28,7 +28,7 @@ export class Wallet extends Signer {
errors.checkNew(this, Wallet); errors.checkNew(this, Wallet);
// Make sure we have a valid signing key // Make sure we have a valid signing key
if (privateKey instanceof SigningKey) { if (SigningKey.isSigningKey(privateKey)) {
defineReadOnly(this, 'signingKey', privateKey); defineReadOnly(this, 'signingKey', privateKey);
} else { } else {
defineReadOnly(this, 'signingKey', new SigningKey(privateKey)); defineReadOnly(this, 'signingKey', new SigningKey(privateKey));
@ -49,7 +49,7 @@ export class Wallet extends Signer {
* Create a new instance of this Wallet connected to provider. * Create a new instance of this Wallet connected to provider.
*/ */
connect(provider: MinimalProvider): Wallet { connect(provider: MinimalProvider): Wallet {
if (!(provider instanceof MinimalProvider)) { if (!(MinimalProvider.isProvider(provider))) {
errors.throwError('invalid provider', errors.INVALID_ARGUMENT, { argument: 'provider', value: provider }); errors.throwError('invalid provider', errors.INVALID_ARGUMENT, { argument: 'provider', value: provider });
} }
return new Wallet(this.signingKey, provider); return new Wallet(this.signingKey, provider);