Refactor API.

This commit is contained in:
Richard Moore 2018-06-15 04:18:17 -04:00
parent 7391cf8d19
commit efbfed0d40
No known key found for this signature in database
GPG Key ID: 525F70A6FCABC295
57 changed files with 997 additions and 763 deletions

189
dist/ethers.d.ts vendored

File diff suppressed because one or more lines are too long

460
dist/ethers.js vendored

File diff suppressed because one or more lines are too long

2
dist/ethers.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -46,7 +46,7 @@
"fs": "./tests/browser-fs.js", "fs": "./tests/browser-fs.js",
"zlib": "browserify-zlib", "zlib": "browserify-zlib",
"./src.ts/utils/base64.ts": "./src.browser/base64.ts", "./src.ts/utils/base64.ts": "./src.browser/base64.ts",
"./src.ts/utils/random-bytes.js": "./src.browser/random-bytes.js", "./src.ts/utils/random-bytes.ts": "./src.browser/random-bytes.ts",
"./providers/ipc-provider.js": "./utils/empty.js", "./providers/ipc-provider.js": "./utils/empty.js",
"xmlhttprequest": "./src.browser/xmlhttprequest.ts" "xmlhttprequest": "./src.browser/xmlhttprequest.ts"
}, },

View File

@ -1,22 +1,21 @@
'use strict'; 'use strict';
import convert = require('./convert'); import { arrayify } from '../src.ts/utils/convert';
import properties = require('./properties'); import { defineReadOnly } from '../src.ts/utils/properties';
var defineProperty = properties.defineProperty;
var crypto = global.crypto || global.msCrypto; let crypto: any = global['crypto'] || global['msCrypto'];
if (!crypto || !crypto.getRandomValues) { if (!crypto || !crypto.getRandomValues) {
console.log('WARNING: Missing strong random number source; using weak randomBytes'); console.log('WARNING: Missing strong random number source; using weak randomBytes');
crypto = { crypto = {
getRandomValues: function(buffer) { getRandomValues: function(buffer: Uint8Array) {
for (var round = 0; round < 20; round++) { for (var round = 0; round < 20; round++) {
for (var i = 0; i < buffer.length; i++) { for (var i = 0; i < buffer.length; i++) {
if (round) { if (round) {
buffer[i] ^= parseInt(256 * Math.random()); buffer[i] ^= Math.trunc(256 * Math.random());
} else { } else {
buffer[i] = parseInt(256 * Math.random()); buffer[i] = Math.trunc(256 * Math.random());
} }
} }
} }
@ -27,18 +26,16 @@ if (!crypto || !crypto.getRandomValues) {
}; };
} }
function randomBytes(length) { export function randomBytes(length) {
if (length <= 0 || length > 1024 || parseInt(length) != length) { if (length <= 0 || length > 1024 || parseInt(length) != length) {
throw new Error('invalid length'); throw new Error('invalid length');
} }
var result = new Uint8Array(length); var result = new Uint8Array(length);
crypto.getRandomValues(result); crypto.getRandomValues(result);
return convert.arrayify(result); return arrayify(result);
}; };
if (crypto._weakCrypto === true) { if (crypto._weakCrypto === true) {
defineProperty(randomBytes, '_weakCrypto', true); defineReadOnly(randomBytes, '_weakCrypto', true);
} }
module.exports = randomBytes;

View File

@ -41,8 +41,7 @@ function parseParams(params: Array<ParamType>): { names: Array<any>, types: Arra
export class Indexed { export class Indexed {
readonly hash: string; readonly hash: string;
constructor(value) { constructor(value: string) {
defineReadOnly(this, 'indexed', true);
defineReadOnly(this, 'hash', value); defineReadOnly(this, 'hash', value);
} }
} }
@ -325,7 +324,7 @@ function addMethod(method: any): void {
} }
export class Interface { export class Interface {
readonly _abi: Array<any>; readonly abi: Array<any>;
readonly functions: Array<FunctionDescription>; readonly functions: Array<FunctionDescription>;
readonly events: Array<EventDescription>; readonly events: Array<EventDescription>;
readonly deployFunction: DeployDescription; readonly deployFunction: DeployDescription;
@ -354,15 +353,17 @@ export class Interface {
defineReadOnly(this, 'events', { }); defineReadOnly(this, 'events', { });
// Convert any supported ABI format into a standard ABI format // Convert any supported ABI format into a standard ABI format
this._abi = []; let _abi = [];
abi.forEach((fragment) => { abi.forEach((fragment) => {
if (typeof(fragment) === 'string') { if (typeof(fragment) === 'string') {
fragment = parseSignature(fragment); fragment = parseSignature(fragment);
} }
this._abi.push(fragment); _abi.push(fragment);
}); });
this._abi.forEach(addMethod, this); defineFrozen(this, 'abi', _abi);
_abi.forEach(addMethod, this);
// If there wasn't a constructor, create the default constructor // If there wasn't a constructor, create the default constructor
if (!this.deployFunction) { if (!this.deployFunction) {
@ -388,6 +389,7 @@ export class Interface {
} }
return null; return null;
} }
// @TODO:
//parseEvent(log: { }): Lo
} }

View File

@ -3,6 +3,7 @@
import { Contract, Interface } from './contracts'; import { Contract, Interface } from './contracts';
import * as providers from './providers'; import * as providers from './providers';
import * as errors from './utils/errors'; import * as errors from './utils/errors';
import { networks } from './providers/networks';
import utils from './utils'; import utils from './utils';
import { HDNode, SigningKey, Wallet } from './wallet'; import { HDNode, SigningKey, Wallet } from './wallet';
@ -19,6 +20,7 @@ export {
Contract, Contract,
Interface, Interface,
networks,
providers, providers,
errors, errors,

View File

@ -36,7 +36,7 @@ export class InfuraProvider extends JsonRpcProvider {
this.apiAccessToken = (apiAccessToken || null); this.apiAccessToken = (apiAccessToken || null);
} }
_startPending() { _startPending(): void {
console.log('WARNING: INFURA does not support pending filters'); console.log('WARNING: INFURA does not support pending filters');
} }
@ -49,7 +49,7 @@ export class InfuraProvider extends JsonRpcProvider {
return null; return null;
} }
listAccounts() { listAccounts(): Promise<Array<string>> {
return Promise.resolve([]); return Promise.resolve([]);
} }
} }

View File

@ -21,7 +21,7 @@ export class IpcProvider extends JsonRpcProvider {
// @TODO: Create a connection to the IPC path and use filters instead of polling for block // @TODO: Create a connection to the IPC path and use filters instead of polling for block
send(method, params) { send(method: string, params: any): Promise<any> {
// This method is very simple right now. We create a new socket // This method is very simple right now. We create a new socket
// connection each time, which may be slower, but the main // connection each time, which may be slower, but the main
// advantage we are aiming for now is security. This simplifies // advantage we are aiming for now is security. This simplifies

View File

@ -206,27 +206,28 @@ export class JsonRpcProvider extends Provider {
} }
} }
getSigner(address) { getSigner(address: string): JsonRpcSigner {
return new JsonRpcSigner(this, address); return new JsonRpcSigner(this, address);
} }
listAccounts() { listAccounts(): Promise<Array<string>> {
return this.send('eth_accounts', []).then((accounts) => { return this.send('eth_accounts', []).then((accounts) => {
return accounts.map((a) => getAddress(a)); return accounts.map((a) => getAddress(a));
}); });
} }
send(method, params) { send(method: string, params: any): Promise<any> {
var request = { var request = {
method: method, method: method,
params: params, params: params,
id: 42, id: 42,
jsonrpc: "2.0" jsonrpc: "2.0"
}; };
return fetchJson(this.connection, JSON.stringify(request), getResult); return fetchJson(this.connection, JSON.stringify(request), getResult);
} }
perform(method, params) { perform(method: string, params: any): Promise<any> {
switch (method) { switch (method) {
case 'getBlockNumber': case 'getBlockNumber':
return this.send('eth_blockNumber', []); return this.send('eth_blockNumber', []);
@ -283,7 +284,7 @@ export class JsonRpcProvider extends Provider {
return null; return null;
} }
_startPending() { _startPending(): void {
if (this._pendingFilter != null) { return; } if (this._pendingFilter != null) { return; }
var self = this; var self = this;
@ -322,7 +323,7 @@ export class JsonRpcProvider extends Provider {
}); });
} }
_stopPending() { _stopPending(): void {
this._pendingFilter = null; this._pendingFilter = null;
} }
} }

View File

@ -58,6 +58,7 @@ export type TransactionRequest = {
export type TransactionResponse = { export type TransactionResponse = {
blockNumber?: number, blockNumber?: number,
blockHash?: string, blockHash?: string,
timestamp?: number,
hash: string, hash: string,
@ -291,7 +292,7 @@ var formatTransaction = {
raw: allowNull(hexlify), raw: allowNull(hexlify),
}; };
export function checkTransactionResponse(transaction) { export function checkTransactionResponse(transaction: any): TransactionResponse {
// Rename gas to gasLimit // Rename gas to gasLimit
if (transaction.gas != null && transaction.gasLimit == null) { if (transaction.gas != null && transaction.gasLimit == null) {
@ -632,7 +633,7 @@ export class Provider {
this._emitted = { block: this._lastBlockNumber }; this._emitted = { block: this._lastBlockNumber };
} }
private _doPoll() { private _doPoll(): void {
this.getBlockNumber().then((blockNumber) => { this.getBlockNumber().then((blockNumber) => {
// If the block hasn't changed, meh. // If the block hasn't changed, meh.
@ -706,12 +707,12 @@ export class Provider {
this.doPoll(); this.doPoll();
} }
resetEventsBlock(blockNumber) { resetEventsBlock(blockNumber: number): void {
this._lastBlockNumber = this.blockNumber; this._lastBlockNumber = this.blockNumber;
this._doPoll(); this._doPoll();
} }
get network() { get network(): Network {
return this._network; return this._network;
} }
@ -724,11 +725,11 @@ export class Provider {
return this._lastBlockNumber; return this._lastBlockNumber;
} }
get polling() { get polling(): boolean {
return (this._poller != null); return (this._poller != null);
} }
set polling(value) { set polling(value: boolean) {
setTimeout(() => { setTimeout(() => {
if (value && !this._poller) { if (value && !this._poller) {
this._poller = setInterval(this._doPoll.bind(this), this.pollingInterval); this._poller = setInterval(this._doPoll.bind(this), this.pollingInterval);
@ -740,7 +741,7 @@ export class Provider {
}, 0); }, 0);
} }
get pollingInterval() { get pollingInterval(): number {
return this._pollingInterval; return this._pollingInterval;
} }
@ -992,7 +993,7 @@ export class Provider {
}); });
} }
_resolveNames(object, keys) { _resolveNames(object: any, keys: Array<string>): Promise<any> {
var promises = []; var promises = [];
var result = copyObject(object); var result = copyObject(object);
@ -1007,7 +1008,7 @@ export class Provider {
return Promise.all(promises).then(function() { return result; }); return Promise.all(promises).then(function() { return result; });
} }
_getResolver(name) { _getResolver(name: string): Promise<string> {
// Get the resolver from the blockchain // Get the resolver from the blockchain
return this.getNetwork().then((network) => { return this.getNetwork().then((network) => {
@ -1115,7 +1116,7 @@ export class Provider {
}); });
} }
doPoll() { doPoll(): void {
} }
perform(method: string, params: any): Promise<any> { perform(method: string, params: any): Promise<any> {

View File

@ -13,6 +13,7 @@ utils.defineProperty(Web3Signer, 'onchange', {
*/ */
export type Callback = (error: any, response: any) => void; export type Callback = (error: any, response: any) => void;
export type AsyncProvider = { export type AsyncProvider = {
isMetaMask: boolean; isMetaMask: boolean;
host?: string; host?: string;
@ -42,7 +43,7 @@ export class Web3Provider extends JsonRpcProvider {
this._web3Provider = web3Provider; this._web3Provider = web3Provider;
} }
send(method, params) { send(method: string, params: any): Promise<any> {
// Metamask complains about eth_sign (and on some versions hangs) // Metamask complains about eth_sign (and on some versions hangs)
if (method == 'eth_sign' && this._web3Provider.isMetaMask) { if (method == 'eth_sign' && this._web3Provider.isMetaMask) {

View File

@ -6,6 +6,7 @@ import { getAddress } from './address';
import { bigNumberify, BigNumberish } from './bignumber'; import { bigNumberify, BigNumberish } from './bignumber';
import { arrayify, Arrayish, concat, hexlify, padZeros } from './convert'; import { arrayify, Arrayish, concat, hexlify, padZeros } from './convert';
import { toUtf8Bytes, toUtf8String } from './utf8'; import { toUtf8Bytes, toUtf8String } from './utf8';
import { defineReadOnly, jsonCopy } from './properties';
import * as errors from './errors'; import * as errors from './errors';
@ -17,7 +18,7 @@ const paramTypeArray = new RegExp(/^(.*)\[([0-9]*)\]$/);
export type CoerceFunc = (type: string, value: any) => any; export type CoerceFunc = (type: string, value: any) => any;
export type ParamType = { name?: string, type: string, indexed?: boolean, components?: Array<any> }; export type ParamType = { name?: string, type: string, indexed?: boolean, components?: Array<any> };
export function defaultCoerceFunc(type: string, value: any): any { export const defaultCoerceFunc: CoerceFunc = function(type: string, value: any): any {
var match = type.match(paramTypeNumber) var match = type.match(paramTypeNumber)
if (match && parseInt(match[2]) <= 48) { return value.toNumber(); } if (match && parseInt(match[2]) <= 48) { return value.toNumber(); }
return value; return value;
@ -173,8 +174,32 @@ function parseParam(param: string, allowIndexed?: boolean): ParamType {
return (<ParamType>parent); return (<ParamType>parent);
} }
// @TODO: should this just be a combined Fragment?
export type EventFragment = {
type: string
name: string,
anonymous: boolean,
inputs: Array<ParamType>,
};
export type FunctionFragment = {
type: string
name: string,
constant: boolean,
inputs: Array<ParamType>,
outputs: Array<ParamType>,
payable: boolean,
stateMutability: string,
};
// @TODO: Better return type // @TODO: Better return type
function parseSignatureEvent(fragment: string): any { function parseSignatureEvent(fragment: string): EventFragment {
var abi = { var abi = {
anonymous: false, anonymous: false,
@ -213,7 +238,7 @@ function parseSignatureEvent(fragment: string): any {
return abi; return abi;
} }
function parseSignatureFunction(fragment: string): any { function parseSignatureFunction(fragment: string): FunctionFragment {
var abi = { var abi = {
constant: false, constant: false,
inputs: [], inputs: [],
@ -276,7 +301,7 @@ function parseSignatureFunction(fragment: string): any {
} }
export function parseSignature(fragment: string): any { export function parseSignature(fragment: string): EventFragment | FunctionFragment {
if(typeof(fragment) === 'string') { if(typeof(fragment) === 'string') {
// Make sure the "returns" is surrounded by a space and all whitespace is exactly one space // Make sure the "returns" is surrounded by a space and all whitespace is exactly one space
fragment = fragment.replace(/\(/g, ' (').replace(/\)/g, ') ').replace(/\s+/g, ' '); fragment = fragment.replace(/\(/g, ' (').replace(/\)/g, ') ').replace(/\s+/g, ' ');
@ -293,7 +318,7 @@ export function parseSignature(fragment: string): any {
} }
} }
throw new Error('unknown fragment'); throw new Error('unknown signature');
} }
@ -908,10 +933,10 @@ function getParamCoder(coerceFunc: CoerceFunc, param: ParamType): Coder {
export class AbiCoder { export class AbiCoder {
readonly coerceFunc: CoerceFunc; readonly coerceFunc: CoerceFunc;
constructor(coerceFunc?: CoerceFunc) { constructor(coerceFunc?: CoerceFunc) {
//if (!(this instanceof Coder)) { throw new Error('missing new'); } errors.checkNew(this, AbiCoder);
if (!coerceFunc) { coerceFunc = defaultCoerceFunc; } if (!coerceFunc) { coerceFunc = defaultCoerceFunc; }
// @TODO: readonly defineReadOnly(this, 'coerceFunc', coerceFunc);
this.coerceFunc = coerceFunc;
} }
encode(types: Array<string | ParamType>, values: Array<any>): string { encode(types: Array<string | ParamType>, values: Array<any>): string {
@ -928,11 +953,16 @@ export class AbiCoder {
// Convert types to type objects // Convert types to type objects
// - "uint foo" => { type: "uint", name: "foo" } // - "uint foo" => { type: "uint", name: "foo" }
// - "tuple(uint, uint)" => { type: "tuple", components: [ { type: "uint" }, { type: "uint" }, ] } // - "tuple(uint, uint)" => { type: "tuple", components: [ { type: "uint" }, { type: "uint" }, ] }
let typeObject: ParamType = null;
if (typeof(type) === 'string') { if (typeof(type) === 'string') {
type = parseParam(type); typeObject = parseParam(type);
} else {
typeObject = jsonCopy(type);
} }
coders.push(getParamCoder(this.coerceFunc, type)); coders.push(getParamCoder(this.coerceFunc, typeObject));
}, this); }, this);
return hexlify(new CoderTuple(this.coerceFunc, coders, '_').encode(values)); return hexlify(new CoderTuple(this.coerceFunc, coders, '_').encode(values));
@ -944,11 +974,14 @@ export class AbiCoder {
types.forEach(function(type) { types.forEach(function(type) {
// See encode for details // See encode for details
let typeObject: ParamType = null;
if (typeof(type) === 'string') { if (typeof(type) === 'string') {
type = parseParam(type); typeObject = parseParam(type);
} else {
typeObject = jsonCopy(type);
} }
coders.push(getParamCoder(this.coerceFunc, type)); coders.push(getParamCoder(this.coerceFunc, typeObject));
}, this); }, this);
return new CoderTuple(this.coerceFunc, coders, '_').decode(arrayify(data), 0).value; return new CoderTuple(this.coerceFunc, coders, '_').decode(arrayify(data), 0).value;

View File

@ -82,7 +82,7 @@ export type BigNumberish = BigNumber | string | number | Arrayish;
export class BigNumber { export class BigNumber {
readonly _bn: _BN.BN; readonly _bn: _BN.BN;
constructor(value: BigNumberish) { constructor(value: BigNumberish) {
if (!(this instanceof BigNumber)) { throw new Error('missing new'); } errors.checkNew(this, BigNumber);
if (typeof(value) === 'string') { if (typeof(value) === 'string') {
if (isHexString(value)) { if (isHexString(value)) {

View File

@ -51,3 +51,13 @@ export function resolveProperties(object: any) {
return object; return object;
}); });
} }
export function shallowCopy(object: any): any {
let result = {};
for (var key in object) { result[key] = object[key]; }
return result;
}
export function jsonCopy(object: any): any {
return JSON.parse(JSON.stringify(object));
}

View File

@ -2,30 +2,11 @@
import { arrayify } from './convert'; import { arrayify } from './convert';
//import * as crypto from 'crypto'; import { randomBytes as _randomBytes } from 'crypto';
//@TODO: Figure out how to fix crypto //function _randomBytes(length) { return "0x00"; }
function getRandomValues(buffer) {
for (var round = 0; round < 20; round++) {
for (var i = 0; i < buffer.length; i++) {
if (round) {
buffer[i] ^= Math.trunc(256 * Math.random());
} else {
buffer[i] = Math.trunc(256 * Math.random());
}
}
}
return buffer; export function randomBytes(length: number): Uint8Array {
} return arrayify(_randomBytes(length));
}
export function randomBytes(length) {
if (length <= 0 || length > 1024 || parseInt(length) != length) {
throw new Error('invalid length');
}
var result = new Uint8Array(length);
getRandomValues(result);
return arrayify(result);
};

View File

@ -2,7 +2,7 @@
import * as _hash from 'hash.js'; import * as _hash from 'hash.js';
import { arrayify } from './convert'; import { arrayify, Arrayish } from './convert';
interface HashFunc { interface HashFunc {
@ -15,10 +15,10 @@ const _sha256: HashFunc = _hash['sha256'];
const _sha512: HashFunc = _hash['sha512']; const _sha512: HashFunc = _hash['sha512'];
export function sha256(data: any): string { export function sha256(data: Arrayish): string {
return '0x' + (_sha256().update(arrayify(data)).digest('hex')); return '0x' + (_sha256().update(arrayify(data)).digest('hex'));
} }
export function sha512(data: any): string { export function sha512(data: Arrayish): string {
return '0x' + (_sha512().update(arrayify(data)).digest('hex')); return '0x' + (_sha512().update(arrayify(data)).digest('hex'));
} }

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
import { bigNumberify, ConstantZero, ConstantNegativeOne } from './bignumber'; import { BigNumber, bigNumberify, BigNumberish, ConstantZero, ConstantNegativeOne } from './bignumber';
import * as errors from './errors'; import * as errors from './errors';
@ -56,7 +56,7 @@ var getUnitInfo = (function() {
} }
})(); })();
export function formatUnits(value: any, unitType: string | number, options?: any): string { export function formatUnits(value: BigNumberish, unitType?: string | number, options?: any): string {
/* /*
if (typeof(unitType) === 'object' && !options) { if (typeof(unitType) === 'object' && !options) {
options = unitType; options = unitType;
@ -75,7 +75,7 @@ export function formatUnits(value: any, unitType: string | number, options?: any
var negative = value.lt(ConstantZero); var negative = value.lt(ConstantZero);
if (negative) { value = value.mul(ConstantNegativeOne); } if (negative) { value = value.mul(ConstantNegativeOne); }
var fraction = value.mod(unitInfo.tenPower).toString(10); var fraction = value.mod(unitInfo.tenPower).toString();
while (fraction.length < unitInfo.decimals) { fraction = '0' + fraction; } while (fraction.length < unitInfo.decimals) { fraction = '0' + fraction; }
// Strip off trailing zeros (but keep one if would otherwise be bare decimal point) // Strip off trailing zeros (but keep one if would otherwise be bare decimal point)
@ -83,7 +83,7 @@ export function formatUnits(value: any, unitType: string | number, options?: any
fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1]; fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1];
} }
var whole = value.div(unitInfo.tenPower).toString(10); var whole = value.div(unitInfo.tenPower).toString();
if (options.commify) { if (options.commify) {
whole = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",") whole = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
@ -96,7 +96,7 @@ export function formatUnits(value: any, unitType: string | number, options?: any
return value; return value;
} }
export function parseUnits(value, unitType) { export function parseUnits(value: string, unitType?: string | number): BigNumber {
if (unitType == null) { unitType = 18; } if (unitType == null) { unitType = 18; }
var unitInfo = getUnitInfo(unitType); var unitInfo = getUnitInfo(unitType);
@ -116,12 +116,12 @@ export function parseUnits(value, unitType) {
} }
// Split it into a whole and fractional part // Split it into a whole and fractional part
var comps = value.split('.'); let comps = value.split('.');
if (comps.length > 2) { if (comps.length > 2) {
errors.throwError('too many decimal points', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); errors.throwError('too many decimal points', errors.INVALID_ARGUMENT, { arg: 'value', value: value });
} }
var whole = comps[0], fraction = comps[1]; let whole = comps[0], fraction = comps[1];
if (!whole) { whole = '0'; } if (!whole) { whole = '0'; }
if (!fraction) { fraction = '0'; } if (!fraction) { fraction = '0'; }
@ -137,21 +137,21 @@ export function parseUnits(value, unitType) {
// Fully pad the string with zeros to get to wei // Fully pad the string with zeros to get to wei
while (fraction.length < unitInfo.decimals) { fraction += '0'; } while (fraction.length < unitInfo.decimals) { fraction += '0'; }
whole = bigNumberify(whole); let wholeValue = bigNumberify(whole);
fraction = bigNumberify(fraction); let fractionValue = bigNumberify(fraction);
var wei = (whole.mul(unitInfo.tenPower)).add(fraction); let wei = (wholeValue.mul(unitInfo.tenPower)).add(fractionValue);
if (negative) { wei = wei.mul(ConstantNegativeOne); } if (negative) { wei = wei.mul(ConstantNegativeOne); }
return wei; return wei;
} }
export function formatEther(wei, options) { export function formatEther(wei: BigNumberish, options: any): string {
return formatUnits(wei, 18, options); return formatUnits(wei, 18, options);
} }
export function parseEther(ether) { export function parseEther(ether: string): BigNumber {
return parseUnits(ether, 18); return parseUnits(ether, 18);
} }

View File

@ -3,12 +3,11 @@
// See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki // See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
// See: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki // See: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
import * as secp256k1 from './secp256k1'; import { KeyPair, N } from './secp256k1';
import words from './words'; import { getWord, getWordIndex } from './words';
var wordlist: Array<string> = words.replace(/([A-Z])/g, ' $1').toLowerCase().substring(1).split(' ');
import { arrayify, hexlify } from '../utils/convert'; import { arrayify, Arrayish, hexlify } from '../utils/convert';
import { bigNumberify } from '../utils/bignumber'; import { bigNumberify } from '../utils/bignumber';
import { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8'; import { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';
import { pbkdf2 } from '../utils/pbkdf2'; import { pbkdf2 } from '../utils/pbkdf2';
@ -33,7 +32,7 @@ function getLowerMask(bits: number): number {
} }
export class HDNode { export class HDNode {
private readonly keyPair: secp256k1.KeyPair; private readonly keyPair: KeyPair;
readonly privateKey: string; readonly privateKey: string;
readonly publicKey: string; readonly publicKey: string;
@ -47,13 +46,13 @@ export class HDNode {
readonly depth: number; readonly depth: number;
// @TODO: Private constructor? // @TODO: Private constructor?
constructor(keyPair: secp256k1.KeyPair, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string) { constructor(keyPair: KeyPair, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string) {
errors.checkNew(this, HDNode); errors.checkNew(this, HDNode);
this.keyPair = keyPair; this.keyPair = keyPair;
this.privateKey = hexlify(keyPair.priv.toArray('be', 32)); this.privateKey = keyPair.privateKey;
this.publicKey = '0x' + keyPair.getPublic(true, 'hex'); this.publicKey = keyPair.compressedPublicKey;
this.chainCode = hexlify(chainCode); this.chainCode = hexlify(chainCode);
@ -88,7 +87,7 @@ export class HDNode {
} else { } else {
// Data = ser_p(point(k_par)) // Data = ser_p(point(k_par))
data.set(this.keyPair.getPublic().encode(null, true)); data.set(this.keyPair.publicKeyBytes);
} }
// Data += ser_32(i) // Data += ser_32(i)
@ -98,9 +97,9 @@ export class HDNode {
var IL = bigNumberify(I.slice(0, 32)); var IL = bigNumberify(I.slice(0, 32));
var IR = I.slice(32); var IR = I.slice(32);
var ki = IL.add('0x' + this.keyPair.getPrivate('hex')).mod('0x' + secp256k1.curve.n.toString(16)); var ki = IL.add(this.keyPair.privateKey).mod(N);
return new HDNode(secp256k1.curve.keyFromPrivate(arrayify(ki)), IR, index, this.depth + 1, mnemonic, path); return new HDNode(new KeyPair(arrayify(ki)), IR, index, this.depth + 1, mnemonic, path);
} }
derivePath(path: string): HDNode { derivePath(path: string): HDNode {
@ -132,13 +131,13 @@ export class HDNode {
} }
} }
function _fromSeed(seed: any, mnemonic: string): HDNode { function _fromSeed(seed: Arrayish, mnemonic: string): HDNode {
seed = arrayify(seed); let seedArray: Uint8Array = arrayify(seed);
if (seed.length < 16 || seed.length > 64) { throw new Error('invalid seed'); } if (seedArray.length < 16 || seedArray.length > 64) { throw new Error('invalid seed'); }
var I = arrayify(createSha512Hmac(MasterSecret).update(seed).digest()); var I: Uint8Array = arrayify(createSha512Hmac(MasterSecret).update(seedArray).digest());
return new HDNode(secp256k1.curve.keyFromPrivate(I.slice(0, 32)), I.slice(32), 0, 0, mnemonic, 'm'); return new HDNode(new KeyPair(I.slice(0, 32)), I.slice(32), 0, 0, mnemonic, 'm');
} }
export function fromMnemonic(mnemonic: string): HDNode { export function fromMnemonic(mnemonic: string): HDNode {
@ -148,7 +147,7 @@ export function fromMnemonic(mnemonic: string): HDNode {
return _fromSeed(mnemonicToSeed(mnemonic), mnemonic); return _fromSeed(mnemonicToSeed(mnemonic), mnemonic);
} }
export function fromSeed(seed: any): HDNode { export function fromSeed(seed: Arrayish): HDNode {
return _fromSeed(seed, null); return _fromSeed(seed, null);
} }
@ -180,7 +179,7 @@ export function mnemonicToEntropy(mnemonic: string): string {
var offset = 0; var offset = 0;
for (var i = 0; i < words.length; i++) { for (var i = 0; i < words.length; i++) {
var index = wordlist.indexOf(words[i]); var index = getWordIndex(words[i]);
if (index === -1) { throw new Error('invalid mnemonic'); } if (index === -1) { throw new Error('invalid mnemonic'); }
for (var bit = 0; bit < 11; bit++) { for (var bit = 0; bit < 11; bit++) {
@ -206,32 +205,32 @@ export function mnemonicToEntropy(mnemonic: string): string {
return hexlify(entropy.slice(0, entropyBits / 8)); return hexlify(entropy.slice(0, entropyBits / 8));
} }
export function entropyToMnemonic(entropy: any): string { export function entropyToMnemonic(entropy: Arrayish): string {
entropy = arrayify(entropy); entropy = arrayify(entropy);
if ((entropy.length % 4) !== 0 || entropy.length < 16 || entropy.length > 32) { if ((entropy.length % 4) !== 0 || entropy.length < 16 || entropy.length > 32) {
throw new Error('invalid entropy'); throw new Error('invalid entropy');
} }
var words: Array<number> = [ 0 ]; var indices: Array<number> = [ 0 ];
var remainingBits = 11; var remainingBits = 11;
for (var i = 0; i < entropy.length; i++) { for (var i = 0; i < entropy.length; i++) {
// Consume the whole byte (with still more to go) // Consume the whole byte (with still more to go)
if (remainingBits > 8) { if (remainingBits > 8) {
words[words.length - 1] <<= 8; indices[indices.length - 1] <<= 8;
words[words.length - 1] |= entropy[i]; indices[indices.length - 1] |= entropy[i];
remainingBits -= 8; remainingBits -= 8;
// This byte will complete an 11-bit index // This byte will complete an 11-bit index
} else { } else {
words[words.length - 1] <<= remainingBits; indices[indices.length - 1] <<= remainingBits;
words[words.length - 1] |= entropy[i] >> (8 - remainingBits); indices[indices.length - 1] |= entropy[i] >> (8 - remainingBits);
// Start the next word // Start the next word
words.push(entropy[i] & getLowerMask(8 - remainingBits)); indices.push(entropy[i] & getLowerMask(8 - remainingBits));
remainingBits += 3; remainingBits += 3;
} }
@ -243,16 +242,10 @@ export function entropyToMnemonic(entropy: any): string {
checksum &= getUpperMask(checksumBits); checksum &= getUpperMask(checksumBits);
// Shift the checksum into the word indices // Shift the checksum into the word indices
words[words.length - 1] <<= checksumBits; indices[indices.length - 1] <<= checksumBits;
words[words.length - 1] |= (checksum >> (8 - checksumBits)); indices[indices.length - 1] |= (checksum >> (8 - checksumBits));
// Convert indices into words return indices.map((index) => getWord(index)).join(' ');
var result = [];
for (var i = 0; i < words.length; i++) {
result.push(wordlist[words[i]]);
}
return result.join(' ');
} }
export function isValidMnemonic(mnemonic: string): boolean { export function isValidMnemonic(mnemonic: string): boolean {
@ -262,22 +255,3 @@ export function isValidMnemonic(mnemonic: string): boolean {
} catch (error) { } } catch (error) { }
return false; return false;
} }
// Exporting
/*
const exporting = {
HDNode: HDNode,
fromMnemonic: fromMnemonic,
fromSeed: fromSeed,
mnemonicToSeed: mnemonicToSeed,
mnemonicToEntropy: mnemonicToEntropy,
entropyToMnemonic: entropyToMnemonic,
isValidMnemonic: isValidMnemonic
}
*/
// Default TypeScript
//export default exporting;
// Node exports
//declare var module: any;
//(module).exports = exporting;

View File

@ -1,38 +1,113 @@
'use strict'; 'use strict';
export interface BN { import { arrayify, Arrayish, hexlify } from '../utils/convert';
import { defineReadOnly } from '../utils/properties';
import * as errors from '../utils/errors';
interface _BN {
toString(radix: number): string; toString(radix: number): string;
encode(encoding: string, compact: boolean): Uint8Array; encode(encoding: string, compact: boolean): Uint8Array;
toArray(endian: string, width: number): Uint8Array; toArray(endian: string, width: number): Uint8Array;
} }
export interface Signature { interface _Signature {
r: BN, r: _BN,
s: BN, s: _BN,
recoveryParam: number recoveryParam: number
} }
export interface KeyPair { interface _KeyPair {
sign(message: Uint8Array, options: { canonical?: boolean }): Signature; sign(message: Uint8Array, options: { canonical?: boolean }): _Signature;
getPublic(compressed: boolean, encoding?: string): string; getPublic(compressed: boolean, encoding?: string): string;
getPublic(): BN; getPublic(): _BN;
getPrivate(encoding?: string): string; getPrivate(encoding?: string): string;
encode(encoding: string, compressed: boolean): string; encode(encoding: string, compressed: boolean): string;
priv: BN; priv: _BN;
} }
export interface EC { interface _EC {
constructor(curve: string); constructor(curve: string);
n: BN; n: _BN;
keyFromPublic(publicKey: string | Uint8Array): KeyPair; keyFromPublic(publicKey: string | Uint8Array): _KeyPair;
keyFromPrivate(privateKey: string | Uint8Array): KeyPair; keyFromPrivate(privateKey: string | Uint8Array): _KeyPair;
recoverPubKey(data: Uint8Array, signature: { r: Uint8Array, s: Uint8Array }, recoveryParam: number): KeyPair; recoverPubKey(data: Uint8Array, signature: { r: Uint8Array, s: Uint8Array }, recoveryParam: number): _KeyPair;
} }
import * as elliptic from 'elliptic'; import * as elliptic from 'elliptic';
export const curve:EC = new elliptic.ec('secp256k1'); const curve:_EC = new elliptic.ec('secp256k1');
//export default secp256k1;
export type Signature = {
r: string;
s: string;
recoveryParam: number;
}
export class KeyPair {
readonly privateKey: string;
readonly publicKey: string;
readonly compressedPublicKey: string;
readonly publicKeyBytes: Uint8Array;
constructor(privateKey: Arrayish) {
let keyPair: _KeyPair = curve.keyFromPrivate(arrayify(privateKey));
defineReadOnly(this, 'privateKey', hexlify(keyPair.priv.toArray('be', 32)));
defineReadOnly(this, 'publicKey', '0x' + keyPair.getPublic(false, 'hex'));
defineReadOnly(this, 'compressedPublicKey', '0x' + keyPair.getPublic(true, 'hex'));
defineReadOnly(this, 'publicKeyBytes', keyPair.getPublic().encode(null, true));
}
sign(digest: Arrayish): Signature {
let keyPair: _KeyPair = curve.keyFromPrivate(arrayify(this.privateKey));
let signature = keyPair.sign(arrayify(digest), {canonical: true});
return {
recoveryParam: signature.recoveryParam,
r: '0x' + signature.r.toString(16),
s: '0x' + signature.s.toString(16)
}
}
}
export function recoverPublicKey(digest: Arrayish, signature: Signature): string {
let sig = {
r: arrayify(signature.r),
s: arrayify(signature.s)
};
return '0x' + curve.recoverPubKey(arrayify(digest), sig, signature.recoveryParam).getPublic(false, 'hex');
}
export function computePublicKey(key: Arrayish, compressed?: boolean): string {
let bytes = arrayify(key);
if (bytes.length === 32) {
let keyPair: KeyPair = new KeyPair(bytes);
if (compressed) {
return keyPair.compressedPublicKey;
}
return keyPair.publicKey;
} else if (bytes.length === 33) {
if (compressed) { return hexlify(bytes); }
return '0x' + curve.keyFromPublic(bytes).getPublic(false, 'hex');
} else if (bytes.length === 65) {
if (!compressed) { return hexlify(bytes); }
return '0x' + curve.keyFromPublic(bytes).getPublic(true, 'hex');
}
errors.throwError('invalid public or private key', errors.INVALID_ARGUMENT, { arg: 'key', value: '[REDACTED]' });
return null;
}
export const N = '0x' + curve.n.toString(16);

View File

@ -292,7 +292,7 @@ export function decrypt(json: string, password: any, progressCallback?: Progress
} }
// @TOOD: Options // @TOOD: Options
export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: any, progressCallback?: ProgressCallback) { export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: any, progressCallback?: ProgressCallback): Promise<string> {
// the options are optional, so adjust the call as needed // the options are optional, so adjust the call as needed
if (typeof(options) === 'function' && !progressCallback) { if (typeof(options) === 'function' && !progressCallback) {
@ -302,11 +302,13 @@ export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish |
if (!options) { options = {}; } if (!options) { options = {}; }
// Check the private key // Check the private key
let privateKeyBytes = null;
if (privateKey instanceof SigningKey) { if (privateKey instanceof SigningKey) {
privateKey = privateKey.privateKey; privateKeyBytes = arrayify(privateKey.privateKey);
} else {
privateKeyBytes = arrayify(privateKey);
} }
privateKey = arrayify(privateKey); if (privateKeyBytes.length !== 32) { throw new Error('invalid private key'); }
if (privateKey.length !== 32) { throw new Error('invalid private key'); }
password = getPassword(password); password = getPassword(password);
@ -387,12 +389,12 @@ export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish |
var mnemonicKey = key.slice(32, 64); var mnemonicKey = key.slice(32, 64);
// Get the address for this private key // Get the address for this private key
var address = (new SigningKey(privateKey)).address; var address = (new SigningKey(privateKeyBytes)).address;
// Encrypt the private key // Encrypt the private key
var counter = new aes.Counter(iv); var counter = new aes.Counter(iv);
var aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter); var aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter);
var ciphertext = arrayify(aesCtr.encrypt(privateKey)); var ciphertext = arrayify(aesCtr.encrypt(privateKeyBytes));
// Compute the message authentication code, used to check the password // Compute the message authentication code, used to check the password
var mac = keccak256(concat([macPrefix, ciphertext])) var mac = keccak256(concat([macPrefix, ciphertext]))

View File

@ -6,15 +6,16 @@
* *
*/ */
import * as secp256k1 from './secp256k1'; import { computePublicKey, KeyPair, recoverPublicKey, Signature } from './secp256k1';
import { getAddress } from '../utils/address'; import { getAddress } from '../utils/address';
import { arrayify, hexlify } from '../utils/convert'; import { arrayify, Arrayish, hexlify } from '../utils/convert';
import { HDNode } from './hdnode';
import { keccak256 } from '../utils/keccak256'; import { keccak256 } from '../utils/keccak256';
import { defineReadOnly } from '../utils/properties';
import errors = require('../utils/errors'); import errors = require('../utils/errors');
export class SigningKey { export class SigningKey {
readonly privateKey: string; readonly privateKey: string;
@ -24,20 +25,23 @@ export class SigningKey {
readonly mnemonic: string; readonly mnemonic: string;
readonly path: string; readonly path: string;
private readonly keyPair: secp256k1.KeyPair; private readonly keyPair: KeyPair;
constructor(privateKey: any) { constructor(privateKey: Arrayish | HDNode) {
errors.checkNew(this, SigningKey); errors.checkNew(this, SigningKey);
if (privateKey.privateKey) { let privateKeyBytes = null;
this.mnemonic = privateKey.mnemonic;
this.path = privateKey.path; if (privateKey instanceof HDNode) {
privateKey = privateKey.privateKey; defineReadOnly(this, 'mnemonic', privateKey.mnemonic);
defineReadOnly(this, 'path', privateKey.path);
privateKeyBytes = arrayify(privateKey.privateKey);
} else {
privateKeyBytes = arrayify(privateKey);
} }
try { try {
privateKey = arrayify(privateKey); if (privateKeyBytes.length !== 32) {
if (privateKey.length !== 32) {
errors.throwError('exactly 32 bytes required', errors.INVALID_ARGUMENT, { value: privateKey }); errors.throwError('exactly 32 bytes required', errors.INVALID_ARGUMENT, { value: privateKey });
} }
} catch(error) { } catch(error) {
@ -51,59 +55,23 @@ export class SigningKey {
errors.throwError('invalid private key', error.code, params); errors.throwError('invalid private key', error.code, params);
} }
this.privateKey = hexlify(privateKey); defineReadOnly(this, 'privateKey', hexlify(privateKeyBytes));
defineReadOnly(this, 'keyPair', new KeyPair(privateKeyBytes));
this.keyPair = secp256k1.curve.keyFromPrivate(privateKey); defineReadOnly(this, 'publicKey', this.keyPair.publicKey);
defineReadOnly(this, 'address', computeAddress(this.keyPair.publicKey));
//utils.defineProperty(this, 'publicKey', '0x' + keyPair.getPublic(true, 'hex'))
this.publicKey = '0x' + this.keyPair.getPublic(true, 'hex');
this.address = SigningKey.publicKeyToAddress('0x' + this.keyPair.getPublic(false, 'hex'));
} }
signDigest(digest) { signDigest(digest: Arrayish): Signature {
var signature = this.keyPair.sign(arrayify(digest), {canonical: true}); return this.keyPair.sign(digest);
return {
recoveryParam: signature.recoveryParam,
r: '0x' + signature.r.toString(16),
s: '0x' + signature.s.toString(16)
}
}
static recover(digest, r, s, recoveryParam) {
var signature = {
r: arrayify(r),
s: arrayify(s)
};
var publicKey = secp256k1.curve.recoverPubKey(arrayify(digest), signature, recoveryParam);
return SigningKey.publicKeyToAddress('0x' + publicKey.encode('hex', false));
}
static getPublicKey(value, compressed) {
value = arrayify(value);
compressed = !!compressed;
if (value.length === 32) {
var keyPair = secp256k1.curve.keyFromPrivate(value);
return '0x' + keyPair.getPublic(compressed, 'hex');
} else if (value.length === 33) {
var keyPair = secp256k1.curve.keyFromPublic(value);
return '0x' + keyPair.getPublic(compressed, 'hex');
} else if (value.length === 65) {
var keyPair = secp256k1.curve.keyFromPublic(value);
return '0x' + keyPair.getPublic(compressed, 'hex');
}
throw new Error('invalid value');
}
static publicKeyToAddress(publicKey) {
publicKey = '0x' + SigningKey.getPublicKey(publicKey, false).slice(4);
return getAddress('0x' + keccak256(publicKey).substring(26));
} }
} }
//export default SigningKey; export function recoverAddress(digest: Arrayish, signature: Signature): string {
return computeAddress(recoverPublicKey(digest, signature));
}
export function computeAddress(key: string): string {
// Strip off the leading "0x04"
let publicKey = '0x' + computePublicKey(key).slice(4);
return getAddress('0x' + keccak256(publicKey).substring(26));
}

View File

@ -2,8 +2,15 @@
import scrypt from 'scrypt-js'; import scrypt from 'scrypt-js';
import { entropyToMnemonic, fromMnemonic, HDNode } from './hdnode';
import * as secretStorage from './secret-storage';
import { ProgressCallback } from './secret-storage';
import { recoverAddress, SigningKey } from './signing-key';
import { BlockTag } from '../providers/provider';
import { getAddress } from '../utils/address'; import { getAddress } from '../utils/address';
import { BigNumber, bigNumberify, ConstantZero } from '../utils/bignumber'; import { BigNumber, bigNumberify, BigNumberish, ConstantZero } from '../utils/bignumber';
import { arrayify, Arrayish, concat, hexlify, stripZeros, hexZeroPad } from '../utils/convert'; import { arrayify, Arrayish, concat, hexlify, stripZeros, hexZeroPad } from '../utils/convert';
import { keccak256 } from '../utils/keccak256'; import { keccak256 } from '../utils/keccak256';
import { randomBytes } from '../utils/random-bytes'; import { randomBytes } from '../utils/random-bytes';
@ -12,9 +19,6 @@ import { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';
import * as errors from '../utils/errors'; import * as errors from '../utils/errors';
import { entropyToMnemonic, fromMnemonic, HDNode } from './hdnode';
import * as secretStorage from './secret-storage';
import { SigningKey } from './signing-key';
// This ensures we inject a setImmediate into the global space, which // This ensures we inject a setImmediate into the global space, which
// dramatically improves the performance of the scrypt PBKDF. // dramatically improves the performance of the scrypt PBKDF.
@ -113,7 +117,7 @@ export class Wallet {
}); });
} }
sign(transaction: TransactionRequest) { sign(transaction: TransactionRequest): string {
var chainId = transaction.chainId; var chainId = transaction.chainId;
if (chainId == null && this.provider) { chainId = this.provider.chainId; } if (chainId == null && this.provider) { chainId = this.provider.chainId; }
if (!chainId) { chainId = 0; } if (!chainId) { chainId = 0; }
@ -238,7 +242,7 @@ export class Wallet {
var digest = keccak256(RLP.encode(raw)); var digest = keccak256(RLP.encode(raw));
try { try {
transaction.from = SigningKey.recover(digest, r, s, recoveryParam); transaction.from = recoverAddress(digest, { r: hexlify(r), s: hexlify(s), recoveryParam });
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@ -247,21 +251,21 @@ export class Wallet {
return transaction; return transaction;
} }
getAddress() { getAddress(): Promise<string> {
return Promise.resolve(this.address); return Promise.resolve(this.address);
} }
getBalance(blockTag) { getBalance(blockTag: BlockTag): Promise<BigNumber> {
if (!this.provider) { throw new Error('missing provider'); } if (!this.provider) { throw new Error('missing provider'); }
return this.provider.getBalance(this.address, blockTag); return this.provider.getBalance(this.address, blockTag);
} }
getTransactionCount(blockTag) { getTransactionCount(blockTag: BlockTag): Promise<number> {
if (!this.provider) { throw new Error('missing provider'); } if (!this.provider) { throw new Error('missing provider'); }
return this.provider.getTransactionCount(this.address, blockTag); return this.provider.getTransactionCount(this.address, blockTag);
} }
estimateGas(transaction: TransactionRequest) { estimateGas(transaction: TransactionRequest): Promise<BigNumber> {
if (!this.provider) { throw new Error('missing provider'); } if (!this.provider) { throw new Error('missing provider'); }
var calculate: TransactionRequest = {}; var calculate: TransactionRequest = {};
@ -275,7 +279,7 @@ export class Wallet {
return this.provider.estimateGas(calculate); return this.provider.estimateGas(calculate);
} }
sendTransaction(transaction) { sendTransaction(transaction: any): Promise<TransactionResponse> {
if (!this.provider) { throw new Error('missing provider'); } if (!this.provider) { throw new Error('missing provider'); }
if (!transaction || typeof(transaction) !== 'object') { if (!transaction || typeof(transaction) !== 'object') {
@ -335,7 +339,7 @@ export class Wallet {
}); });
} }
send(addressOrName, amountWei, options) { send(addressOrName: string, amountWei: BigNumberish, options: any): Promise<TransactionResponse> {
if (!options) { options = {}; } if (!options) { options = {}; }
return this.sendTransaction({ return this.sendTransaction({
@ -348,7 +352,7 @@ export class Wallet {
} }
static hashMessage(message) { static hashMessage(message: Arrayish | string): string {
var payload = concat([ var payload = concat([
toUtf8Bytes('\x19Ethereum Signed Message:\n'), toUtf8Bytes('\x19Ethereum Signed Message:\n'),
toUtf8Bytes(String(message.length)), toUtf8Bytes(String(message.length)),
@ -357,14 +361,14 @@ export class Wallet {
return keccak256(payload); return keccak256(payload);
} }
signMessage(message) { signMessage(message: Arrayish | string): string {
var signingKey = new SigningKey(this.privateKey); var signingKey = new SigningKey(this.privateKey);
var sig = signingKey.signDigest(Wallet.hashMessage(message)); var sig = signingKey.signDigest(Wallet.hashMessage(message));
return (hexZeroPad(sig.r, 32) + hexZeroPad(sig.s, 32).substring(2) + (sig.recoveryParam ? '1c': '1b')); return (hexZeroPad(sig.r, 32) + hexZeroPad(sig.s, 32).substring(2) + (sig.recoveryParam ? '1c': '1b'));
} }
static verifyMessage(message, signature) { static verifyMessage(message: Arrayish | string, signature: string): string {
signature = hexlify(signature); signature = hexlify(signature);
if (signature.length != 132) { throw new Error('invalid signature'); } if (signature.length != 132) { throw new Error('invalid signature'); }
var digest = Wallet.hashMessage(message); var digest = Wallet.hashMessage(message);
@ -373,15 +377,17 @@ export class Wallet {
if (recoveryParam >= 27) { recoveryParam -= 27; } if (recoveryParam >= 27) { recoveryParam -= 27; }
if (recoveryParam < 0) { throw new Error('invalid signature'); } if (recoveryParam < 0) { throw new Error('invalid signature'); }
return SigningKey.recover( return recoverAddress(
digest, digest,
signature.substring(0, 66), {
'0x' + signature.substring(66, 130), r: signature.substring(0, 66),
recoveryParam s: '0x' + signature.substring(66, 130),
recoveryParam: recoveryParam
}
); );
} }
encrypt(password, options, progressCallback) { encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string> {
if (typeof(options) === 'function' && !progressCallback) { if (typeof(options) === 'function' && !progressCallback) {
progressCallback = options; progressCallback = options;
options = {}; options = {};
@ -408,7 +414,7 @@ export class Wallet {
} }
static createRandom(options) { static createRandom(options: any): Wallet {
var entropy: Uint8Array = randomBytes(16); var entropy: Uint8Array = randomBytes(16);
if (!options) { options = { }; } if (!options) { options = { }; }
@ -422,12 +428,12 @@ export class Wallet {
} }
static isEncryptedWallet(json: string) { static isEncryptedWallet(json: string): boolean {
return (secretStorage.isValidWallet(json) || secretStorage.isCrowdsaleWallet(json)); return (secretStorage.isValidWallet(json) || secretStorage.isCrowdsaleWallet(json));
} }
static fromEncryptedWallet(json, password, progressCallback) { static fromEncryptedWallet(json: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet> {
if (progressCallback && typeof(progressCallback) !== 'function') { if (progressCallback && typeof(progressCallback) !== 'function') {
throw new Error('invalid callback'); throw new Error('invalid callback');
} }
@ -463,13 +469,13 @@ export class Wallet {
}); });
} }
static fromMnemonic(mnemonic: string, path?: string) { static fromMnemonic(mnemonic: string, path?: string): Wallet {
if (!path) { path = defaultPath; } if (!path) { path = defaultPath; }
return new Wallet(fromMnemonic(mnemonic).derivePath(path)); return new Wallet(fromMnemonic(mnemonic).derivePath(path));
} }
static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback) { static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback: ProgressCallback): Promise<Wallet> {
if (progressCallback && typeof(progressCallback) !== 'function') { if (progressCallback && typeof(progressCallback) !== 'function') {
throw new Error('invalid callback'); throw new Error('invalid callback');
} }

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@ import { ParamType } from '../utils/abi-coder';
import { BigNumber, BigNumberish } from '../utils/bignumber'; import { BigNumber, BigNumberish } from '../utils/bignumber';
export declare class Indexed { export declare class Indexed {
readonly hash: string; readonly hash: string;
constructor(value: any); constructor(value: string);
} }
export declare class Description { export declare class Description {
readonly type: string; readonly type: string;
@ -37,7 +37,7 @@ export declare class EventDescription extends Description {
decode(data: string, topics?: Array<string>): any; decode(data: string, topics?: Array<string>): any;
} }
export declare class Interface { export declare class Interface {
readonly _abi: Array<any>; readonly abi: Array<any>;
readonly functions: Array<FunctionDescription>; readonly functions: Array<FunctionDescription>;
readonly events: Array<EventDescription>; readonly events: Array<EventDescription>;
readonly deployFunction: DeployDescription; readonly deployFunction: DeployDescription;

View File

@ -54,7 +54,6 @@ function parseParams(params) {
} }
var Indexed = /** @class */ (function () { var Indexed = /** @class */ (function () {
function Indexed(value) { function Indexed(value) {
properties_1.defineReadOnly(this, 'indexed', true);
properties_1.defineReadOnly(this, 'hash', value); properties_1.defineReadOnly(this, 'hash', value);
} }
return Indexed; return Indexed;
@ -302,7 +301,6 @@ function addMethod(method) {
} }
var Interface = /** @class */ (function () { var Interface = /** @class */ (function () {
function Interface(abi) { function Interface(abi) {
var _this = this;
errors.checkNew(this, Interface); errors.checkNew(this, Interface);
if (typeof (abi) === 'string') { if (typeof (abi) === 'string') {
try { try {
@ -323,14 +321,15 @@ var Interface = /** @class */ (function () {
properties_1.defineReadOnly(this, 'functions', {}); properties_1.defineReadOnly(this, 'functions', {});
properties_1.defineReadOnly(this, 'events', {}); properties_1.defineReadOnly(this, 'events', {});
// Convert any supported ABI format into a standard ABI format // Convert any supported ABI format into a standard ABI format
this._abi = []; var _abi = [];
abi.forEach(function (fragment) { abi.forEach(function (fragment) {
if (typeof (fragment) === 'string') { if (typeof (fragment) === 'string') {
fragment = abi_coder_1.parseSignature(fragment); fragment = abi_coder_1.parseSignature(fragment);
} }
_this._abi.push(fragment); _abi.push(fragment);
}); });
this._abi.forEach(addMethod, this); properties_1.defineFrozen(this, 'abi', _abi);
_abi.forEach(addMethod, this);
// If there wasn't a constructor, create the default constructor // If there wasn't a constructor, create the default constructor
if (!this.deployFunction) { if (!this.deployFunction) {
addMethod.call(this, { type: 'constructor', inputs: [] }); addMethod.call(this, { type: 'constructor', inputs: [] });

3
src/index.d.ts vendored
View File

@ -1,6 +1,7 @@
import { Contract, Interface } from './contracts'; import { Contract, Interface } from './contracts';
import * as providers from './providers'; import * as providers from './providers';
import * as errors from './utils/errors'; import * as errors from './utils/errors';
import { networks } from './providers/networks';
import utils from './utils'; import utils from './utils';
import { HDNode, SigningKey, Wallet } from './wallet'; import { HDNode, SigningKey, Wallet } from './wallet';
export { Wallet, HDNode, SigningKey, Contract, Interface, providers, errors, utils, }; export { Wallet, HDNode, SigningKey, Contract, Interface, networks, providers, errors, utils, };

View File

@ -17,6 +17,8 @@ var providers = __importStar(require("./providers"));
exports.providers = providers; exports.providers = providers;
var errors = __importStar(require("./utils/errors")); var errors = __importStar(require("./utils/errors"));
exports.errors = errors; exports.errors = errors;
var networks_1 = require("./providers/networks");
exports.networks = networks_1.networks;
var utils_1 = __importDefault(require("./utils")); var utils_1 = __importDefault(require("./utils"));
exports.utils = utils_1.default; exports.utils = utils_1.default;
var wallet_1 = require("./wallet"); var wallet_1 = require("./wallet");

View File

@ -5,5 +5,5 @@ export declare class InfuraProvider extends JsonRpcProvider {
constructor(network?: Network | string, apiAccessToken?: string); constructor(network?: Network | string, apiAccessToken?: string);
_startPending(): void; _startPending(): void;
getSigner(address?: string): JsonRpcSigner; getSigner(address?: string): JsonRpcSigner;
listAccounts(): Promise<any[]>; listAccounts(): Promise<Array<string>>;
} }

View File

@ -3,5 +3,5 @@ import { Network } from './networks';
export declare class IpcProvider extends JsonRpcProvider { export declare class IpcProvider extends JsonRpcProvider {
readonly path: string; readonly path: string;
constructor(path: string, network?: Network | string); constructor(path: string, network?: Network | string);
send(method: any, params: any): Promise<{}>; send(method: string, params: any): Promise<any>;
} }

View File

@ -20,10 +20,10 @@ export declare class JsonRpcProvider extends Provider {
readonly connection: ConnectionInfo; readonly connection: ConnectionInfo;
private _pendingFilter; private _pendingFilter;
constructor(url?: ConnectionInfo | string, network?: Network | string); constructor(url?: ConnectionInfo | string, network?: Network | string);
getSigner(address: any): JsonRpcSigner; getSigner(address: string): JsonRpcSigner;
listAccounts(): Promise<any>; listAccounts(): Promise<Array<string>>;
send(method: any, params: any): Promise<any>; send(method: string, params: any): Promise<any>;
perform(method: any, params: any): Promise<any>; perform(method: string, params: any): Promise<any>;
_startPending(): void; _startPending(): void;
_stopPending(): void; _stopPending(): void;
} }

View File

@ -28,6 +28,7 @@ export declare type TransactionRequest = {
export declare type TransactionResponse = { export declare type TransactionResponse = {
blockNumber?: number; blockNumber?: number;
blockHash?: string; blockHash?: string;
timestamp?: number;
hash: string; hash: string;
to?: string; to?: string;
from?: string; from?: string;
@ -72,7 +73,7 @@ export declare type Log = {
transactionHash?: string; transactionHash?: string;
logIndex?: number; logIndex?: number;
}; };
export declare function checkTransactionResponse(transaction: any): any; export declare function checkTransactionResponse(transaction: any): TransactionResponse;
export declare class Provider { export declare class Provider {
private _network; private _network;
protected ready: Promise<Network>; protected ready: Promise<Network>;
@ -89,7 +90,7 @@ export declare class Provider {
*/ */
constructor(network: string | Network); constructor(network: string | Network);
private _doPoll; private _doPoll;
resetEventsBlock(blockNumber: any): void; resetEventsBlock(blockNumber: number): void;
readonly network: Network; readonly network: Network;
getNetwork(): Promise<Network>; getNetwork(): Promise<Network>;
readonly blockNumber: number; readonly blockNumber: number;
@ -110,8 +111,8 @@ export declare class Provider {
getTransactionReceipt(transactionHash: string): Promise<TransactionReceipt>; getTransactionReceipt(transactionHash: string): Promise<TransactionReceipt>;
getLogs(filter: Filter): Promise<Array<Log>>; getLogs(filter: Filter): Promise<Array<Log>>;
getEtherPrice(): Promise<number>; getEtherPrice(): Promise<number>;
_resolveNames(object: any, keys: any): Promise<{}>; _resolveNames(object: any, keys: Array<string>): Promise<any>;
_getResolver(name: any): Promise<string>; _getResolver(name: string): Promise<string>;
resolveName(name: string | Promise<string>): Promise<string>; resolveName(name: string | Promise<string>): Promise<string>;
lookupAddress(address: string | Promise<string>): Promise<string>; lookupAddress(address: string | Promise<string>): Promise<string>;
doPoll(): void; doPoll(): void;

View File

@ -10,5 +10,5 @@ export declare type AsyncProvider = {
export declare class Web3Provider extends JsonRpcProvider { export declare class Web3Provider extends JsonRpcProvider {
readonly _web3Provider: AsyncProvider; readonly _web3Provider: AsyncProvider;
constructor(web3Provider: AsyncProvider, network?: Network | string); constructor(web3Provider: AsyncProvider, network?: Network | string);
send(method: any, params: any): Promise<{}>; send(method: string, params: any): Promise<any>;
} }

View File

@ -6,8 +6,23 @@ export declare type ParamType = {
indexed?: boolean; indexed?: boolean;
components?: Array<any>; components?: Array<any>;
}; };
export declare function defaultCoerceFunc(type: string, value: any): any; export declare const defaultCoerceFunc: CoerceFunc;
export declare function parseSignature(fragment: string): any; export declare type EventFragment = {
type: string;
name: string;
anonymous: boolean;
inputs: Array<ParamType>;
};
export declare type FunctionFragment = {
type: string;
name: string;
constant: boolean;
inputs: Array<ParamType>;
outputs: Array<ParamType>;
payable: boolean;
stateMutability: string;
};
export declare function parseSignature(fragment: string): EventFragment | FunctionFragment;
export declare class AbiCoder { export declare class AbiCoder {
readonly coerceFunc: CoerceFunc; readonly coerceFunc: CoerceFunc;
constructor(coerceFunc?: CoerceFunc); constructor(coerceFunc?: CoerceFunc);

View File

@ -22,18 +22,18 @@ var address_1 = require("./address");
var bignumber_1 = require("./bignumber"); var bignumber_1 = require("./bignumber");
var convert_1 = require("./convert"); var convert_1 = require("./convert");
var utf8_1 = require("./utf8"); var utf8_1 = require("./utf8");
var properties_1 = require("./properties");
var errors = __importStar(require("./errors")); var errors = __importStar(require("./errors"));
var paramTypeBytes = new RegExp(/^bytes([0-9]*)$/); var paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);
var paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/); var paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);
var paramTypeArray = new RegExp(/^(.*)\[([0-9]*)\]$/); var paramTypeArray = new RegExp(/^(.*)\[([0-9]*)\]$/);
function defaultCoerceFunc(type, value) { exports.defaultCoerceFunc = function (type, value) {
var match = type.match(paramTypeNumber); var match = type.match(paramTypeNumber);
if (match && parseInt(match[2]) <= 48) { if (match && parseInt(match[2]) <= 48) {
return value.toNumber(); return value.toNumber();
} }
return value; return value;
} };
exports.defaultCoerceFunc = defaultCoerceFunc;
/////////////////////////////////// ///////////////////////////////////
// Parsing for Solidity Signatures // Parsing for Solidity Signatures
var regexParen = new RegExp("^([^)(]*)\\((.*)\\)([^)(]*)$"); var regexParen = new RegExp("^([^)(]*)\\((.*)\\)([^)(]*)$");
@ -259,7 +259,7 @@ function parseSignature(fragment) {
return parseSignatureFunction(fragment.trim()); return parseSignatureFunction(fragment.trim());
} }
} }
throw new Error('unknown fragment'); throw new Error('unknown signature');
} }
exports.parseSignature = parseSignature; exports.parseSignature = parseSignature;
var Coder = /** @class */ (function () { var Coder = /** @class */ (function () {
@ -837,12 +837,11 @@ function getParamCoder(coerceFunc, param) {
} }
var AbiCoder = /** @class */ (function () { var AbiCoder = /** @class */ (function () {
function AbiCoder(coerceFunc) { function AbiCoder(coerceFunc) {
//if (!(this instanceof Coder)) { throw new Error('missing new'); } errors.checkNew(this, AbiCoder);
if (!coerceFunc) { if (!coerceFunc) {
coerceFunc = defaultCoerceFunc; coerceFunc = exports.defaultCoerceFunc;
} }
// @TODO: readonly properties_1.defineReadOnly(this, 'coerceFunc', coerceFunc);
this.coerceFunc = coerceFunc;
} }
AbiCoder.prototype.encode = function (types, values) { AbiCoder.prototype.encode = function (types, values) {
if (types.length !== values.length) { if (types.length !== values.length) {
@ -856,10 +855,14 @@ var AbiCoder = /** @class */ (function () {
// Convert types to type objects // Convert types to type objects
// - "uint foo" => { type: "uint", name: "foo" } // - "uint foo" => { type: "uint", name: "foo" }
// - "tuple(uint, uint)" => { type: "tuple", components: [ { type: "uint" }, { type: "uint" }, ] } // - "tuple(uint, uint)" => { type: "tuple", components: [ { type: "uint" }, { type: "uint" }, ] }
var typeObject = null;
if (typeof (type) === 'string') { if (typeof (type) === 'string') {
type = parseParam(type); typeObject = parseParam(type);
} }
coders.push(getParamCoder(this.coerceFunc, type)); else {
typeObject = properties_1.jsonCopy(type);
}
coders.push(getParamCoder(this.coerceFunc, typeObject));
}, this); }, this);
return convert_1.hexlify(new CoderTuple(this.coerceFunc, coders, '_').encode(values)); return convert_1.hexlify(new CoderTuple(this.coerceFunc, coders, '_').encode(values));
}; };
@ -867,10 +870,14 @@ var AbiCoder = /** @class */ (function () {
var coders = []; var coders = [];
types.forEach(function (type) { types.forEach(function (type) {
// See encode for details // See encode for details
var typeObject = null;
if (typeof (type) === 'string') { if (typeof (type) === 'string') {
type = parseParam(type); typeObject = parseParam(type);
} }
coders.push(getParamCoder(this.coerceFunc, type)); else {
typeObject = properties_1.jsonCopy(type);
}
coders.push(getParamCoder(this.coerceFunc, typeObject));
}, this); }, this);
return new CoderTuple(this.coerceFunc, coders, '_').decode(convert_1.arrayify(data), 0).value; return new CoderTuple(this.coerceFunc, coders, '_').decode(convert_1.arrayify(data), 0).value;
}; };

View File

@ -56,9 +56,7 @@ function _isBigNumber(value) {
} }
var BigNumber = /** @class */ (function () { var BigNumber = /** @class */ (function () {
function BigNumber(value) { function BigNumber(value) {
if (!(this instanceof BigNumber)) { errors.checkNew(this, BigNumber);
throw new Error('missing new');
}
if (typeof (value) === 'string') { if (typeof (value) === 'string') {
if (convert_1.isHexString(value)) { if (convert_1.isHexString(value)) {
if (value == '0x') { if (value == '0x') {

View File

@ -5,11 +5,6 @@
*/ */
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var errors = require("./errors"); var errors = require("./errors");
/*
declare class BigNumber {
toHexString(): string;
}
*/
function isBigNumber(value) { function isBigNumber(value) {
return !!value._bn; return !!value._bn;
} }

View File

@ -3,3 +3,5 @@ export declare function defineFrozen(object: any, name: any, value: any): void;
export declare type DeferredSetter = (value: any) => void; export declare type DeferredSetter = (value: any) => void;
export declare function defineDeferredReadOnly(object: any, name: any, value: any): DeferredSetter; export declare function defineDeferredReadOnly(object: any, name: any, value: any): DeferredSetter;
export declare function resolveProperties(object: any): Promise<any>; export declare function resolveProperties(object: any): Promise<any>;
export declare function shallowCopy(object: any): any;
export declare function jsonCopy(object: any): any;

View File

@ -46,3 +46,15 @@ function resolveProperties(object) {
}); });
} }
exports.resolveProperties = resolveProperties; exports.resolveProperties = resolveProperties;
function shallowCopy(object) {
var result = {};
for (var key in object) {
result[key] = object[key];
}
return result;
}
exports.shallowCopy = shallowCopy;
function jsonCopy(object) {
return JSON.parse(JSON.stringify(object));
}
exports.jsonCopy = jsonCopy;

View File

@ -1 +1 @@
export declare function randomBytes(length: any): Uint8Array; export declare function randomBytes(length: number): Uint8Array;

View File

@ -1,28 +1,8 @@
'use strict'; 'use strict';
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var convert_1 = require("./convert"); var convert_1 = require("./convert");
//import * as crypto from 'crypto'; var crypto_1 = require("crypto");
//@TODO: Figure out how to fix crypto
function getRandomValues(buffer) {
for (var round = 0; round < 20; round++) {
for (var i = 0; i < buffer.length; i++) {
if (round) {
buffer[i] ^= Math.trunc(256 * Math.random());
}
else {
buffer[i] = Math.trunc(256 * Math.random());
}
}
}
return buffer;
}
function randomBytes(length) { function randomBytes(length) {
if (length <= 0 || length > 1024 || parseInt(length) != length) { return convert_1.arrayify(crypto_1.randomBytes(length));
throw new Error('invalid length');
}
var result = new Uint8Array(length);
getRandomValues(result);
return convert_1.arrayify(result);
} }
exports.randomBytes = randomBytes; exports.randomBytes = randomBytes;
;

5
src/utils/sha2.d.ts vendored
View File

@ -1,2 +1,3 @@
export declare function sha256(data: any): string; import { Arrayish } from './convert';
export declare function sha512(data: any): string; export declare function sha256(data: Arrayish): string;
export declare function sha512(data: Arrayish): string;

View File

@ -1,4 +1,5 @@
export declare function formatUnits(value: any, unitType: string | number, options?: any): string; import { BigNumber, BigNumberish } from './bignumber';
export declare function parseUnits(value: any, unitType: any): any; export declare function formatUnits(value: BigNumberish, unitType?: string | number, options?: any): string;
export declare function formatEther(wei: any, options: any): string; export declare function parseUnits(value: string, unitType?: string | number): BigNumber;
export declare function parseEther(ether: any): any; export declare function formatEther(wei: BigNumberish, options: any): string;
export declare function parseEther(ether: string): BigNumber;

View File

@ -69,7 +69,7 @@ function formatUnits(value, unitType, options) {
if (negative) { if (negative) {
value = value.mul(bignumber_1.ConstantNegativeOne); value = value.mul(bignumber_1.ConstantNegativeOne);
} }
var fraction = value.mod(unitInfo.tenPower).toString(10); var fraction = value.mod(unitInfo.tenPower).toString();
while (fraction.length < unitInfo.decimals) { while (fraction.length < unitInfo.decimals) {
fraction = '0' + fraction; fraction = '0' + fraction;
} }
@ -77,7 +77,7 @@ function formatUnits(value, unitType, options) {
if (!options.pad) { if (!options.pad) {
fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1]; fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1];
} }
var whole = value.div(unitInfo.tenPower).toString(10); var whole = value.div(unitInfo.tenPower).toString();
if (options.commify) { if (options.commify) {
whole = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ","); whole = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
@ -126,9 +126,9 @@ function parseUnits(value, unitType) {
while (fraction.length < unitInfo.decimals) { while (fraction.length < unitInfo.decimals) {
fraction += '0'; fraction += '0';
} }
whole = bignumber_1.bigNumberify(whole); var wholeValue = bignumber_1.bigNumberify(whole);
fraction = bignumber_1.bigNumberify(fraction); var fractionValue = bignumber_1.bigNumberify(fraction);
var wei = (whole.mul(unitInfo.tenPower)).add(fraction); var wei = (wholeValue.mul(unitInfo.tenPower)).add(fractionValue);
if (negative) { if (negative) {
wei = wei.mul(bignumber_1.ConstantNegativeOne); wei = wei.mul(bignumber_1.ConstantNegativeOne);
} }

View File

@ -1,4 +1,5 @@
import * as secp256k1 from './secp256k1'; import { KeyPair } from './secp256k1';
import { Arrayish } from '../utils/convert';
export declare class HDNode { export declare class HDNode {
private readonly keyPair; private readonly keyPair;
readonly privateKey: string; readonly privateKey: string;
@ -8,13 +9,13 @@ export declare class HDNode {
readonly chainCode: string; readonly chainCode: string;
readonly index: number; readonly index: number;
readonly depth: number; readonly depth: number;
constructor(keyPair: secp256k1.KeyPair, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string); constructor(keyPair: KeyPair, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string);
private _derive; private _derive;
derivePath(path: string): HDNode; derivePath(path: string): HDNode;
} }
export declare function fromMnemonic(mnemonic: string): HDNode; export declare function fromMnemonic(mnemonic: string): HDNode;
export declare function fromSeed(seed: any): HDNode; export declare function fromSeed(seed: Arrayish): HDNode;
export declare function mnemonicToSeed(mnemonic: string, password?: string): string; export declare function mnemonicToSeed(mnemonic: string, password?: string): string;
export declare function mnemonicToEntropy(mnemonic: string): string; export declare function mnemonicToEntropy(mnemonic: string): string;
export declare function entropyToMnemonic(entropy: any): string; export declare function entropyToMnemonic(entropy: Arrayish): string;
export declare function isValidMnemonic(mnemonic: string): boolean; export declare function isValidMnemonic(mnemonic: string): boolean;

View File

@ -6,15 +6,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
result["default"] = mod; result["default"] = mod;
return result; return result;
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
// See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki // See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
// See: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki // See: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
var secp256k1 = __importStar(require("./secp256k1")); var secp256k1_1 = require("./secp256k1");
var words_1 = __importDefault(require("./words")); var words_1 = require("./words");
var wordlist = words_1.default.replace(/([A-Z])/g, ' $1').toLowerCase().substring(1).split(' ');
var convert_1 = require("../utils/convert"); var convert_1 = require("../utils/convert");
var bignumber_1 = require("../utils/bignumber"); var bignumber_1 = require("../utils/bignumber");
var utf8_1 = require("../utils/utf8"); var utf8_1 = require("../utils/utf8");
@ -38,8 +34,8 @@ var HDNode = /** @class */ (function () {
function HDNode(keyPair, chainCode, index, depth, mnemonic, path) { function HDNode(keyPair, chainCode, index, depth, mnemonic, path) {
errors.checkNew(this, HDNode); errors.checkNew(this, HDNode);
this.keyPair = keyPair; this.keyPair = keyPair;
this.privateKey = convert_1.hexlify(keyPair.priv.toArray('be', 32)); this.privateKey = keyPair.privateKey;
this.publicKey = '0x' + keyPair.getPublic(true, 'hex'); this.publicKey = keyPair.compressedPublicKey;
this.chainCode = convert_1.hexlify(chainCode); this.chainCode = convert_1.hexlify(chainCode);
this.index = index; this.index = index;
this.depth = depth; this.depth = depth;
@ -71,7 +67,7 @@ var HDNode = /** @class */ (function () {
} }
else { else {
// Data = ser_p(point(k_par)) // Data = ser_p(point(k_par))
data.set(this.keyPair.getPublic().encode(null, true)); data.set(this.keyPair.publicKeyBytes);
} }
// Data += ser_32(i) // Data += ser_32(i)
for (var i = 24; i >= 0; i -= 8) { for (var i = 24; i >= 0; i -= 8) {
@ -80,8 +76,8 @@ var HDNode = /** @class */ (function () {
var I = convert_1.arrayify(hmac_1.createSha512Hmac(this.chainCode).update(data).digest()); var I = convert_1.arrayify(hmac_1.createSha512Hmac(this.chainCode).update(data).digest());
var IL = bignumber_1.bigNumberify(I.slice(0, 32)); var IL = bignumber_1.bigNumberify(I.slice(0, 32));
var IR = I.slice(32); var IR = I.slice(32);
var ki = IL.add('0x' + this.keyPair.getPrivate('hex')).mod('0x' + secp256k1.curve.n.toString(16)); var ki = IL.add(this.keyPair.privateKey).mod(secp256k1_1.N);
return new HDNode(secp256k1.curve.keyFromPrivate(convert_1.arrayify(ki)), IR, index, this.depth + 1, mnemonic, path); return new HDNode(new secp256k1_1.KeyPair(convert_1.arrayify(ki)), IR, index, this.depth + 1, mnemonic, path);
}; };
HDNode.prototype.derivePath = function (path) { HDNode.prototype.derivePath = function (path) {
var components = path.split('/'); var components = path.split('/');
@ -118,12 +114,12 @@ var HDNode = /** @class */ (function () {
}()); }());
exports.HDNode = HDNode; exports.HDNode = HDNode;
function _fromSeed(seed, mnemonic) { function _fromSeed(seed, mnemonic) {
seed = convert_1.arrayify(seed); var seedArray = convert_1.arrayify(seed);
if (seed.length < 16 || seed.length > 64) { if (seedArray.length < 16 || seedArray.length > 64) {
throw new Error('invalid seed'); throw new Error('invalid seed');
} }
var I = convert_1.arrayify(hmac_1.createSha512Hmac(MasterSecret).update(seed).digest()); var I = convert_1.arrayify(hmac_1.createSha512Hmac(MasterSecret).update(seedArray).digest());
return new HDNode(secp256k1.curve.keyFromPrivate(I.slice(0, 32)), I.slice(32), 0, 0, mnemonic, 'm'); return new HDNode(new secp256k1_1.KeyPair(I.slice(0, 32)), I.slice(32), 0, 0, mnemonic, 'm');
} }
function fromMnemonic(mnemonic) { function fromMnemonic(mnemonic) {
// Check that the checksum s valid (will throw an error) // Check that the checksum s valid (will throw an error)
@ -162,7 +158,7 @@ function mnemonicToEntropy(mnemonic) {
var entropy = convert_1.arrayify(new Uint8Array(Math.ceil(11 * words.length / 8))); var entropy = convert_1.arrayify(new Uint8Array(Math.ceil(11 * words.length / 8)));
var offset = 0; var offset = 0;
for (var i = 0; i < words.length; i++) { for (var i = 0; i < words.length; i++) {
var index = wordlist.indexOf(words[i]); var index = words_1.getWordIndex(words[i]);
if (index === -1) { if (index === -1) {
throw new Error('invalid mnemonic'); throw new Error('invalid mnemonic');
} }
@ -189,21 +185,21 @@ function entropyToMnemonic(entropy) {
if ((entropy.length % 4) !== 0 || entropy.length < 16 || entropy.length > 32) { if ((entropy.length % 4) !== 0 || entropy.length < 16 || entropy.length > 32) {
throw new Error('invalid entropy'); throw new Error('invalid entropy');
} }
var words = [0]; var indices = [0];
var remainingBits = 11; var remainingBits = 11;
for (var i = 0; i < entropy.length; i++) { for (var i = 0; i < entropy.length; i++) {
// Consume the whole byte (with still more to go) // Consume the whole byte (with still more to go)
if (remainingBits > 8) { if (remainingBits > 8) {
words[words.length - 1] <<= 8; indices[indices.length - 1] <<= 8;
words[words.length - 1] |= entropy[i]; indices[indices.length - 1] |= entropy[i];
remainingBits -= 8; remainingBits -= 8;
// This byte will complete an 11-bit index // This byte will complete an 11-bit index
} }
else { else {
words[words.length - 1] <<= remainingBits; indices[indices.length - 1] <<= remainingBits;
words[words.length - 1] |= entropy[i] >> (8 - remainingBits); indices[indices.length - 1] |= entropy[i] >> (8 - remainingBits);
// Start the next word // Start the next word
words.push(entropy[i] & getLowerMask(8 - remainingBits)); indices.push(entropy[i] & getLowerMask(8 - remainingBits));
remainingBits += 3; remainingBits += 3;
} }
} }
@ -212,14 +208,9 @@ function entropyToMnemonic(entropy) {
var checksumBits = entropy.length / 4; var checksumBits = entropy.length / 4;
checksum &= getUpperMask(checksumBits); checksum &= getUpperMask(checksumBits);
// Shift the checksum into the word indices // Shift the checksum into the word indices
words[words.length - 1] <<= checksumBits; indices[indices.length - 1] <<= checksumBits;
words[words.length - 1] |= (checksum >> (8 - checksumBits)); indices[indices.length - 1] |= (checksum >> (8 - checksumBits));
// Convert indices into words return indices.map(function (index) { return words_1.getWord(index); }).join(' ');
var result = [];
for (var i = 0; i < words.length; i++) {
result.push(wordlist[words[i]]);
}
return result.join(' ');
} }
exports.entropyToMnemonic = entropyToMnemonic; exports.entropyToMnemonic = entropyToMnemonic;
function isValidMnemonic(mnemonic) { function isValidMnemonic(mnemonic) {

View File

@ -1,31 +1,17 @@
export interface BN { import { Arrayish } from '../utils/convert';
toString(radix: number): string; export declare type Signature = {
encode(encoding: string, compact: boolean): Uint8Array; r: string;
toArray(endian: string, width: number): Uint8Array; s: string;
}
export interface Signature {
r: BN;
s: BN;
recoveryParam: number; recoveryParam: number;
};
export declare class KeyPair {
readonly privateKey: string;
readonly publicKey: string;
readonly compressedPublicKey: string;
readonly publicKeyBytes: Uint8Array;
constructor(privateKey: Arrayish);
sign(digest: Arrayish): Signature;
} }
export interface KeyPair { export declare function recoverPublicKey(digest: Arrayish, signature: Signature): string;
sign(message: Uint8Array, options: { export declare function computePublicKey(key: Arrayish, compressed?: boolean): string;
canonical?: boolean; export declare const N: string;
}): Signature;
getPublic(compressed: boolean, encoding?: string): string;
getPublic(): BN;
getPrivate(encoding?: string): string;
encode(encoding: string, compressed: boolean): string;
priv: BN;
}
export interface EC {
constructor(curve: string): any;
n: BN;
keyFromPublic(publicKey: string | Uint8Array): KeyPair;
keyFromPrivate(privateKey: string | Uint8Array): KeyPair;
recoverPubKey(data: Uint8Array, signature: {
r: Uint8Array;
s: Uint8Array;
}, recoveryParam: number): KeyPair;
}
export declare const curve: EC;

View File

@ -7,5 +7,62 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result; return result;
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var convert_1 = require("../utils/convert");
var properties_1 = require("../utils/properties");
var errors = __importStar(require("../utils/errors"));
var elliptic = __importStar(require("elliptic")); var elliptic = __importStar(require("elliptic"));
exports.curve = new elliptic.ec('secp256k1'); var curve = new elliptic.ec('secp256k1');
var KeyPair = /** @class */ (function () {
function KeyPair(privateKey) {
var keyPair = curve.keyFromPrivate(convert_1.arrayify(privateKey));
properties_1.defineReadOnly(this, 'privateKey', convert_1.hexlify(keyPair.priv.toArray('be', 32)));
properties_1.defineReadOnly(this, 'publicKey', '0x' + keyPair.getPublic(false, 'hex'));
properties_1.defineReadOnly(this, 'compressedPublicKey', '0x' + keyPair.getPublic(true, 'hex'));
properties_1.defineReadOnly(this, 'publicKeyBytes', keyPair.getPublic().encode(null, true));
}
KeyPair.prototype.sign = function (digest) {
var keyPair = curve.keyFromPrivate(convert_1.arrayify(this.privateKey));
var signature = keyPair.sign(convert_1.arrayify(digest), { canonical: true });
return {
recoveryParam: signature.recoveryParam,
r: '0x' + signature.r.toString(16),
s: '0x' + signature.s.toString(16)
};
};
return KeyPair;
}());
exports.KeyPair = KeyPair;
function recoverPublicKey(digest, signature) {
var sig = {
r: convert_1.arrayify(signature.r),
s: convert_1.arrayify(signature.s)
};
return '0x' + curve.recoverPubKey(convert_1.arrayify(digest), sig, signature.recoveryParam).getPublic(false, 'hex');
}
exports.recoverPublicKey = recoverPublicKey;
function computePublicKey(key, compressed) {
var bytes = convert_1.arrayify(key);
if (bytes.length === 32) {
var keyPair = new KeyPair(bytes);
if (compressed) {
return keyPair.compressedPublicKey;
}
return keyPair.publicKey;
}
else if (bytes.length === 33) {
if (compressed) {
return convert_1.hexlify(bytes);
}
return '0x' + curve.keyFromPublic(bytes).getPublic(false, 'hex');
}
else if (bytes.length === 65) {
if (!compressed) {
return convert_1.hexlify(bytes);
}
return '0x' + curve.keyFromPublic(bytes).getPublic(true, 'hex');
}
errors.throwError('invalid public or private key', errors.INVALID_ARGUMENT, { arg: 'key', value: '[REDACTED]' });
return null;
}
exports.computePublicKey = computePublicKey;
exports.N = '0x' + curve.n.toString(16);

View File

@ -7,4 +7,4 @@ export declare function isCrowdsaleWallet(json: string): boolean;
export declare function isValidWallet(json: string): boolean; export declare function isValidWallet(json: string): boolean;
export declare function decryptCrowdsale(json: string, password: Arrayish | string): SigningKey; export declare function decryptCrowdsale(json: string, password: Arrayish | string): SigningKey;
export declare function decrypt(json: string, password: any, progressCallback?: ProgressCallback): Promise<SigningKey>; export declare function decrypt(json: string, password: any, progressCallback?: ProgressCallback): Promise<SigningKey>;
export declare function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: any, progressCallback?: ProgressCallback): Promise<{}>; export declare function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: any, progressCallback?: ProgressCallback): Promise<string>;

View File

@ -262,11 +262,14 @@ function encrypt(privateKey, password, options, progressCallback) {
options = {}; options = {};
} }
// Check the private key // Check the private key
var privateKeyBytes = null;
if (privateKey instanceof signing_key_1.SigningKey) { if (privateKey instanceof signing_key_1.SigningKey) {
privateKey = privateKey.privateKey; privateKeyBytes = convert_1.arrayify(privateKey.privateKey);
} }
privateKey = convert_1.arrayify(privateKey); else {
if (privateKey.length !== 32) { privateKeyBytes = convert_1.arrayify(privateKey);
}
if (privateKeyBytes.length !== 32) {
throw new Error('invalid private key'); throw new Error('invalid private key');
} }
password = getPassword(password); password = getPassword(password);
@ -353,11 +356,11 @@ function encrypt(privateKey, password, options, progressCallback) {
// This will be used to encrypt the mnemonic phrase (if any) // This will be used to encrypt the mnemonic phrase (if any)
var mnemonicKey = key.slice(32, 64); var mnemonicKey = key.slice(32, 64);
// Get the address for this private key // Get the address for this private key
var address = (new signing_key_1.SigningKey(privateKey)).address; var address = (new signing_key_1.SigningKey(privateKeyBytes)).address;
// Encrypt the private key // Encrypt the private key
var counter = new aes.Counter(iv); var counter = new aes.Counter(iv);
var aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter); var aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter);
var ciphertext = convert_1.arrayify(aesCtr.encrypt(privateKey)); var ciphertext = convert_1.arrayify(aesCtr.encrypt(privateKeyBytes));
// Compute the message authentication code, used to check the password // Compute the message authentication code, used to check the password
var mac = keccak256_1.keccak256(convert_1.concat([macPrefix, ciphertext])); var mac = keccak256_1.keccak256(convert_1.concat([macPrefix, ciphertext]));
// See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition // See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition

View File

@ -1,3 +1,11 @@
/**
* SigningKey
*
*
*/
import { Signature } from './secp256k1';
import { Arrayish } from '../utils/convert';
import { HDNode } from './hdnode';
export declare class SigningKey { export declare class SigningKey {
readonly privateKey: string; readonly privateKey: string;
readonly publicKey: string; readonly publicKey: string;
@ -5,13 +13,8 @@ export declare class SigningKey {
readonly mnemonic: string; readonly mnemonic: string;
readonly path: string; readonly path: string;
private readonly keyPair; private readonly keyPair;
constructor(privateKey: any); constructor(privateKey: Arrayish | HDNode);
signDigest(digest: any): { signDigest(digest: Arrayish): Signature;
recoveryParam: number;
r: string;
s: string;
};
static recover(digest: any, r: any, s: any, recoveryParam: any): string;
static getPublicKey(value: any, compressed: any): string;
static publicKeyToAddress(publicKey: any): string;
} }
export declare function recoverAddress(digest: Arrayish, signature: Signature): string;
export declare function computeAddress(key: string): string;

View File

@ -1,33 +1,31 @@
'use strict'; 'use strict';
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
/** /**
* SigningKey * SigningKey
* *
* *
*/ */
var secp256k1 = __importStar(require("./secp256k1")); var secp256k1_1 = require("./secp256k1");
var address_1 = require("../utils/address"); var address_1 = require("../utils/address");
var convert_1 = require("../utils/convert"); var convert_1 = require("../utils/convert");
var hdnode_1 = require("./hdnode");
var keccak256_1 = require("../utils/keccak256"); var keccak256_1 = require("../utils/keccak256");
var properties_1 = require("../utils/properties");
var errors = require("../utils/errors"); var errors = require("../utils/errors");
var SigningKey = /** @class */ (function () { var SigningKey = /** @class */ (function () {
function SigningKey(privateKey) { function SigningKey(privateKey) {
errors.checkNew(this, SigningKey); errors.checkNew(this, SigningKey);
if (privateKey.privateKey) { var privateKeyBytes = null;
this.mnemonic = privateKey.mnemonic; if (privateKey instanceof hdnode_1.HDNode) {
this.path = privateKey.path; properties_1.defineReadOnly(this, 'mnemonic', privateKey.mnemonic);
privateKey = privateKey.privateKey; properties_1.defineReadOnly(this, 'path', privateKey.path);
privateKeyBytes = convert_1.arrayify(privateKey.privateKey);
}
else {
privateKeyBytes = convert_1.arrayify(privateKey);
} }
try { try {
privateKey = convert_1.arrayify(privateKey); if (privateKeyBytes.length !== 32) {
if (privateKey.length !== 32) {
errors.throwError('exactly 32 bytes required', errors.INVALID_ARGUMENT, { value: privateKey }); errors.throwError('exactly 32 bytes required', errors.INVALID_ARGUMENT, { value: privateKey });
} }
} }
@ -41,49 +39,24 @@ var SigningKey = /** @class */ (function () {
} }
errors.throwError('invalid private key', error.code, params); errors.throwError('invalid private key', error.code, params);
} }
this.privateKey = convert_1.hexlify(privateKey); properties_1.defineReadOnly(this, 'privateKey', convert_1.hexlify(privateKeyBytes));
this.keyPair = secp256k1.curve.keyFromPrivate(privateKey); properties_1.defineReadOnly(this, 'keyPair', new secp256k1_1.KeyPair(privateKeyBytes));
//utils.defineProperty(this, 'publicKey', '0x' + keyPair.getPublic(true, 'hex')) properties_1.defineReadOnly(this, 'publicKey', this.keyPair.publicKey);
this.publicKey = '0x' + this.keyPair.getPublic(true, 'hex'); properties_1.defineReadOnly(this, 'address', computeAddress(this.keyPair.publicKey));
this.address = SigningKey.publicKeyToAddress('0x' + this.keyPair.getPublic(false, 'hex'));
} }
SigningKey.prototype.signDigest = function (digest) { SigningKey.prototype.signDigest = function (digest) {
var signature = this.keyPair.sign(convert_1.arrayify(digest), { canonical: true }); return this.keyPair.sign(digest);
return {
recoveryParam: signature.recoveryParam,
r: '0x' + signature.r.toString(16),
s: '0x' + signature.s.toString(16)
};
};
SigningKey.recover = function (digest, r, s, recoveryParam) {
var signature = {
r: convert_1.arrayify(r),
s: convert_1.arrayify(s)
};
var publicKey = secp256k1.curve.recoverPubKey(convert_1.arrayify(digest), signature, recoveryParam);
return SigningKey.publicKeyToAddress('0x' + publicKey.encode('hex', false));
};
SigningKey.getPublicKey = function (value, compressed) {
value = convert_1.arrayify(value);
compressed = !!compressed;
if (value.length === 32) {
var keyPair = secp256k1.curve.keyFromPrivate(value);
return '0x' + keyPair.getPublic(compressed, 'hex');
}
else if (value.length === 33) {
var keyPair = secp256k1.curve.keyFromPublic(value);
return '0x' + keyPair.getPublic(compressed, 'hex');
}
else if (value.length === 65) {
var keyPair = secp256k1.curve.keyFromPublic(value);
return '0x' + keyPair.getPublic(compressed, 'hex');
}
throw new Error('invalid value');
};
SigningKey.publicKeyToAddress = function (publicKey) {
publicKey = '0x' + SigningKey.getPublicKey(publicKey, false).slice(4);
return address_1.getAddress('0x' + keccak256_1.keccak256(publicKey).substring(26));
}; };
return SigningKey; return SigningKey;
}()); }());
exports.SigningKey = SigningKey; exports.SigningKey = SigningKey;
function recoverAddress(digest, signature) {
return computeAddress(secp256k1_1.recoverPublicKey(digest, signature));
}
exports.recoverAddress = recoverAddress;
function computeAddress(key) {
// Strip off the leading "0x04"
var publicKey = '0x' + secp256k1_1.computePublicKey(key).slice(4);
return address_1.getAddress('0x' + keccak256_1.keccak256(publicKey).substring(26));
}
exports.computeAddress = computeAddress;

View File

@ -1,7 +1,9 @@
import { BigNumber } from '../utils/bignumber';
import { Arrayish } from '../utils/convert';
import { HDNode } from './hdnode'; import { HDNode } from './hdnode';
import { ProgressCallback } from './secret-storage';
import { SigningKey } from './signing-key'; import { SigningKey } from './signing-key';
import { BlockTag } from '../providers/provider';
import { BigNumber, BigNumberish } from '../utils/bignumber';
import { Arrayish } from '../utils/convert';
interface Provider { interface Provider {
chainId: number; chainId: number;
getBalance(address: string, blockTag: number | string): Promise<BigNumber>; getBalance(address: string, blockTag: number | string): Promise<BigNumber>;
@ -43,19 +45,19 @@ export declare class Wallet {
sign(transaction: TransactionRequest): string; sign(transaction: TransactionRequest): string;
static parseTransaction(rawTransaction: Arrayish): TransactionRequest; static parseTransaction(rawTransaction: Arrayish): TransactionRequest;
getAddress(): Promise<string>; getAddress(): Promise<string>;
getBalance(blockTag: any): any; getBalance(blockTag: BlockTag): Promise<BigNumber>;
getTransactionCount(blockTag: any): any; getTransactionCount(blockTag: BlockTag): Promise<number>;
estimateGas(transaction: TransactionRequest): any; estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
sendTransaction(transaction: any): Promise<any>; sendTransaction(transaction: any): Promise<TransactionResponse>;
send(addressOrName: any, amountWei: any, options: any): Promise<any>; send(addressOrName: string, amountWei: BigNumberish, options: any): Promise<TransactionResponse>;
static hashMessage(message: any): string; static hashMessage(message: Arrayish | string): string;
signMessage(message: any): string; signMessage(message: Arrayish | string): string;
static verifyMessage(message: any, signature: any): string; static verifyMessage(message: Arrayish | string, signature: string): string;
encrypt(password: any, options: any, progressCallback: any): Promise<{}>; encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string>;
static createRandom(options: any): Wallet; static createRandom(options: any): Wallet;
static isEncryptedWallet(json: string): boolean; static isEncryptedWallet(json: string): boolean;
static fromEncryptedWallet(json: any, password: any, progressCallback: any): Promise<{}>; static fromEncryptedWallet(json: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet>;
static fromMnemonic(mnemonic: string, path?: string): Wallet; static fromMnemonic(mnemonic: string, path?: string): Wallet;
static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback: any): Promise<{}>; static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback: ProgressCallback): Promise<Wallet>;
} }
export {}; export {};

View File

@ -11,6 +11,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var scrypt_js_1 = __importDefault(require("scrypt-js")); var scrypt_js_1 = __importDefault(require("scrypt-js"));
var hdnode_1 = require("./hdnode");
var secretStorage = __importStar(require("./secret-storage"));
var signing_key_1 = require("./signing-key");
var address_1 = require("../utils/address"); var address_1 = require("../utils/address");
var bignumber_1 = require("../utils/bignumber"); var bignumber_1 = require("../utils/bignumber");
var convert_1 = require("../utils/convert"); var convert_1 = require("../utils/convert");
@ -19,9 +22,6 @@ var random_bytes_1 = require("../utils/random-bytes");
var RLP = __importStar(require("../utils/rlp")); var RLP = __importStar(require("../utils/rlp"));
var utf8_1 = require("../utils/utf8"); var utf8_1 = require("../utils/utf8");
var errors = __importStar(require("../utils/errors")); var errors = __importStar(require("../utils/errors"));
var hdnode_1 = require("./hdnode");
var secretStorage = __importStar(require("./secret-storage"));
var signing_key_1 = require("./signing-key");
// This ensures we inject a setImmediate into the global space, which // This ensures we inject a setImmediate into the global space, which
// dramatically improves the performance of the scrypt PBKDF. // dramatically improves the performance of the scrypt PBKDF.
console.log("Fix this! Setimmediate"); console.log("Fix this! Setimmediate");
@ -177,7 +177,7 @@ var Wallet = /** @class */ (function () {
} }
var digest = keccak256_1.keccak256(RLP.encode(raw)); var digest = keccak256_1.keccak256(RLP.encode(raw));
try { try {
transaction.from = signing_key_1.SigningKey.recover(digest, r, s, recoveryParam); transaction.from = signing_key_1.recoverAddress(digest, { r: convert_1.hexlify(r), s: convert_1.hexlify(s), recoveryParam: recoveryParam });
} }
catch (error) { catch (error) {
console.log(error); console.log(error);
@ -310,7 +310,11 @@ var Wallet = /** @class */ (function () {
if (recoveryParam < 0) { if (recoveryParam < 0) {
throw new Error('invalid signature'); throw new Error('invalid signature');
} }
return signing_key_1.SigningKey.recover(digest, signature.substring(0, 66), '0x' + signature.substring(66, 130), recoveryParam); return signing_key_1.recoverAddress(digest, {
r: signature.substring(0, 66),
s: '0x' + signature.substring(66, 130),
recoveryParam: recoveryParam
});
}; };
Wallet.prototype.encrypt = function (password, options, progressCallback) { Wallet.prototype.encrypt = function (password, options, progressCallback) {
if (typeof (options) === 'function' && !progressCallback) { if (typeof (options) === 'function' && !progressCallback) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long