Migrating to modern syntax and scoping (#634).
This commit is contained in:
parent
1d4f90a958
commit
394c36cad4
|
@ -132,13 +132,13 @@ export abstract class Signer {
|
|||
// - estimateGas
|
||||
// - populateTransaction (and therefor sendTransaction)
|
||||
checkTransaction(transaction: TransactionRequest): TransactionRequest {
|
||||
for (let key in transaction) {
|
||||
for (const key in transaction) {
|
||||
if (allowedTransactionKeys.indexOf(key) === -1) {
|
||||
logger.throwArgumentError("invalid transaction key: " + key, "transaction", transaction);
|
||||
}
|
||||
}
|
||||
|
||||
let tx = shallowCopy(transaction);
|
||||
const tx = shallowCopy(transaction);
|
||||
if (tx.from == null) { tx.from = this.getAddress(); }
|
||||
return tx;
|
||||
}
|
||||
|
@ -147,39 +147,38 @@ export abstract class Signer {
|
|||
// this Signer. Should be used by sendTransaction but NOT by signTransaction.
|
||||
// By default called from: (overriding these prevents it)
|
||||
// - sendTransaction
|
||||
populateTransaction(transaction: TransactionRequest): Promise<TransactionRequest> {
|
||||
return resolveProperties(this.checkTransaction(transaction)).then((tx) => {
|
||||
async populateTransaction(transaction: TransactionRequest): Promise<TransactionRequest> {
|
||||
const tx = await resolveProperties(this.checkTransaction(transaction))
|
||||
|
||||
if (tx.to != null) { tx.to = Promise.resolve(tx.to).then((to) => this.resolveName(to)); }
|
||||
if (tx.gasPrice == null) { tx.gasPrice = this.getGasPrice(); }
|
||||
if (tx.nonce == null) { tx.nonce = this.getTransactionCount("pending"); }
|
||||
if (tx.to != null) { tx.to = Promise.resolve(tx.to).then((to) => this.resolveName(to)); }
|
||||
if (tx.gasPrice == null) { tx.gasPrice = this.getGasPrice(); }
|
||||
if (tx.nonce == null) { tx.nonce = this.getTransactionCount("pending"); }
|
||||
|
||||
// Make sure any provided address matches this signer
|
||||
if (tx.from == null) {
|
||||
tx.from = this.getAddress();
|
||||
} else {
|
||||
tx.from = Promise.all([
|
||||
this.getAddress(),
|
||||
this.provider.resolveName(tx.from)
|
||||
]).then((results) => {
|
||||
if (results[0] !== results[1]) {
|
||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
||||
}
|
||||
return results[0];
|
||||
// Make sure any provided address matches this signer
|
||||
if (tx.from == null) {
|
||||
tx.from = this.getAddress();
|
||||
} else {
|
||||
tx.from = Promise.all([
|
||||
this.getAddress(),
|
||||
this.provider.resolveName(tx.from)
|
||||
]).then((results) => {
|
||||
if (results[0] !== results[1]) {
|
||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
||||
}
|
||||
return results[0];
|
||||
});
|
||||
}
|
||||
|
||||
if (tx.gasLimit == null) {
|
||||
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||
tx: tx
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (tx.chainId == null) { tx.chainId = this.getChainId(); }
|
||||
|
||||
if (tx.gasLimit == null) {
|
||||
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||
tx: tx
|
||||
});
|
||||
});
|
||||
}
|
||||
if (tx.chainId == null) { tx.chainId = this.getChainId(); }
|
||||
|
||||
return resolveProperties(tx);
|
||||
});
|
||||
return await resolveProperties(tx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,13 +19,14 @@ function getChecksumAddress(address: string): string {
|
|||
|
||||
address = address.toLowerCase();
|
||||
|
||||
let chars = address.substring(2).split("");
|
||||
const chars = address.substring(2).split("");
|
||||
|
||||
let hashed = new Uint8Array(40);
|
||||
const expanded = new Uint8Array(40);
|
||||
for (let i = 0; i < 40; i++) {
|
||||
hashed[i] = chars[i].charCodeAt(0);
|
||||
expanded[i] = chars[i].charCodeAt(0);
|
||||
}
|
||||
hashed = arrayify(keccak256(hashed));
|
||||
|
||||
const hashed = arrayify(keccak256(expanded));
|
||||
|
||||
for (let i = 0; i < 40; i += 2) {
|
||||
if ((hashed[i >> 1] >> 4) >= 8) {
|
||||
|
@ -51,21 +52,18 @@ function log10(x: number): number {
|
|||
// See: https://en.wikipedia.org/wiki/International_Bank_Account_Number
|
||||
|
||||
// Create lookup table
|
||||
let ibanLookup: { [character: string]: string } = {};
|
||||
const ibanLookup: { [character: string]: string } = { };
|
||||
for (let i = 0; i < 10; i++) { ibanLookup[String(i)] = String(i); }
|
||||
for (let i = 0; i < 26; i++) { ibanLookup[String.fromCharCode(65 + i)] = String(10 + i); }
|
||||
|
||||
// How many decimal digits can we process? (for 64-bit float, this is 15)
|
||||
let safeDigits = Math.floor(log10(MAX_SAFE_INTEGER));
|
||||
const safeDigits = Math.floor(log10(MAX_SAFE_INTEGER));
|
||||
|
||||
function ibanChecksum(address: string): string {
|
||||
address = address.toUpperCase();
|
||||
address = address.substring(4) + address.substring(0, 2) + "00";
|
||||
|
||||
let expanded = "";
|
||||
address.split("").forEach(function(c) {
|
||||
expanded += ibanLookup[c];
|
||||
});
|
||||
let expanded = address.split("").map((c) => { return ibanLookup[c]; }).join("");
|
||||
|
||||
// Javascript can handle integers safely up to 15 (decimal) digits
|
||||
while (expanded.length >= safeDigits){
|
||||
|
@ -140,7 +138,7 @@ export function getContractAddress(transaction: { from: string, nonce: BigNumber
|
|||
logger.throwArgumentError("missing from address", "transaction", transaction);
|
||||
}
|
||||
|
||||
let nonce = stripZeros(arrayify(BigNumber.from(transaction.nonce).toHexString()));
|
||||
const nonce = stripZeros(arrayify(BigNumber.from(transaction.nonce).toHexString()));
|
||||
|
||||
return getAddress(hexDataSlice(keccak256(encode([ from, nonce ])), 12));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { arrayify, BytesLike } from "@ethersproject/bytes";
|
|||
|
||||
export function decode(textData: string): Uint8Array {
|
||||
textData = atob(textData);
|
||||
let data = [];
|
||||
const data = [];
|
||||
for (let i = 0; i < textData.length; i++) {
|
||||
data.push(textData.charCodeAt(i));
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ export class BigNumber implements Hexable {
|
|||
}
|
||||
|
||||
div(other: BigNumberish): BigNumber {
|
||||
let o = BigNumber.from(other);
|
||||
const o = BigNumber.from(other);
|
||||
if (o.isZero()) {
|
||||
throwFault("division by zero", "div");
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ function toBigNumber(value: BN): BigNumber {
|
|||
}
|
||||
|
||||
function toBN(value: BigNumberish): BN {
|
||||
let hex = BigNumber.from(value).toHexString();
|
||||
const hex = BigNumber.from(value).toHexString();
|
||||
if (hex[0] === "-") {
|
||||
return (new BN("-" + hex.substring(3), 16));
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ function toBN(value: BigNumberish): BN {
|
|||
}
|
||||
|
||||
function throwFault(fault: string, operation: string, value?: any): never {
|
||||
let params: any = { fault: fault, operation: operation };
|
||||
const params: any = { fault: fault, operation: operation };
|
||||
if (value != null) { params.value = value; }
|
||||
|
||||
return logger.throwError(fault, Logger.errors.NUMERIC_FAULT, params);
|
||||
|
|
|
@ -14,7 +14,7 @@ const Zero = BigNumber.from(0);
|
|||
const NegativeOne = BigNumber.from(-1);
|
||||
|
||||
function throwFault(message: string, fault: string, operation: string, value?: any): never {
|
||||
let params: any = { fault: fault, operation: operation };
|
||||
const params: any = { fault: fault, operation: operation };
|
||||
if (value !== undefined) { params.value = value; }
|
||||
return logger.throwError(message, Logger.errors.NUMERIC_FAULT, params);
|
||||
}
|
||||
|
@ -41,12 +41,12 @@ function getMultiplier(decimals: BigNumberish): string {
|
|||
|
||||
export function formatFixed(value: BigNumberish, decimals?: string | BigNumberish): string {
|
||||
if (decimals == null) { decimals = 0; }
|
||||
let multiplier = getMultiplier(decimals);
|
||||
const multiplier = getMultiplier(decimals);
|
||||
|
||||
// Make sure wei is a big number (convert as necessary)
|
||||
value = BigNumber.from(value);
|
||||
|
||||
let negative = value.lt(Zero);
|
||||
const negative = value.lt(Zero);
|
||||
if (negative) { value = value.mul(NegativeOne); }
|
||||
|
||||
let fraction = value.mod(multiplier).toString();
|
||||
|
@ -55,7 +55,7 @@ export function formatFixed(value: BigNumberish, decimals?: string | BigNumberis
|
|||
// Strip training 0
|
||||
fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1];
|
||||
|
||||
let whole = value.div(multiplier).toString();
|
||||
const whole = value.div(multiplier).toString();
|
||||
|
||||
value = whole + "." + fraction;
|
||||
|
||||
|
@ -66,7 +66,7 @@ export function formatFixed(value: BigNumberish, decimals?: string | BigNumberis
|
|||
|
||||
export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
|
||||
if (decimals == null) { decimals = 0; }
|
||||
let multiplier = getMultiplier(decimals);
|
||||
const multiplier = getMultiplier(decimals);
|
||||
|
||||
if (typeof(value) !== "string" || !value.match(/^-?[0-9.,]+$/)) {
|
||||
logger.throwArgumentError("invalid decimal value", "value", value);
|
||||
|
@ -77,7 +77,7 @@ export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
|
|||
}
|
||||
|
||||
// Is it negative?
|
||||
let negative = (value.substring(0, 1) === "-");
|
||||
const negative = (value.substring(0, 1) === "-");
|
||||
if (negative) { value = value.substring(1); }
|
||||
|
||||
if (value === ".") {
|
||||
|
@ -85,7 +85,7 @@ export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
|
|||
}
|
||||
|
||||
// Split it into a whole and fractional part
|
||||
let comps = value.split(".");
|
||||
const comps = value.split(".");
|
||||
if (comps.length > 2) {
|
||||
logger.throwArgumentError("too many decimal points", "value", value);
|
||||
}
|
||||
|
@ -102,8 +102,8 @@ export function parseFixed(value: string, decimals?: BigNumberish): BigNumber {
|
|||
// Fully pad the string with zeros to get to wei
|
||||
while (fraction.length < multiplier.length - 1) { fraction += "0"; }
|
||||
|
||||
let wholeValue = BigNumber.from(whole);
|
||||
let fractionValue = BigNumber.from(fraction);
|
||||
const wholeValue = BigNumber.from(whole);
|
||||
const fractionValue = BigNumber.from(fraction);
|
||||
|
||||
let wei = (wholeValue.mul(multiplier)).add(fractionValue);
|
||||
|
||||
|
@ -144,14 +144,14 @@ export class FixedFormat {
|
|||
} else if (value === "ufixed") {
|
||||
signed = false;
|
||||
} else if (value != null) {
|
||||
let match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);
|
||||
const match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);
|
||||
if (!match) { logger.throwArgumentError("invalid fixed format", "format", value); }
|
||||
signed = (match[1] !== "u");
|
||||
width = parseInt(match[2]);
|
||||
decimals = parseInt(match[3]);
|
||||
}
|
||||
} else if (value) {
|
||||
let check = (key: string, type: string, defaultValue: any): any => {
|
||||
const check = (key: string, type: string, defaultValue: any): any => {
|
||||
if (value[key] == null) { return defaultValue; }
|
||||
if (typeof(value[key]) !== type) {
|
||||
logger.throwArgumentError("invalid fixed format (" + key + " not " + type +")", "format." + key, value[key]);
|
||||
|
@ -202,29 +202,29 @@ export class FixedNumber {
|
|||
|
||||
addUnsafe(other: FixedNumber): FixedNumber {
|
||||
this._checkFormat(other);
|
||||
let a = parseFixed(this._value, this.format.decimals);
|
||||
let b = parseFixed(other._value, other.format.decimals);
|
||||
const a = parseFixed(this._value, this.format.decimals);
|
||||
const b = parseFixed(other._value, other.format.decimals);
|
||||
return FixedNumber.fromValue(a.add(b), this.format.decimals, this.format);
|
||||
}
|
||||
|
||||
subUnsafe(other: FixedNumber): FixedNumber {
|
||||
this._checkFormat(other);
|
||||
let a = parseFixed(this._value, this.format.decimals);
|
||||
let b = parseFixed(other._value, other.format.decimals);
|
||||
const a = parseFixed(this._value, this.format.decimals);
|
||||
const b = parseFixed(other._value, other.format.decimals);
|
||||
return FixedNumber.fromValue(a.sub(b), this.format.decimals, this.format);
|
||||
}
|
||||
|
||||
mulUnsafe(other: FixedNumber): FixedNumber {
|
||||
this._checkFormat(other);
|
||||
let a = parseFixed(this._value, this.format.decimals);
|
||||
let b = parseFixed(other._value, other.format.decimals);
|
||||
const a = parseFixed(this._value, this.format.decimals);
|
||||
const b = parseFixed(other._value, other.format.decimals);
|
||||
return FixedNumber.fromValue(a.mul(b).div(this.format._multiplier), this.format.decimals, this.format);
|
||||
}
|
||||
|
||||
divUnsafe(other: FixedNumber): FixedNumber {
|
||||
this._checkFormat(other);
|
||||
let a = parseFixed(this._value, this.format.decimals);
|
||||
let b = parseFixed(other._value, other.format.decimals);
|
||||
const a = parseFixed(this._value, this.format.decimals);
|
||||
const b = parseFixed(other._value, other.format.decimals);
|
||||
return FixedNumber.fromValue(a.mul(this.format._multiplier).div(b), this.format.decimals, this.format);
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ export class FixedNumber {
|
|||
if (comps[1].length <= decimals) { return this; }
|
||||
|
||||
// Bump the value up by the 0.00...0005
|
||||
let bump = "0." + zeros.substring(0, decimals) + "5";
|
||||
const bump = "0." + zeros.substring(0, decimals) + "5";
|
||||
comps = this.addUnsafe(FixedNumber.fromString(bump, this.format))._value.split(".");
|
||||
|
||||
// Now it is safe to truncate
|
||||
|
@ -253,7 +253,7 @@ export class FixedNumber {
|
|||
toHexString(width?: number): string {
|
||||
if (width == null) { return this._hex; }
|
||||
if (width % 8) { logger.throwArgumentError("invalid byte width", "width", width); }
|
||||
let hex = BigNumber.from(this._hex).fromTwos(this.format.width).toTwos(width).toHexString();
|
||||
const hex = BigNumber.from(this._hex).fromTwos(this.format.width).toTwos(width).toHexString();
|
||||
return hexZeroPad(hex, width / 8);
|
||||
}
|
||||
|
||||
|
@ -281,9 +281,9 @@ export class FixedNumber {
|
|||
static fromString(value: string, format?: FixedFormat | string): FixedNumber {
|
||||
if (format == null) { format = "fixed"; }
|
||||
|
||||
let fixedFormat = FixedFormat.from(format);
|
||||
const fixedFormat = FixedFormat.from(format);
|
||||
|
||||
let numeric = parseFixed(value, fixedFormat.decimals);
|
||||
const numeric = parseFixed(value, fixedFormat.decimals);
|
||||
|
||||
if (!fixedFormat.signed && numeric.lt(Zero)) {
|
||||
throwFault("unsigned value cannot be negative", "overflow", "value", value);
|
||||
|
@ -297,7 +297,7 @@ export class FixedNumber {
|
|||
hex = hexZeroPad(hex, fixedFormat.width / 8);
|
||||
}
|
||||
|
||||
let decimal = formatFixed(numeric, fixedFormat.decimals);
|
||||
const decimal = formatFixed(numeric, fixedFormat.decimals);
|
||||
|
||||
return new FixedNumber(_constructorGuard, hex, decimal, fixedFormat);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ export class FixedNumber {
|
|||
static fromBytes(value: BytesLike, format?: FixedFormat | string): FixedNumber {
|
||||
if (format == null) { format = "fixed"; }
|
||||
|
||||
let fixedFormat = FixedFormat.from(format);
|
||||
const fixedFormat = FixedFormat.from(format);
|
||||
|
||||
if (arrayify(value).length > fixedFormat.width / 8) {
|
||||
throw new Error("overflow");
|
||||
|
@ -314,8 +314,8 @@ export class FixedNumber {
|
|||
let numeric = BigNumber.from(value);
|
||||
if (fixedFormat.signed) { numeric = numeric.fromTwos(fixedFormat.width); }
|
||||
|
||||
let hex = numeric.toTwos((fixedFormat.signed ? 0: 1) + fixedFormat.width).toHexString();
|
||||
let decimal = formatFixed(numeric, fixedFormat.decimals);
|
||||
const hex = numeric.toTwos((fixedFormat.signed ? 0: 1) + fixedFormat.width).toHexString();
|
||||
const decimal = formatFixed(numeric, fixedFormat.decimals);
|
||||
|
||||
return new FixedNumber(_constructorGuard, hex, decimal, fixedFormat);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ function addSlice(array: Uint8Array): Uint8Array {
|
|||
if (array.slice) { return array; }
|
||||
|
||||
array.slice = function() {
|
||||
let args = Array.prototype.slice.call(arguments);
|
||||
const args = Array.prototype.slice.call(arguments);
|
||||
return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args)));
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ export function isBytes(value: any): value is Bytes {
|
|||
if (value.length == null) { return false; }
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
let v = value[i];
|
||||
const v = value[i];
|
||||
if (v < 0 || v >= 256 || (v % 1)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
|
|||
if (typeof(value) === "number") {
|
||||
logger.checkSafeUint53(value, "invalid arrayify value");
|
||||
|
||||
let result = [];
|
||||
const result = [];
|
||||
while (value) {
|
||||
result.unshift(value & 0xff);
|
||||
value /= 256;
|
||||
|
@ -122,7 +122,7 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
|
|||
}
|
||||
}
|
||||
|
||||
let result = [];
|
||||
const result = [];
|
||||
for (let i = 0; i < hex.length; i += 2) {
|
||||
result.push(parseInt(hex.substring(i, i + 2), 16));
|
||||
}
|
||||
|
@ -138,10 +138,10 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
|
|||
}
|
||||
|
||||
export function concat(items: Array<BytesLike>): Uint8Array {
|
||||
let objects = items.map(item => arrayify(item));
|
||||
let length = objects.reduce((accum, item) => (accum + item.length), 0);
|
||||
const objects = items.map(item => arrayify(item));
|
||||
const length = objects.reduce((accum, item) => (accum + item.length), 0);
|
||||
|
||||
let result = new Uint8Array(length);
|
||||
const result = new Uint8Array(length);
|
||||
|
||||
objects.reduce((offset, object) => {
|
||||
result.set(object, offset);
|
||||
|
@ -175,7 +175,7 @@ export function zeroPad(value: BytesLike, length: number): Uint8Array {
|
|||
logger.throwArgumentError("value out of range", "value", arguments[0]);
|
||||
}
|
||||
|
||||
let result = new Uint8Array(length);
|
||||
const result = new Uint8Array(length);
|
||||
result.set(value, length - value.length);
|
||||
return addSlice(result);
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ export function hexConcat(items: Array<BytesLike>): string {
|
|||
}
|
||||
|
||||
export function hexValue(value: BytesLike | Hexable | number): string {
|
||||
let trimmed = hexStripZeros(hexlify(value, { hexPad: "left" }));
|
||||
const trimmed = hexStripZeros(hexlify(value, { hexPad: "left" }));
|
||||
if (trimmed === "0x") { return "0x0"; }
|
||||
return trimmed;
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ export function hexZeroPad(value: BytesLike, length: number): string {
|
|||
}
|
||||
|
||||
export function splitSignature(signature: SignatureLike): Signature {
|
||||
let result = {
|
||||
const result = {
|
||||
r: "0x",
|
||||
s: "0x",
|
||||
_vs: "0x",
|
||||
|
@ -330,7 +330,7 @@ export function splitSignature(signature: SignatureLike): Signature {
|
|||
};
|
||||
|
||||
if (isBytesLike(signature)) {
|
||||
let bytes: Uint8Array = arrayify(signature);
|
||||
const bytes: Uint8Array = arrayify(signature);
|
||||
if (bytes.length !== 65) {
|
||||
logger.throwArgumentError("invalid signature string; must be 65 bytes", "signature", signature);
|
||||
}
|
||||
|
@ -387,14 +387,14 @@ export function splitSignature(signature: SignatureLike): Signature {
|
|||
logger.throwArgumentError("signature _vs overflow", "signature", signature);
|
||||
}
|
||||
|
||||
let vs = arrayify(result._vs);
|
||||
const vs = arrayify(result._vs);
|
||||
|
||||
let recoveryParam = ((vs[0] >= 128) ? 1: 0);
|
||||
let v = 27 + result.recoveryParam;
|
||||
const recoveryParam = ((vs[0] >= 128) ? 1: 0);
|
||||
const v = 27 + result.recoveryParam;
|
||||
|
||||
// Use _vs to compute s
|
||||
vs[0] &= 0x7f;
|
||||
let s = hexlify(vs);
|
||||
const s = hexlify(vs);
|
||||
|
||||
// Check _vs aggress with other parameters
|
||||
|
||||
|
@ -433,7 +433,7 @@ export function splitSignature(signature: SignatureLike): Signature {
|
|||
}
|
||||
|
||||
if (result._vs == null) {
|
||||
let vs = arrayify(result.s);
|
||||
const vs = arrayify(result.s);
|
||||
if (vs[0] >= 128) {
|
||||
logger.throwArgumentError("signature s out of range", "signature", signature);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ const Partition = new RegExp("^((.*)\\.)?([^.]+)$");
|
|||
|
||||
export function isValidName(name: string): boolean {
|
||||
try {
|
||||
let comps = name.split(".");
|
||||
const comps = name.split(".");
|
||||
for (let i = 0; i < comps.length; i++) {
|
||||
if (nameprep(comps[i]).length === 0) {
|
||||
throw new Error("empty")
|
||||
|
@ -33,8 +33,8 @@ export function namehash(name: string): string {
|
|||
|
||||
let result: string | Uint8Array = Zeros;
|
||||
while (name.length) {
|
||||
let partition = name.match(Partition);
|
||||
let label = toUtf8Bytes(nameprep(partition[3]));
|
||||
const partition = name.match(Partition);
|
||||
const label = toUtf8Bytes(nameprep(partition[3]));
|
||||
result = keccak256(concat([result, keccak256(label)]));
|
||||
|
||||
name = partition[2] || "";
|
||||
|
|
|
@ -43,8 +43,7 @@ function bytes32(value: BigNumber | Uint8Array): string {
|
|||
}
|
||||
|
||||
function base58check(data: Uint8Array): string {
|
||||
let checksum = hexDataSlice(sha256(sha256(data)), 0, 4);
|
||||
return Base58.encode(concat([ data, checksum ]));
|
||||
return Base58.encode(concat([ data, hexDataSlice(sha256(sha256(data)), 0, 4) ]));
|
||||
}
|
||||
|
||||
const _constructorGuard: any = {};
|
||||
|
@ -83,7 +82,7 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
}
|
||||
|
||||
if (privateKey) {
|
||||
let signingKey = new SigningKey(privateKey);
|
||||
const signingKey = new SigningKey(privateKey);
|
||||
defineReadOnly(this, "privateKey", signingKey.privateKey);
|
||||
defineReadOnly(this, "publicKey", signingKey.compressedPublicKey);
|
||||
} else {
|
||||
|
@ -135,7 +134,7 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
let path = this.path;
|
||||
if (path) { path += "/" + (index & ~HardenedBit); }
|
||||
|
||||
let data = new Uint8Array(37);
|
||||
const data = new Uint8Array(37);
|
||||
|
||||
if (index & HardenedBit) {
|
||||
if (!this.privateKey) {
|
||||
|
@ -156,20 +155,20 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
// Data += ser_32(i)
|
||||
for (let i = 24; i >= 0; i -= 8) { data[33 + (i >> 3)] = ((index >> (24 - i)) & 0xff); }
|
||||
|
||||
let I = arrayify(computeHmac(SupportedAlgorithms.sha512, this.chainCode, data));
|
||||
let IL = I.slice(0, 32);
|
||||
let IR = I.slice(32);
|
||||
const I = arrayify(computeHmac(SupportedAlgorithms.sha512, this.chainCode, data));
|
||||
const IL = I.slice(0, 32);
|
||||
const IR = I.slice(32);
|
||||
|
||||
// The private key
|
||||
|
||||
let ki: string = null
|
||||
|
||||
// The public key
|
||||
let Ki: string = null;
|
||||
|
||||
if (this.privateKey) {
|
||||
ki = bytes32(BigNumber.from(IL).add(this.privateKey).mod(N));
|
||||
} else {
|
||||
let ek = new SigningKey(hexlify(IL));
|
||||
const ek = new SigningKey(hexlify(IL));
|
||||
Ki = ek._addPoint(this.publicKey);
|
||||
}
|
||||
|
||||
|
@ -177,7 +176,7 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
}
|
||||
|
||||
derivePath(path: string): HDNode {
|
||||
let components = path.split("/");
|
||||
const components = path.split("/");
|
||||
|
||||
if (components.length === 0 || (components[0] === "m" && this.depth !== 0)) {
|
||||
throw new Error("invalid path - " + path);
|
||||
|
@ -187,13 +186,13 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
|
||||
let result: HDNode = this;
|
||||
for (let i = 0; i < components.length; i++) {
|
||||
let component = components[i];
|
||||
const component = components[i];
|
||||
if (component.match(/^[0-9]+'$/)) {
|
||||
let index = parseInt(component.substring(0, component.length - 1));
|
||||
const index = parseInt(component.substring(0, component.length - 1));
|
||||
if (index >= HardenedBit) { throw new Error("invalid path index - " + component); }
|
||||
result = result._derive(HardenedBit + index);
|
||||
} else if (component.match(/^[0-9]+$/)) {
|
||||
let index = parseInt(component);
|
||||
const index = parseInt(component);
|
||||
if (index >= HardenedBit) { throw new Error("invalid path index - " + component); }
|
||||
result = result._derive(index);
|
||||
} else {
|
||||
|
@ -206,10 +205,10 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
|
||||
|
||||
static _fromSeed(seed: BytesLike, mnemonic: string): HDNode {
|
||||
let seedArray: Uint8Array = arrayify(seed);
|
||||
const seedArray: Uint8Array = arrayify(seed);
|
||||
if (seedArray.length < 16 || seedArray.length > 64) { throw new Error("invalid seed"); }
|
||||
|
||||
let I: Uint8Array = arrayify(computeHmac(SupportedAlgorithms.sha512, MasterSecret, seedArray));
|
||||
const I: Uint8Array = arrayify(computeHmac(SupportedAlgorithms.sha512, MasterSecret, seedArray));
|
||||
|
||||
return new HDNode(_constructorGuard, bytes32(I.slice(0, 32)), null, "0x00000000", bytes32(I.slice(32)), 0, 0, mnemonic, "m");
|
||||
}
|
||||
|
@ -226,17 +225,17 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
}
|
||||
|
||||
static fromExtendedKey(extendedKey: string): HDNode {
|
||||
let bytes = Base58.decode(extendedKey);
|
||||
const bytes = Base58.decode(extendedKey);
|
||||
|
||||
if (bytes.length !== 82 || base58check(bytes.slice(0, 78)) !== extendedKey) {
|
||||
logger.throwArgumentError("invalid extended key", "extendedKey", "[REDACTED]");
|
||||
}
|
||||
|
||||
let depth = bytes[4];
|
||||
let parentFingerprint = hexlify(bytes.slice(5, 9));
|
||||
let index = parseInt(hexlify(bytes.slice(9, 13)).substring(2), 16);
|
||||
let chainCode = hexlify(bytes.slice(13, 45));
|
||||
let key = bytes.slice(45, 78);
|
||||
const depth = bytes[4];
|
||||
const parentFingerprint = hexlify(bytes.slice(5, 9));
|
||||
const index = parseInt(hexlify(bytes.slice(9, 13)).substring(2), 16);
|
||||
const chainCode = hexlify(bytes.slice(13, 45));
|
||||
const key = bytes.slice(45, 78);
|
||||
|
||||
switch (hexlify(bytes.slice(0, 4))) {
|
||||
// Public Key
|
||||
|
@ -250,14 +249,13 @@ export class HDNode implements ExternallyOwnedAccount {
|
|||
}
|
||||
|
||||
return logger.throwError("invalid extended key", "extendedKey", "[REDACTED]");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export function mnemonicToSeed(mnemonic: string, password?: string): string {
|
||||
if (!password) { password = ""; }
|
||||
|
||||
let salt = toUtf8Bytes("mnemonic" + password, UnicodeNormalizationForm.NFKD);
|
||||
const salt = toUtf8Bytes("mnemonic" + password, UnicodeNormalizationForm.NFKD);
|
||||
|
||||
return pbkdf2(toUtf8Bytes(mnemonic, UnicodeNormalizationForm.NFKD), salt, 2048, 64, "sha512");
|
||||
}
|
||||
|
@ -267,10 +265,10 @@ export function mnemonicToEntropy(mnemonic: string, wordlist?: Wordlist): string
|
|||
|
||||
logger.checkNormalize();
|
||||
|
||||
let words = wordlist.split(mnemonic);
|
||||
const words = wordlist.split(mnemonic);
|
||||
if ((words.length % 3) !== 0) { throw new Error("invalid mnemonic"); }
|
||||
|
||||
let entropy = arrayify(new Uint8Array(Math.ceil(11 * words.length / 8)));
|
||||
const entropy = arrayify(new Uint8Array(Math.ceil(11 * words.length / 8)));
|
||||
|
||||
let offset = 0;
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
|
@ -285,13 +283,12 @@ export function mnemonicToEntropy(mnemonic: string, wordlist?: Wordlist): string
|
|||
}
|
||||
}
|
||||
|
||||
let entropyBits = 32 * words.length / 3;
|
||||
const entropyBits = 32 * words.length / 3;
|
||||
|
||||
let checksumBits = words.length / 3;
|
||||
let checksumMask = getUpperMask(checksumBits);
|
||||
const checksumBits = words.length / 3;
|
||||
const checksumMask = getUpperMask(checksumBits);
|
||||
|
||||
let checksum = arrayify(sha256(entropy.slice(0, entropyBits / 8)))[0];
|
||||
checksum &= checksumMask;
|
||||
const checksum = arrayify(sha256(entropy.slice(0, entropyBits / 8)))[0] & checksumMask;
|
||||
|
||||
if (checksum !== (entropy[entropy.length - 1] & checksumMask)) {
|
||||
throw new Error("invalid checksum");
|
||||
|
@ -307,7 +304,7 @@ export function entropyToMnemonic(entropy: BytesLike, wordlist?: Wordlist): stri
|
|||
throw new Error("invalid entropy");
|
||||
}
|
||||
|
||||
let indices: Array<number> = [ 0 ];
|
||||
const indices: Array<number> = [ 0 ];
|
||||
|
||||
let remainingBits = 11;
|
||||
for (let i = 0; i < entropy.length; i++) {
|
||||
|
@ -332,9 +329,8 @@ export function entropyToMnemonic(entropy: BytesLike, wordlist?: Wordlist): stri
|
|||
}
|
||||
|
||||
// Compute the checksum bits
|
||||
let checksum = arrayify(sha256(entropy))[0];
|
||||
let checksumBits = entropy.length / 4;
|
||||
checksum &= getUpperMask(checksumBits);
|
||||
const checksumBits = entropy.length / 4;
|
||||
const checksum = arrayify(sha256(entropy))[0] & getUpperMask(checksumBits);
|
||||
|
||||
// Shift the checksum into the word indices
|
||||
indices[indices.length - 1] <<= checksumBits;
|
||||
|
|
|
@ -31,28 +31,27 @@ export class CrowdsaleAccount extends Description implements ExternallyOwnedAcco
|
|||
|
||||
// See: https://github.com/ethereum/pyethsaletool
|
||||
export function decrypt(json: string, password: Bytes | string): ExternallyOwnedAccount {
|
||||
let data = JSON.parse(json);
|
||||
const data = JSON.parse(json);
|
||||
|
||||
password = getPassword(password);
|
||||
|
||||
// Ethereum Address
|
||||
let ethaddr = getAddress(searchPath(data, "ethaddr"));
|
||||
const ethaddr = getAddress(searchPath(data, "ethaddr"));
|
||||
|
||||
// Encrypted Seed
|
||||
let encseed = looseArrayify(searchPath(data, "encseed"));
|
||||
const encseed = looseArrayify(searchPath(data, "encseed"));
|
||||
if (!encseed || (encseed.length % 16) !== 0) {
|
||||
logger.throwArgumentError("invalid encseed", "json", json);
|
||||
}
|
||||
|
||||
let key = arrayify(pbkdf2(password, password, 2000, 32, "sha256")).slice(0, 16);
|
||||
const key = arrayify(pbkdf2(password, password, 2000, 32, "sha256")).slice(0, 16);
|
||||
|
||||
let iv = encseed.slice(0, 16);
|
||||
let encryptedSeed = encseed.slice(16);
|
||||
const iv = encseed.slice(0, 16);
|
||||
const encryptedSeed = encseed.slice(16);
|
||||
|
||||
// Decrypt the seed
|
||||
let aesCbc = new aes.ModeOfOperation.cbc(key, iv);
|
||||
let seed = arrayify(aesCbc.decrypt(encryptedSeed));
|
||||
seed = aes.padding.pkcs7.strip(seed);
|
||||
const aesCbc = new aes.ModeOfOperation.cbc(key, iv);
|
||||
const seed = aes.padding.pkcs7.strip(arrayify(aesCbc.decrypt(encryptedSeed)));
|
||||
|
||||
// This wallet format is weird... Convert the binary encoded hex to a string.
|
||||
let seedHex = "";
|
||||
|
@ -60,9 +59,9 @@ export function decrypt(json: string, password: Bytes | string): ExternallyOwned
|
|||
seedHex += String.fromCharCode(seed[i]);
|
||||
}
|
||||
|
||||
let seedHexBytes = toUtf8Bytes(seedHex);
|
||||
const seedHexBytes = toUtf8Bytes(seedHex);
|
||||
|
||||
let privateKey = keccak256(seedHexBytes);
|
||||
const privateKey = keccak256(seedHexBytes);
|
||||
|
||||
return new CrowdsaleAccount ({
|
||||
_isCrowdsaleAccount: true,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { decrypt as decryptKeystore, encrypt as encryptKeystore, EncryptOptions,
|
|||
function decryptJsonWallet(json: string, password: Bytes | string, progressCallback?: ProgressCallback): Promise<ExternallyOwnedAccount> {
|
||||
if (isCrowdsaleWallet(json)) {
|
||||
if (progressCallback) { progressCallback(0); }
|
||||
let account = decryptCrowdsale(json, password)
|
||||
const account = decryptCrowdsale(json, password)
|
||||
if (progressCallback) { progressCallback(1); }
|
||||
return Promise.resolve(account);
|
||||
}
|
||||
|
|
|
@ -47,17 +47,17 @@ export type EncryptOptions = {
|
|||
}
|
||||
|
||||
export function decrypt(json: string, password: Bytes | string, progressCallback?: ProgressCallback): Promise<KeystoreAccount> {
|
||||
let data = JSON.parse(json);
|
||||
const data = JSON.parse(json);
|
||||
|
||||
let passwordBytes = getPassword(password);
|
||||
const passwordBytes = getPassword(password);
|
||||
|
||||
let decrypt = function(key: Uint8Array, ciphertext: Uint8Array): Uint8Array {
|
||||
let cipher = searchPath(data, "crypto/cipher");
|
||||
const decrypt = function(key: Uint8Array, ciphertext: Uint8Array): Uint8Array {
|
||||
const cipher = searchPath(data, "crypto/cipher");
|
||||
if (cipher === "aes-128-ctr") {
|
||||
let iv = looseArrayify(searchPath(data, "crypto/cipherparams/iv"))
|
||||
let counter = new aes.Counter(iv);
|
||||
const iv = looseArrayify(searchPath(data, "crypto/cipherparams/iv"))
|
||||
const counter = new aes.Counter(iv);
|
||||
|
||||
let aesCtr = new aes.ModeOfOperation.ctr(key, counter);
|
||||
const aesCtr = new aes.ModeOfOperation.ctr(key, counter);
|
||||
|
||||
return arrayify(aesCtr.decrypt(ciphertext));
|
||||
}
|
||||
|
@ -65,28 +65,28 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
return null;
|
||||
};
|
||||
|
||||
let computeMAC = function(derivedHalf: Uint8Array, ciphertext: Uint8Array) {
|
||||
const computeMAC = function(derivedHalf: Uint8Array, ciphertext: Uint8Array) {
|
||||
return keccak256(concat([ derivedHalf, ciphertext ]));
|
||||
}
|
||||
|
||||
let getAccount = function(key: Uint8Array, reject: (error?: Error) => void) {
|
||||
let ciphertext = looseArrayify(searchPath(data, "crypto/ciphertext"));
|
||||
const getAccount = function(key: Uint8Array, reject: (error?: Error) => void) {
|
||||
const ciphertext = looseArrayify(searchPath(data, "crypto/ciphertext"));
|
||||
|
||||
let computedMAC = hexlify(computeMAC(key.slice(16, 32), ciphertext)).substring(2);
|
||||
const computedMAC = hexlify(computeMAC(key.slice(16, 32), ciphertext)).substring(2);
|
||||
if (computedMAC !== searchPath(data, "crypto/mac").toLowerCase()) {
|
||||
reject(new Error("invalid password"));
|
||||
return null;
|
||||
}
|
||||
|
||||
let privateKey = decrypt(key.slice(0, 16), ciphertext);
|
||||
let mnemonicKey = key.slice(32, 64);
|
||||
const privateKey = decrypt(key.slice(0, 16), ciphertext);
|
||||
const mnemonicKey = key.slice(32, 64);
|
||||
|
||||
if (!privateKey) {
|
||||
reject(new Error("unsupported cipher"));
|
||||
return null;
|
||||
}
|
||||
|
||||
let address = computeAddress(privateKey);
|
||||
const address = computeAddress(privateKey);
|
||||
if (data.address) {
|
||||
let check = data.address.toLowerCase();
|
||||
if (check.substring(0, 2) !== "0x") { check = "0x" + check; }
|
||||
|
@ -99,7 +99,7 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
} catch (e) { }
|
||||
}
|
||||
|
||||
let account: any = {
|
||||
const account: any = {
|
||||
_isKeystoreAccount: true,
|
||||
address: address,
|
||||
privateKey: hexlify(privateKey)
|
||||
|
@ -107,18 +107,18 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
|
||||
// Version 0.1 x-ethers metadata must contain an encrypted mnemonic phrase
|
||||
if (searchPath(data, "x-ethers/version") === "0.1") {
|
||||
let mnemonicCiphertext = looseArrayify(searchPath(data, "x-ethers/mnemonicCiphertext"));
|
||||
let mnemonicIv = looseArrayify(searchPath(data, "x-ethers/mnemonicCounter"));
|
||||
const mnemonicCiphertext = looseArrayify(searchPath(data, "x-ethers/mnemonicCiphertext"));
|
||||
const mnemonicIv = looseArrayify(searchPath(data, "x-ethers/mnemonicCounter"));
|
||||
|
||||
let mnemonicCounter = new aes.Counter(mnemonicIv);
|
||||
let mnemonicAesCtr = new aes.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
||||
const mnemonicCounter = new aes.Counter(mnemonicIv);
|
||||
const mnemonicAesCtr = new aes.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
||||
|
||||
let path = searchPath(data, "x-ethers/path") || defaultPath;
|
||||
const path = searchPath(data, "x-ethers/path") || defaultPath;
|
||||
|
||||
let entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));
|
||||
let mnemonic = entropyToMnemonic(entropy);
|
||||
const entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));
|
||||
const mnemonic = entropyToMnemonic(entropy);
|
||||
|
||||
let node = HDNode.fromMnemonic(mnemonic).derivePath(path);
|
||||
const node = HDNode.fromMnemonic(mnemonic).derivePath(path);
|
||||
|
||||
if (node.privateKey != account.privateKey) {
|
||||
reject(new Error("mnemonic mismatch"));
|
||||
|
@ -134,13 +134,13 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
let kdf = searchPath(data, "crypto/kdf");
|
||||
const kdf = searchPath(data, "crypto/kdf");
|
||||
if (kdf && typeof(kdf) === "string") {
|
||||
if (kdf.toLowerCase() === "scrypt") {
|
||||
let salt = looseArrayify(searchPath(data, "crypto/kdfparams/salt"));
|
||||
let N = parseInt(searchPath(data, "crypto/kdfparams/n"));
|
||||
let r = parseInt(searchPath(data, "crypto/kdfparams/r"));
|
||||
let p = parseInt(searchPath(data, "crypto/kdfparams/p"));
|
||||
const salt = looseArrayify(searchPath(data, "crypto/kdfparams/salt"));
|
||||
const N = parseInt(searchPath(data, "crypto/kdfparams/n"));
|
||||
const r = parseInt(searchPath(data, "crypto/kdfparams/r"));
|
||||
const p = parseInt(searchPath(data, "crypto/kdfparams/p"));
|
||||
if (!N || !r || !p) {
|
||||
reject(new Error("unsupported key-derivation function parameters"));
|
||||
return;
|
||||
|
@ -152,7 +152,7 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
return;
|
||||
}
|
||||
|
||||
let dkLen = parseInt(searchPath(data, "crypto/kdfparams/dklen"));
|
||||
const dkLen = parseInt(searchPath(data, "crypto/kdfparams/dklen"));
|
||||
if (dkLen !== 32) {
|
||||
reject( new Error("unsupported key-derivation derived-key length"));
|
||||
return;
|
||||
|
@ -167,7 +167,7 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
} else if (key) {
|
||||
key = arrayify(key);
|
||||
|
||||
let account = getAccount(key, reject);
|
||||
const account = getAccount(key, reject);
|
||||
if (!account) { return; }
|
||||
|
||||
if (progressCallback) { progressCallback(1); }
|
||||
|
@ -180,10 +180,10 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
|
||||
} else if (kdf.toLowerCase() === "pbkdf2") {
|
||||
|
||||
let salt = looseArrayify(searchPath(data, "crypto/kdfparams/salt"));
|
||||
const salt = looseArrayify(searchPath(data, "crypto/kdfparams/salt"));
|
||||
|
||||
let prfFunc = null;
|
||||
let prf = searchPath(data, "crypto/kdfparams/prf");
|
||||
let prfFunc: string = null;
|
||||
const prf = searchPath(data, "crypto/kdfparams/prf");
|
||||
if (prf === "hmac-sha256") {
|
||||
prfFunc = "sha256";
|
||||
} else if (prf === "hmac-sha512") {
|
||||
|
@ -193,17 +193,17 @@ export function decrypt(json: string, password: Bytes | string, progressCallback
|
|||
return;
|
||||
}
|
||||
|
||||
let c = parseInt(searchPath(data, "crypto/kdfparams/c"));
|
||||
const c = parseInt(searchPath(data, "crypto/kdfparams/c"));
|
||||
|
||||
let dkLen = parseInt(searchPath(data, "crypto/kdfparams/dklen"));
|
||||
const dkLen = parseInt(searchPath(data, "crypto/kdfparams/dklen"));
|
||||
if (dkLen !== 32) {
|
||||
reject( new Error("unsupported key-derivation derived-key length"));
|
||||
return;
|
||||
}
|
||||
|
||||
let key = arrayify(pbkdf2(passwordBytes, salt, c, dkLen, prfFunc));
|
||||
const key = arrayify(pbkdf2(passwordBytes, salt, c, dkLen, prfFunc));
|
||||
|
||||
let account = getAccount(key, reject);
|
||||
const account = getAccount(key, reject);
|
||||
if (!account) { return; }
|
||||
|
||||
resolve(account);
|
||||
|
@ -226,7 +226,7 @@ export function encrypt(account: ExternallyOwnedAccount, password: Bytes | strin
|
|||
}
|
||||
|
||||
if (account.mnemonic != null){
|
||||
let node = HDNode.fromMnemonic(account.mnemonic).derivePath(account.path || defaultPath);
|
||||
const node = HDNode.fromMnemonic(account.mnemonic).derivePath(account.path || defaultPath);
|
||||
|
||||
if (node.privateKey != account.privateKey) {
|
||||
throw new Error("mnemonic mismatch");
|
||||
|
@ -246,8 +246,8 @@ export function encrypt(account: ExternallyOwnedAccount, password: Bytes | strin
|
|||
}
|
||||
if (!options) { options = {}; }
|
||||
|
||||
let privateKey: Uint8Array = arrayify(account.privateKey);
|
||||
let passwordBytes = getPassword(password);
|
||||
const privateKey: Uint8Array = arrayify(account.privateKey);
|
||||
const passwordBytes = getPassword(password);
|
||||
|
||||
let entropy: Uint8Array = null
|
||||
let path: string = account.path;
|
||||
|
@ -308,22 +308,22 @@ export function encrypt(account: ExternallyOwnedAccount, password: Bytes | strin
|
|||
key = arrayify(key);
|
||||
|
||||
// This will be used to encrypt the wallet (as per Web3 secret storage)
|
||||
let derivedKey = key.slice(0, 16);
|
||||
let macPrefix = key.slice(16, 32);
|
||||
const derivedKey = key.slice(0, 16);
|
||||
const macPrefix = key.slice(16, 32);
|
||||
|
||||
// This will be used to encrypt the mnemonic phrase (if any)
|
||||
let mnemonicKey = key.slice(32, 64);
|
||||
const mnemonicKey = key.slice(32, 64);
|
||||
|
||||
// Encrypt the private key
|
||||
let counter = new aes.Counter(iv);
|
||||
let aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter);
|
||||
let ciphertext = arrayify(aesCtr.encrypt(privateKey));
|
||||
const counter = new aes.Counter(iv);
|
||||
const aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter);
|
||||
const ciphertext = arrayify(aesCtr.encrypt(privateKey));
|
||||
|
||||
// Compute the message authentication code, used to check the password
|
||||
let mac = keccak256(concat([macPrefix, ciphertext]))
|
||||
const mac = keccak256(concat([macPrefix, ciphertext]))
|
||||
|
||||
// See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
|
||||
let data: { [key: string]: any } = {
|
||||
const data: { [key: string]: any } = {
|
||||
address: account.address.substring(2).toLowerCase(),
|
||||
id: uuid.v4({ random: uuidRandom }),
|
||||
version: 3,
|
||||
|
@ -347,18 +347,18 @@ export function encrypt(account: ExternallyOwnedAccount, password: Bytes | strin
|
|||
|
||||
// If we have a mnemonic, encrypt it into the JSON wallet
|
||||
if (entropy) {
|
||||
let mnemonicIv = randomBytes(16);
|
||||
let mnemonicCounter = new aes.Counter(mnemonicIv);
|
||||
let mnemonicAesCtr = new aes.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
||||
let mnemonicCiphertext = arrayify(mnemonicAesCtr.encrypt(entropy));
|
||||
let now = new Date();
|
||||
let timestamp = (now.getUTCFullYear() + "-" +
|
||||
zpad(now.getUTCMonth() + 1, 2) + "-" +
|
||||
zpad(now.getUTCDate(), 2) + "T" +
|
||||
zpad(now.getUTCHours(), 2) + "-" +
|
||||
zpad(now.getUTCMinutes(), 2) + "-" +
|
||||
zpad(now.getUTCSeconds(), 2) + ".0Z"
|
||||
);
|
||||
const mnemonicIv = randomBytes(16);
|
||||
const mnemonicCounter = new aes.Counter(mnemonicIv);
|
||||
const mnemonicAesCtr = new aes.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
||||
const mnemonicCiphertext = arrayify(mnemonicAesCtr.encrypt(entropy));
|
||||
const now = new Date();
|
||||
const timestamp = (now.getUTCFullYear() + "-" +
|
||||
zpad(now.getUTCMonth() + 1, 2) + "-" +
|
||||
zpad(now.getUTCDate(), 2) + "T" +
|
||||
zpad(now.getUTCHours(), 2) + "-" +
|
||||
zpad(now.getUTCMinutes(), 2) + "-" +
|
||||
zpad(now.getUTCSeconds(), 2) + ".0Z"
|
||||
);
|
||||
data["x-ethers"] = {
|
||||
client: client,
|
||||
gethFilename: ("UTC--" + timestamp + "--" + data.address),
|
||||
|
|
|
@ -1,23 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
import { arrayify, Bytes } from "@ethersproject/bytes";
|
||||
//import { Description } from "@ethersproject/properties";
|
||||
import { toUtf8Bytes, UnicodeNormalizationForm } from '@ethersproject/strings';
|
||||
|
||||
/*
|
||||
export class Account extends Description implements ExternallyOwnedAccount {
|
||||
readonly address: string;
|
||||
readonly privateKey: string;
|
||||
readonly mnemonic?: string;
|
||||
readonly path?: string;
|
||||
|
||||
// static isAccount(value: any): value is Account {
|
||||
// return Description._isType(value);
|
||||
// }
|
||||
}
|
||||
//defineReadOnly(Account, "name", "Account");
|
||||
*/
|
||||
|
||||
export function looseArrayify(hexString: string): Uint8Array {
|
||||
if (typeof(hexString) === 'string' && hexString.substring(0, 2) !== '0x') {
|
||||
hexString = '0x' + hexString;
|
||||
|
@ -41,12 +26,12 @@ export function getPassword(password: Bytes | string): Uint8Array {
|
|||
export function searchPath(object: any, path: string): string {
|
||||
let currentChild = object;
|
||||
|
||||
let comps = path.toLowerCase().split('/');
|
||||
const comps = path.toLowerCase().split('/');
|
||||
for (let i = 0; i < comps.length; i++) {
|
||||
|
||||
// Search for a child object with a case-insensitive matching key
|
||||
let matchingChild = null;
|
||||
for (let key in currentChild) {
|
||||
for (const key in currentChild) {
|
||||
if (key.toLowerCase() === comps[i]) {
|
||||
matchingChild = currentChild[key];
|
||||
break;
|
||||
|
|
|
@ -14,7 +14,7 @@ export type LogLevel = "DEBUG" | "INFO" | "WARNING" | "ERROR" | "OFF";
|
|||
|
||||
function _checkNormalize(): string {
|
||||
try {
|
||||
let missing: Array<string> = [ ];
|
||||
const missing: Array<string> = [ ];
|
||||
|
||||
// Make sure all forms of normalization are supported
|
||||
["NFD", "NFC", "NFKD", "NFKC"].forEach((form) => {
|
||||
|
@ -41,7 +41,7 @@ function _checkNormalize(): string {
|
|||
return null;
|
||||
}
|
||||
|
||||
let _normalizeError = _checkNormalize();
|
||||
const _normalizeError = _checkNormalize();
|
||||
|
||||
export class Logger {
|
||||
readonly version: string;
|
||||
|
@ -152,7 +152,7 @@ export class Logger {
|
|||
}
|
||||
|
||||
setLogLevel(logLevel: LogLevel): void {
|
||||
let level = LogLevels[logLevel];
|
||||
const level = LogLevels[logLevel];
|
||||
if (level == null) {
|
||||
this.warn("invalid log level - " + logLevel);
|
||||
return;
|
||||
|
@ -185,7 +185,7 @@ export class Logger {
|
|||
if (!code) { code = Logger.errors.UNKNOWN_ERROR; }
|
||||
if (!params) { params = {}; }
|
||||
|
||||
let messageDetails: Array<string> = [];
|
||||
const messageDetails: Array<string> = [];
|
||||
Object.keys(params).forEach((key) => {
|
||||
try {
|
||||
messageDetails.push(key + "=" + JSON.stringify(params[key]));
|
||||
|
@ -195,13 +195,13 @@ export class Logger {
|
|||
});
|
||||
messageDetails.push("version=" + this.version);
|
||||
|
||||
let reason = message;
|
||||
const reason = message;
|
||||
if (messageDetails.length) {
|
||||
message += " (" + messageDetails.join(", ") + ")";
|
||||
}
|
||||
|
||||
// @TODO: Any??
|
||||
let error: any = new Error(message);
|
||||
const error: any = new Error(message);
|
||||
error.reason = reason;
|
||||
error.code = code
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ export {
|
|||
function ethDefaultProvider(network: string): (providers: any) => any {
|
||||
return function(providers: any, options?: any): any {
|
||||
if (options == null) { options = { }; }
|
||||
let providerList: Array<any> = [];
|
||||
const providerList: Array<any> = [];
|
||||
|
||||
if (providers.InfuraProvider) {
|
||||
try {
|
||||
|
@ -49,7 +49,13 @@ function ethDefaultProvider(network: string): (providers: any) => any {
|
|||
if (providerList.length === 0) { return null; }
|
||||
|
||||
if (providers.FallbackProvider) {
|
||||
return new providers.FallbackProvider(providerList);;
|
||||
let quorum = providerList.length / 2;
|
||||
if (options.quorum != null) {
|
||||
quorum = options.quorum;
|
||||
} else if (quorum > 2) {
|
||||
quorum = 2;
|
||||
}
|
||||
return new providers.FallbackProvider(providerList, quorum);
|
||||
}
|
||||
|
||||
return providerList[0];
|
||||
|
@ -141,8 +147,8 @@ export function getNetwork(network: Networkish): Network {
|
|||
if (network == null) { return null; }
|
||||
|
||||
if (typeof(network) === "number") {
|
||||
for (let name in networks) {
|
||||
let standard = networks[name];
|
||||
for (const name in networks) {
|
||||
const standard = networks[name];
|
||||
if (standard.chainId === network) {
|
||||
return {
|
||||
name: standard.name,
|
||||
|
@ -160,7 +166,7 @@ export function getNetwork(network: Networkish): Network {
|
|||
}
|
||||
|
||||
if (typeof(network) === "string") {
|
||||
let standard = networks[network];
|
||||
const standard = networks[network];
|
||||
if (standard == null) { return null; }
|
||||
return {
|
||||
name: standard.name,
|
||||
|
@ -170,7 +176,7 @@ export function getNetwork(network: Networkish): Network {
|
|||
};
|
||||
}
|
||||
|
||||
let standard = networks[network.name];
|
||||
const standard = networks[network.name];
|
||||
|
||||
// Not a standard network; check that it is a valid network in general
|
||||
if (!standard) {
|
||||
|
|
|
@ -6,10 +6,10 @@ import { computeHmac, SupportedAlgorithms } from "@ethersproject/sha2";
|
|||
export function pbkdf2(password: BytesLike, salt: BytesLike, iterations: number, keylen: number, hashAlgorithm: SupportedAlgorithms): string {
|
||||
password = arrayify(password);
|
||||
salt = arrayify(salt);
|
||||
let hLen
|
||||
let l = 1
|
||||
let DK = new Uint8Array(keylen)
|
||||
let block1 = new Uint8Array(salt.length + 4)
|
||||
let hLen;
|
||||
let l = 1;
|
||||
const DK = new Uint8Array(keylen)
|
||||
const block1 = new Uint8Array(salt.length + 4)
|
||||
block1.set(salt);
|
||||
//salt.copy(block1, 0, 0, salt.length)
|
||||
|
||||
|
@ -44,8 +44,8 @@ export function pbkdf2(password: BytesLike, salt: BytesLike, iterations: number,
|
|||
}
|
||||
|
||||
|
||||
let destPos = (i - 1) * hLen
|
||||
let len = (i === l ? r : hLen)
|
||||
const destPos = (i - 1) * hLen
|
||||
const len = (i === l ? r : hLen)
|
||||
//T.copy(DK, destPos, 0, len)
|
||||
DK.set(arrayify(T).slice(0, len), destPos);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ export function getStatic<T>(ctor: any, key: string): T {
|
|||
type Result = { key: string, value: any};
|
||||
export function resolveProperties(object: any): Promise<any> {
|
||||
|
||||
let promises: Array<Promise<Result>> = Object.keys(object).map((key) => {
|
||||
let value = object[key];
|
||||
const promises: Array<Promise<Result>> = Object.keys(object).map((key) => {
|
||||
const value = object[key];
|
||||
|
||||
if (!(value instanceof Promise)) {
|
||||
return Promise.resolve({ key: key, value: value });
|
||||
|
@ -38,7 +38,7 @@ export function resolveProperties(object: any): Promise<any> {
|
|||
});
|
||||
|
||||
return Promise.all(promises).then((results) => {
|
||||
let result: any = { };
|
||||
const result: any = { };
|
||||
return results.reduce((accum, result) => {
|
||||
accum[result.key] = result.value;
|
||||
return accum;
|
||||
|
@ -59,12 +59,12 @@ export function checkProperties(object: any, properties: { [ name: string ]: boo
|
|||
}
|
||||
|
||||
export function shallowCopy(object: any): any {
|
||||
let result: any = {};
|
||||
for (let key in object) { result[key] = object[key]; }
|
||||
const result: any = {};
|
||||
for (const key in object) { result[key] = object[key]; }
|
||||
return result;
|
||||
}
|
||||
|
||||
let opaque: { [key: string]: boolean } = { bigint: true, boolean: true, number: true, string: true };
|
||||
const opaque: { [key: string]: boolean } = { bigint: true, boolean: true, number: true, string: true };
|
||||
|
||||
// Returns a new copy of object, such that no properties may be replaced.
|
||||
// New properties may be added only to objects.
|
||||
|
@ -83,9 +83,9 @@ export function deepCopy(object: any): any {
|
|||
// Immutable objects are safe to just use
|
||||
if (Object.isFrozen(object)) { return object; }
|
||||
|
||||
let result: { [ key: string ]: any } = {};
|
||||
for (let key in object) {
|
||||
let value = object[key];
|
||||
const result: { [ key: string ]: any } = {};
|
||||
for (const key in object) {
|
||||
const value = object[key];
|
||||
if (value === undefined) { continue; }
|
||||
defineReadOnly(result, key, deepCopy(value));
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ export function deepCopy(object: any): any {
|
|||
|
||||
export class Description {
|
||||
constructor(info: any) {
|
||||
for (let key in info) {
|
||||
for (const key in info) {
|
||||
(<any>this)[key] = deepCopy(info[key]);
|
||||
}
|
||||
Object.freeze(this);
|
||||
|
|
|
@ -27,7 +27,7 @@ export function randomBytes(length: number): Uint8Array {
|
|||
logger.throwArgumentError("invalid length", "length", length);
|
||||
}
|
||||
|
||||
let result = new Uint8Array(length);
|
||||
const result = new Uint8Array(length);
|
||||
crypto.getRandomValues(result);
|
||||
return arrayify(result);
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@ export function shuffled(array: Array<any>): Array<any> {
|
|||
array = array.slice();
|
||||
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
let j = Math.floor(Math.random() * (i + 1));
|
||||
let tmp = array[i];
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
const tmp = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = tmp;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { arrayify, BytesLike, hexlify } from "@ethersproject/bytes";
|
||||
|
||||
function arrayifyInteger(value: number): Array<number> {
|
||||
let result = [];
|
||||
const result = [];
|
||||
while (value) {
|
||||
result.unshift(value & 0xff);
|
||||
value >>= 8;
|
||||
|
@ -34,14 +34,14 @@ function _encode(object: Array<any> | string): Array<number> {
|
|||
return payload;
|
||||
}
|
||||
|
||||
let length = arrayifyInteger(payload.length);
|
||||
const length = arrayifyInteger(payload.length);
|
||||
length.unshift(0xf7 + length.length);
|
||||
|
||||
return length.concat(payload);
|
||||
|
||||
}
|
||||
|
||||
let data: Array<number> = Array.prototype.slice.call(arrayify(object));
|
||||
const data: Array<number> = Array.prototype.slice.call(arrayify(object));
|
||||
|
||||
if (data.length === 1 && data[0] <= 0x7f) {
|
||||
return data;
|
||||
|
@ -51,7 +51,7 @@ function _encode(object: Array<any> | string): Array<number> {
|
|||
return data;
|
||||
}
|
||||
|
||||
let length = arrayifyInteger(data.length);
|
||||
const length = arrayifyInteger(data.length);
|
||||
length.unshift(0xb7 + length.length);
|
||||
|
||||
return length.concat(data);
|
||||
|
@ -67,10 +67,10 @@ type Decoded = {
|
|||
};
|
||||
|
||||
function _decodeChildren(data: Uint8Array, offset: number, childOffset: number, length: number): Decoded {
|
||||
let result = [];
|
||||
const result = [];
|
||||
|
||||
while (childOffset < offset + 1 + length) {
|
||||
let decoded = _decode(data, childOffset);
|
||||
const decoded = _decode(data, childOffset);
|
||||
|
||||
result.push(decoded.result);
|
||||
|
||||
|
@ -89,12 +89,12 @@ function _decode(data: Uint8Array, offset: number): { consumed: number, result:
|
|||
|
||||
// Array with extra length prefix
|
||||
if (data[offset] >= 0xf8) {
|
||||
let lengthLength = data[offset] - 0xf7;
|
||||
const lengthLength = data[offset] - 0xf7;
|
||||
if (offset + 1 + lengthLength > data.length) {
|
||||
throw new Error("too short");
|
||||
}
|
||||
|
||||
let length = unarrayifyInteger(data, offset + 1, lengthLength);
|
||||
const length = unarrayifyInteger(data, offset + 1, lengthLength);
|
||||
if (offset + 1 + lengthLength + length > data.length) {
|
||||
throw new Error("to short");
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ function _decode(data: Uint8Array, offset: number): { consumed: number, result:
|
|||
return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);
|
||||
|
||||
} else if (data[offset] >= 0xc0) {
|
||||
let length = data[offset] - 0xc0;
|
||||
const length = data[offset] - 0xc0;
|
||||
if (offset + 1 + length > data.length) {
|
||||
throw new Error("invalid rlp data");
|
||||
}
|
||||
|
@ -110,34 +110,34 @@ function _decode(data: Uint8Array, offset: number): { consumed: number, result:
|
|||
return _decodeChildren(data, offset, offset + 1, length);
|
||||
|
||||
} else if (data[offset] >= 0xb8) {
|
||||
let lengthLength = data[offset] - 0xb7;
|
||||
const lengthLength = data[offset] - 0xb7;
|
||||
if (offset + 1 + lengthLength > data.length) {
|
||||
throw new Error("invalid rlp data");
|
||||
}
|
||||
|
||||
let length = unarrayifyInteger(data, offset + 1, lengthLength);
|
||||
const length = unarrayifyInteger(data, offset + 1, lengthLength);
|
||||
if (offset + 1 + lengthLength + length > data.length) {
|
||||
throw new Error("invalid rlp data");
|
||||
}
|
||||
|
||||
let result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));
|
||||
const result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));
|
||||
return { consumed: (1 + lengthLength + length), result: result }
|
||||
|
||||
} else if (data[offset] >= 0x80) {
|
||||
let length = data[offset] - 0x80;
|
||||
const length = data[offset] - 0x80;
|
||||
if (offset + 1 + length > data.length) {
|
||||
throw new Error("invalid rlp data");
|
||||
}
|
||||
|
||||
let result = hexlify(data.slice(offset + 1, offset + 1 + length));
|
||||
const result = hexlify(data.slice(offset + 1, offset + 1 + length));
|
||||
return { consumed: (1 + length), result: result }
|
||||
}
|
||||
return { consumed: 1, result: hexlify(data[offset]) };
|
||||
}
|
||||
|
||||
export function decode(data: BytesLike): any {
|
||||
let bytes = arrayify(data);
|
||||
let decoded = _decode(bytes, 0);
|
||||
const bytes = arrayify(data);
|
||||
const decoded = _decode(bytes, 0);
|
||||
if (decoded.consumed !== bytes.length) {
|
||||
throw new Error("invalid rlp data");
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export class SigningKey {
|
|||
|
||||
defineReadOnly(this, "privateKey", hexlify(privateKey));
|
||||
|
||||
let keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey));
|
||||
const keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey));
|
||||
|
||||
defineReadOnly(this, "publicKey", "0x" + keyPair.getPublic(false, "hex"));
|
||||
defineReadOnly(this, "compressedPublicKey", "0x" + keyPair.getPublic(true, "hex"));
|
||||
|
@ -43,14 +43,14 @@ export class SigningKey {
|
|||
}
|
||||
|
||||
_addPoint(other: BytesLike): string {
|
||||
let p0 = getCurve().keyFromPublic(arrayify(this.publicKey));
|
||||
let p1 = getCurve().keyFromPublic(arrayify(other));
|
||||
const p0 = getCurve().keyFromPublic(arrayify(this.publicKey));
|
||||
const p1 = getCurve().keyFromPublic(arrayify(other));
|
||||
return "0x" + p0.pub.add(p1.pub).encodeCompressed("hex");
|
||||
}
|
||||
|
||||
signDigest(digest: BytesLike): Signature {
|
||||
let keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey));
|
||||
let signature = keyPair.sign(arrayify(digest), { canonical: true });
|
||||
const keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey));
|
||||
const signature = keyPair.sign(arrayify(digest), { canonical: true });
|
||||
return splitSignature({
|
||||
recoveryParam: signature.recoveryParam,
|
||||
r: hexZeroPad("0x" + signature.r.toString(16), 32),
|
||||
|
@ -59,8 +59,8 @@ export class SigningKey {
|
|||
}
|
||||
|
||||
computeSharedSecret(otherKey: BytesLike): string {
|
||||
let keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey));
|
||||
let otherKeyPair = getCurve().keyFromPublic(arrayify(computePublicKey(otherKey)));
|
||||
const keyPair = getCurve().keyFromPrivate(arrayify(this.privateKey));
|
||||
const otherKeyPair = getCurve().keyFromPublic(arrayify(computePublicKey(otherKey)));
|
||||
return hexZeroPad("0x" + keyPair.derive(otherKeyPair.getPublic()).toString(16), 32);
|
||||
}
|
||||
|
||||
|
@ -70,16 +70,16 @@ export class SigningKey {
|
|||
}
|
||||
|
||||
export function recoverPublicKey(digest: BytesLike, signature: SignatureLike): string {
|
||||
let sig = splitSignature(signature);
|
||||
let rs = { r: arrayify(sig.r), s: arrayify(sig.s) };
|
||||
const sig = splitSignature(signature);
|
||||
const rs = { r: arrayify(sig.r), s: arrayify(sig.s) };
|
||||
return "0x" + getCurve().recoverPubKey(arrayify(digest), rs, sig.recoveryParam).encode("hex", false);
|
||||
}
|
||||
|
||||
export function computePublicKey(key: BytesLike, compressed?: boolean): string {
|
||||
let bytes = arrayify(key);
|
||||
const bytes = arrayify(key);
|
||||
|
||||
if (bytes.length === 32) {
|
||||
let signingKey = new SigningKey(bytes);
|
||||
const signingKey = new SigningKey(bytes);
|
||||
if (compressed) {
|
||||
return "0x" + getCurve().keyFromPrivate(bytes).getPublic(true, "hex");
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ function _pack(type: string, value: any, isArray?: boolean): Uint8Array {
|
|||
|
||||
match = type.match(regexBytes);
|
||||
if (match) {
|
||||
let size = parseInt(match[1]);
|
||||
const size = parseInt(match[1]);
|
||||
if (String(size) != match[1] || size === 0 || size > 32) {
|
||||
throw new Error("invalid number type - " + type);
|
||||
}
|
||||
|
@ -55,10 +55,10 @@ function _pack(type: string, value: any, isArray?: boolean): Uint8Array {
|
|||
|
||||
match = type.match(regexArray);
|
||||
if (match && Array.isArray(value)) {
|
||||
let baseType = match[1];
|
||||
let count = parseInt(match[2] || String(value.length));
|
||||
const baseType = match[1];
|
||||
const count = parseInt(match[2] || String(value.length));
|
||||
if (count != value.length) { throw new Error("invalid value for " + type); }
|
||||
let result: Array<Uint8Array> = [];
|
||||
const result: Array<Uint8Array> = [];
|
||||
value.forEach(function(value) {
|
||||
result.push(_pack(baseType, value, true));
|
||||
});
|
||||
|
@ -72,7 +72,7 @@ function _pack(type: string, value: any, isArray?: boolean): Uint8Array {
|
|||
|
||||
export function pack(types: Array<string>, values: Array<any>) {
|
||||
if (types.length != values.length) { throw new Error("type/value count mismatch"); }
|
||||
let tight: Array<Uint8Array> = [];
|
||||
const tight: Array<Uint8Array> = [];
|
||||
types.forEach(function(type, index) {
|
||||
tight.push(_pack(type, values[index]));
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ import { toUtf8Bytes, toUtf8String } from "./utf8";
|
|||
export function formatBytes32String(text: string): string {
|
||||
|
||||
// Get the bytes
|
||||
let bytes = toUtf8Bytes(text);
|
||||
const bytes = toUtf8Bytes(text);
|
||||
|
||||
// Check we have room for null-termination
|
||||
if (bytes.length > 31) { throw new Error("bytes32 string must be less than 32 bytes"); }
|
||||
|
@ -19,7 +19,7 @@ export function formatBytes32String(text: string): string {
|
|||
}
|
||||
|
||||
export function parseBytes32String(bytes: BytesLike): string {
|
||||
let data = arrayify(bytes);
|
||||
const data = arrayify(bytes);
|
||||
|
||||
// Must be 32 bytes with a null-termination
|
||||
if (data.length !== 32) { throw new Error("invalid bytes32 - not 32 bytes long"); }
|
||||
|
|
|
@ -20,13 +20,13 @@ export enum UnicodeNormalizationForm {
|
|||
function getUtf8CodePoints(bytes: BytesLike, ignoreErrors?: boolean): Array<number> {
|
||||
bytes = arrayify(bytes);
|
||||
|
||||
let result: Array<number> = [];
|
||||
const result: Array<number> = [];
|
||||
let i = 0;
|
||||
|
||||
// Invalid bytes are ignored
|
||||
while(i < bytes.length) {
|
||||
|
||||
let c = bytes[i++];
|
||||
const c = bytes[i++];
|
||||
// 0xxx xxxx
|
||||
if (c >> 7 === 0) {
|
||||
result.push(c);
|
||||
|
@ -129,7 +129,7 @@ export function toUtf8Bytes(str: string, form: UnicodeNormalizationForm = Unicod
|
|||
|
||||
let result = [];
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let c = str.charCodeAt(i);
|
||||
const c = str.charCodeAt(i);
|
||||
|
||||
if (c < 0x80) {
|
||||
result.push(c);
|
||||
|
@ -140,18 +140,18 @@ export function toUtf8Bytes(str: string, form: UnicodeNormalizationForm = Unicod
|
|||
|
||||
} else if ((c & 0xfc00) == 0xd800) {
|
||||
i++;
|
||||
let c2 = str.charCodeAt(i);
|
||||
const c2 = str.charCodeAt(i);
|
||||
|
||||
if (i >= str.length || (c2 & 0xfc00) !== 0xdc00) {
|
||||
throw new Error("invalid utf-8 string");
|
||||
}
|
||||
|
||||
// Surrogate Pair
|
||||
c = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);
|
||||
result.push((c >> 18) | 0xf0);
|
||||
result.push(((c >> 12) & 0x3f) | 0x80);
|
||||
result.push(((c >> 6) & 0x3f) | 0x80);
|
||||
result.push((c & 0x3f) | 0x80);
|
||||
const pair = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);
|
||||
result.push((pair >> 18) | 0xf0);
|
||||
result.push(((pair >> 12) & 0x3f) | 0x80);
|
||||
result.push(((pair >> 6) & 0x3f) | 0x80);
|
||||
result.push((pair & 0x3f) | 0x80);
|
||||
|
||||
} else {
|
||||
result.push((c >> 12) | 0xe0);
|
||||
|
@ -164,7 +164,7 @@ export function toUtf8Bytes(str: string, form: UnicodeNormalizationForm = Unicod
|
|||
};
|
||||
|
||||
function escapeChar(value: number) {
|
||||
let hex = ("0000" + value.toString(16));
|
||||
const hex = ("0000" + value.toString(16));
|
||||
return "\\u" + hex.substring(hex.length - 4);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ const allowedTransactionKeys: { [ key: string ]: boolean } = {
|
|||
}
|
||||
|
||||
export function computeAddress(key: BytesLike | string): string {
|
||||
let publicKey = computePublicKey(key);
|
||||
const publicKey = computePublicKey(key);
|
||||
return getAddress(hexDataSlice(keccak256(hexDataSlice(publicKey, 1)), 12));
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ export function recoverAddress(digest: BytesLike, signature: SignatureLike): str
|
|||
export function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string {
|
||||
checkProperties(transaction, allowedTransactionKeys);
|
||||
|
||||
let raw: Array<string | Uint8Array> = [];
|
||||
const raw: Array<string | Uint8Array> = [];
|
||||
|
||||
transactionFields.forEach(function(fieldInfo) {
|
||||
let value = (<any>transaction)[fieldInfo.name] || ([]);
|
||||
|
@ -115,7 +115,7 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
|
|||
raw.push("0x");
|
||||
}
|
||||
|
||||
let unsignedTransaction = RLP.encode(raw);
|
||||
const unsignedTransaction = RLP.encode(raw);
|
||||
|
||||
// Requesting an unsigned transation
|
||||
if (!signature) {
|
||||
|
@ -124,7 +124,7 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
|
|||
|
||||
// The splitSignature will ensure the transaction has a recoveryParam in the
|
||||
// case that the signTransaction function only adds a v.
|
||||
let sig = splitSignature(signature);
|
||||
const sig = splitSignature(signature);
|
||||
|
||||
// We pushed a chainId and null r, s on for hashing only; remove those
|
||||
let v = 27 + sig.recoveryParam
|
||||
|
@ -143,12 +143,12 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
|
|||
}
|
||||
|
||||
export function parse(rawTransaction: BytesLike): Transaction {
|
||||
let transaction = RLP.decode(rawTransaction);
|
||||
const transaction = RLP.decode(rawTransaction);
|
||||
if (transaction.length !== 9 && transaction.length !== 6) {
|
||||
logger.throwArgumentError("invalid raw transaction", "rawTransactin", rawTransaction);
|
||||
}
|
||||
|
||||
let tx: Transaction = {
|
||||
const tx: Transaction = {
|
||||
nonce: handleNumber(transaction[0]).toNumber(),
|
||||
gasPrice: handleNumber(transaction[1]),
|
||||
gasLimit: handleNumber(transaction[2]),
|
||||
|
@ -185,7 +185,7 @@ export function parse(rawTransaction: BytesLike): Transaction {
|
|||
|
||||
let recoveryParam = tx.v - 27;
|
||||
|
||||
let raw = transaction.slice(0, 6);
|
||||
const raw = transaction.slice(0, 6);
|
||||
|
||||
if (tx.chainId !== 0) {
|
||||
raw.push(hexlify(tx.chainId));
|
||||
|
@ -194,7 +194,7 @@ export function parse(rawTransaction: BytesLike): Transaction {
|
|||
recoveryParam -= tx.chainId * 2 + 8;
|
||||
}
|
||||
|
||||
let digest = keccak256(RLP.encode(raw));
|
||||
const digest = keccak256(RLP.encode(raw));
|
||||
try {
|
||||
tx.from = recoverAddress(digest, { r: hexlify(tx.r), s: hexlify(tx.s), recoveryParam: recoveryParam });
|
||||
} catch (error) {
|
||||
|
|
|
@ -21,7 +21,7 @@ const names = [
|
|||
// Some environments have issues with RegEx that contain back-tracking, so we cannot
|
||||
// use them.
|
||||
export function commify(value: string | number): string {
|
||||
let comps = String(value).split(".");
|
||||
const comps = String(value).split(".");
|
||||
|
||||
if (comps.length > 2 || !comps[0].match(/^-?[0-9]*$/) || (comps[1] && !comps[1].match(/^[0-9]*$/)) || value === "." || value === "-.") {
|
||||
logger.throwArgumentError("invalid value", "value", value);
|
||||
|
@ -43,13 +43,13 @@ export function commify(value: string | number): string {
|
|||
let suffix = "";
|
||||
if (comps.length === 2) { suffix = "." + (comps[1] || "0"); }
|
||||
|
||||
let formatted = [];
|
||||
const formatted = [];
|
||||
while (whole.length) {
|
||||
if (whole.length <= 3) {
|
||||
formatted.unshift(whole);
|
||||
break;
|
||||
} else {
|
||||
let index = whole.length - 3;
|
||||
const index = whole.length - 3;
|
||||
formatted.unshift(whole.substring(index));
|
||||
whole = whole.substring(0, index);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export function commify(value: string | number): string {
|
|||
|
||||
export function formatUnits(value: BigNumberish, unitName?: string | BigNumberish): string {
|
||||
if (typeof(unitName) === "string") {
|
||||
let index = names.indexOf(unitName);
|
||||
const index = names.indexOf(unitName);
|
||||
if (index !== -1) { unitName = 3 * index; }
|
||||
}
|
||||
return formatFixed(value, (unitName != null) ? unitName: 18);
|
||||
|
@ -68,7 +68,7 @@ export function formatUnits(value: BigNumberish, unitName?: string | BigNumberis
|
|||
|
||||
export function parseUnits(value: string, unitName?: BigNumberish): BigNumber {
|
||||
if (typeof(unitName) === "string") {
|
||||
let index = names.indexOf(unitName);
|
||||
const index = names.indexOf(unitName);
|
||||
if (index !== -1) { unitName = 3 * index; }
|
||||
}
|
||||
return parseFixed(value, (unitName != null) ? unitName: 18);
|
||||
|
|
|
@ -40,7 +40,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
|
|||
super();
|
||||
|
||||
if (isAccount(privateKey)) {
|
||||
let signingKey = new SigningKey(privateKey.privateKey);
|
||||
const signingKey = new SigningKey(privateKey.privateKey);
|
||||
defineReadOnly(this, "_signingKey", () => signingKey);
|
||||
defineReadOnly(this, "address", computeAddress(this.publicKey));
|
||||
|
||||
|
@ -49,11 +49,11 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
|
|||
}
|
||||
|
||||
if (privateKey.mnemonic != null) {
|
||||
let mnemonic = privateKey.mnemonic;
|
||||
let path = privateKey.path || defaultPath;
|
||||
const mnemonic = privateKey.mnemonic;
|
||||
const path = privateKey.path || defaultPath;
|
||||
defineReadOnly(this, "_mnemonic", () => mnemonic);
|
||||
defineReadOnly(this, "path", privateKey.path);
|
||||
let node = HDNode.fromMnemonic(mnemonic).derivePath(path);
|
||||
const node = HDNode.fromMnemonic(mnemonic).derivePath(path);
|
||||
if (computeAddress(node.privateKey) !== this.address) {
|
||||
logger.throwArgumentError("mnemonic/address mismatch", "privateKey", "[REDCACTED]");
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
|
|||
}
|
||||
defineReadOnly(this, "_signingKey", () => privateKey);
|
||||
} else {
|
||||
let signingKey = new SigningKey(privateKey);
|
||||
const signingKey = new SigningKey(privateKey);
|
||||
defineReadOnly(this, "_signingKey", () => signingKey);
|
||||
}
|
||||
defineReadOnly(this, "_mnemonic", (): string => null);
|
||||
|
@ -106,7 +106,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
|
|||
delete tx.from;
|
||||
}
|
||||
|
||||
let signature = this._signingKey().signDigest(keccak256(serialize(tx)));
|
||||
const signature = this._signingKey().signDigest(keccak256(serialize(tx)));
|
||||
return serialize(tx, signature);
|
||||
});
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ export class Wallet extends Signer implements ExternallyOwnedAccount {
|
|||
entropy = arrayify(hexDataSlice(keccak256(concat([ entropy, options.extraEntropy ])), 0, 16));
|
||||
}
|
||||
|
||||
let mnemonic = entropyToMnemonic(entropy, options.locale);
|
||||
const mnemonic = entropyToMnemonic(entropy, options.locale);
|
||||
return Wallet.fromMnemonic(mnemonic, options.path, options.locale);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,12 +43,12 @@ export type FetchJsonResponse = {
|
|||
type Header = { key: string, value: string };
|
||||
|
||||
export function fetchJson(connection: string | ConnectionInfo, json?: string, processFunc?: (value: any, response: FetchJsonResponse) => any): Promise<any> {
|
||||
let headers: { [key: string]: Header } = { };
|
||||
const headers: { [key: string]: Header } = { };
|
||||
|
||||
let url: string = null;
|
||||
|
||||
// @TODO: Allow ConnectionInfo to override some of these values
|
||||
let options: any = {
|
||||
const options: any = {
|
||||
method: "GET",
|
||||
mode: "cors", // no-cors, cors, *same-origin
|
||||
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
|
||||
|
@ -76,7 +76,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||
}
|
||||
|
||||
if (connection.headers) {
|
||||
for (let key in connection.headers) {
|
||||
for (const key in connection.headers) {
|
||||
headers[key.toLowerCase()] = { key: key, value: String(connection.headers[key]) };
|
||||
if (["if-none-match", "if-modified-since"].indexOf(key.toLowerCase()) >= 0) {
|
||||
allow304 = true;
|
||||
|
@ -93,7 +93,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||
);
|
||||
}
|
||||
|
||||
let authorization = connection.user + ":" + connection.password;
|
||||
const authorization = connection.user + ":" + connection.password;
|
||||
headers["authorization"] = {
|
||||
key: "Authorization",
|
||||
value: "Basic " + base64Encode(toUtf8Bytes(authorization))
|
||||
|
@ -113,7 +113,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||
}, timeout);
|
||||
}
|
||||
|
||||
let cancelTimeout = () => {
|
||||
const cancelTimeout = () => {
|
||||
if (timer == null) { return; }
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
|
@ -125,9 +125,9 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
|
|||
headers["content-type"] = { key: "Content-Type", value: "application/json" };
|
||||
}
|
||||
|
||||
let flatHeaders: { [ key: string ]: string } = { };
|
||||
const flatHeaders: { [ key: string ]: string } = { };
|
||||
Object.keys(headers).forEach((key) => {
|
||||
let header = headers[key];
|
||||
const header = headers[key];
|
||||
flatHeaders[header.key] = header.value;
|
||||
});
|
||||
options.headers = flatHeaders;
|
||||
|
@ -213,7 +213,7 @@ export function poll(func: () => Promise<any>, options?: PollOptions): Promise<a
|
|||
let done: boolean = false;
|
||||
|
||||
// Returns true if cancel was successful. Unsuccessful cancel means we're already done.
|
||||
let cancel = (): boolean => {
|
||||
const cancel = (): boolean => {
|
||||
if (done) { return false; }
|
||||
done = true;
|
||||
if (timer) { clearTimeout(timer); }
|
||||
|
@ -226,7 +226,7 @@ export function poll(func: () => Promise<any>, options?: PollOptions): Promise<a
|
|||
}, options.timeout)
|
||||
}
|
||||
|
||||
let retryLimit = options.retryLimit;
|
||||
const retryLimit = options.retryLimit;
|
||||
|
||||
let attempt = 0;
|
||||
function check() {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -52,7 +52,7 @@ function loadWords(lang: Wordlist) {
|
|||
wordlist = [];
|
||||
|
||||
// Transforms for normalizing (sort is a not quite UTF-8)
|
||||
let transform: { [key: string]: string | boolean } = {};
|
||||
const transform: { [key: string]: string | boolean } = {};
|
||||
|
||||
// Delete the diacritic marks
|
||||
transform[toUtf8String([227, 130, 154])] = false;
|
||||
|
@ -70,7 +70,7 @@ function loadWords(lang: Wordlist) {
|
|||
let result = "";
|
||||
for (let i = 0; i < word.length; i++) {
|
||||
let kana = word[i];
|
||||
let target = transform[kana];
|
||||
const target = transform[kana];
|
||||
if (target === false) { continue; }
|
||||
if (target) { kana = <string>target; }
|
||||
result += kana;
|
||||
|
@ -89,11 +89,11 @@ function loadWords(lang: Wordlist) {
|
|||
|
||||
// Load all the words
|
||||
for (let length = 3; length <= 9; length++) {
|
||||
let d = data[length - 3];
|
||||
const d = data[length - 3];
|
||||
for (let offset = 0; offset < d.length; offset += length) {
|
||||
let word = [];
|
||||
const word = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
let k = mapping.indexOf(d[offset + i]);
|
||||
const k = mapping.indexOf(d[offset + i]);
|
||||
word.push(227);
|
||||
word.push((k & 0x40) ? 130: 129);
|
||||
word.push((k & 0x3f) + 128);
|
||||
|
@ -109,7 +109,7 @@ function loadWords(lang: Wordlist) {
|
|||
// - kiyoku
|
||||
|
||||
if (hex(wordlist[442]) === KiYoKu && hex(wordlist[443]) === KyoKu) {
|
||||
let tmp = wordlist[442];
|
||||
const tmp = wordlist[442];
|
||||
wordlist[442] = wordlist[443];
|
||||
wordlist[443] = tmp;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ const data = [
|
|||
"AbDl8SToJU8An3RbAb8ST8DUSTrGnrAgoLbFU6Db8LTrMg8AaHT8Jb8ObDl8SToJU8Pb3RlvFYoJl"
|
||||
]
|
||||
|
||||
let codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*"
|
||||
const codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*"
|
||||
|
||||
function getHangul(code: number): string {
|
||||
if (code >= 40) {
|
||||
|
|
|
@ -30,15 +30,15 @@ function loadWords(lang: Wordlist) {
|
|||
|
||||
let deltaOffset = 0;
|
||||
for (let i = 0; i < 2048; i++) {
|
||||
let s = style.indexOf(data[i * 3]);
|
||||
let bytes = [
|
||||
const s = style.indexOf(data[i * 3]);
|
||||
const bytes = [
|
||||
228 + (s >> 2),
|
||||
128 + codes.indexOf(data[i * 3 + 1]),
|
||||
128 + codes.indexOf(data[i * 3 + 2]),
|
||||
];
|
||||
|
||||
if (lang.locale === "zh_tw") {
|
||||
let common = s % 4;
|
||||
const common = s % 4;
|
||||
for (let i = common; i < 3; i++) {
|
||||
bytes[i] = codes.indexOf(deltaData[deltaOffset++]) + ((i == 0) ? 228: 128);
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ import { version } from "./_version";
|
|||
const logger = new Logger(version);
|
||||
|
||||
export function check(wordlist: Wordlist) {
|
||||
let words = [];
|
||||
const words = [];
|
||||
for (let i = 0; i < 2048; i++) {
|
||||
let word = wordlist.getWord(i);
|
||||
const word = wordlist.getWord(i);
|
||||
if (i !== wordlist.getWordIndex(word)) { return "0x"; }
|
||||
words.push(word);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ export abstract class Wordlist {
|
|||
export function register(lang: Wordlist, name?: string): void {
|
||||
if (!name) { name = lang.locale; }
|
||||
if (exportWordlist) {
|
||||
let g: any = (<any>global)
|
||||
const g: any = (<any>global)
|
||||
if (!(g.wordlists)) { defineReadOnly(g, "wordlists", { }); }
|
||||
if (!g.wordlists[name]) {
|
||||
defineReadOnly(g.wordlists, name, lang);
|
||||
|
|
Loading…
Reference in New Issue