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

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

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

@ -1,9 +1,11 @@
"use strict"; "use strict";
import { BigNumber } from "@ethersproject/bignumber"; import { BigNumber } from "@ethersproject/bignumber";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties"; import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export interface JsonFragmentType { export interface JsonFragmentType {
name?: string; name?: string;
@ -58,7 +60,7 @@ function checkModifier(type: string, name: string): boolean {
if (name === "payable") { return true; } if (name === "payable") { return true; }
} }
if (ModifiersBytes[name] || name === "payable") { if (ModifiersBytes[name] || name === "payable") {
errors.throwArgumentError("invalid modifier", "name", name); logger.throwArgumentError("invalid modifier", "name", name);
} }
return false; return false;
} }
@ -299,7 +301,7 @@ export class ParamType {
format(format?: string): string { format(format?: string): string {
if (!format) { format = FormatTypes.sighash; } if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) { if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format); logger.throwArgumentError("invalid format type", "format", format);
} }
if (format === FormatTypes.json) { if (format === FormatTypes.json) {
@ -426,7 +428,7 @@ export abstract class Fragment {
return null; return null;
} }
return errors.throwArgumentError("invalid fragment object", "value", value); return logger.throwArgumentError("invalid fragment object", "value", value);
} }
static fromString(value: string): Fragment { static fromString(value: string): Fragment {
@ -457,7 +459,7 @@ export class EventFragment extends Fragment {
format(format?: string): string { format(format?: string): string {
if (!format) { format = FormatTypes.sighash; } if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) { if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format); logger.throwArgumentError("invalid format type", "format", format);
} }
if (format === FormatTypes.json) { if (format === FormatTypes.json) {
@ -522,7 +524,7 @@ export class EventFragment extends Fragment {
case "": case "":
break; break;
default: default:
errors.warn("unknown modifier: " + modifier); logger.warn("unknown modifier: " + modifier);
} }
}); });
@ -638,7 +640,7 @@ export class ConstructorFragment extends Fragment {
format(format?: string): string { format(format?: string): string {
if (!format) { format = FormatTypes.sighash; } if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) { if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format); logger.throwArgumentError("invalid format type", "format", format);
} }
if (format === FormatTypes.json) { if (format === FormatTypes.json) {
@ -652,7 +654,7 @@ export class ConstructorFragment extends Fragment {
} }
if (format === FormatTypes.sighash) { 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)" operation: "format(sighash)"
}); });
} }
@ -722,7 +724,7 @@ export class FunctionFragment extends ConstructorFragment {
format(format?: string): string { format(format?: string): string {
if (!format) { format = FormatTypes.sighash; } if (!format) { format = FormatTypes.sighash; }
if (!FormatTypes[format]) { if (!FormatTypes[format]) {
errors.throwArgumentError("invalid format type", "format", format); logger.throwArgumentError("invalid format type", "format", format);
} }
if (format === FormatTypes.json) { 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 { arrayify, BytesLike, concat, hexDataSlice, hexlify, hexZeroPad, isHexString } from "@ethersproject/bytes";
import { id } from "@ethersproject/hash"; import { id } from "@ethersproject/hash";
import { keccak256 } from "@ethersproject/keccak256" import { keccak256 } from "@ethersproject/keccak256"
import * as errors from "@ethersproject/errors";
import { defineReadOnly, Description, getStatic } from "@ethersproject/properties"; import { defineReadOnly, Description, getStatic } from "@ethersproject/properties";
import { AbiCoder, defaultAbiCoder } from "./abi-coder"; import { AbiCoder, defaultAbiCoder } from "./abi-coder";
import { ConstructorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments"; 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 { export class LogDescription extends Description {
readonly eventFragment: EventFragment; readonly eventFragment: EventFragment;
@ -58,7 +60,7 @@ export class Interface {
static _isInterface: boolean; static _isInterface: boolean;
constructor(fragments: string | Array<Fragment | JsonFragment | string>) { constructor(fragments: string | Array<Fragment | JsonFragment | string>) {
errors.checkNew(new.target, Interface); logger.checkNew(new.target, Interface);
let abi: Array<Fragment | JsonFragment | string> = [ ]; let abi: Array<Fragment | JsonFragment | string> = [ ];
if (typeof(fragments) === "string") { if (typeof(fragments) === "string") {
@ -84,7 +86,7 @@ export class Interface {
switch (fragment.type) { switch (fragment.type) {
case "constructor": case "constructor":
if (this.deploy) { if (this.deploy) {
errors.warn("duplicate definition - constructor"); logger.warn("duplicate definition - constructor");
return; return;
} }
defineReadOnly(this, "deploy", fragment); defineReadOnly(this, "deploy", fragment);
@ -101,7 +103,7 @@ export class Interface {
let signature = fragment.format(); let signature = fragment.format();
if (bucket[signature]) { if (bucket[signature]) {
errors.warn("duplicate definition - " + signature); logger.warn("duplicate definition - " + signature);
return; return;
} }
@ -114,7 +116,7 @@ export class Interface {
Object.keys(bucket).forEach((signature) => { Object.keys(bucket).forEach((signature) => {
let fragment = bucket[signature]; let fragment = bucket[signature];
if (count[fragment.name] !== 1) { if (count[fragment.name] !== 1) {
errors.warn("duplicate definition - " + fragment.name); logger.warn("duplicate definition - " + fragment.name);
return; return;
} }
bucket[fragment.name] = fragment; bucket[fragment.name] = fragment;
@ -233,7 +235,7 @@ export class Interface {
break; break;
} }
return errors.throwError("call revert exception", errors.CALL_EXCEPTION, { return logger.throwError("call revert exception", Logger.errors.CALL_EXCEPTION, {
method: functionFragment.format(), method: functionFragment.format(),
errorSignature: errorSignature, errorSignature: errorSignature,
errorArgs: [ reason ], errorArgs: [ reason ],
@ -247,7 +249,7 @@ export class Interface {
} }
if (values.length > eventFragment.inputs.length) { 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", argument: "values",
value: values value: values
}) })
@ -262,7 +264,7 @@ export class Interface {
if (!param.indexed) { if (!param.indexed) {
if (value != null) { 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; return;
} }
@ -274,7 +276,7 @@ export class Interface {
} else if (param.type === "bytes") { } else if (param.type === "bytes") {
topics.push(keccak256(hexlify(value))); topics.push(keccak256(hexlify(value)));
} else if (param.type.indexOf("[") !== -1 || param.type.substring(0, 5) === "tuple") { } 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 { } else {
// Check addresses are valid // Check addresses are valid
if (param.type === "address") { this._abiCoder.encode( [ "address" ], [ value ]); } if (param.type === "address") { this._abiCoder.encode( [ "address" ], [ value ]); }
@ -298,7 +300,7 @@ export class Interface {
if (topics != null && !eventFragment.anonymous) { if (topics != null && !eventFragment.anonymous) {
let topicHash = this.getEventTopic(eventFragment); let topicHash = this.getEventTopic(eventFragment);
if (!isHexString(topics[0], 32) || topics[0].toLowerCase() !== topicHash) { 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); topics = topics.slice(1);
} }

@ -13,7 +13,7 @@
"dependencies": { "dependencies": {
"@ethersproject/bignumber": ">5.0.0-beta.0", "@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">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/networks": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0", "@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/transactions": ">5.0.0-beta.0", "@ethersproject/transactions": ">5.0.0-beta.0",

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

@ -10,7 +10,7 @@
"@ethersproject/abstract-provider": ">5.0.0-beta.0", "@ethersproject/abstract-provider": ">5.0.0-beta.0",
"@ethersproject/bignumber": ">5.0.0-beta.0", "@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">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" "@ethersproject/properties": ">5.0.0-beta.0"
}, },
"keywords": [ "keywords": [

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

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

@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/bytes": ">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", "@ethersproject/properties": ">5.0.0-beta.0",
"bn.js": "^4.4.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 { 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 = { }; const _constructorGuard = { };
@ -37,10 +39,10 @@ export class BigNumber implements Hexable {
readonly _isBigNumber: boolean; readonly _isBigNumber: boolean;
constructor(constructorGuard: any, hex: string) { constructor(constructorGuard: any, hex: string) {
errors.checkNew(new.target, BigNumber); logger.checkNew(new.target, BigNumber);
if (constructorGuard !== _constructorGuard) { 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)" operation: "new (BigNumber)"
}); });
} }
@ -134,7 +136,7 @@ export class BigNumber implements Hexable {
toString(): string { toString(): string {
// Lots of people expect this, which we do not support, so check // Lots of people expect this, which we do not support, so check
if (arguments.length !== 0) { 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); return toBN(this).toString(10);
} }
@ -155,7 +157,7 @@ export class BigNumber implements Hexable {
return new BigNumber(_constructorGuard, toHex(new BN.BN(value))); 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") { 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 { static isBigNumber(value: any): value is BigNumber {
@ -211,7 +213,7 @@ function toHex(value: string | BN.BN): string {
value = value.substring(1); value = value.substring(1);
// Cannot have mulitple negative signs (e.g. "--0x04") // 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 // Call toHex on the positive component
value = toHex(value); value = toHex(value);
@ -256,5 +258,5 @@ function throwFault(fault: string, operation: string, value?: any): never {
let params: any = { fault: fault, operation: operation }; let params: any = { fault: fault, operation: operation };
if (value != null) { params.value = value; } 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"; "use strict";
import { arrayify, BytesLike, hexZeroPad, isBytes } from "@ethersproject/bytes"; 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"; 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 { function throwFault(message: string, fault: string, operation: string, value?: any): never {
let params: any = { fault: fault, operation: operation }; let params: any = { fault: fault, operation: operation };
if (value !== undefined) { params.value = value; } 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 // Constant to pull zeros from for multipliers
@ -33,7 +36,7 @@ function getMultiplier(decimals: BigNumberish): string {
return ("1" + zeros.substring(0, decimals)); 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 { 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); let multiplier = getMultiplier(decimals);
if (typeof(value) !== "string" || !value.match(/^-?[0-9.,]+$/)) { 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) { if (multiplier.length - 1 === 0) {
@ -78,13 +81,13 @@ export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
if (negative) { value = value.substring(1); } if (negative) { value = value.substring(1); }
if (value === ".") { if (value === ".") {
errors.throwArgumentError("missing value", "value", value); logger.throwArgumentError("missing value", "value", value);
} }
// Split it into a whole and fractional part // Split it into a whole and fractional part
let comps = value.split("."); let comps = value.split(".");
if (comps.length > 2) { 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]; let whole = comps[0], fraction = comps[1];
@ -142,7 +145,7 @@ export class FixedFormat {
signed = false; signed = false;
} else if (value != null) { } else if (value != null) {
let match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/); 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"); signed = (match[1] !== "u");
width = parseInt(match[2]); width = parseInt(match[2]);
decimals = parseInt(match[3]); decimals = parseInt(match[3]);
@ -151,7 +154,7 @@ export class FixedFormat {
let check = (key: string, type: string, defaultValue: any): any => { let check = (key: string, type: string, defaultValue: any): any => {
if (value[key] == null) { return defaultValue; } if (value[key] == null) { return defaultValue; }
if (typeof(value[key]) !== type) { 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]; return value[key];
} }
@ -161,11 +164,11 @@ export class FixedFormat {
} }
if (width % 8) { 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) { 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); return new FixedFormat(_constructorGuard, signed, width, decimals);
@ -180,7 +183,7 @@ export class FixedNumber {
readonly _isFixedNumber: boolean; readonly _isFixedNumber: boolean;
constructor(constructorGuard: any, hex: string, value: string, format?: FixedFormat) { constructor(constructorGuard: any, hex: string, value: string, format?: FixedFormat) {
errors.checkNew(new.target, FixedNumber); logger.checkNew(new.target, FixedNumber);
this.format = format; this.format = format;
this._hex = hex; this._hex = hex;
@ -193,7 +196,7 @@ export class FixedNumber {
_checkFormat(other: FixedNumber): void { _checkFormat(other: FixedNumber): void {
if (this.format.name !== other.format.name) { 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 { round(decimals?: number): FixedNumber {
if (decimals == null) { decimals = 0; } if (decimals == null) { decimals = 0; }
if (decimals < 0 || decimals > 80 || (decimals % 1)) { 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 // If we are already in range, we're done
@ -249,7 +252,7 @@ export class FixedNumber {
toHexString(width?: number): string { toHexString(width?: number): string {
if (width == null) { return this._hex; } 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(); let hex = BigNumber.from(this._hex).fromTwos(this.format.width).toTwos(width).toHexString();
return hexZeroPad(hex, width / 8); return hexZeroPad(hex, width / 8);
} }
@ -330,12 +333,12 @@ export class FixedNumber {
return FixedNumber.fromValue(value, 0, format); return FixedNumber.fromValue(value, 0, format);
} catch (error) { } catch (error) {
// Allow NUMERIC_FAULT to bubble up // Allow NUMERIC_FAULT to bubble up
if (error.code !== errors.INVALID_ARGUMENT) { if (error.code !== Logger.errors.INVALID_ARGUMENT) {
throw error; 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 { static isFixedNumber(value: any): value is FixedNumber {

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

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

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

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

@ -8,8 +8,8 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/bytes": ">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/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0" "@ethersproject/strings": ">5.0.0-beta.0"
}, },
"keywords": [ "keywords": [

@ -1,11 +1,13 @@
"use strict"; "use strict";
import * as errors from "@ethersproject/errors";
import { Bytes, concat, hexlify } from "@ethersproject/bytes"; import { Bytes, concat, hexlify } from "@ethersproject/bytes";
import { nameprep, toUtf8Bytes } from "@ethersproject/strings"; import { nameprep, toUtf8Bytes } from "@ethersproject/strings";
import { keccak256 } from "@ethersproject/keccak256"; 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]); 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 { export function namehash(name: string): string {
if (typeof(name) !== "string") { if (typeof(name) !== "string") {
errors.throwError("invalid address - " + String(name), errors.INVALID_ARGUMENT, { logger.throwArgumentError("invalid address - " + String(name), "name", name);
argument: "name",
value: name
});
} }
let result: string | Uint8Array = Zeros; let result: string | Uint8Array = Zeros;

@ -11,7 +11,7 @@
"@ethersproject/basex": ">5.0.0-beta.0", "@ethersproject/basex": ">5.0.0-beta.0",
"@ethersproject/bignumber": ">5.0.0-beta.0", "@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">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/pbkdf2": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0", "@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/sha2": ">5.0.0-beta.0", "@ethersproject/sha2": ">5.0.0-beta.0",

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

@ -10,9 +10,9 @@
"@ethersproject/abstract-signer": ">5.0.0-beta.0", "@ethersproject/abstract-signer": ">5.0.0-beta.0",
"@ethersproject/address": ">5.0.0-beta.0", "@ethersproject/address": ">5.0.0-beta.0",
"@ethersproject/bytes": ">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/hdnode": ">5.0.0-beta.0",
"@ethersproject/keccak256": ">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/pbkdf2": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0", "@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/random": ">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 { ExternallyOwnedAccount } from "@ethersproject/abstract-signer";
import { getAddress } from "@ethersproject/address"; import { getAddress } from "@ethersproject/address";
import { arrayify, Bytes } from "@ethersproject/bytes"; import { arrayify, Bytes } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { keccak256 } from "@ethersproject/keccak256"; import { keccak256 } from "@ethersproject/keccak256";
import { pbkdf2 } from "@ethersproject/pbkdf2"; import { pbkdf2 } from "@ethersproject/pbkdf2";
import { toUtf8Bytes } from "@ethersproject/strings"; import { toUtf8Bytes } from "@ethersproject/strings";
import { Description } from "@ethersproject/properties"; 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"; import { getPassword, looseArrayify, searchPath } from "./utils";
export class CrowdsaleAccount extends Description implements ExternallyOwnedAccount { export class CrowdsaleAccount extends Description implements ExternallyOwnedAccount {
@ -38,10 +41,7 @@ export function decrypt(json: string, password: Bytes | string): ExternallyOwned
// Encrypted Seed // Encrypted Seed
let encseed = looseArrayify(searchPath(data, "encseed")); let encseed = looseArrayify(searchPath(data, "encseed"));
if (!encseed || (encseed.length % 16) !== 0) { if (!encseed || (encseed.length % 16) !== 0) {
errors.throwError("invalid encseed", errors.INVALID_ARGUMENT, { logger.throwArgumentError("invalid encseed", "json", json);
argument: "json",
value: json
});
} }
let key = arrayify(pbkdf2(password, password, 2000, 32, "sha256")).slice(0, 16); 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" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"dependencies": { "dependencies": {
"@ethersproject/errors": ">5.0.0-beta.0" "@ethersproject/logger": ">5.0.0-beta.0"
}, },
"keywords": [ "keywords": [
"Ethereum", "Ethereum",

@ -1,6 +1,8 @@
"use strict"; "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"; 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 // Not a standard network; check that it is a valid network in general
if (!standard) { if (!standard) {
if (typeof(network.chainId) !== "number") { 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; return network;
} }
// Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155) // Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)
if (network.chainId !== 0 && network.chainId !== standard.chainId) { 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) // Standard Network (allow overriding the ENS address)

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

@ -1,6 +1,8 @@
"use strict"; "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 { export function defineReadOnly(object: any, name: string, value: any): void {
Object.defineProperty(object, name, { 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 { export function checkProperties(object: any, properties: { [ name: string ]: boolean }): void {
if (!object || typeof(object) !== "object") { if (!object || typeof(object) !== "object") {
errors.throwError("invalid object", errors.INVALID_ARGUMENT, { logger.throwArgumentError("invalid object", "object", object);
argument: "object",
value: object
});
} }
Object.keys(object).forEach((key) => { Object.keys(object).forEach((key) => {
if (!properties[key]) { if (!properties[key]) {
errors.throwError("invalid object key - " + key, errors.INVALID_ARGUMENT, { logger.throwArgumentError("invalid object key - " + key, "transaction:" + key, object);
argument: "transaction",
value: object,
key: key
});
} }
}); });
} }

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

@ -1,8 +1,11 @@
"use strict"; "use strict";
import * as errors from "@ethersproject/errors";
import { Network } from "@ethersproject/networks"; 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"; import { UrlJsonRpcProvider } from "./url-json-rpc-provider";
// This key was provided to ethers.js by Alchemy to be used by the // 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/"; host = "eth-kovan.alchemyapi.io/jsonrpc/";
break; break;
default: default:
errors.throwArgumentError("unsupported network", "network", arguments[0]); logger.throwArgumentError("unsupported network", "network", arguments[0]);
} }
return ("https:/" + "/" + host + apiKey); return ("https:/" + "/" + host + apiKey);

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

@ -2,11 +2,14 @@
import { BlockTag, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider"; import { BlockTag, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
import { hexlify, hexValue } from "@ethersproject/bytes"; import { hexlify, hexValue } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { Networkish } from "@ethersproject/networks"; import { Networkish } from "@ethersproject/networks";
import { deepCopy, defineReadOnly } from "@ethersproject/properties"; import { deepCopy, defineReadOnly } from "@ethersproject/properties";
import { fetchJson } from "@ethersproject/web"; import { fetchJson } from "@ethersproject/web";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
import { BaseProvider } from "./base-provider"; import { BaseProvider } from "./base-provider";
@ -72,7 +75,7 @@ export class EtherscanProvider extends BaseProvider{
readonly baseUrl: string; readonly baseUrl: string;
readonly apiKey: string; readonly apiKey: string;
constructor(network?: Networkish, apiKey?: string) { constructor(network?: Networkish, apiKey?: string) {
errors.checkNew(new.target, EtherscanProvider); logger.checkNew(new.target, EtherscanProvider);
super(network); super(network);
@ -169,15 +172,15 @@ export class EtherscanProvider extends BaseProvider{
if (error.responseText) { if (error.responseText) {
// "Insufficient funds. The account you tried to send transaction from does not have enough funds. Required 21464000000000 and got: 0" // "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) { 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." // "Transaction with the same hash was already imported."
if (error.responseText.indexOf("same hash was already imported") >= 0) { 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." // "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) { 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; throw error;

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

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

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

@ -2,10 +2,13 @@
import net from "net"; import net from "net";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties"; import { defineReadOnly } from "@ethersproject/properties";
import { Networkish } from "@ethersproject/networks"; 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"; import { JsonRpcProvider } from "./json-rpc-provider";
@ -13,10 +16,10 @@ export class IpcProvider extends JsonRpcProvider {
readonly path: string; readonly path: string;
constructor(path: string, network?: Networkish) { constructor(path: string, network?: Networkish) {
errors.checkNew(new.target, IpcProvider); logger.checkNew(new.target, IpcProvider);
if (path == null) { 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); super("ipc://" + path, network);

@ -6,12 +6,15 @@ import { Provider, TransactionRequest, TransactionResponse } from "@ethersprojec
import { Signer } from "@ethersproject/abstract-signer"; import { Signer } from "@ethersproject/abstract-signer";
import { BigNumber } from "@ethersproject/bignumber"; import { BigNumber } from "@ethersproject/bignumber";
import { Bytes, hexlify, hexValue } from "@ethersproject/bytes"; import { Bytes, hexlify, hexValue } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { getNetwork, Network, Networkish } from "@ethersproject/networks"; import { getNetwork, Network, Networkish } from "@ethersproject/networks";
import { checkProperties, deepCopy, defineReadOnly, resolveProperties, shallowCopy } from "@ethersproject/properties"; import { checkProperties, deepCopy, defineReadOnly, resolveProperties, shallowCopy } from "@ethersproject/properties";
import { toUtf8Bytes } from "@ethersproject/strings"; import { toUtf8Bytes } from "@ethersproject/strings";
import { ConnectionInfo, fetchJson, poll } from "@ethersproject/web"; 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"; import { BaseProvider } from "./base-provider";
@ -48,7 +51,7 @@ export class JsonRpcSigner extends Signer {
_address: string; _address: string;
constructor(constructorGuard: any, provider: JsonRpcProvider, addressOrIndex?: string | number) { constructor(constructorGuard: any, provider: JsonRpcProvider, addressOrIndex?: string | number) {
errors.checkNew(new.target, JsonRpcSigner); logger.checkNew(new.target, JsonRpcSigner);
super(); super();
@ -69,12 +72,12 @@ export class JsonRpcSigner extends Signer {
defineReadOnly(this, "_address", null); defineReadOnly(this, "_address", null);
} else { } 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 { 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" operation: "connect"
}); });
} }
@ -90,7 +93,9 @@ export class JsonRpcSigner extends Signer {
return this.provider.send("eth_accounts", []).then((accounts) => { return this.provider.send("eth_accounts", []).then((accounts) => {
if (accounts.length <= this._index) { 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]) return this.provider.formatter.address(accounts[this._index])
}); });
@ -126,17 +131,17 @@ export class JsonRpcSigner extends Signer {
if (error.responseText) { if (error.responseText) {
// See: JsonRpcProvider.sendTransaction (@TODO: Expose a ._throwError??) // See: JsonRpcProvider.sendTransaction (@TODO: Expose a ._throwError??)
if (error.responseText.indexOf("insufficient funds") >= 0) { if (error.responseText.indexOf("insufficient funds") >= 0) {
errors.throwError("insufficient funds", errors.INSUFFICIENT_FUNDS, { logger.throwError("insufficient funds", Logger.errors.INSUFFICIENT_FUNDS, {
transaction: tx transaction: tx
}); });
} }
if (error.responseText.indexOf("nonce too low") >= 0) { 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 transaction: tx
}); });
} }
if (error.responseText.indexOf("replacement transaction underpriced") >= 0) { 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 transaction: tx
}); });
} }
@ -147,7 +152,7 @@ export class JsonRpcSigner extends Signer {
} }
signTransaction(transaction: TransactionRequest): Promise<string> { 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" operation: "signTransaction"
}); });
} }
@ -214,7 +219,7 @@ export class JsonRpcProvider extends BaseProvider {
_nextId: number; _nextId: number;
constructor(url?: ConnectionInfo | string, network?: Networkish) { 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 // One parameter, but it is a network name, so swap it with the URL
if (typeof(url) === "string") { if (typeof(url) === "string") {
@ -239,7 +244,7 @@ export class JsonRpcProvider extends BaseProvider {
this.send("net_version", [ ]).then((result) => { this.send("net_version", [ ]).then((result) => {
resolve(getNetwork(BigNumber.from(result).toNumber())); resolve(getNetwork(BigNumber.from(result).toNumber()));
}).catch((error) => { }).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) { if (error.responseText) {
// "insufficient funds for gas * price + value" // "insufficient funds for gas * price + value"
if (error.responseText.indexOf("insufficient funds") > 0) { 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" // "nonce too low"
if (error.responseText.indexOf("nonce too low") > 0) { 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" // "replacement transaction underpriced"
if (error.responseText.indexOf("replacement transaction underpriced") > 0) { 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; throw error;
@ -369,7 +374,7 @@ export class JsonRpcProvider extends BaseProvider {
break; 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 { _startPending(): void {

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

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

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

@ -9,7 +9,7 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/bytes": ">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"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "10.3.2" "@types/node": "10.3.2"

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

@ -9,7 +9,7 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/bytes": ">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",
"hash.js": "1.1.3" "hash.js": "1.1.3"
}, },
"keywords": [ "keywords": [

@ -3,8 +3,10 @@
import * as hash from "hash.js"; import * as hash from "hash.js";
import { arrayify, BytesLike } from "@ethersproject/bytes"; 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" }; 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 { export function computeHmac(algorithm: SupportedAlgorithms, key: BytesLike, data: BytesLike): string {
if (!SupportedAlgorithms[algorithm]) { if (!SupportedAlgorithms[algorithm]) {
errors.throwError("unsupported algorithm " + algorithm, errors.UNSUPPORTED_OPERATION, { logger.throwError("unsupported algorithm " + algorithm, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "hmac", operation: "hmac",
algorithm: algorithm algorithm: algorithm
}); });

@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/bytes": ">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", "@ethersproject/properties": ">5.0.0-beta.0",
"elliptic": "6.3.3" "elliptic": "6.3.3"
}, },

@ -3,9 +3,12 @@
import { ec as EC } from "elliptic"; import { ec as EC } from "elliptic";
import { arrayify, BytesLike, hexlify, hexZeroPad, Signature, SignatureLike, splitSignature } from "@ethersproject/bytes"; import { arrayify, BytesLike, hexlify, hexZeroPad, Signature, SignatureLike, splitSignature } from "@ethersproject/bytes";
import * as errors from "@ethersproject/errors";
import { defineReadOnly } from "@ethersproject/properties"; import { defineReadOnly } from "@ethersproject/properties";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
let _curve: EC = null let _curve: EC = null
function getCurve() { function getCurve() {
if (!_curve) { if (!_curve) {
@ -91,6 +94,6 @@ export function computePublicKey(key: BytesLike, compressed?: boolean): string {
return "0x" + getCurve().keyFromPublic(bytes).getPublic(true, "hex"); 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/bignumber": ">5.0.0-beta.0",
"@ethersproject/bytes": ">5.0.0-beta.0", "@ethersproject/bytes": ">5.0.0-beta.0",
"@ethersproject/constants": ">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/keccak256": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0", "@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/rlp": ">5.0.0-beta.0", "@ethersproject/rlp": ">5.0.0-beta.0",
"@ethersproject/signing-key": ">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 { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { arrayify, BytesLike, hexDataSlice, hexlify, hexZeroPad, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes"; import { arrayify, BytesLike, hexDataSlice, hexlify, hexZeroPad, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { Zero } from "@ethersproject/constants"; import { Zero } from "@ethersproject/constants";
import * as errors from "@ethersproject/errors";
import { keccak256 } from "@ethersproject/keccak256"; import { keccak256 } from "@ethersproject/keccak256";
import { checkProperties } from "@ethersproject/properties"; import { checkProperties } from "@ethersproject/properties";
import * as RLP from "@ethersproject/rlp"; import * as RLP from "@ethersproject/rlp";
import { computePublicKey, recoverPublicKey } from "@ethersproject/signing-key"; import { computePublicKey, recoverPublicKey } from "@ethersproject/signing-key";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
/////////////////////////////// ///////////////////////////////
// Exported Types // Exported Types
@ -90,14 +93,14 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
// Fixed-width field // Fixed-width field
if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) { 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) // Variable-width (with a maximum)
if (fieldInfo.maxLength) { if (fieldInfo.maxLength) {
value = stripZeros(value); value = stripZeros(value);
if (value.length > fieldInfo.maxLength) { 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 { export function parse(rawTransaction: BytesLike): Transaction {
let transaction = RLP.decode(rawTransaction); let transaction = RLP.decode(rawTransaction);
if (transaction.length !== 9 && transaction.length !== 6) { 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 = { let tx: Transaction = {

@ -9,7 +9,7 @@
"dependencies": { "dependencies": {
"@ethersproject/bignumber": ">5.0.0-beta.0", "@ethersproject/bignumber": ">5.0.0-beta.0",
"@ethersproject/constants": ">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": [ "keywords": [
"Ethereum", "Ethereum",

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

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

@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/base64": ">5.0.0-beta.0", "@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/properties": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0", "@ethersproject/strings": ">5.0.0-beta.0",
"cross-fetch": "3.0.4" "cross-fetch": "3.0.4"

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

@ -9,8 +9,8 @@
}, },
"dependencies": { "dependencies": {
"@ethersproject/bytes": ">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/hash": ">5.0.0-beta.0",
"@ethersproject/logger": ">5.0.0-beta.0",
"@ethersproject/properties": ">5.0.0-beta.0", "@ethersproject/properties": ">5.0.0-beta.0",
"@ethersproject/strings": ">5.0.0-beta.0" "@ethersproject/strings": ">5.0.0-beta.0"
}, },

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

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

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

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

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