Deprecating errors for logger.

This commit is contained in:
Richard Moore 2019-08-01 18:04:06 -04:00
parent e8f28b55d7
commit 0b224e8fb5
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651
68 changed files with 727 additions and 342 deletions

@ -11,9 +11,9 @@
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/constants": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/hash": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0"
},

@ -3,9 +3,12 @@
// See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
import { arrayify, BytesLike } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { Coder, Reader, Writer } from "./coders/abstract-coder";
import { AddressCoder } from "./coders/address";
import { ArrayCoder } from "./coders/array";
@ -30,7 +33,7 @@ export class AbiCoder {
readonly coerceFunc: CoerceFunc;
constructor(coerceFunc?: CoerceFunc) {
errors.checkNew(new.target, AbiCoder);
logger.checkNew(new.target, AbiCoder);
defineReadOnly(this, "coerceFunc", coerceFunc || null);
}
@ -60,10 +63,7 @@ export class AbiCoder {
if (match) {
let size = parseInt(match[2] || "256");
if (size === 0 || size > 256 || (size % 8) !== 0) {
errors.throwError("invalid " + match[1] + " bit length", errors.INVALID_ARGUMENT, {
arg: "param",
value: param
});
logger.throwArgumentError("invalid " + match[1] + " bit length", "param", param);
}
return new NumberCoder(size / 8, (match[1] === "int"), param.name);
}
@ -73,18 +73,12 @@ export class AbiCoder {
if (match) {
let size = parseInt(match[1]);
if (size === 0 || size > 32) {
errors.throwError("invalid bytes length", errors.INVALID_ARGUMENT, {
arg: "param",
value: param
});
logger.throwArgumentError("invalid bytes length", "param", param);
}
return new FixedBytesCoder(size, param.name);
}
return errors.throwError("invalid type", errors.INVALID_ARGUMENT, {
arg: "type",
value: param.type
});
return logger.throwError("invalid type", "type", param.type);
}
_getWordSize(): number { return 32; }
@ -99,7 +93,7 @@ export class AbiCoder {
encode(types: Array<string | ParamType>, values: Array<any>): string {
if (types.length !== values.length) {
errors.throwError("types/values length mismatch", errors.INVALID_ARGUMENT, {
logger.throwError("types/values length mismatch", Logger.errors.INVALID_ARGUMENT, {
count: { types: types.length, values: values.length },
value: { types: types, values: values }
});

@ -2,9 +2,12 @@
import { arrayify, BytesLike, concat, hexlify } from "@ethersproject/bytes";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "../_version";
const logger = new Logger(version);
export type CoerceFunc = (type: string, value: any) => any;
export abstract class Coder {
@ -34,11 +37,7 @@ export abstract class Coder {
}
_throwError(message: string, value: any): void {
errors.throwError(message, errors.INVALID_ARGUMENT, {
argument: this.localName,
coder: this,
value: value
});
logger.throwArgumentError(message, this.localName, value);
}
abstract encode(writer: Writer, value: any): number;
@ -77,7 +76,7 @@ export class Writer {
_getValue(value: BigNumberish): Uint8Array {
let bytes = arrayify(BigNumber.from(value));
if (bytes.length > this.wordSize) {
errors.throwError("value out-of-bounds", errors.BUFFER_OVERRUN, {
logger.throwError("value out-of-bounds", Logger.errors.BUFFER_OVERRUN, {
length: this.wordSize,
offset: bytes.length
});
@ -136,7 +135,7 @@ export class Reader {
_peekBytes(offset: number, length: number): Uint8Array {
let alignedLength = Math.ceil(length / this.wordSize) * this.wordSize;
if (this._offset + alignedLength > this._data.length) {
errors.throwError("data out-of-bounds", errors.BUFFER_OVERRUN, {
logger.throwError("data out-of-bounds", Logger.errors.BUFFER_OVERRUN, {
length: this._data.length,
offset: this._offset + alignedLength
});

@ -1,6 +1,8 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "../_version";
const logger = new Logger(version);
import { Coder, Reader, Writer } from "./abstract-coder";
import { AnonymousCoder } from "./anonymous";
@ -18,17 +20,11 @@ export function pack(writer: Writer, coders: Array<Coder>, values: Array<any>):
values = arrayValues;
} else {
errors.throwError("invalid tuple value", errors.INVALID_ARGUMENT, {
coderType: "tuple",
value: values
});
logger.throwArgumentError("invalid tuple value", "tuple", values);
}
if (coders.length !== values.length) {
errors.throwError("types/value length mismatch", errors.INVALID_ARGUMENT, {
coderType: "tuple",
value: values
});
logger.throwArgumentError("types/value length mismatch", "tuple", values);
}
let staticWriter = new Writer(writer.wordSize);
@ -136,7 +132,7 @@ export class ArrayCoder extends Coder {
writer.writeValue(value.length);
}
errors.checkArgumentCount(count, value.length, " in coder array" + (this.localName? (" "+ this.localName): ""));
logger.checkArgumentCount(count, value.length, "coder array" + (this.localName? (" "+ this.localName): ""));
let coders = [];
for (let i = 0; i < value.length; i++) { coders.push(this.coder); }

@ -1,9 +1,11 @@
"use strict";
import { BigNumber } from "@ethersproject/bignumber";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export interface JsonFragmentType {
name?: string;
@ -58,7 +60,7 @@ function checkModifier(type: string, name: string): boolean {
if (name === "payable") { return true; }
}
if (ModifiersBytes[name] || name === "payable") {
errors.throwArgumentError("invalid modifier", "name", name);
logger.throwArgumentError("invalid modifier", "name", name);
}
return false;
}
@ -299,7 +301,7 @@ export class ParamType {
format(format?: string): string {
if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format);
logger.throwArgumentError("invalid format type", "format", format);
}
if (format === FormatTypes.json) {
@ -426,7 +428,7 @@ export abstract class Fragment {
return null;
}
return errors.throwArgumentError("invalid fragment object", "value", value);
return logger.throwArgumentError("invalid fragment object", "value", value);
}
static fromString(value: string): Fragment {
@ -457,7 +459,7 @@ export class EventFragment extends Fragment {
format(format?: string): string {
if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format);
logger.throwArgumentError("invalid format type", "format", format);
}
if (format === FormatTypes.json) {
@ -522,7 +524,7 @@ export class EventFragment extends Fragment {
case "":
break;
default:
errors.warn("unknown modifier: " + modifier);
logger.warn("unknown modifier: " + modifier);
}
});
@ -638,7 +640,7 @@ export class ConstructorFragment extends Fragment {
format(format?: string): string {
if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format);
logger.throwArgumentError("invalid format type", "format", format);
}
if (format === FormatTypes.json) {
@ -652,7 +654,7 @@ export class ConstructorFragment extends Fragment {
}
if (format === FormatTypes.sighash) {
errors.throwError("cannot format a constructor for sighash", errors.UNSUPPORTED_OPERATION, {
logger.throwError("cannot format a constructor for sighash", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "format(sighash)"
});
}
@ -722,7 +724,7 @@ export class FunctionFragment extends ConstructorFragment {
format(format?: string): string {
if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format);
logger.throwArgumentError("invalid format type", "format", format);
}
if (format === FormatTypes.json) {

@ -5,12 +5,14 @@ import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { arrayify, BytesLike, concat, hexDataSlice, hexlify, hexZeroPad, isHexString } from "@ethersproject/bytes";
import { id } from "@ethersproject/hash";
import { keccak256 } from "@ethersproject/keccak256"
import * as errors from "@ethersproject/errors";
import { defineReadOnly, Description, getStatic } from "@ethersproject/properties";
import { AbiCoder, defaultAbiCoder } from "./abi-coder";
import { ConstructorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export class LogDescription extends Description {
readonly eventFragment: EventFragment;
@ -58,7 +60,7 @@ export class Interface {
static _isInterface: boolean;
constructor(fragments: string | Array<Fragment | JsonFragment | string>) {
errors.checkNew(new.target, Interface);
logger.checkNew(new.target, Interface);
let abi: Array<Fragment | JsonFragment | string> = [ ];
if (typeof(fragments) === "string") {
@ -84,7 +86,7 @@ export class Interface {
switch (fragment.type) {
case "constructor":
if (this.deploy) {
errors.warn("duplicate definition - constructor");
logger.warn("duplicate definition - constructor");
return;
}
defineReadOnly(this, "deploy", fragment);
@ -101,7 +103,7 @@ export class Interface {
let signature = fragment.format();
if (bucket[signature]) {
errors.warn("duplicate definition - " + signature);
logger.warn("duplicate definition - " + signature);
return;
}
@ -114,7 +116,7 @@ export class Interface {
Object.keys(bucket).forEach((signature) => {
let fragment = bucket[signature];
if (count[fragment.name] !== 1) {
errors.warn("duplicate definition - " + fragment.name);
logger.warn("duplicate definition - " + fragment.name);
return;
}
bucket[fragment.name] = fragment;
@ -233,7 +235,7 @@ export class Interface {
break;
}
return errors.throwError("call revert exception", errors.CALL_EXCEPTION, {
return logger.throwError("call revert exception", Logger.errors.CALL_EXCEPTION, {
method: functionFragment.format(),
errorSignature: errorSignature,
errorArgs: [ reason ],
@ -247,7 +249,7 @@ export class Interface {
}
if (values.length > eventFragment.inputs.length) {
errors.throwError("too many arguments for " + eventFragment.format(), errors.UNEXPECTED_ARGUMENT, {
logger.throwError("too many arguments for " + eventFragment.format(), Logger.errors.UNEXPECTED_ARGUMENT, {
argument: "values",
value: values
})
@ -262,7 +264,7 @@ export class Interface {
if (!param.indexed) {
if (value != null) {
errors.throwArgumentError("cannot filter non-indexed parameters; must be null", ("contract." + param.name), value);
logger.throwArgumentError("cannot filter non-indexed parameters; must be null", ("contract." + param.name), value);
}
return;
}
@ -274,7 +276,7 @@ export class Interface {
} else if (param.type === "bytes") {
topics.push(keccak256(hexlify(value)));
} else if (param.type.indexOf("[") !== -1 || param.type.substring(0, 5) === "tuple") {
errors.throwArgumentError("filtering with tuples or arrays not supported", ("contract." + param.name), value);
logger.throwArgumentError("filtering with tuples or arrays not supported", ("contract." + param.name), value);
} else {
// Check addresses are valid
if (param.type === "address") { this._abiCoder.encode( [ "address" ], [ value ]); }
@ -298,7 +300,7 @@ export class Interface {
if (topics != null && !eventFragment.anonymous) {
let topicHash = this.getEventTopic(eventFragment);
if (!isHexString(topics[0], 32) || topics[0].toLowerCase() !== topicHash) {
errors.throwError("fragment/topic mismatch", errors.INVALID_ARGUMENT, { argument: "topics[0]", expected: topicHash, value: topics[0] });
logger.throwError("fragment/topic mismatch", Logger.errors.INVALID_ARGUMENT, { argument: "topics[0]", expected: topicHash, value: topics[0] });
}
topics = topics.slice(1);
}

@ -13,7 +13,7 @@
"dependencies": {
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/networks": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/transactions": ">5.0.0-beta.0",

@ -2,13 +2,15 @@
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { BytesLike, isHexString } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { checkAbstract } from "@ethersproject/errors";
import { Network } from "@ethersproject/networks";
import { Description, defineReadOnly } from "@ethersproject/properties";
import { Transaction } from "@ethersproject/transactions";
import { OnceBlockable } from "@ethersproject/web";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
///////////////////////////////
// Exported Types
@ -143,7 +145,7 @@ export class BlockForkEvent extends ForkEvent {
constructor(blockhash: string, expiry?: number) {
if (!isHexString(blockhash, 32)) {
errors.throwArgumentError("invalid blockhash", "blockhash", blockhash);
logger.throwArgumentError("invalid blockhash", "blockhash", blockhash);
}
super({
@ -160,7 +162,7 @@ export class TransactionForkEvent extends ForkEvent {
constructor(hash: string, expiry?: number) {
if (!isHexString(hash, 32)) {
errors.throwArgumentError("invalid transaction hash", "hash", hash);
logger.throwArgumentError("invalid transaction hash", "hash", hash);
}
super({
@ -178,10 +180,10 @@ export class TransactionOrderForkEvent extends ForkEvent {
constructor(beforeHash: string, afterHash: string, expiry?: number) {
if (!isHexString(beforeHash, 32)) {
errors.throwArgumentError("invalid transaction hash", "beforeHash", beforeHash);
logger.throwArgumentError("invalid transaction hash", "beforeHash", beforeHash);
}
if (!isHexString(afterHash, 32)) {
errors.throwArgumentError("invalid transaction hash", "afterHash", afterHash);
logger.throwArgumentError("invalid transaction hash", "afterHash", afterHash);
}
super({

@ -10,7 +10,7 @@
"@ethersproject/abstract-provider": ">5.0.0-beta.0",
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0"
},
"keywords": [

@ -3,9 +3,12 @@
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
import { BigNumber } from "@ethersproject/bignumber";
import { Bytes } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { defineReadOnly, resolveProperties, shallowCopy } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
const allowedTransactionKeys: Array<string> = [
"chainId", "data", "from", "gasLimit", "gasPrice", "nonce", "to", "value"
];
@ -57,7 +60,7 @@ export abstract class Signer {
///////////////////
// Sub-classes MUST call super
constructor() {
errors.checkAbstract(new.target, Signer);
logger.checkAbstract(new.target, Signer);
defineReadOnly(this, "_isSigner", true);
}
@ -131,7 +134,7 @@ export abstract class Signer {
checkTransaction(transaction: TransactionRequest): TransactionRequest {
for (let key in transaction) {
if (allowedTransactionKeys.indexOf(key) === -1) {
errors.throwArgumentError("invalid transaction key: " + key, "transaction", transaction);
logger.throwArgumentError("invalid transaction key: " + key, "transaction", transaction);
}
}
@ -160,7 +163,7 @@ export abstract class Signer {
this.provider.resolveName(tx.from)
]).then((results) => {
if (results[0] !== results[1]) {
errors.throwArgumentError("from address mismatch", "transaction", transaction);
logger.throwArgumentError("from address mismatch", "transaction", transaction);
}
return results[0];
});
@ -178,7 +181,7 @@ export abstract class Signer {
// Sub-classes SHOULD leave these alone
_checkProvider(operation?: string): void {
if (!this.provider) { errors.throwError("missing provider", errors.UNSUPPORTED_OPERATION, {
if (!this.provider) { logger.throwError("missing provider", Logger.errors.UNSUPPORTED_OPERATION, {
operation: (operation || "_checkProvider") });
}
}
@ -192,7 +195,7 @@ export class VoidSigner extends Signer {
readonly address: string;
constructor(address: string, provider?: Provider) {
errors.checkNew(new.target, VoidSigner);
logger.checkNew(new.target, VoidSigner);
super();
defineReadOnly(this, "address", address);
defineReadOnly(this, "provider", provider || null);
@ -204,7 +207,7 @@ export class VoidSigner extends Signer {
_fail(message: string, operation: string): Promise<any> {
return Promise.resolve().then(() => {
errors.throwError(message, errors.UNSUPPORTED_OPERATION, { operation: operation });
logger.throwError(message, Logger.errors.UNSUPPORTED_OPERATION, { operation: operation });
});
}

@ -9,8 +9,8 @@
"dependencies": {
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/rlp": ">5.0.0-beta.0",
"bn.js": "^4.4.0"
},

@ -3,17 +3,18 @@
// We use this for base 36 maths
import * as BN from "bn.js";
import * as errors from "@ethersproject/errors";
import { arrayify, hexDataSlice, isHexString, stripZeros } from "@ethersproject/bytes";
import { BigNumberish } from "@ethersproject/bignumber";
import { keccak256 } from "@ethersproject/keccak256";
import { encode } from "@ethersproject/rlp";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
function getChecksumAddress(address: string): string {
if (!isHexString(address, 20)) {
errors.throwError("invalid address", errors.INVALID_ARGUMENT, { arg: "address", value: address });
logger.throwArgumentError("invalid address", "address", address);
}
address = address.toLowerCase();
@ -82,7 +83,7 @@ export function getAddress(address: string): string {
let result = null;
if (typeof(address) !== "string") {
errors.throwArgumentError("invalid address", "address", address);
logger.throwArgumentError("invalid address", "address", address);
}
if (address.match(/^(0x)?[0-9a-fA-F]{40}$/)) {
@ -94,7 +95,7 @@ export function getAddress(address: string): string {
// It is a checksummed address with a bad checksum
if (address.match(/([A-F].*[a-f])|([a-f].*[A-F])/) && result !== address) {
errors.throwArgumentError("bad address checksum", "address", address);
logger.throwArgumentError("bad address checksum", "address", address);
}
// Maybe ICAP? (we only support direct mode)
@ -102,7 +103,7 @@ export function getAddress(address: string): string {
// It is an ICAP address with a bad checksum
if (address.substring(2, 4) !== ibanChecksum(address)) {
errors.throwArgumentError("bad icap checksum", "address", address);
logger.throwArgumentError("bad icap checksum", "address", address);
}
result = (new BN.BN(address.substring(4), 36)).toString(16);
@ -110,7 +111,7 @@ export function getAddress(address: string): string {
result = getChecksumAddress("0x" + result);
} else {
errors.throwArgumentError("invalid address", "address", address);
logger.throwArgumentError("invalid address", "address", address);
}
return result;
@ -136,7 +137,7 @@ export function getContractAddress(transaction: { from: string, nonce: BigNumber
try {
from = getAddress(transaction.from);
} catch (error) {
errors.throwArgumentError("missing from address", "transaction", transaction);
logger.throwArgumentError("missing from address", "transaction", transaction);
}
let nonce = stripZeros(arrayify(transaction.nonce));

@ -8,7 +8,7 @@
},
"dependencies": {
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"bn.js": "^4.4.0"
},

@ -12,7 +12,9 @@ import * as BN from "bn.js";
import { Bytes, Hexable, hexlify, isBytes, isHexString } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
const _constructorGuard = { };
@ -37,10 +39,10 @@ export class BigNumber implements Hexable {
readonly _isBigNumber: boolean;
constructor(constructorGuard: any, hex: string) {
errors.checkNew(new.target, BigNumber);
logger.checkNew(new.target, BigNumber);
if (constructorGuard !== _constructorGuard) {
errors.throwError("cannot call consturtor directly; use BigNumber.from", errors.UNSUPPORTED_OPERATION, {
logger.throwError("cannot call consturtor directly; use BigNumber.from", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "new (BigNumber)"
});
}
@ -134,7 +136,7 @@ export class BigNumber implements Hexable {
toString(): string {
// Lots of people expect this, which we do not support, so check
if (arguments.length !== 0) {
errors.throwError("bigNumber.toString does not accept parameters", errors.UNEXPECTED_ARGUMENT, { });
logger.throwError("bigNumber.toString does not accept parameters", Logger.errors.UNEXPECTED_ARGUMENT, { });
}
return toBN(this).toString(10);
}
@ -155,7 +157,7 @@ export class BigNumber implements Hexable {
return new BigNumber(_constructorGuard, toHex(new BN.BN(value)));
}
return errors.throwArgumentError("invalid BigNumber string", "value", value);
return logger.throwArgumentError("invalid BigNumber string", "value", value);
}
if (typeof(value) === "number") {
@ -189,7 +191,7 @@ export class BigNumber implements Hexable {
}
}
return errors.throwArgumentError("invalid BigNumber value", "value", value);
return logger.throwArgumentError("invalid BigNumber value", "value", value);
}
static isBigNumber(value: any): value is BigNumber {
@ -211,7 +213,7 @@ function toHex(value: string | BN.BN): string {
value = value.substring(1);
// Cannot have mulitple negative signs (e.g. "--0x04")
if (value[0] === "-") { errors.throwArgumentError("invalid hex", "value", value); }
if (value[0] === "-") { logger.throwArgumentError("invalid hex", "value", value); }
// Call toHex on the positive component
value = toHex(value);
@ -256,5 +258,5 @@ function throwFault(fault: string, operation: string, value?: any): never {
let params: any = { fault: fault, operation: operation };
if (value != null) { params.value = value; }
return errors.throwError(fault, errors.NUMERIC_FAULT, params);
return logger.throwError(fault, Logger.errors.NUMERIC_FAULT, params);
}

@ -1,7 +1,10 @@
"use strict";
import { arrayify, BytesLike, hexZeroPad, isBytes } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { BigNumber, BigNumberish, isBigNumberish } from "./bignumber";
@ -13,7 +16,7 @@ const NegativeOne = BigNumber.from(-1);
function throwFault(message: string, fault: string, operation: string, value?: any): never {
let params: any = { fault: fault, operation: operation };
if (value !== undefined) { params.value = value; }
return errors.throwError(message, errors.NUMERIC_FAULT, params);
return logger.throwError(message, Logger.errors.NUMERIC_FAULT, params);
}
// Constant to pull zeros from for multipliers
@ -33,7 +36,7 @@ function getMultiplier(decimals: BigNumberish): string {
return ("1" + zeros.substring(0, decimals));
}
return errors.throwArgumentError("invalid decimal size", "decimals", decimals);
return logger.throwArgumentError("invalid decimal size", "decimals", decimals);
}
export function formatFixed(value: BigNumberish, decimals?: string | BigNumberish): string {
@ -66,7 +69,7 @@ export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
let multiplier = getMultiplier(decimals);
if (typeof(value) !== "string" || !value.match(/^-?[0-9.,]+$/)) {
errors.throwArgumentError("invalid decimal value", "value", value);
logger.throwArgumentError("invalid decimal value", "value", value);
}
if (multiplier.length - 1 === 0) {
@ -78,13 +81,13 @@ export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
if (negative) { value = value.substring(1); }
if (value === ".") {
errors.throwArgumentError("missing value", "value", value);
logger.throwArgumentError("missing value", "value", value);
}
// Split it into a whole and fractional part
let comps = value.split(".");
if (comps.length > 2) {
errors.throwArgumentError("too many decimal points", "value", value);
logger.throwArgumentError("too many decimal points", "value", value);
}
let whole = comps[0], fraction = comps[1];
@ -142,7 +145,7 @@ export class FixedFormat {
signed = false;
} else if (value != null) {
let match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);
if (!match) { errors.throwArgumentError("invalid fixed format", "format", value); }
if (!match) { logger.throwArgumentError("invalid fixed format", "format", value); }
signed = (match[1] !== "u");
width = parseInt(match[2]);
decimals = parseInt(match[3]);
@ -151,7 +154,7 @@ export class FixedFormat {
let check = (key: string, type: string, defaultValue: any): any => {
if (value[key] == null) { return defaultValue; }
if (typeof(value[key]) !== type) {
errors.throwArgumentError("invalid fixed format (" + key + " not " + type +")", "format." + key, value[key]);
logger.throwArgumentError("invalid fixed format (" + key + " not " + type +")", "format." + key, value[key]);
}
return value[key];
}
@ -161,11 +164,11 @@ export class FixedFormat {
}
if (width % 8) {
errors.throwArgumentError("invalid fixed format width (not byte aligned)", "format.width", width);
logger.throwArgumentError("invalid fixed format width (not byte aligned)", "format.width", width);
}
if (decimals > 80) {
errors.throwArgumentError("invalid fixed format (decimals too large)", "format.decimals", decimals);
logger.throwArgumentError("invalid fixed format (decimals too large)", "format.decimals", decimals);
}
return new FixedFormat(_constructorGuard, signed, width, decimals);
@ -180,7 +183,7 @@ export class FixedNumber {
readonly _isFixedNumber: boolean;
constructor(constructorGuard: any, hex: string, value: string, format?: FixedFormat) {
errors.checkNew(new.target, FixedNumber);
logger.checkNew(new.target, FixedNumber);
this.format = format;
this._hex = hex;
@ -193,7 +196,7 @@ export class FixedNumber {
_checkFormat(other: FixedNumber): void {
if (this.format.name !== other.format.name) {
errors.throwArgumentError("incompatible format; use fixedNumber.toFormat", "other", other);
logger.throwArgumentError("incompatible format; use fixedNumber.toFormat", "other", other);
}
}
@ -229,7 +232,7 @@ export class FixedNumber {
round(decimals?: number): FixedNumber {
if (decimals == null) { decimals = 0; }
if (decimals < 0 || decimals > 80 || (decimals % 1)) {
errors.throwArgumentError("invalid decimal cound", "decimals", decimals);
logger.throwArgumentError("invalid decimal cound", "decimals", decimals);
}
// If we are already in range, we're done
@ -249,7 +252,7 @@ export class FixedNumber {
toHexString(width?: number): string {
if (width == null) { return this._hex; }
if (width % 8) { errors.throwArgumentError("invalid byte width", "width", width); }
if (width % 8) { logger.throwArgumentError("invalid byte width", "width", width); }
let hex = BigNumber.from(this._hex).fromTwos(this.format.width).toTwos(width).toHexString();
return hexZeroPad(hex, width / 8);
}
@ -330,12 +333,12 @@ export class FixedNumber {
return FixedNumber.fromValue(value, 0, format);
} catch (error) {
// Allow NUMERIC_FAULT to bubble up
if (error.code !== errors.INVALID_ARGUMENT) {
if (error.code !== Logger.errors.INVALID_ARGUMENT) {
throw error;
}
}
return errors.throwArgumentError("invalid FixedNumber value", "value", value);
return logger.throwArgumentError("invalid FixedNumber value", "value", value);
}
static isFixedNumber(value: any): value is FixedNumber {

@ -9,7 +9,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@ethersproject/errors": ">5.0.0-beta.0"
"@ethersproject/logger": ">5.0.0-beta.0"
},
"keywords": [
"Ethereum",

@ -1,8 +1,8 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
///////////////////////////////
// Exported Types
@ -92,7 +92,7 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
if (!options) { options = { }; }
if (typeof(value) === "number") {
errors.checkSafeUint53(value, "invalid arrayify value");
logger.checkSafeUint53(value, "invalid arrayify value");
let result = [];
while (value) {
@ -113,7 +113,7 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
if (isHexString(value)) {
let hex = (<string>value).substring(2);
if (!options.allowOddLength && hex.length % 2) {
errors.throwArgumentError("hex data is odd-length", "value", value);
logger.throwArgumentError("hex data is odd-length", "value", value);
}
let result = [];
@ -128,7 +128,7 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
return addSlice(new Uint8Array(value));
}
return errors.throwArgumentError("invalid arrayify value", "value", value);
return logger.throwArgumentError("invalid arrayify value", "value", value);
}
export function concat(items: Array<BytesLike>): Uint8Array {
@ -166,7 +166,7 @@ export function zeroPad(value: BytesLike, length: number): Uint8Array {
value = arrayify(value);
if (value.length > length) {
errors.throwArgumentError("value out of range", "value", arguments[0]);
logger.throwArgumentError("value out of range", "value", arguments[0]);
}
let result = new Uint8Array(length);
@ -189,7 +189,7 @@ export function hexlify(value: BytesLike | Hexable | number, options?: DataOptio
if (!options) { options = { }; }
if (typeof(value) === "number") {
errors.checkSafeUint53(value, "invalid hexlify value");
logger.checkSafeUint53(value, "invalid hexlify value");
let hex = "";
while (value) {
@ -213,7 +213,7 @@ export function hexlify(value: BytesLike | Hexable | number, options?: DataOptio
if (isHexString(value)) {
if (!options.allowOddLength && (<string>value).length % 2) {
errors.throwArgumentError("hex data is odd-length", "value", value);
logger.throwArgumentError("hex data is odd-length", "value", value);
}
return (<string>value).toLowerCase();
}
@ -227,7 +227,7 @@ export function hexlify(value: BytesLike | Hexable | number, options?: DataOptio
return result;
}
return errors.throwArgumentError("invalid hexlify value", "value", value);
return logger.throwArgumentError("invalid hexlify value", "value", value);
}
/*
@ -252,7 +252,7 @@ export function hexDataSlice(data: BytesLike, offset: number, endOffset?: number
if (typeof(data) !== "string") {
data = hexlify(data);
} else if (!isHexString(data) || (data.length % 2)) {
errors.throwArgumentError("invalid hexData", "value", data );
logger.throwArgumentError("invalid hexData", "value", data );
}
offset = 2 + 2 * offset;
@ -282,7 +282,7 @@ export function hexStripZeros(value: BytesLike): string {
if (typeof(value) !== "string") { value = hexlify(value); }
if (!isHexString(value)) {
errors.throwArgumentError("invalid hex string", "value", value);
logger.throwArgumentError("invalid hex string", "value", value);
}
value = value.substring(2);
let offset = 0;
@ -294,11 +294,11 @@ export function hexZeroPad(value: BytesLike, length: number): string {
if (typeof(value) !== "string") {
value = hexlify(value);
} else if (!isHexString(value)) {
errors.throwArgumentError("invalid hex string", "value", value);
logger.throwArgumentError("invalid hex string", "value", value);
}
if (value.length > 2 * length + 2) {
errors.throwArgumentError("value out of range", "value", arguments[1]);
logger.throwArgumentError("value out of range", "value", arguments[1]);
}
while (value.length < 2 * length + 2) {
@ -320,7 +320,7 @@ export function splitSignature(signature: SignatureLike): Signature {
if (isBytesLike(signature)) {
let bytes: Uint8Array = arrayify(signature);
if (bytes.length !== 65) {
errors.throwArgumentError("invalid signature string; must be 65 bytes", "signature", signature);
logger.throwArgumentError("invalid signature string; must be 65 bytes", "signature", signature);
}
// Get the r and s
@ -359,7 +359,7 @@ export function splitSignature(signature: SignatureLike): Signature {
result.v = 27 + result.recoveryParam;
} else if (result.recoveryParam != null && result.v != null) {
if (result.v !== 27 + result.recoveryParam) {
errors.throwArgumentError("signature v mismatch recoveryParam", "signature", signature);
logger.throwArgumentError("signature v mismatch recoveryParam", "signature", signature);
}
}
@ -372,7 +372,7 @@ export function splitSignature(signature: SignatureLike): Signature {
if (result._vs != null) {
result._vs = hexZeroPad(result._vs, 32);
if (result._vs.length > 66) {
errors.throwArgumentError("signature _vs overflow", "signature", signature);
logger.throwArgumentError("signature _vs overflow", "signature", signature);
}
let vs = arrayify(result._vs);
@ -389,41 +389,41 @@ export function splitSignature(signature: SignatureLike): Signature {
if (result.s == null) {
result.s = s;
} else if (result.s !== s) {
errors.throwArgumentError("signature v mismatch _vs", "signature", signature);
logger.throwArgumentError("signature v mismatch _vs", "signature", signature);
}
if (result.v == null) {
result.v = v;
} else if (result.v !== v) {
errors.throwArgumentError("signature v mismatch _vs", "signature", signature);
logger.throwArgumentError("signature v mismatch _vs", "signature", signature);
}
if (recoveryParam == null) {
result.recoveryParam = recoveryParam;
} else if (result.recoveryParam !== recoveryParam) {
errors.throwArgumentError("signature recoveryParam mismatch _vs", "signature", signature);
logger.throwArgumentError("signature recoveryParam mismatch _vs", "signature", signature);
}
}
// After all populating, both v and recoveryParam are still missing...
if (result.v == null && result.recoveryParam == null) {
errors.throwArgumentError("signature requires at least one of recoveryParam, v or _vs", "signature", signature);
logger.throwArgumentError("signature requires at least one of recoveryParam, v or _vs", "signature", signature);
}
// Check for canonical v
if (result.v !== 27 && result.v !== 28) {
errors.throwArgumentError("signature v not canonical", "signature", signature);
logger.throwArgumentError("signature v not canonical", "signature", signature);
}
// Check that r and s are in range
if (result.r.length > 66 || result.s.length > 66) {
errors.throwArgumentError("signature overflow r or s", "signature", signature);
logger.throwArgumentError("signature overflow r or s", "signature", signature);
}
if (result._vs == null) {
let vs = arrayify(result.s);
if (vs[0] >= 128) {
errors.throwArgumentError("signature s out of range", "signature", signature);
logger.throwArgumentError("signature s out of range", "signature", signature);
}
if (result.recoveryParam) { vs[0] |= 0x80; }
result._vs = hexlify(vs);

@ -14,7 +14,7 @@
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/constants": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/transactions": ">5.0.0-beta.0"
},

@ -7,10 +7,12 @@ import { getContractAddress } from "@ethersproject/address";
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, getStatic, resolveProperties, shallowCopy } from "@ethersproject/properties";
import { UnsignedTransaction } from "@ethersproject/transactions";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export interface Overrides {
gasLimit?: BigNumberish | Promise<BigNumberish>;
@ -131,17 +133,17 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
for (let key in tx) {
if (!allowedTransactionKeys[key]) {
errors.throwError(("unknown transaxction override - " + key), "overrides", tx);
logger.throwError(("unknown transaxction override - " + key), "overrides", tx);
}
}
}
errors.checkArgumentCount(params.length, method.inputs.length, "passed to contract");
logger.checkArgumentCount(params.length, method.inputs.length, "passed to contract");
// Check overrides make sense
["data", "to"].forEach(function(key) {
if (tx[key] != null) {
errors.throwError("cannot override " + key, errors.UNSUPPORTED_OPERATION, { operation: key });
logger.throwError("cannot override " + key, Logger.errors.UNSUPPORTED_OPERATION, { operation: key });
}
});
@ -164,7 +166,7 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions
}
if (!contract.provider && !contract.signer) {
errors.throwError("call (constant functions) require a provider or signer", errors.UNSUPPORTED_OPERATION, { operation: "call" })
logger.throwError("call (constant functions) require a provider or signer", Logger.errors.UNSUPPORTED_OPERATION, { operation: "call" })
}
// Check overrides make sense
@ -186,7 +188,7 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions
return result;
} catch (error) {
if (error.code === errors.CALL_EXCEPTION) {
if (error.code === Logger.errors.CALL_EXCEPTION) {
error.address = contract.address;
error.args = params;
error.transaction = tx;
@ -200,7 +202,7 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions
// Only computing the transaction estimate
if (options.estimate) {
if (!contract.provider && !contract.signer) {
errors.throwError("estimate require a provider or signer", errors.UNSUPPORTED_OPERATION, { operation: "estimateGas" })
logger.throwError("estimate require a provider or signer", Logger.errors.UNSUPPORTED_OPERATION, { operation: "estimateGas" })
}
return (contract.signer || contract.provider).estimateGas(tx);
@ -211,17 +213,13 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions
}
if (tx.value != null && !method.payable) {
errors.throwError("contract method is not payable", errors.INVALID_ARGUMENT, {
argument: "sendTransaction",
value: tx,
method: method.format()
})
logger.throwArgumentError("contract method is not payable", "sendTransaction:" + method.format(), tx);
}
if (options.transaction) { return resolveProperties(tx); }
if (!contract.signer) {
errors.throwError("sending a transaction require a signer", errors.UNSUPPORTED_OPERATION, { operation: "sendTransaction" })
logger.throwError("sending a transaction require a signer", Logger.errors.UNSUPPORTED_OPERATION, { operation: "sendTransaction" })
}
return contract.signer.sendTransaction(tx).then((tx) => {
@ -353,7 +351,7 @@ class FragmentRunningEvent extends RunningEvent {
let topic = contractInterface.getEventTopic(fragment);
if (topics) {
if (topic !== topics[0]) { errors.throwArgumentError("topic mismatch", "topics", topics); }
if (topic !== topics[0]) { logger.throwArgumentError("topic mismatch", "topics", topics); }
filter.topics = topics.slice();
} else {
filter.topics = [ topic ];
@ -442,7 +440,7 @@ export class Contract {
private _wrappedEmits: { [ eventTag: string ]: (...args: Array<any>) => void };
constructor(addressOrName: string, contractInterface: ContractInterface, signerOrProvider: Signer | Provider) {
errors.checkNew(new.target, Contract);
logger.checkNew(new.target, Contract);
// @TODO: Maybe still check the addressOrName looks like a valid address or name?
//address = getAddress(address);
@ -455,7 +453,7 @@ export class Contract {
defineReadOnly(this, "provider", signerOrProvider);
defineReadOnly(this, "signer", null);
} else {
errors.throwError("invalid signer or provider", errors.INVALID_ARGUMENT, { arg: "signerOrProvider", value: signerOrProvider });
logger.throwArgumentError("invalid signer or provider", "signerOrProvider", signerOrProvider);
}
defineReadOnly(this, "callStatic", { });
@ -492,7 +490,7 @@ export class Contract {
defineReadOnly(this, "addressPromise", Promise.resolve((<any>(this.interface.constructor)).getAddress(addressOrName)));
} catch (error) {
// Without a provider, we cannot use ENS names
errors.throwError("provider is required to use non-address contract address", errors.INVALID_ARGUMENT, { argument: "addressOrName", value: addressOrName });
logger.throwArgumentError("provider is required to use non-address contract address", "addressOrName", addressOrName);
}
}
@ -553,7 +551,7 @@ export class Contract {
// Otherwise, poll for our code to be deployed
this._deployedPromise = this.provider.getCode(this.address, blockTag).then((code) => {
if (code === "0x") {
errors.throwError("contract not deployed", errors.UNSUPPORTED_OPERATION, {
logger.throwError("contract not deployed", Logger.errors.UNSUPPORTED_OPERATION, {
contractAddress: this.address,
operation: "getDeployed"
});
@ -574,14 +572,14 @@ export class Contract {
fallback(overrides?: TransactionRequest): Promise<TransactionResponse> {
if (!this.signer) {
errors.throwError("sending a transaction require a signer", errors.UNSUPPORTED_OPERATION, { operation: "sendTransaction(fallback)" })
logger.throwError("sending a transaction require a signer", Logger.errors.UNSUPPORTED_OPERATION, { operation: "sendTransaction(fallback)" })
}
let tx: TransactionRequest = shallowCopy(overrides || {});
["from", "to"].forEach(function(key) {
if ((<any>tx)[key] == null) { return; }
errors.throwError("cannot override " + key, errors.UNSUPPORTED_OPERATION, { operation: key })
logger.throwError("cannot override " + key, Logger.errors.UNSUPPORTED_OPERATION, { operation: key })
});
tx.to = this.addressPromise;
@ -637,7 +635,7 @@ export class Contract {
let fragment = this.interface.getEvent(eventName)
if (!fragment) {
errors.throwError("unknown event - " + eventName, errors.INVALID_ARGUMENT, { argumnet: "eventName", value: eventName });
logger.throwArgumentError("unknown event - " + eventName, "eventName", eventName);
}
return this._normalizeRunningEvent(new FragmentRunningEvent(this.address, this.interface, fragment));
@ -701,7 +699,7 @@ export class Contract {
private _addEventListener(runningEvent: RunningEvent, listener: Listener, once: boolean): void {
if (!this.provider) {
errors.throwError("events require a provider or a signer with a provider", errors.UNSUPPORTED_OPERATION, { operation: "once" })
logger.throwError("events require a provider or a signer with a provider", Logger.errors.UNSUPPORTED_OPERATION, { operation: "once" })
}
runningEvent.addListener(listener, once);
@ -732,7 +730,7 @@ export class Contract {
if (typeof(fromBlockOrBlockhash) === "string" && isHexString(fromBlockOrBlockhash, 32)) {
if (toBlock != null) {
errors.throwArgumentError("cannot specify toBlock with blockhash", "toBlock", toBlock);
logger.throwArgumentError("cannot specify toBlock with blockhash", "toBlock", toBlock);
}
filter.blockhash = fromBlockOrBlockhash;
} else {
@ -849,12 +847,12 @@ export class ContractFactory {
// Make sure the final result is valid bytecode
if (!isHexString(bytecodeHex) || (bytecodeHex.length % 2)) {
errors.throwArgumentError("invalid bytecode", "bytecode", bytecode);
logger.throwArgumentError("invalid bytecode", "bytecode", bytecode);
}
// If we have a signer, make sure it is valid
if (signer && !Signer.isSigner(signer)) {
errors.throwArgumentError("invalid signer", "signer", signer);
logger.throwArgumentError("invalid signer", "signer", signer);
}
defineReadOnly(this, "bytecode", bytecodeHex);
@ -879,11 +877,11 @@ export class ContractFactory {
// Do not allow these to be overridden in a deployment transaction
["data", "from", "to"].forEach((key) => {
if ((<any>tx)[key] == null) { return; }
errors.throwError("cannot override " + key, errors.UNSUPPORTED_OPERATION, { operation: key })
logger.throwError("cannot override " + key, Logger.errors.UNSUPPORTED_OPERATION, { operation: key })
});
// Make sure the call matches the constructor signature
errors.checkArgumentCount(args.length, this.interface.deploy.inputs.length, " in Contract constructor");
logger.checkArgumentCount(args.length, this.interface.deploy.inputs.length, " in Contract constructor");
// Set the data to the bytecode + the encoded constructor arguments
tx.data = hexlify(concat([
@ -920,7 +918,7 @@ export class ContractFactory {
static fromSolidity(compilerOutput: any, signer?: Signer): ContractFactory {
if (compilerOutput == null) {
errors.throwError("missing compiler output", errors.MISSING_ARGUMENT, { argument: "compilerOutput" });
logger.throwError("missing compiler output", Logger.errors.MISSING_ARGUMENT, { argument: "compilerOutput" });
}
if (typeof(compilerOutput) === "string") {

@ -1,17 +1,6 @@
Error Generalizations and Utilities
===================================
**EXPERIMENTAL**
**DEPRECATED**
Please see the [ethers](https://github.com/ethers-io/ethers.js) repository
for more informations.
API
---
`@TODO`
License
-------
MIT License
Please use `@ethersproject/logger` instead.

@ -8,8 +8,8 @@
},
"dependencies": {
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0"
},
"keywords": [

@ -1,11 +1,13 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Bytes, concat, hexlify } from "@ethersproject/bytes";
import { nameprep, toUtf8Bytes } from "@ethersproject/strings";
import { keccak256 } from "@ethersproject/keccak256";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
///////////////////////////////
const Zeros = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
@ -26,10 +28,7 @@ export function isValidName(name: string): boolean {
export function namehash(name: string): string {
if (typeof(name) !== "string") {
errors.throwError("invalid address - " + String(name), errors.INVALID_ARGUMENT, {
argument: "name",
value: name
});
logger.throwArgumentError("invalid address - " + String(name), "name", name);
}
let result: string | Uint8Array = Zeros;

@ -11,7 +11,7 @@
"@ethersproject/basex": ">5.0.0-beta.0",
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/pbkdf2": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/sha2": ">5.0.0-beta.0",

@ -6,7 +6,6 @@
import { ExternallyOwnedAccount } from "@ethersproject/abstract-signer";
import { Base58 } from "@ethersproject/basex";
import * as errors from "@ethersproject/errors";
import { arrayify, BytesLike, concat, hexDataSlice, hexZeroPad, hexlify } from "@ethersproject/bytes";
import { BigNumber } from "@ethersproject/bignumber";
import { toUtf8Bytes, UnicodeNormalizationForm } from "@ethersproject/strings";
@ -17,6 +16,10 @@ import { computeHmac, ripemd160, sha256, SupportedAlgorithms } from "@ethersproj
import { computeAddress } from "@ethersproject/transactions";
import { Wordlist, wordlists } from "@ethersproject/wordlists";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
const N = BigNumber.from("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
@ -73,7 +76,7 @@ export class HDNode implements ExternallyOwnedAccount {
* - fromSeed
*/
constructor(constructorGuard: any, privateKey: string, publicKey: string, parentFingerprint: string, chainCode: string, index: number, depth: number, mnemonic: string, path: string) {
errors.checkNew(new.target, HDNode);
logger.checkNew(new.target, HDNode);
if (constructorGuard !== _constructorGuard) {
throw new Error("HDNode constructor cannot be called directly");
@ -226,10 +229,7 @@ export class HDNode implements ExternallyOwnedAccount {
let bytes = Base58.decode(extendedKey);
if (bytes.length !== 82 || base58check(bytes.slice(0, 78)) !== extendedKey) {
errors.throwError("invalid extended key", errors.INVALID_ARGUMENT, {
argument: "extendedKey",
value: "[REDACTED]"
});
logger.throwArgumentError("invalid extended key", "extendedKey", "[REDACTED]");
}
let depth = bytes[4];
@ -249,10 +249,7 @@ export class HDNode implements ExternallyOwnedAccount {
return new HDNode(_constructorGuard, hexlify(key.slice(1)), null, parentFingerprint, chainCode, index, depth, null, null);
}
return errors.throwError("invalid extended key", errors.INVALID_ARGUMENT, {
argument: "extendedKey",
value: "[REDACTED]"
});
return logger.throwError("invalid extended key", "extendedKey", "[REDACTED]");
}
}
@ -268,7 +265,7 @@ export function mnemonicToSeed(mnemonic: string, password?: string): string {
export function mnemonicToEntropy(mnemonic: string, wordlist?: Wordlist): string {
if (!wordlist) { wordlist = wordlists["en"]; }
errors.checkNormalize();
logger.checkNormalize();
let words = wordlist.split(mnemonic);
if ((words.length % 3) !== 0) { throw new Error("invalid mnemonic"); }

@ -10,9 +10,9 @@
"@ethersproject/abstract-signer": ">5.0.0-beta.0",
"@ethersproject/address": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/hdnode": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/pbkdf2": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/random": ">5.0.0-beta.0",

@ -5,12 +5,15 @@ import aes from "aes-js";
import { ExternallyOwnedAccount } from "@ethersproject/abstract-signer";
import { getAddress } from "@ethersproject/address";
import { arrayify, Bytes } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { keccak256 } from "@ethersproject/keccak256";
import { pbkdf2 } from "@ethersproject/pbkdf2";
import { toUtf8Bytes } from "@ethersproject/strings";
import { Description } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { getPassword, looseArrayify, searchPath } from "./utils";
export class CrowdsaleAccount extends Description implements ExternallyOwnedAccount {
@ -38,10 +41,7 @@ export function decrypt(json: string, password: Bytes | string): ExternallyOwned
// Encrypted Seed
let encseed = looseArrayify(searchPath(data, "encseed"));
if (!encseed || (encseed.length % 16) !== 0) {
errors.throwError("invalid encseed", errors.INVALID_ARGUMENT, {
argument: "json",
value: json
});
logger.throwArgumentError("invalid encseed", "json", json);
}
let key = arrayify(pbkdf2(password, password, 2000, 32, "sha256")).slice(0, 16);

@ -0,0 +1,4 @@
# We do not need the TypeScipt source in deployments
tsconfig.json
src.ts/

@ -0,0 +1,9 @@
Logger
======
@TODO:
License
-------
MIT License.

@ -0,0 +1,19 @@
{
"name": "@ethersproject/logger",
"version": "5.0.0-beta.127",
"description": "Logger utility functions for ethers.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Ethereum",
"ethers"
],
"author": "Richard Moore <me@ricmoo.com>",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"tarballHash": "0xd285051d17a97638f3840564e5121f34ac194907818e337e0a1339784d8daeff"
}

@ -0,0 +1,2 @@
export const version = "willbeaddedlater";

@ -0,0 +1,313 @@
"use strict";
let _permanentCensorErrors = false;
let _censorErrors = false;
const LogLevels: { [ name: string ]: number } = { debug: 1, "default": 2, info: 2, warn: 3, error: 4, off: 5 };
let LogLevel = LogLevels["default"];
import { version } from "./_version";
let _globalLogger: Logger = null;
export type LogLevel = "DEBUG" | "INFO" | "WARNING" | "ERROR" | "OFF";
function _checkNormalize(): string {
try {
let missing: Array<string> = [ ];
// Make sure all forms of normalization are supported
["NFD", "NFC", "NFKD", "NFKC"].forEach((form) => {
try {
if ("test".normalize(form) !== "test") {
throw new Error("bad normalize");
};
} catch(error) {
missing.push(form);
}
});
if (missing.length) {
throw new Error("missing " + missing.join(", "));
}
if (String.fromCharCode(0xe9).normalize("NFD") !== String.fromCharCode(0x65, 0x0301)) {
throw new Error("broken implementation")
}
} catch (error) {
return error.message;
}
return null;
}
let _normalizeError = _checkNormalize();
export class Logger {
readonly version: string;
static errors = {
///////////////////
// Generic Errors
// Unknown Error
UNKNOWN_ERROR: "UNKNOWN_ERROR",
// Not Implemented
NOT_IMPLEMENTED: "NOT_IMPLEMENTED",
// Unsupported Operation
// - operation
UNSUPPORTED_OPERATION: "UNSUPPORTED_OPERATION",
// Network Error (i.e. Ethereum Network, such as an invalid chain ID)
NETWORK_ERROR: "NETWORK_ERROR",
// Some sort of bad response from the server
SERVER_ERROR: "SERVER_ERROR",
// Timeout
TIMEOUT: "TIMEOUT",
///////////////////
// Operational Errors
// Buffer Overrun
BUFFER_OVERRUN: "BUFFER_OVERRUN",
// Numeric Fault
// - operation: the operation being executed
// - fault: the reason this faulted
NUMERIC_FAULT: "NUMERIC_FAULT",
///////////////////
// Argument Errors
// Missing new operator to an object
// - name: The name of the class
MISSING_NEW: "MISSING_NEW",
// Invalid argument (e.g. value is incompatible with type) to a function:
// - argument: The argument name that was invalid
// - value: The value of the argument
INVALID_ARGUMENT: "INVALID_ARGUMENT",
// Missing argument to a function:
// - count: The number of arguments received
// - expectedCount: The number of arguments expected
MISSING_ARGUMENT: "MISSING_ARGUMENT",
// Too many arguments
// - count: The number of arguments received
// - expectedCount: The number of arguments expected
UNEXPECTED_ARGUMENT: "UNEXPECTED_ARGUMENT",
///////////////////
// Blockchain Errors
// Call exception
// - transaction: the transaction
// - address?: the contract address
// - args?: The arguments passed into the function
// - method?: The Solidity method signature
// - errorSignature?: The EIP848 error signature
// - errorArgs?: The EIP848 error parameters
// - reason: The reason (only for EIP848 "Error(string)")
CALL_EXCEPTION: "CALL_EXCEPTION",
// Insufficien funds (< value + gasLimit * gasPrice)
// - transaction: the transaction attempted
INSUFFICIENT_FUNDS: "INSUFFICIENT_FUNDS",
// Nonce has already been used
// - transaction: the transaction attempted
NONCE_EXPIRED: "NONCE_EXPIRED",
// The replacement fee for the transaction is too low
// - transaction: the transaction attempted
REPLACEMENT_UNDERPRICED: "REPLACEMENT_UNDERPRICED",
// The gas limit could not be estimated
// - transaction: the transaction passed to estimateGas
UNPREDICTABLE_GAS_LIMIT: "UNPREDICTABLE_GAS_LIMIT",
};
static levels: { [ name: string ]: LogLevel } = {
DEBUG: "DEBUG",
INFO: "INFO",
WARNING: "WARNING",
ERROR: "ERROR",
OFF: "OFF"
};
constructor(version: string) {
Object.defineProperty(this, "version", {
enumerable: true,
value: version,
writable: false
});
}
setLogLevel(logLevel: LogLevel): void {
let level = LogLevels[logLevel];
if (level == null) {
this.warn("invliad log level - " + logLevel);
return;
}
LogLevel = level;
}
_log(logLevel: LogLevel, args: Array<any>): void {
if (LogLevel > LogLevels[logLevel]) { return; }
console.log.apply(console, args);
}
debug(...args: Array<any>): void {
this._log(Logger.levels.DEBUG, args);
}
info(...args: Array<any>): void {
this._log(Logger.levels.INFO, args);
}
warn(...args: Array<any>): void {
this._log(Logger.levels.WARNING, args);
}
makeError(message: string, code?: string, params?: any): Error {
if (_censorErrors) {
return new Error("unknown error");
}
if (!code) { code = Logger.errors.UNKNOWN_ERROR; }
if (!params) { params = {}; }
let messageDetails: Array<string> = [];
Object.keys(params).forEach((key) => {
try {
messageDetails.push(key + "=" + JSON.stringify(params[key]));
} catch (error) {
messageDetails.push(key + "=" + JSON.stringify(params[key].toString()));
}
});
messageDetails.push("version=" + this.version);
let reason = message;
if (messageDetails.length) {
message += " (" + messageDetails.join(", ") + ")";
}
// @TODO: Any??
let error: any = new Error(message);
error.reason = reason;
error.code = code
Object.keys(params).forEach(function(key) {
error[key] = params[key];
});
return error;
}
throwError(message: string, code?: string, params?: any): never {
throw this.makeError(message, code, params);
}
throwArgumentError(message: string, name: string, value: any): never {
return this.throwError(message, Logger.errors.INVALID_ARGUMENT, {
argument: name,
value: value
});
}
checkNormalize(message?: string): void {
if (message == null) { message = "platform missing String.prototype.normalize"; }
if (_normalizeError) {
this.throwError("platform missing String.prototype.normalize", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "String.prototype.normalize", form: _normalizeError
});
}
}
checkSafeUint53(value: number, message?: string): void {
if (typeof(value) !== "number") { return; }
if (message == null) { message = "value not safe"; }
if (value < 0 || value >= 0x1fffffffffffff) {
this.throwError(message, Logger.errors.NUMERIC_FAULT, {
operation: "checkSafeInteger",
fault: "out-of-safe-range",
value: value
});
}
if (value % 1) {
this.throwError(message, Logger.errors.NUMERIC_FAULT, {
operation: "checkSafeInteger",
fault: "non-integer",
value: value
});
}
}
checkArgumentCount(count: number, expectedCount: number, message?: string): void {
if (message) {
message = ": " + message;
} else {
message = "";
}
if (count < expectedCount) {
this.throwError("missing argument" + message, Logger.errors.MISSING_ARGUMENT, {
count: count,
expectedCount: expectedCount
});
}
if (count > expectedCount) {
this.throwError("too many arguments" + message, Logger.errors.UNEXPECTED_ARGUMENT, {
count: count,
expectedCount: expectedCount
});
}
}
checkNew(target: any, kind: any): void {
if (target === Object || target == null) {
this.throwError("missing new", Logger.errors.MISSING_NEW, { name: kind.name });
}
}
checkAbstract(target: any, kind: any): void {
if (target === kind) {
this.throwError(
"cannot instantiate abstract class " + JSON.stringify(kind.name) + " directly; use a sub-class",
Logger.errors.UNSUPPORTED_OPERATION,
{ name: target.name, operation: "new" }
);
} else if (target === Object || target == null) {
this.throwError("missing new", Logger.errors.MISSING_NEW, { name: kind.name });
}
}
static globalLogger(): Logger {
if (!_globalLogger) { _globalLogger = new Logger(version); }
return _globalLogger;
}
static setCensorship(censorship: boolean, permanent?: boolean): void {
if (_permanentCensorErrors) {
if (!censorship) { return; }
this.globalLogger().throwError("error censorship permanent", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "setCensorship"
});
}
_censorErrors = !!censorship;
_permanentCensorErrors = !!permanent;
}
}

@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.package.json",
"compilerOptions": {
"rootDir": "./src.ts",
"outDir": "./"
},
"include": [
"./src.ts/*"
],
"exclude": [ ]
}

@ -7,7 +7,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@ethersproject/errors": ">5.0.0-beta.0"
"@ethersproject/logger": ">5.0.0-beta.0"
},
"keywords": [
"Ethereum",

@ -1,6 +1,8 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { Network, Networkish } from "./types";
@ -167,14 +169,14 @@ export function getNetwork(network: Networkish): Network {
// Not a standard network; check that it is a valid network in general
if (!standard) {
if (typeof(network.chainId) !== "number") {
errors.throwError("invalid network chainId", errors.INVALID_ARGUMENT, { arg: "network", value: network });
logger.throwArgumentError("invalid network chainId", "network", network);
}
return network;
}
// Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)
if (network.chainId !== 0 && network.chainId !== standard.chainId) {
errors.throwError("network chainId mismatch", errors.INVALID_ARGUMENT, { arg: "network", value: network });
logger.throwArgumentError("network chainId mismatch", "network", network);
}
// Standard Network (allow overriding the ENS address)

@ -9,7 +9,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@ethersproject/errors": ">5.0.0-beta.0"
"@ethersproject/logger": ">5.0.0-beta.0"
},
"keywords": [
"Ethereum",

@ -1,6 +1,8 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export function defineReadOnly(object: any, name: string, value: any): void {
Object.defineProperty(object, name, {
@ -46,19 +48,12 @@ export function resolveProperties(object: any): Promise<any> {
export function checkProperties(object: any, properties: { [ name: string ]: boolean }): void {
if (!object || typeof(object) !== "object") {
errors.throwError("invalid object", errors.INVALID_ARGUMENT, {
argument: "object",
value: object
});
logger.throwArgumentError("invalid object", "object", object);
}
Object.keys(object).forEach((key) => {
if (!properties[key]) {
errors.throwError("invalid object key - " + key, errors.INVALID_ARGUMENT, {
argument: "transaction",
value: object,
key: key
});
logger.throwArgumentError("invalid object key - " + key, "transaction:" + key, object);
}
});
}

@ -1,7 +1,7 @@
{
"name": "@ethersproject/providers",
"version": "5.0.0-beta.136",
"description": "Error utility functions for ethers.",
"description": "Ethereum Providers for ethers.",
"main": "index.js",
"browser": {
"net": "./browser-net.js",
@ -17,8 +17,8 @@
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/constants": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/hash": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/networks": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/random": ">5.0.0-beta.0",

@ -1,8 +1,11 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Network } from "@ethersproject/networks";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { UrlJsonRpcProvider } from "./url-json-rpc-provider";
// This key was provided to ethers.js by Alchemy to be used by the
@ -36,7 +39,7 @@ export class AlchemyProvider extends UrlJsonRpcProvider {
host = "eth-kovan.alchemyapi.io/jsonrpc/";
break;
default:
errors.throwArgumentError("unsupported network", "network", arguments[0]);
logger.throwArgumentError("unsupported network", "network", arguments[0]);
}
return ("https:/" + "/" + host + apiKey);

@ -6,7 +6,6 @@ import {
} from "@ethersproject/abstract-provider";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { arrayify, hexDataLength, hexlify, hexValue, isHexString } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { namehash } from "@ethersproject/hash";
import { getNetwork, Network, Networkish } from "@ethersproject/networks";
import { defineReadOnly, getStatic, resolveProperties } from "@ethersproject/properties";
@ -14,6 +13,10 @@ import { Transaction } from "@ethersproject/transactions";
import { toUtf8String } from "@ethersproject/strings";
import { poll } from "@ethersproject/web";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { Formatter } from "./formatter";
@ -23,7 +26,7 @@ import { Formatter } from "./formatter";
function checkTopic(topic: string): string {
if (topic == null) { return "null"; }
if (hexDataLength(topic) !== 32) {
errors.throwArgumentError("invalid topic", "topic", topic);
logger.throwArgumentError("invalid topic", "topic", topic);
}
return topic.toLowerCase();
}
@ -78,7 +81,7 @@ function getEventTag(eventName: EventType): string {
return "filter:*:" + serializeTopics(eventName);
} else if (ForkEvent.isForkEvent(eventName)) {
errors.warn("not implemented");
logger.warn("not implemented");
throw new Error("not implemented");
} else if (eventName && typeof(eventName) === "object") {
@ -171,7 +174,7 @@ export class BaseProvider extends Provider {
ready: Promise<Network>;
constructor(network: Networkish | Promise<Network>) {
errors.checkNew(new.target, Provider);
logger.checkNew(new.target, Provider);
super();
@ -193,7 +196,7 @@ export class BaseProvider extends Provider {
defineReadOnly(this, "ready", Promise.resolve(this._network));
} else {
errors.throwError("invalid network", errors.INVALID_ARGUMENT, { arg: "network", value: network });
logger.throwArgumentError("invalid network", "network", network);
}
}
@ -499,7 +502,7 @@ export class BaseProvider extends Provider {
// Check the hash we expect is the same as the hash the server reported
if (hash != null && tx.hash !== hash) {
errors.throwError("Transaction hash mismatch from Provider.sendTransaction.", errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
logger.throwError("Transaction hash mismatch from Provider.sendTransaction.", Logger.errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
}
// @TODO: (confirmations? number, timeout? number)
@ -519,7 +522,7 @@ export class BaseProvider extends Provider {
this._emitted["t:" + tx.hash] = receipt.blockNumber;
if (receipt.status === 0) {
errors.throwError("transaction failed", errors.CALL_EXCEPTION, {
logger.throwError("transaction failed", Logger.errors.CALL_EXCEPTION, {
transactionHash: tx.hash,
transaction: tx
});
@ -606,7 +609,7 @@ export class BaseProvider extends Provider {
_getAddress(addressOrName: string | Promise<string>): Promise<string> {
return this.resolveName(addressOrName).then((address) => {
if (address == null) {
errors.throwError("ENS name not configured", errors.UNSUPPORTED_OPERATION, {
logger.throwError("ENS name not configured", Logger.errors.UNSUPPORTED_OPERATION, {
operation: `resolveName(${ JSON.stringify(addressOrName) })`
});
}
@ -637,7 +640,7 @@ export class BaseProvider extends Provider {
blockNumber = parseInt(params.blockTag.substring(2), 16);
}
} catch (error) {
errors.throwError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
logger.throwArgumentError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
}
}
@ -782,7 +785,7 @@ export class BaseProvider extends Provider {
if (typeof(blockTag) === "number" && blockTag < 0) {
if (blockTag % 1) {
errors.throwArgumentError("invalid BlockTag", "blockTag", blockTag);
logger.throwArgumentError("invalid BlockTag", "blockTag", blockTag);
}
return this._getFastBlockNumber().then((bn) => {
@ -802,9 +805,9 @@ export class BaseProvider extends Provider {
// No ENS...
if (!network.ensAddress) {
errors.throwError(
logger.throwError(
"network does support ENS",
errors.UNSUPPORTED_OPERATION,
Logger.errors.UNSUPPORTED_OPERATION,
{ operation: "ENS", network: network.name }
);
}
@ -883,7 +886,7 @@ export class BaseProvider extends Provider {
}
perform(method: string, params: any): Promise<any> {
return errors.throwError(method + " not implemented", errors.NOT_IMPLEMENTED, { operation: method });
return logger.throwError(method + " not implemented", Logger.errors.NOT_IMPLEMENTED, { operation: method });
}
_startPending(): void {

@ -2,11 +2,14 @@
import { BlockTag, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
import { hexlify, hexValue } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { Networkish } from "@ethersproject/networks";
import { deepCopy, defineReadOnly } from "@ethersproject/properties";
import { fetchJson } from "@ethersproject/web";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { BaseProvider } from "./base-provider";
@ -72,7 +75,7 @@ export class EtherscanProvider extends BaseProvider{
readonly baseUrl: string;
readonly apiKey: string;
constructor(network?: Networkish, apiKey?: string) {
errors.checkNew(new.target, EtherscanProvider);
logger.checkNew(new.target, EtherscanProvider);
super(network);
@ -169,15 +172,15 @@ export class EtherscanProvider extends BaseProvider{
if (error.responseText) {
// "Insufficient funds. The account you tried to send transaction from does not have enough funds. Required 21464000000000 and got: 0"
if (error.responseText.toLowerCase().indexOf("insufficient funds") >= 0) {
errors.throwError("insufficient funds", errors.INSUFFICIENT_FUNDS, { });
logger.throwError("insufficient funds", Logger.errors.INSUFFICIENT_FUNDS, { });
}
// "Transaction with the same hash was already imported."
if (error.responseText.indexOf("same hash was already imported") >= 0) {
errors.throwError("nonce has already been used", errors.NONCE_EXPIRED, { });
logger.throwError("nonce has already been used", Logger.errors.NONCE_EXPIRED, { });
}
// "Transaction gas price is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce."
if (error.responseText.indexOf("another transaction with same nonce") >= 0) {
errors.throwError("replacement fee too low", errors.REPLACEMENT_UNDERPRICED, { });
logger.throwError("replacement fee too low", Logger.errors.REPLACEMENT_UNDERPRICED, { });
}
}
throw error;

@ -1,10 +1,13 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Network } from "@ethersproject/networks";
import { shuffled } from "@ethersproject/random";
import { deepCopy, defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { BaseProvider } from "./base-provider";
function now() { return (new Date()).getTime(); }
@ -37,11 +40,7 @@ function checkNetworks(networks: Array<Network>): boolean {
((check.ensAddress === network.ensAddress) ||
(check.ensAddress == null && network.ensAddress == null))) { return; }
errors.throwError(
"provider mismatch",
errors.INVALID_ARGUMENT,
{ arg: "networks", value: networks }
);
logger.throwArgumentError("provider mismatch", "networks", networks);
});
return result;
@ -87,20 +86,20 @@ export class FallbackProvider extends BaseProvider {
readonly quorum: number;
constructor(providers: Array<BaseProvider>, quorum?: number, weights?: Array<number>) {
errors.checkNew(new.target, FallbackProvider);
logger.checkNew(new.target, FallbackProvider);
if (providers.length === 0) {
errors.throwArgumentError("missing providers", "providers", providers);
logger.throwArgumentError("missing providers", "providers", providers);
}
if (weights != null && weights.length !== providers.length) {
errors.throwArgumentError("too many weights", "weights", weights);
logger.throwArgumentError("too many weights", "weights", weights);
} else if (!weights) {
weights = providers.map((p) => 1);
} else {
weights.forEach((w) => {
if (w % 1 || w > 512 || w < 1) {
errors.throwArgumentError("invalid weight; must be integer in [1, 512]", "weights", weights);
logger.throwArgumentError("invalid weight; must be integer in [1, 512]", "weights", weights);
}
});
}
@ -111,7 +110,7 @@ export class FallbackProvider extends BaseProvider {
quorum = total / 2;
} else {
if (quorum > total) {
errors.throwArgumentError("quorum will always fail; larger than total weight", "quorum", quorum);
logger.throwArgumentError("quorum will always fail; larger than total weight", "quorum", quorum);
}
}
@ -125,7 +124,7 @@ export class FallbackProvider extends BaseProvider {
// The network won't be known until all child providers know
let ready = Promise.all(providers.map((p) => p.getNetwork())).then((networks) => {
if (!checkNetworks(networks)) {
errors.throwError("getNetwork returned null", errors.UNKNOWN_ERROR, { })
logger.throwError("getNetwork returned null", Logger.errors.UNKNOWN_ERROR)
}
return networks[0];
});

@ -5,10 +5,13 @@ import { getAddress, getContractAddress } from "@ethersproject/address";
import { BigNumber } from "@ethersproject/bignumber";
import { hexDataLength, hexDataSlice, hexValue, hexZeroPad, isHexString } from "@ethersproject/bytes";
import { AddressZero } from "@ethersproject/constants";
import * as errors from "@ethersproject/errors";
import { shallowCopy } from "@ethersproject/properties";
import { parse as parseTransaction } from "@ethersproject/transactions";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export type FormatFunc = (value: any) => any;
export type FormatFuncs = { [ key: string ]: FormatFunc };
@ -28,7 +31,7 @@ export class Formatter {
readonly formats: Formats;
constructor() {
errors.checkNew(new.target, Formatter);
logger.checkNew(new.target, Formatter);
this.formats = this.getDefaultFormats();
}
@ -188,10 +191,7 @@ export class Formatter {
return value.toLowerCase();
}
}
return errors.throwError("invalid hash", errors.INVALID_ARGUMENT, {
argument: "value",
value: value
});
return logger.throwArgumentError("invalid hash", "value", value);
}
data(value: any, strict?: boolean): string {
@ -239,10 +239,7 @@ export class Formatter {
hash(value: any, strict?: boolean): string {
let result = this.hex(value, strict);
if (hexDataLength(result) !== 32) {
return errors.throwError("invalid hash", errors.INVALID_ARGUMENT, {
argument: "value",
value: value
});
return logger.throwArgumentError("invalid hash", "value", value);
}
return result;
}

@ -1,8 +1,11 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Network } from "@ethersproject/networks";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { UrlJsonRpcProvider } from "./url-json-rpc-provider";
@ -35,7 +38,7 @@ export class InfuraProvider extends UrlJsonRpcProvider {
host = "goerli.infura.io";
break;
default:
errors.throwError("unsupported network", errors.INVALID_ARGUMENT, {
logger.throwError("unsupported network", Logger.errors.INVALID_ARGUMENT, {
argument: "network",
value: network
});

@ -2,10 +2,13 @@
import net from "net";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties";
import { Networkish } from "@ethersproject/networks";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { JsonRpcProvider } from "./json-rpc-provider";
@ -13,10 +16,10 @@ export class IpcProvider extends JsonRpcProvider {
readonly path: string;
constructor(path: string, network?: Networkish) {
errors.checkNew(new.target, IpcProvider);
logger.checkNew(new.target, IpcProvider);
if (path == null) {
errors.throwError("missing path", errors.MISSING_ARGUMENT, { arg: "path" });
logger.throwError("missing path", Logger.errors.MISSING_ARGUMENT, { arg: "path" });
}
super("ipc://" + path, network);

@ -6,12 +6,15 @@ import { Provider, TransactionRequest, TransactionResponse } from "@ethersprojec
import { Signer } from "@ethersproject/abstract-signer";
import { BigNumber } from "@ethersproject/bignumber";
import { Bytes, hexlify, hexValue } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { getNetwork, Network, Networkish } from "@ethersproject/networks";
import { checkProperties, deepCopy, defineReadOnly, resolveProperties, shallowCopy } from "@ethersproject/properties";
import { toUtf8Bytes } from "@ethersproject/strings";
import { ConnectionInfo, fetchJson, poll } from "@ethersproject/web";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { BaseProvider } from "./base-provider";
@ -48,7 +51,7 @@ export class JsonRpcSigner extends Signer {
_address: string;
constructor(constructorGuard: any, provider: JsonRpcProvider, addressOrIndex?: string | number) {
errors.checkNew(new.target, JsonRpcSigner);
logger.checkNew(new.target, JsonRpcSigner);
super();
@ -69,12 +72,12 @@ export class JsonRpcSigner extends Signer {
defineReadOnly(this, "_address", null);
} else {
errors.throwError("invalid address or index", errors.INVALID_ARGUMENT, { argument: "addressOrIndex", value: addressOrIndex });
logger.throwArgumentError("invalid address or index", "addressOrIndex", addressOrIndex);
}
}
connect(provider: Provider): JsonRpcSigner {
return errors.throwError("cannot alter JSON-RPC Signer connection", errors.UNSUPPORTED_OPERATION, {
return logger.throwError("cannot alter JSON-RPC Signer connection", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "connect"
});
}
@ -90,7 +93,9 @@ export class JsonRpcSigner extends Signer {
return this.provider.send("eth_accounts", []).then((accounts) => {
if (accounts.length <= this._index) {
errors.throwError("unknown account #" + this._index, errors.UNSUPPORTED_OPERATION, { operation: "getAddress" });
logger.throwError("unknown account #" + this._index, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "getAddress"
});
}
return this.provider.formatter.address(accounts[this._index])
});
@ -126,17 +131,17 @@ export class JsonRpcSigner extends Signer {
if (error.responseText) {
// See: JsonRpcProvider.sendTransaction (@TODO: Expose a ._throwError??)
if (error.responseText.indexOf("insufficient funds") >= 0) {
errors.throwError("insufficient funds", errors.INSUFFICIENT_FUNDS, {
logger.throwError("insufficient funds", Logger.errors.INSUFFICIENT_FUNDS, {
transaction: tx
});
}
if (error.responseText.indexOf("nonce too low") >= 0) {
errors.throwError("nonce has already been used", errors.NONCE_EXPIRED, {
logger.throwError("nonce has already been used", Logger.errors.NONCE_EXPIRED, {
transaction: tx
});
}
if (error.responseText.indexOf("replacement transaction underpriced") >= 0) {
errors.throwError("replacement fee too low", errors.REPLACEMENT_UNDERPRICED, {
logger.throwError("replacement fee too low", Logger.errors.REPLACEMENT_UNDERPRICED, {
transaction: tx
});
}
@ -147,7 +152,7 @@ export class JsonRpcSigner extends Signer {
}
signTransaction(transaction: TransactionRequest): Promise<string> {
return errors.throwError("signing transactions is unsupported", errors.UNSUPPORTED_OPERATION, {
return logger.throwError("signing transactions is unsupported", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "signTransaction"
});
}
@ -214,7 +219,7 @@ export class JsonRpcProvider extends BaseProvider {
_nextId: number;
constructor(url?: ConnectionInfo | string, network?: Networkish) {
errors.checkNew(new.target, JsonRpcProvider);
logger.checkNew(new.target, JsonRpcProvider);
// One parameter, but it is a network name, so swap it with the URL
if (typeof(url) === "string") {
@ -239,7 +244,7 @@ export class JsonRpcProvider extends BaseProvider {
this.send("net_version", [ ]).then((result) => {
resolve(getNetwork(BigNumber.from(result).toNumber()));
}).catch((error) => {
reject(errors.makeError("could not detect network", errors.NETWORK_ERROR, { }));
reject(logger.makeError("could not detect network", Logger.errors.NETWORK_ERROR));
});
});
});
@ -325,15 +330,15 @@ export class JsonRpcProvider extends BaseProvider {
if (error.responseText) {
// "insufficient funds for gas * price + value"
if (error.responseText.indexOf("insufficient funds") > 0) {
errors.throwError("insufficient funds", errors.INSUFFICIENT_FUNDS, { });
logger.throwError("insufficient funds", Logger.errors.INSUFFICIENT_FUNDS, { });
}
// "nonce too low"
if (error.responseText.indexOf("nonce too low") > 0) {
errors.throwError("nonce has already been used", errors.NONCE_EXPIRED, { });
logger.throwError("nonce has already been used", Logger.errors.NONCE_EXPIRED, { });
}
// "replacement transaction underpriced"
if (error.responseText.indexOf("replacement transaction underpriced") > 0) {
errors.throwError("replacement fee too low", errors.REPLACEMENT_UNDERPRICED, { });
logger.throwError("replacement fee too low", Logger.errors.REPLACEMENT_UNDERPRICED, { });
}
}
throw error;
@ -369,7 +374,7 @@ export class JsonRpcProvider extends BaseProvider {
break;
}
return errors.throwError(method + " not implemented", errors.NOT_IMPLEMENTED, { operation: method });
return logger.throwError(method + " not implemented", Logger.errors.NOT_IMPLEMENTED, { operation: method });
}
_startPending(): void {

@ -1,10 +1,11 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Network } from "@ethersproject/networks";
import { UrlJsonRpcProvider } from "./url-json-rpc-provider";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
// Special API key provided by Nodesmith for ethers.js
const defaultApiKey = "ETHERS_JS_SHARED";
@ -34,7 +35,7 @@ export class NodesmithProvider extends UrlJsonRpcProvider {
host = "https://ethereum.api.nodesmith.io/v1/kovan/jsonrpc";
break;
default:
errors.throwArgumentError("unsupported network", "network", arguments[0]);
logger.throwArgumentError("unsupported network", "network", arguments[0]);
}
return (host + "?apiKey=" + apiKey);

@ -1,16 +1,19 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { getNetwork, Network, Networkish } from "@ethersproject/networks";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { JsonRpcProvider, JsonRpcSigner } from "./json-rpc-provider";
export class UrlJsonRpcProvider extends JsonRpcProvider {
readonly apiKey: string;
constructor(network?: Networkish, apiKey?: string) {
errors.checkAbstract(new.target, UrlJsonRpcProvider);
logger.checkAbstract(new.target, UrlJsonRpcProvider);
// Normalize the Network and API Key
network = new.target.getNetwork(network);
@ -24,13 +27,13 @@ export class UrlJsonRpcProvider extends JsonRpcProvider {
}
_startPending(): void {
errors.warn("WARNING: API provider does not support pending filters");
logger.warn("WARNING: API provider does not support pending filters");
}
getSigner(address?: string): JsonRpcSigner {
errors.throwError(
logger.throwError(
"API provider does not support signing",
errors.UNSUPPORTED_OPERATION,
Logger.errors.UNSUPPORTED_OPERATION,
{ operation: "getSigner" }
);
return null;
@ -51,7 +54,7 @@ export class UrlJsonRpcProvider extends JsonRpcProvider {
// Returns the url for the given network and API key
static getUrl(network: Network, apiKey: string): string {
return errors.throwError("not implemented; sub-classes must override getUrl", errors.NOT_IMPLEMENTED, {
return logger.throwError("not implemented; sub-classes must override getUrl", Logger.errors.NOT_IMPLEMENTED, {
operation: "getUrl"
});
}

@ -1,9 +1,12 @@
"use strict";
import * as errors from "@ethersproject/errors";
import { Networkish } from "@ethersproject/networks";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { JsonRpcProvider } from "./json-rpc-provider";
@ -29,7 +32,7 @@ export class Web3Provider extends JsonRpcProvider {
private _sendAsync: (request: any, callback: (error: any, response: any) => void) => void;
constructor(web3Provider: AsyncSendable, network?: Networkish) {
errors.checkNew(new.target, Web3Provider);
logger.checkNew(new.target, Web3Provider);
// HTTP has a host; IPC has a path.
super(web3Provider.host || web3Provider.path || "", network);
@ -43,11 +46,7 @@ export class Web3Provider extends JsonRpcProvider {
}
if (!web3Provider || !this._sendAsync) {
errors.throwError(
"invalid web3Provider",
errors.INVALID_ARGUMENT,
{ arg: "web3Provider", value: web3Provider }
);
logger.throwArgumentError("invalid web3Provider", "web3Provider", web3Provider);
}
defineReadOnly(this, "_web3Provider", web3Provider);

@ -9,7 +9,7 @@
},
"dependencies": {
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0"
"@ethersproject/logger": ">5.0.0-beta.0"
},
"devDependencies": {
"@types/node": "10.3.2"

@ -1,18 +1,21 @@
"use strict";
import { arrayify } from "@ethersproject/bytes";
import * as errors from"@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export { shuffled } from "./shuffle";
let crypto: any = (<any>global).crypto || (<any>global).msCrypto;
if (!crypto || !crypto.getRandomValues) {
errors.warn("WARNING: Missing strong random number source");
logger.warn("WARNING: Missing strong random number source");
crypto = {
getRandomValues: function(buffer: Uint8Array): Uint8Array {
return errors.throwError("no secure random source avaialble", errors.UNSUPPORTED_OPERATION, {
return logger.throwError("no secure random source avaialble", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "crypto.getRandomValues"
});
}
@ -21,10 +24,7 @@ if (!crypto || !crypto.getRandomValues) {
export function randomBytes(length: number): Uint8Array {
if (length <= 0 || length > 1024 || parseInt(String(length)) != length) {
errors.throwError("invalid length", errors.INVALID_ARGUMENT, {
argument: "length",
value: length
});
logger.throwArgumentError("invalid length", "length", length);
}
let result = new Uint8Array(length);

@ -9,7 +9,7 @@
},
"dependencies": {
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"hash.js": "1.1.3"
},
"keywords": [

@ -3,8 +3,10 @@
import * as hash from "hash.js";
import { arrayify, BytesLike } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export enum SupportedAlgorithms { sha256 = "sha256", sha512 = "sha512" };
@ -23,7 +25,7 @@ export function sha512(data: BytesLike): string {
export function computeHmac(algorithm: SupportedAlgorithms, key: BytesLike, data: BytesLike): string {
if (!SupportedAlgorithms[algorithm]) {
errors.throwError("unsupported algorithm " + algorithm, errors.UNSUPPORTED_OPERATION, {
logger.throwError("unsupported algorithm " + algorithm, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "hmac",
algorithm: algorithm
});

@ -8,7 +8,7 @@
},
"dependencies": {
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"elliptic": "6.3.3"
},

@ -3,9 +3,12 @@
import { ec as EC } from "elliptic";
import { arrayify, BytesLike, hexlify, hexZeroPad, Signature, SignatureLike, splitSignature } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
let _curve: EC = null
function getCurve() {
if (!_curve) {
@ -91,6 +94,6 @@ export function computePublicKey(key: BytesLike, compressed?: boolean): string {
return "0x" + getCurve().keyFromPublic(bytes).getPublic(true, "hex");
}
return errors.throwArgumentError("invalid public or private key", "key", "[REDACTED]");
return logger.throwArgumentError("invalid public or private key", "key", "[REDACTED]");
}

@ -11,8 +11,8 @@
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/constants": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/rlp": ">5.0.0-beta.0",
"@ethersproject/signing-key": ">5.0.0-beta.0"

@ -4,12 +4,15 @@ import { getAddress } from "@ethersproject/address";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { arrayify, BytesLike, hexDataSlice, hexlify, hexZeroPad, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { Zero } from "@ethersproject/constants";
import * as errors from "@ethersproject/errors";
import { keccak256 } from "@ethersproject/keccak256";
import { checkProperties } from "@ethersproject/properties";
import * as RLP from "@ethersproject/rlp";
import { computePublicKey, recoverPublicKey } from "@ethersproject/signing-key";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
///////////////////////////////
// Exported Types
@ -90,14 +93,14 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
// Fixed-width field
if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
errors.throwError("invalid length for " + fieldInfo.name, errors.INVALID_ARGUMENT, { arg: ("transaction" + fieldInfo.name), value: value });
logger.throwArgumentError("invalid length for " + fieldInfo.name, ("transaction:" + fieldInfo.name), value);
}
// Variable-width (with a maximum)
if (fieldInfo.maxLength) {
value = stripZeros(value);
if (value.length > fieldInfo.maxLength) {
errors.throwError("invalid length for " + fieldInfo.name, errors.INVALID_ARGUMENT, { arg: ("transaction" + fieldInfo.name), value: value });
logger.throwArgumentError("invalid length for " + fieldInfo.name, ("transaction:" + fieldInfo.name), value );
}
}
@ -140,7 +143,7 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
export function parse(rawTransaction: BytesLike): Transaction {
let transaction = RLP.decode(rawTransaction);
if (transaction.length !== 9 && transaction.length !== 6) {
errors.throwError("invalid raw transaction", errors.INVALID_ARGUMENT, { arg: "rawTransactin", value: rawTransaction });
logger.throwArgumentError("invalid raw transaction", "rawTransactin", rawTransaction);
}
let tx: Transaction = {

@ -9,7 +9,7 @@
"dependencies": {
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/constants": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0"
"@ethersproject/logger": ">5.0.0-beta.0"
},
"keywords": [
"Ethereum",

@ -2,8 +2,10 @@
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { formatFixed, parseFixed } from "@ethersproject/bignumber/fixednumber";
import * as errors from "@ethersproject/errors";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
const names = [
"wei",
@ -22,7 +24,7 @@ export function commify(value: string | number): string {
let comps = String(value).split(".");
if (comps.length > 2 || !comps[0].match(/^-?[0-9]*$/) || (comps[1] && !comps[1].match(/^[0-9]*$/)) || value === "." || value === "-.") {
errors.throwError("invalid value", errors.INVALID_ARGUMENT, { argument: "value", value: value });
logger.throwArgumentError("invalid value", "value", value);
}
// Make sure we have at least one whole digit (0 if none)

@ -12,11 +12,11 @@
"@ethersproject/address": ">5.0.0-beta.0",
"@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/hash": ">5.0.0-beta.0",
"@ethersproject/hdnode": ">5.0.0-beta.0",
"@ethersproject/json-wallets": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/random": ">5.0.0-beta.0",
"@ethersproject/signing-key": ">5.0.0-beta.0",

@ -4,7 +4,6 @@ import { getAddress } from "@ethersproject/address";
import { Provider, TransactionRequest } from "@ethersproject/abstract-provider";
import { ExternallyOwnedAccount, Signer } from "@ethersproject/abstract-signer";
import { arrayify, Bytes, BytesLike, concat, hexDataSlice, isHexString, joinSignature, SignatureLike } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { hashMessage } from "@ethersproject/hash";
import { defaultPath, HDNode, entropyToMnemonic } from "@ethersproject/hdnode";
import { keccak256 } from "@ethersproject/keccak256";
@ -15,6 +14,10 @@ import { decryptJsonWallet, encryptKeystore, ProgressCallback } from "@etherspro
import { computeAddress, recoverAddress, serialize } from "@ethersproject/transactions";
import { Wordlist } from "@ethersproject/wordlists/wordlist";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
function isAccount(value: any): value is ExternallyOwnedAccount {
return (value != null && isHexString(value.privateKey, 32) && value.address != null);
}
@ -32,7 +35,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
readonly _mnemonic: () => string;
constructor(privateKey: BytesLike | ExternallyOwnedAccount | SigningKey, provider?: Provider) {
errors.checkNew(new.target, Wallet);
logger.checkNew(new.target, Wallet);
super();
@ -42,7 +45,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
defineReadOnly(this, "address", computeAddress(this.publicKey));
if (this.address !== getAddress(privateKey.address)) {
errors.throwArgumentError("privateKey/address mismatch", "privateKey", "[REDCACTED]");
logger.throwArgumentError("privateKey/address mismatch", "privateKey", "[REDCACTED]");
}
if (privateKey.mnemonic != null) {
@ -52,7 +55,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
defineReadOnly(this, "path", privateKey.path);
let node = HDNode.fromMnemonic(mnemonic).derivePath(path);
if (computeAddress(node.privateKey) !== this.address) {
errors.throwArgumentError("mnemonic/address mismatch", "privateKey", "[REDCACTED]");
logger.throwArgumentError("mnemonic/address mismatch", "privateKey", "[REDCACTED]");
}
} else {
defineReadOnly(this, "_mnemonic", (): string => null);
@ -63,7 +66,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
} else {
if (SigningKey.isSigningKey(privateKey)) {
if (privateKey.curve !== "secp256k1") {
errors.throwArgumentError("unsupported curve; must be secp256k1", "privateKey", "[REDACTED]");
logger.throwArgumentError("unsupported curve; must be secp256k1", "privateKey", "[REDACTED]");
}
defineReadOnly(this, "_signingKey", () => privateKey);
} else {
@ -76,10 +79,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
}
if (provider && !Provider.isProvider(provider)) {
errors.throwError("invalid provider", errors.INVALID_ARGUMENT, {
argument: "provider",
value: provider
});
logger.throwArgumentError("invalid provider", "provider", provider);
}
defineReadOnly(this, "provider", provider || null);

@ -8,7 +8,7 @@
},
"dependencies": {
"@ethersproject/base64": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0",
"cross-fetch": "3.0.4"

@ -3,10 +3,12 @@
import fetch from "cross-fetch";
import { encode as base64Encode } from "@ethersproject/base64";
import * as errors from "@ethersproject/errors";
import { shallowCopy } from "@ethersproject/properties";
import { toUtf8Bytes } from "@ethersproject/strings";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
// Exported Types
export type ConnectionInfo = {
@ -57,7 +59,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
} else if (typeof(connection) === "object") {
if (connection == null || connection.url == null) {
errors.throwArgumentError("missing URL", "connection.url", connection);
logger.throwArgumentError("missing URL", "connection.url", connection);
}
url = connection.url;
@ -74,10 +76,10 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
if (connection.user != null && connection.password != null) {
if (url.substring(0, 6) !== "https:" && connection.allowInsecureAuthentication !== true) {
errors.throwError(
logger.throwError(
"basic authentication requires a secure https url",
errors.INVALID_ARGUMENT,
{ arg: "url", url: url, user: connection.user, password: "[REDACTED]" }
Logger.errors.INVALID_ARGUMENT,
{ argument: "url", url: url, user: connection.user, password: "[REDACTED]" }
);
}
@ -97,10 +99,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
if (timer == null) { return; }
timer = null;
reject(errors.makeError("timeout", errors.TIMEOUT, { }));
//setTimeout(() => {
// request.abort();
//}, 0);
reject(logger.makeError("timeout", Logger.errors.TIMEOUT, { timeout: timeout }));
}, timeout);
}
@ -126,7 +125,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
return fetch(url, options).then((response) => {
return response.text().then((body) => {
if (!response.ok) {
errors.throwError("bad response", errors.SERVER_ERROR, {
logger.throwError("bad response", Logger.errors.SERVER_ERROR, {
status: response.status,
body: body,
type: response.type,
@ -142,7 +141,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
try {
json = JSON.parse(text);
} catch (error) {
errors.throwError("invalid JSON", errors.SERVER_ERROR, {
logger.throwError("invalid JSON", Logger.errors.SERVER_ERROR, {
body: text,
error: error,
url: url
@ -153,7 +152,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
try {
json = processFunc(json);
} catch (error) {
errors.throwError("processing response error", errors.SERVER_ERROR, {
logger.throwError("processing response error", Logger.errors.SERVER_ERROR, {
body: json,
error: error
});

@ -9,8 +9,8 @@
},
"dependencies": {
"@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/errors": ">5.0.0-beta.0",
"@ethersproject/hash": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0"
},

@ -1,8 +1,11 @@
"use strict";
import { checkNormalize } from "@ethersproject/errors";
import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { check, register, Wordlist } from "./wordlist";
@ -12,7 +15,7 @@ let lookup: { [word: string]: number } = {};
let wordlist: Array<string> = null;
function dropDiacritic(word: string): string {
checkNormalize();
logger.checkNormalize();
return toUtf8String(Array.prototype.filter.call(toUtf8Bytes(word.normalize("NFD").toLowerCase()), (c: number) => {
return ((c >= 65 && c <= 90) || (c >= 97 && c <= 123));
}));

@ -1,8 +1,11 @@
"use strict";
import { checkNormalize } from "@ethersproject/errors";
import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { check, register, Wordlist } from "./wordlist";
@ -12,7 +15,7 @@ let wordlist: Array<string> = null;
let lookup: { [word: string]: number } = { }
function dropDiacritic(word: string): string {
checkNormalize();
logger.checkNormalize();
return toUtf8String(Array.prototype.filter.call(toUtf8Bytes(word.normalize("NFD").toLowerCase()), (c: number) => {
return ((c >= 65 && c <= 90) || (c >= 97 && c <= 123));
}));

@ -1,9 +1,12 @@
"use strict";
import { hexlify } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { check, register, Wordlist } from "./wordlist";
@ -133,7 +136,7 @@ class LangJa extends Wordlist {
}
split(mnemonic: string): Array<string> {
errors.checkNormalize();
logger.checkNormalize();
return mnemonic.split(/(?:\u3000| )+/g);
}

@ -3,10 +3,12 @@
// This gets overriddenby gulp during bip39-XX
let exportWordlist = false;
import { checkAbstract } from "@ethersproject/errors";
import { id } from "@ethersproject/hash";
import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export function check(wordlist: Wordlist) {
let words = [];
@ -22,7 +24,7 @@ export abstract class Wordlist {
readonly locale: string;
constructor(locale: string) {
checkAbstract(new.target, Wordlist);
logger.checkAbstract(new.target, Wordlist);
defineReadOnly(this, "locale", locale);
}

@ -12,6 +12,9 @@
{
"path": "./packages/errors"
},
{
"path": "./packages/logger"
},
{
"path": "./packages/bytes"
},