Refactored types for TypeScript and to remove circular dependencies.
This commit is contained in:
parent
3f9f0e02e5
commit
5f3ceec6f9
@ -2,16 +2,17 @@
|
||||
|
||||
import { EventDescription, Interface } from './interface';
|
||||
|
||||
import { Block, Log, Provider, TransactionReceipt, TransactionRequest, TransactionResponse } from '../providers/provider';
|
||||
import { Signer } from '../wallet/wallet';
|
||||
|
||||
import { defaultAbiCoder, formatSignature, ParamType, parseSignature } from '../utils/abi-coder';
|
||||
import { getContractAddress } from '../utils/address';
|
||||
import { getAddress, getContractAddress } from '../utils/address';
|
||||
import { BigNumber, ConstantZero } from '../utils/bignumber';
|
||||
import { hexDataLength, hexDataSlice, isHexString } from '../utils/bytes';
|
||||
import { defineReadOnly, jsonCopy, shallowCopy } from '../utils/properties';
|
||||
import { poll } from '../utils/web';
|
||||
|
||||
import { MinimalProvider, Signer } from '../utils/types';
|
||||
import { EventFilter, Event, Listener, Log, TransactionRequest, TransactionResponse } from '../utils/types';
|
||||
export { EventFilter, Event, Listener, Log, TransactionRequest, TransactionResponse };
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
var allowedTransactionKeys: { [ key: string ]: boolean } = {
|
||||
@ -21,7 +22,7 @@ var allowedTransactionKeys: { [ key: string ]: boolean } = {
|
||||
// Recursively replaces ENS names with promises to resolve the name and
|
||||
// stalls until all promises have returned
|
||||
// @TODO: Expand this to resolve any promises too
|
||||
function resolveAddresses(provider: Provider, value: any, paramType: ParamType | Array<ParamType>): Promise<any> {
|
||||
function resolveAddresses(provider: MinimalProvider, value: any, paramType: ParamType | Array<ParamType>): Promise<any> {
|
||||
if (Array.isArray(paramType)) {
|
||||
var promises: Array<Promise<string>> = [];
|
||||
paramType.forEach((paramType, index) => {
|
||||
@ -171,32 +172,6 @@ function runMethod(contract: Contract, functionName: string, estimateOnly: boole
|
||||
}
|
||||
}
|
||||
|
||||
export type Listener = (...args: Array<any>) => void;
|
||||
|
||||
export type EventFilter = {
|
||||
address?: string;
|
||||
topics?: Array<string>;
|
||||
// @TODO: Support OR-style topcis; backwards compatible to make this change
|
||||
//topics?: Array<string | Array<string>>
|
||||
};
|
||||
|
||||
export type ContractEstimate = (...params: Array<any>) => Promise<BigNumber>;
|
||||
export type ContractFunction = (...params: Array<any>) => Promise<any>;
|
||||
export type ContractFilter = (...params: Array<any>) => EventFilter;
|
||||
|
||||
export interface Event extends Log {
|
||||
args: Array<any>;
|
||||
decode: (data: string, topics?: Array<string>) => any;
|
||||
event: string;
|
||||
eventSignature: string;
|
||||
|
||||
removeListener: () => void;
|
||||
|
||||
getBlock: () => Promise<Block>;
|
||||
getTransaction: () => Promise<TransactionResponse>;
|
||||
getTransactionReceipt: () => Promise<TransactionReceipt>;
|
||||
}
|
||||
|
||||
function getEventTag(filter: EventFilter): string {
|
||||
return (filter.address || '') + (filter.topics ? filter.topics.join(':'): '');
|
||||
}
|
||||
@ -220,32 +195,28 @@ type _Event = {
|
||||
};
|
||||
|
||||
|
||||
export type ErrorCallback = (error: Error) => void;
|
||||
export type Contractish = Array<string | ParamType> | Interface | string;
|
||||
export class Contract {
|
||||
readonly address: string;
|
||||
readonly interface: Interface;
|
||||
|
||||
readonly signer: Signer;
|
||||
readonly provider: Provider;
|
||||
readonly provider: MinimalProvider;
|
||||
|
||||
readonly estimate: Bucket<ContractEstimate>;
|
||||
readonly functions: Bucket<ContractFunction>;
|
||||
readonly estimate: Bucket<(...params: Array<any>) => Promise<BigNumber>>;
|
||||
readonly functions: Bucket<(...params: Array<any>) => Promise<any>>;
|
||||
|
||||
readonly filters: Bucket<ContractFilter>;
|
||||
readonly filters: Bucket<(...params: Array<any>) => EventFilter>;
|
||||
|
||||
readonly addressPromise: Promise<string>;
|
||||
|
||||
// This is only set if the contract was created with a call to deploy
|
||||
readonly deployTransaction: TransactionResponse;
|
||||
|
||||
private _onerror: ErrorCallback;
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/5453
|
||||
// Once this issue is resolved (there are open PR) we can do this nicer
|
||||
// by making addressOrName default to null for 2 operand calls. :)
|
||||
|
||||
constructor(addressOrName: string, contractInterface: Contractish, signerOrProvider: Signer | Provider) {
|
||||
constructor(addressOrName: string, contractInterface: Array<string | ParamType> | string | Interface, signerOrProvider: Signer | MinimalProvider) {
|
||||
errors.checkNew(this, Contract);
|
||||
|
||||
// @TODO: Maybe still check the addressOrName looks like a valid address or name?
|
||||
@ -259,7 +230,7 @@ export class Contract {
|
||||
if (signerOrProvider instanceof Signer) {
|
||||
defineReadOnly(this, 'provider', signerOrProvider.provider);
|
||||
defineReadOnly(this, 'signer', signerOrProvider);
|
||||
} else if (signerOrProvider instanceof Provider) {
|
||||
} else if (signerOrProvider instanceof MinimalProvider) {
|
||||
defineReadOnly(this, 'provider', signerOrProvider);
|
||||
defineReadOnly(this, 'signer', null);
|
||||
} else {
|
||||
@ -291,13 +262,21 @@ export class Contract {
|
||||
this._events = [];
|
||||
|
||||
defineReadOnly(this, 'address', addressOrName);
|
||||
defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName).then((address) => {
|
||||
if (address == null) { throw new Error('name not found'); }
|
||||
return address;
|
||||
}).catch((error: Error) => {
|
||||
console.log('ERROR: Cannot find Contract - ' + addressOrName);
|
||||
throw error;
|
||||
}));
|
||||
if (this.provider) {
|
||||
defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName).then((address) => {
|
||||
if (address == null) { throw new Error('name not found'); }
|
||||
return address;
|
||||
}).catch((error: Error) => {
|
||||
console.log('ERROR: Cannot find Contract - ' + addressOrName);
|
||||
throw error;
|
||||
}));
|
||||
} else {
|
||||
try {
|
||||
defineReadOnly(this, 'addressPromise', Promise.resolve(getAddress(addressOrName)));
|
||||
} catch (error) {
|
||||
errors.throwError('provider is required to use non-address contract address', errors.INVALID_ARGUMENT, { argument: 'addressOrName', value: addressOrName });
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(this.interface.functions).forEach((name) => {
|
||||
var run = runMethod(this, name, false);
|
||||
@ -315,14 +294,9 @@ export class Contract {
|
||||
});
|
||||
}
|
||||
|
||||
get onerror() { return this._onerror; }
|
||||
|
||||
set onerror(callback: ErrorCallback) {
|
||||
this._onerror = callback;
|
||||
}
|
||||
|
||||
// @TODO: Allow timeout?
|
||||
deployed(): Promise<Contract> {
|
||||
|
||||
// If we were just deployed, we know the transaction we should occur in
|
||||
if (this.deployTransaction) {
|
||||
return this.deployTransaction.wait().then(() => {
|
||||
@ -362,7 +336,7 @@ export class Contract {
|
||||
}
|
||||
|
||||
// Reconnect to a different signer or provider
|
||||
connect(signerOrProvider: Signer | Provider): Contract {
|
||||
connect(signerOrProvider: Signer | MinimalProvider): Contract {
|
||||
return new Contract(this.address, this.interface, signerOrProvider);
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,19 @@ import { id } from '../utils/hash';
|
||||
import { keccak256 } from '../utils/keccak256';
|
||||
import { defineReadOnly, defineFrozen } from '../utils/properties';
|
||||
|
||||
import { DeployDescription, EventDescription, FunctionDescription, Indexed } from '../utils/types';
|
||||
export { DeployDescription, EventDescription, FunctionDescription, Indexed };
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
export class Description {
|
||||
class _Indexed extends Indexed {
|
||||
constructor(hash: string) {
|
||||
super();
|
||||
defineReadOnly(this, 'hash', hash);
|
||||
}
|
||||
}
|
||||
|
||||
class _Description {
|
||||
readonly type: string;
|
||||
constructor(info: any) {
|
||||
for (var key in info) {
|
||||
@ -26,11 +36,8 @@ export class Description {
|
||||
}
|
||||
}
|
||||
|
||||
export class Indexed extends Description {
|
||||
readonly hash: string;
|
||||
}
|
||||
|
||||
export class DeployDescription extends Description {
|
||||
class _DeployDescription extends _Description implements DeployDescription {
|
||||
readonly type: "deploy";
|
||||
readonly inputs: Array<ParamType>;
|
||||
readonly payable: boolean;
|
||||
|
||||
@ -58,7 +65,8 @@ export class DeployDescription extends Description {
|
||||
}
|
||||
}
|
||||
|
||||
export class FunctionDescription extends Description {
|
||||
class _FunctionDescription extends _Description implements FunctionDescription {
|
||||
readonly type: "call" | "transaction";
|
||||
readonly name: string;
|
||||
readonly signature: string;
|
||||
readonly sighash: string;
|
||||
@ -98,12 +106,13 @@ export class FunctionDescription extends Description {
|
||||
}
|
||||
}
|
||||
|
||||
class Result extends Description {
|
||||
class Result extends _Description {
|
||||
[key: string]: any;
|
||||
[key: number]: any;
|
||||
}
|
||||
|
||||
export class EventDescription extends Description {
|
||||
class _EventDescription extends _Description implements EventDescription {
|
||||
readonly type: "event";
|
||||
readonly name: string;
|
||||
readonly signature: string;
|
||||
|
||||
@ -190,10 +199,11 @@ export class EventDescription extends Description {
|
||||
this.inputs.forEach(function(input, index) {
|
||||
if (input.indexed) {
|
||||
if (topics == null) {
|
||||
result[index] = new Indexed({ type: 'indexed', hash: null });
|
||||
result[index] = new _Indexed(null);
|
||||
|
||||
} else if (inputDynamic[index]) {
|
||||
result[index] = new Indexed({ type: 'indexed', hash: resultIndexed[indexedIndex++] });
|
||||
result[index] = new _Indexed(resultIndexed[indexedIndex++]);
|
||||
|
||||
} else {
|
||||
result[index] = resultIndexed[indexedIndex++];
|
||||
}
|
||||
@ -209,7 +219,7 @@ export class EventDescription extends Description {
|
||||
}
|
||||
}
|
||||
|
||||
class TransactionDescription extends Description {
|
||||
class TransactionDescription extends _Description {
|
||||
readonly name: string;
|
||||
readonly args: Array<any>;
|
||||
readonly signature: string;
|
||||
@ -218,7 +228,7 @@ class TransactionDescription extends Description {
|
||||
readonly value: BigNumber;
|
||||
}
|
||||
|
||||
class LogDescription extends Description {
|
||||
class LogDescription extends _Description {
|
||||
readonly name: string;
|
||||
readonly signature: string;
|
||||
readonly topic: string;
|
||||
@ -229,10 +239,10 @@ class LogDescription extends Description {
|
||||
function addMethod(method: any): void {
|
||||
switch (method.type) {
|
||||
case 'constructor': {
|
||||
let description = new DeployDescription({
|
||||
let description = new _DeployDescription({
|
||||
inputs: method.inputs,
|
||||
payable: (method.payable == null || !!method.payable),
|
||||
type: 'deploy'
|
||||
type: "deploy"
|
||||
});
|
||||
|
||||
if (!this.deployFunction) { this.deployFunction = description; }
|
||||
@ -244,7 +254,7 @@ function addMethod(method: any): void {
|
||||
let signature = formatSignature(method).replace(/tuple/g, '');
|
||||
let sighash = id(signature).substring(0, 10);
|
||||
|
||||
let description = new FunctionDescription({
|
||||
let description = new _FunctionDescription({
|
||||
inputs: method.inputs,
|
||||
outputs: method.outputs,
|
||||
|
||||
@ -271,7 +281,7 @@ function addMethod(method: any): void {
|
||||
case 'event': {
|
||||
let signature = formatSignature(method).replace(/tuple/g, '');
|
||||
|
||||
let description = new EventDescription({
|
||||
let description = new _EventDescription({
|
||||
name: method.name,
|
||||
signature: signature,
|
||||
|
||||
|
@ -5,10 +5,11 @@ import {} from './utils/shims';
|
||||
|
||||
|
||||
import { Contract, Interface } from './contracts';
|
||||
import providers from './providers';
|
||||
import * as providers from './providers';
|
||||
import * as errors from './utils/errors';
|
||||
import { getNetwork } from './providers/networks';
|
||||
import utils from './utils';
|
||||
import * as types from './utils/types';
|
||||
import * as utils from './utils';
|
||||
import { HDNode, SigningKey, Wallet } from './wallet';
|
||||
import * as wordlists from './wordlists';
|
||||
|
||||
@ -28,6 +29,8 @@ export {
|
||||
getNetwork,
|
||||
providers,
|
||||
|
||||
types,
|
||||
|
||||
errors,
|
||||
constants,
|
||||
utils,
|
||||
@ -49,6 +52,8 @@ export default {
|
||||
getNetwork,
|
||||
providers,
|
||||
|
||||
types,
|
||||
|
||||
errors,
|
||||
constants,
|
||||
utils,
|
||||
|
@ -1,9 +1,9 @@
|
||||
|
||||
import { BlockTag, checkTransactionResponse, Provider, TransactionRequest, TransactionResponse } from './provider';
|
||||
import { Networkish } from './networks';
|
||||
import { Provider } from './provider';
|
||||
|
||||
import { hexlify, hexStripZeros } from '../utils/bytes';
|
||||
import { defineReadOnly } from '../utils/properties';
|
||||
import { BlockTag, Networkish, TransactionRequest, TransactionResponse } from '../utils/types';
|
||||
import { fetchJson } from '../utils/web';
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
@ -278,7 +278,7 @@ export class EtherscanProvider extends Provider{
|
||||
if (tx.creates == null && tx.contractAddress != null) {
|
||||
tx.creates = tx.contractAddress;
|
||||
}
|
||||
let item = checkTransactionResponse(tx);
|
||||
let item = Provider.checkTransactionResponse(tx);
|
||||
if (tx.timeStamp) { item.timestamp = parseInt(tx.timeStamp); }
|
||||
output.push(item);
|
||||
});
|
||||
|
@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
import { Network } from './networks';
|
||||
import { Provider } from './provider';
|
||||
|
||||
import { Network } from '../utils/types';
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
// Returns:
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
import { Provider } from './provider';
|
||||
|
||||
import { Network } from './networks';
|
||||
|
||||
import { EtherscanProvider } from './etherscan-provider';
|
||||
import { FallbackProvider } from './fallback-provider';
|
||||
import { IpcProvider } from './ipc-provider';
|
||||
import { InfuraProvider } from './infura-provider';
|
||||
import { JsonRpcProvider } from './json-rpc-provider';
|
||||
import { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';
|
||||
import { Web3Provider } from './web3-provider';
|
||||
|
||||
import { Network } from '../utils/types';
|
||||
|
||||
function getDefaultProvider(network?: Network | string): FallbackProvider {
|
||||
return new FallbackProvider([
|
||||
new InfuraProvider(network),
|
||||
@ -29,7 +29,9 @@ export {
|
||||
JsonRpcProvider,
|
||||
Web3Provider,
|
||||
|
||||
IpcProvider
|
||||
IpcProvider,
|
||||
|
||||
JsonRpcSigner
|
||||
};
|
||||
|
||||
export default {
|
||||
@ -43,5 +45,7 @@ export default {
|
||||
JsonRpcProvider,
|
||||
Web3Provider,
|
||||
|
||||
IpcProvider
|
||||
IpcProvider,
|
||||
|
||||
JsonRpcSigner
|
||||
};
|
||||
|
@ -1,9 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
import { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';
|
||||
import { getNetwork, Networkish } from './networks';
|
||||
import { getNetwork } from './networks';
|
||||
|
||||
import { defineReadOnly } from '../utils/properties';
|
||||
import { Networkish } from '../utils/types';
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
import net from 'net';
|
||||
|
||||
import { JsonRpcProvider } from './json-rpc-provider';
|
||||
import { Networkish } from './networks';
|
||||
|
||||
import { Networkish } from '../utils/types';
|
||||
import { defineReadOnly } from '../utils/properties';
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC
|
||||
|
||||
import { getNetwork, Network, Networkish } from './networks';
|
||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from './provider';
|
||||
import { Signer } from '../wallet/wallet';
|
||||
import { getNetwork } from './networks';
|
||||
import { Provider } from './provider';
|
||||
|
||||
import { getAddress } from '../utils/address';
|
||||
import { BigNumber } from '../utils/bignumber';
|
||||
import { Arrayish, hexlify, hexStripZeros } from '../utils/bytes';
|
||||
import { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';
|
||||
import { BlockTag, Network, Networkish, Signer, TransactionRequest, TransactionResponse } from '../utils/types';
|
||||
import { toUtf8Bytes } from '../utils/utf8';
|
||||
import { ConnectionInfo, fetchJson, poll } from '../utils/web';
|
||||
|
||||
@ -35,30 +35,6 @@ function getResult(payload: { error?: { code?: number, data?: any, message?: str
|
||||
return payload.result;
|
||||
}
|
||||
|
||||
// Convert an ethers.js transaction into a JSON-RPC transaction
|
||||
// - gasLimit => gas
|
||||
// - All values hexlified
|
||||
// - All numeric values zero-striped
|
||||
// @TODO: Not any, a dictionary of string to strings
|
||||
export function hexlifyTransaction(transaction: TransactionRequest): any {
|
||||
var result: any = {};
|
||||
|
||||
// Some nodes (INFURA ropsten; INFURA mainnet is fine) don't like extra zeros.
|
||||
['gasLimit', 'gasPrice', 'nonce', 'value'].forEach(function(key) {
|
||||
if ((<any>transaction)[key] == null) { return; }
|
||||
let value = hexStripZeros(hexlify((<any>transaction)[key]));
|
||||
if (key === 'gasLimit') { key = 'gas'; }
|
||||
result[key] = value;
|
||||
});
|
||||
|
||||
['from', 'to', 'data'].forEach(function(key) {
|
||||
if ((<any>transaction)[key] == null) { return; }
|
||||
result[key] = hexlify((<any>transaction)[key]);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLowerCase(value: string): string {
|
||||
if (value) { return value.toLowerCase(); }
|
||||
return value;
|
||||
@ -119,7 +95,7 @@ export class JsonRpcSigner extends Signer {
|
||||
}
|
||||
|
||||
return resolveProperties(tx).then((tx) => {
|
||||
tx = hexlifyTransaction(tx);
|
||||
tx = JsonRpcProvider.hexlifyTransaction(tx);
|
||||
return this.provider.send('eth_sendTransaction', [ tx ]).then((hash) => {
|
||||
return poll(() => {
|
||||
return this.provider.getTransaction(hash).then((tx: TransactionResponse) => {
|
||||
@ -260,10 +236,10 @@ export class JsonRpcProvider extends Provider {
|
||||
return this.send('eth_getTransactionReceipt', [ params.transactionHash ]);
|
||||
|
||||
case 'call':
|
||||
return this.send('eth_call', [ hexlifyTransaction(params.transaction), 'latest' ]);
|
||||
return this.send('eth_call', [ JsonRpcProvider.hexlifyTransaction(params.transaction), 'latest' ]);
|
||||
|
||||
case 'estimateGas':
|
||||
return this.send('eth_estimateGas', [ hexlifyTransaction(params.transaction) ]);
|
||||
return this.send('eth_estimateGas', [ JsonRpcProvider.hexlifyTransaction(params.transaction) ]);
|
||||
|
||||
case 'getLogs':
|
||||
if (params.filter && params.filter.address != null) {
|
||||
@ -324,4 +300,28 @@ export class JsonRpcProvider extends Provider {
|
||||
_stopPending(): void {
|
||||
this._pendingFilter = null;
|
||||
}
|
||||
|
||||
// Convert an ethers.js transaction into a JSON-RPC transaction
|
||||
// - gasLimit => gas
|
||||
// - All values hexlified
|
||||
// - All numeric values zero-striped
|
||||
// @TODO: Not any, a dictionary of string to strings
|
||||
static hexlifyTransaction(transaction: TransactionRequest): any {
|
||||
var result: any = {};
|
||||
|
||||
// Some nodes (INFURA ropsten; INFURA mainnet is fine) don't like extra zeros.
|
||||
['gasLimit', 'gasPrice', 'nonce', 'value'].forEach(function(key) {
|
||||
if ((<any>transaction)[key] == null) { return; }
|
||||
let value = hexStripZeros(hexlify((<any>transaction)[key]));
|
||||
if (key === 'gasLimit') { key = 'gas'; }
|
||||
result[key] = value;
|
||||
});
|
||||
|
||||
['from', 'to', 'data'].forEach(function(key) {
|
||||
if ((<any>transaction)[key] == null) { return; }
|
||||
result[key] = hexlify((<any>transaction)[key]);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
import { Network, Networkish } from '../utils/types';
|
||||
export { Network, Networkish };
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
export type Network = {
|
||||
name: string,
|
||||
chainId: number,
|
||||
ensAddress?: string,
|
||||
}
|
||||
|
||||
export type Networkish = Network | string | number;
|
||||
|
||||
|
||||
const homestead = {
|
||||
chainId: 1,
|
||||
|
@ -4,7 +4,7 @@ import { getNetwork, Network, Networkish } from './networks';
|
||||
|
||||
import { getAddress, getContractAddress } from '../utils/address';
|
||||
import { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber';
|
||||
import { Arrayish, hexDataLength, hexDataSlice, hexlify, hexStripZeros, isHexString, stripZeros } from '../utils/bytes';
|
||||
import { hexDataLength, hexDataSlice, hexlify, hexStripZeros, isHexString, stripZeros } from '../utils/bytes';
|
||||
import { namehash } from '../utils/hash';
|
||||
import { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';
|
||||
import { encode as rlpEncode } from '../utils/rlp';
|
||||
@ -12,102 +12,13 @@ import { parse as parseTransaction, Transaction } from '../utils/transaction';
|
||||
import { toUtf8String } from '../utils/utf8';
|
||||
import { poll } from '../utils/web';
|
||||
|
||||
import { MinimalProvider } from '../utils/types';
|
||||
import { Block, BlockTag, EventType, Filter, Listener, Log, TransactionReceipt, TransactionRequest, TransactionResponse } from '../utils/types';
|
||||
export { Block, BlockTag, EventType, Filter, Listener, Log, TransactionReceipt, TransactionRequest, TransactionResponse };
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Exported Types
|
||||
|
||||
export type BlockTag = string | number;
|
||||
|
||||
export interface Block {
|
||||
hash: string;
|
||||
parentHash: string;
|
||||
number: number;
|
||||
|
||||
timestamp: number;
|
||||
nonce: string;
|
||||
difficulty: number;
|
||||
|
||||
gasLimit: BigNumber;
|
||||
gasUsed: BigNumber;
|
||||
|
||||
miner: string;
|
||||
extraData: string;
|
||||
|
||||
transactions: Array<string>;
|
||||
}
|
||||
|
||||
export type TransactionRequest = {
|
||||
to?: string | Promise<string>,
|
||||
from?: string | Promise<string>,
|
||||
nonce?: number | string | Promise<number | string>,
|
||||
|
||||
gasLimit?: BigNumberish | Promise<BigNumberish>,
|
||||
gasPrice?: BigNumberish | Promise<BigNumberish>,
|
||||
|
||||
data?: Arrayish | Promise<Arrayish>,
|
||||
value?: BigNumberish | Promise<BigNumberish>,
|
||||
chainId?: number | Promise<number>,
|
||||
}
|
||||
|
||||
export interface TransactionResponse extends Transaction {
|
||||
// Only if a transaction has been mined
|
||||
blockNumber?: number,
|
||||
blockHash?: string,
|
||||
timestamp?: number,
|
||||
|
||||
// Not optional (as it is in Transaction)
|
||||
from: string;
|
||||
|
||||
// The raw transaction
|
||||
raw?: string,
|
||||
|
||||
// This function waits until the transaction has been mined
|
||||
wait: (timeout?: number) => Promise<TransactionReceipt>
|
||||
};
|
||||
|
||||
export interface TransactionReceipt {
|
||||
contractAddress?: string,
|
||||
transactionIndex?: number,
|
||||
root?: string,
|
||||
gasUsed?: BigNumber,
|
||||
logsBloom?: string,
|
||||
blockHash?: string,
|
||||
transactionHash?: string,
|
||||
logs?: Array<Log>,
|
||||
blockNumber?: number,
|
||||
cumulativeGasUsed?: BigNumber,
|
||||
byzantium: boolean,
|
||||
status?: number // @TOOD: Check 0 or 1?
|
||||
};
|
||||
|
||||
export type Filter = {
|
||||
fromBlock?: BlockTag,
|
||||
toBlock?: BlockTag,
|
||||
address?: string,
|
||||
topics?: Array<string | Array<string>>,
|
||||
}
|
||||
|
||||
export interface Log {
|
||||
blockNumber?: number;
|
||||
blockHash?: string;
|
||||
transactionIndex?: number;
|
||||
|
||||
removed?: boolean;
|
||||
|
||||
transactionLogIndex?: number,
|
||||
|
||||
address: string;
|
||||
data: string;
|
||||
|
||||
topics: Array<string>;
|
||||
|
||||
transactionHash?: string;
|
||||
logIndex?: number;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Request and Response Checking
|
||||
|
||||
@ -282,7 +193,7 @@ var formatTransaction = {
|
||||
raw: allowNull(hexlify),
|
||||
};
|
||||
|
||||
export function checkTransactionResponse(transaction: any): TransactionResponse {
|
||||
function checkTransactionResponse(transaction: any): TransactionResponse {
|
||||
|
||||
// Rename gas to gasLimit
|
||||
if (transaction.gas != null && transaction.gasLimit == null) {
|
||||
@ -594,8 +505,6 @@ export class ProviderSigner extends Signer {
|
||||
}
|
||||
*/
|
||||
|
||||
export type Listener = (...args: Array<any>) => void;
|
||||
|
||||
/**
|
||||
* EventType
|
||||
* - "block"
|
||||
@ -607,15 +516,13 @@ export type Listener = (...args: Array<any>) => void;
|
||||
* - transaction hash
|
||||
*/
|
||||
|
||||
export type EventType = string | Array<string> | Filter;
|
||||
|
||||
type _Event = {
|
||||
listener: Listener;
|
||||
once: boolean;
|
||||
tag: string;
|
||||
}
|
||||
|
||||
export class Provider {
|
||||
export class Provider extends MinimalProvider {
|
||||
private _network: Network;
|
||||
|
||||
private _events: Array<_Event>;
|
||||
@ -642,6 +549,7 @@ export class Provider {
|
||||
protected ready: Promise<Network>;
|
||||
|
||||
constructor(network: Networkish | Promise<Network>) {
|
||||
super();
|
||||
errors.checkNew(this, Provider);
|
||||
|
||||
if (network instanceof Promise) {
|
||||
@ -1040,7 +948,7 @@ export class Provider {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return checkTransactionResponse(result);
|
||||
return Provider.checkTransactionResponse(result);
|
||||
});
|
||||
}, { onceBlock: this });
|
||||
});
|
||||
@ -1213,6 +1121,10 @@ export class Provider {
|
||||
});
|
||||
}
|
||||
|
||||
static checkTransactionResponse(transaction: any): TransactionResponse {
|
||||
return checkTransactionResponse(transaction);
|
||||
}
|
||||
|
||||
doPoll(): void {
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,11 @@ utils.defineProperty(Web3Signer, 'onchange', {
|
||||
});
|
||||
*/
|
||||
|
||||
export type Callback = (error: any, response: any) => void;
|
||||
|
||||
export type AsyncProvider = {
|
||||
isMetaMask: boolean;
|
||||
host?: string;
|
||||
path?: string;
|
||||
sendAsync: (request: any, callback: Callback) => void
|
||||
sendAsync: (request: any, callback: (error: any, response: any) => void) => void
|
||||
}
|
||||
|
||||
export class Web3Provider extends JsonRpcProvider {
|
||||
|
@ -8,16 +8,15 @@ import { arrayify, Arrayish, concat, hexlify, padZeros } from './bytes';
|
||||
import { toUtf8Bytes, toUtf8String } from './utf8';
|
||||
import { defineReadOnly, jsonCopy } from './properties';
|
||||
|
||||
import { CoerceFunc, EventFragment, FunctionFragment, ParamType }from './types';
|
||||
export { CoerceFunc, EventFragment, FunctionFragment, ParamType }
|
||||
|
||||
import * as errors from './errors';
|
||||
|
||||
const paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);
|
||||
const paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);
|
||||
const paramTypeArray = new RegExp(/^(.*)\[([0-9]*)\]$/);
|
||||
|
||||
// @TODO: Add enum for param types
|
||||
export type CoerceFunc = (type: string, value: any) => any;
|
||||
export type ParamType = { name?: string, type: string, indexed?: boolean, components?: Array<any> };
|
||||
|
||||
export const defaultCoerceFunc: CoerceFunc = function(type: string, value: any): any {
|
||||
var match = type.match(paramTypeNumber)
|
||||
if (match && parseInt(match[2]) <= 48) { return value.toNumber(); }
|
||||
@ -188,29 +187,6 @@ function parseParam(param: string, allowIndexed?: boolean): ParamType {
|
||||
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
|
||||
function parseSignatureEvent(fragment: string): EventFragment {
|
||||
|
@ -10,14 +10,16 @@
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
import { Arrayish, hexlify, isArrayish, isHexString } from './bytes';
|
||||
import { hexlify, isArrayish, isHexString } from './bytes';
|
||||
import { defineReadOnly } from './properties';
|
||||
|
||||
import { BigNumber, BigNumberish } from './types';
|
||||
export { BigNumber, BigNumberish };
|
||||
|
||||
import * as errors from './errors';
|
||||
|
||||
const BN_1 = new BN.BN(-1);
|
||||
|
||||
export type BigNumberish = BigNumber | string | number | Arrayish;
|
||||
|
||||
function toHex(bn: BN.BN): string {
|
||||
let value = bn.toString(16);
|
||||
if (value[0] === '-') {
|
||||
@ -38,29 +40,6 @@ function toBigNumber(bn: BN.BN): _BigNumber {
|
||||
return new _BigNumber(toHex(bn));
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface BigNumber {
|
||||
fromTwos(value: number): BigNumber;
|
||||
toTwos(value: number): BigNumber;
|
||||
add(other: BigNumberish): BigNumber;
|
||||
sub(other: BigNumberish): BigNumber;
|
||||
div(other: BigNumberish): BigNumber;
|
||||
mul(other: BigNumberish): BigNumber;
|
||||
mod(other: BigNumberish): BigNumber;
|
||||
pow(other: BigNumberish): BigNumber;
|
||||
maskn(value: number): BigNumber;
|
||||
eq(other: BigNumberish): boolean;
|
||||
lt(other: BigNumberish): boolean;
|
||||
lte(other: BigNumberish): boolean;
|
||||
gt(other: BigNumberish): boolean;
|
||||
gte(other: BigNumberish): boolean;
|
||||
isZero(): boolean;
|
||||
toNumber(): number;
|
||||
toString(): string;
|
||||
toHexString(): string;
|
||||
};
|
||||
|
||||
class _BigNumber implements BigNumber {
|
||||
private readonly _hex: string;
|
||||
|
||||
|
@ -5,14 +5,15 @@
|
||||
|
||||
import { BigNumber } from './bignumber';
|
||||
|
||||
import { Arrayish, Signature } from './types';
|
||||
export { Arrayish, Signature };
|
||||
|
||||
import errors = require('./errors');
|
||||
|
||||
|
||||
export const AddressZero = '0x0000000000000000000000000000000000000000';
|
||||
export const HashZero = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
export type Arrayish = string | ArrayLike<number>;
|
||||
|
||||
|
||||
function isBigNumber(value: any): value is BigNumber {
|
||||
return !!value._bn;
|
||||
@ -245,13 +246,6 @@ function isSignature(value: any): value is Signature {
|
||||
return (value && value.r != null && value.s != null);
|
||||
}
|
||||
|
||||
export interface Signature {
|
||||
r: string;
|
||||
s: string;
|
||||
recoveryParam: number;
|
||||
v?: number;
|
||||
}
|
||||
|
||||
export function splitSignature(signature: Arrayish | Signature): Signature {
|
||||
let v = 0;
|
||||
let r = '0x', s = '0x';
|
||||
|
@ -4,16 +4,16 @@ import { createHmac } from 'crypto';
|
||||
|
||||
import { arrayify, Arrayish } from './bytes';
|
||||
|
||||
import * as errors from './errors';
|
||||
import { SupportedAlgorithms } from './types';
|
||||
export { SupportedAlgorithms };
|
||||
|
||||
export type SupportedAlgorithms = 'sha256' | 'sha512';
|
||||
import * as errors from './errors';
|
||||
|
||||
const supportedAlgorithms = { sha256: true, sha512: true };
|
||||
export function computeHmac(algorithm: SupportedAlgorithms, key: Arrayish, data: Arrayish): Uint8Array {
|
||||
if (!supportedAlgorithms[algorithm]) {
|
||||
errors.throwError('unsupported algorithm ' + algorithm, errors.UNSUPPORTED_OPERATION, { operation: 'hmac', algorithm: algorithm });
|
||||
}
|
||||
//return arrayify(_hmac(_hash[algorithm], arrayify(key)).update(arrayify(data)).digest());
|
||||
return arrayify(createHmac(algorithm, new Buffer(arrayify(key))).update(new Buffer(arrayify(data))).digest());
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
|
||||
import { getAddress } from './address';
|
||||
import { BigNumber, bigNumberify, BigNumberish, ConstantZero } from './bignumber';
|
||||
import { BigNumber, bigNumberify, ConstantZero } from './bignumber';
|
||||
import { arrayify, Arrayish, hexlify, hexZeroPad, Signature, splitSignature, stripZeros, } from './bytes';
|
||||
import { keccak256 } from './keccak256';
|
||||
|
||||
import * as RLP from './rlp';
|
||||
|
||||
import { Transaction, UnsignedTransaction } from './types';
|
||||
export { Transaction, UnsignedTransaction };
|
||||
|
||||
import * as errors from './errors';
|
||||
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!
|
||||
@ -17,38 +20,6 @@ import * as errors from './errors';
|
||||
*
|
||||
*/
|
||||
|
||||
export type UnsignedTransaction = {
|
||||
to?: string;
|
||||
nonce?: number;
|
||||
|
||||
gasLimit?: BigNumberish;
|
||||
gasPrice?: BigNumberish;
|
||||
|
||||
data?: Arrayish;
|
||||
value?: BigNumberish;
|
||||
chainId?: number;
|
||||
}
|
||||
|
||||
|
||||
export interface Transaction {
|
||||
hash?: string;
|
||||
|
||||
to?: string;
|
||||
from?: string;
|
||||
nonce: number;
|
||||
|
||||
gasLimit: BigNumber;
|
||||
gasPrice: BigNumber;
|
||||
|
||||
data: string;
|
||||
value: BigNumber;
|
||||
chainId: number;
|
||||
|
||||
r?: string;
|
||||
s?: string;
|
||||
v?: number;
|
||||
}
|
||||
|
||||
function handleAddress(value: string): string {
|
||||
if (value === '0x') { return null; }
|
||||
return getAddress(value);
|
||||
|
383
src.ts/utils/types.ts
Normal file
383
src.ts/utils/types.ts
Normal file
@ -0,0 +1,383 @@
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Bytes
|
||||
|
||||
export type Arrayish = string | ArrayLike<number>;
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// BigNumber
|
||||
|
||||
export interface BigNumber {
|
||||
fromTwos(value: number): BigNumber;
|
||||
toTwos(value: number): BigNumber;
|
||||
add(other: BigNumberish): BigNumber;
|
||||
sub(other: BigNumberish): BigNumber;
|
||||
div(other: BigNumberish): BigNumber;
|
||||
mul(other: BigNumberish): BigNumber;
|
||||
mod(other: BigNumberish): BigNumber;
|
||||
pow(other: BigNumberish): BigNumber;
|
||||
maskn(value: number): BigNumber;
|
||||
eq(other: BigNumberish): boolean;
|
||||
lt(other: BigNumberish): boolean;
|
||||
lte(other: BigNumberish): boolean;
|
||||
gt(other: BigNumberish): boolean;
|
||||
gte(other: BigNumberish): boolean;
|
||||
isZero(): boolean;
|
||||
toNumber(): number;
|
||||
toString(): string;
|
||||
toHexString(): string;
|
||||
};
|
||||
|
||||
export type BigNumberish = BigNumber | string | number | Arrayish;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Connection
|
||||
|
||||
export type ConnectionInfo = {
|
||||
url: string,
|
||||
user?: string,
|
||||
password?: string,
|
||||
allowInsecure?: boolean
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Crypto
|
||||
|
||||
export type SupportedAlgorithms = 'sha256' | 'sha512';
|
||||
|
||||
export interface Signature {
|
||||
r: string;
|
||||
s: string;
|
||||
recoveryParam: number;
|
||||
v?: number;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Network
|
||||
|
||||
export type Network = {
|
||||
name: string,
|
||||
chainId: number,
|
||||
ensAddress?: string,
|
||||
}
|
||||
|
||||
export type Networkish = Network | string | number;
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// ABI Coder
|
||||
|
||||
export type CoerceFunc = (type: string, value: any) => any;
|
||||
|
||||
export type ParamType = {
|
||||
name?: string,
|
||||
type: string,
|
||||
indexed?: boolean,
|
||||
components?: Array<any>
|
||||
};
|
||||
|
||||
// @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,
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Transactions
|
||||
|
||||
export type UnsignedTransaction = {
|
||||
to?: string;
|
||||
nonce?: number;
|
||||
|
||||
gasLimit?: BigNumberish;
|
||||
gasPrice?: BigNumberish;
|
||||
|
||||
data?: Arrayish;
|
||||
value?: BigNumberish;
|
||||
chainId?: number;
|
||||
}
|
||||
|
||||
export interface Transaction {
|
||||
hash?: string;
|
||||
|
||||
to?: string;
|
||||
from?: string;
|
||||
nonce: number;
|
||||
|
||||
gasLimit: BigNumber;
|
||||
gasPrice: BigNumber;
|
||||
|
||||
data: string;
|
||||
value: BigNumber;
|
||||
chainId: number;
|
||||
|
||||
r?: string;
|
||||
s?: string;
|
||||
v?: number;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Blockchain
|
||||
|
||||
export type BlockTag = string | number;
|
||||
|
||||
export interface Block {
|
||||
hash: string;
|
||||
parentHash: string;
|
||||
number: number;
|
||||
|
||||
timestamp: number;
|
||||
nonce: string;
|
||||
difficulty: number;
|
||||
|
||||
gasLimit: BigNumber;
|
||||
gasUsed: BigNumber;
|
||||
|
||||
miner: string;
|
||||
extraData: string;
|
||||
|
||||
transactions: Array<string>;
|
||||
}
|
||||
|
||||
export type Filter = {
|
||||
fromBlock?: BlockTag,
|
||||
toBlock?: BlockTag,
|
||||
address?: string,
|
||||
topics?: Array<string | Array<string>>,
|
||||
}
|
||||
|
||||
export interface Log {
|
||||
blockNumber?: number;
|
||||
blockHash?: string;
|
||||
transactionIndex?: number;
|
||||
|
||||
removed?: boolean;
|
||||
|
||||
transactionLogIndex?: number,
|
||||
|
||||
address: string;
|
||||
data: string;
|
||||
|
||||
topics: Array<string>;
|
||||
|
||||
transactionHash?: string;
|
||||
logIndex?: number;
|
||||
}
|
||||
|
||||
export interface TransactionReceipt {
|
||||
contractAddress?: string,
|
||||
transactionIndex?: number,
|
||||
root?: string,
|
||||
gasUsed?: BigNumber,
|
||||
logsBloom?: string,
|
||||
blockHash?: string,
|
||||
transactionHash?: string,
|
||||
logs?: Array<Log>,
|
||||
blockNumber?: number,
|
||||
cumulativeGasUsed?: BigNumber,
|
||||
byzantium: boolean,
|
||||
status?: number
|
||||
};
|
||||
|
||||
export type TransactionRequest = {
|
||||
to?: string | Promise<string>,
|
||||
from?: string | Promise<string>,
|
||||
nonce?: number | string | Promise<number | string>,
|
||||
|
||||
gasLimit?: BigNumberish | Promise<BigNumberish>,
|
||||
gasPrice?: BigNumberish | Promise<BigNumberish>,
|
||||
|
||||
data?: Arrayish | Promise<Arrayish>,
|
||||
value?: BigNumberish | Promise<BigNumberish>,
|
||||
chainId?: number | Promise<number>,
|
||||
}
|
||||
|
||||
export interface TransactionResponse extends Transaction {
|
||||
// Only if a transaction has been mined
|
||||
blockNumber?: number,
|
||||
blockHash?: string,
|
||||
timestamp?: number,
|
||||
|
||||
// Not optional (as it is in Transaction)
|
||||
from: string;
|
||||
|
||||
// The raw transaction
|
||||
raw?: string,
|
||||
|
||||
// This function waits until the transaction has been mined
|
||||
wait: (timeout?: number) => Promise<TransactionReceipt>
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Interface
|
||||
|
||||
export class Indexed {
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export interface DeployDescription {
|
||||
type: "deploy";
|
||||
inputs: Array<ParamType>;
|
||||
payable: boolean;
|
||||
encode(bytecode: string, params: Array<any>): string;
|
||||
}
|
||||
|
||||
export interface FunctionDescription {
|
||||
type: "call" | "transaction";
|
||||
name: string;
|
||||
signature: string;
|
||||
sighash: string;
|
||||
inputs: Array<ParamType>;
|
||||
outputs: Array<ParamType>;
|
||||
payable: boolean;
|
||||
encode(params: Array<any>): string;
|
||||
decode(data: string): any;
|
||||
}
|
||||
|
||||
export interface EventDescription {
|
||||
type: "event";
|
||||
name: string;
|
||||
signature: string;
|
||||
inputs: Array<ParamType>;
|
||||
anonymous: boolean;
|
||||
topic: string;
|
||||
encodeTopics(params: Array<any>): Array<string>;
|
||||
decode(data: string, topics?: Array<string>): any;
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// Contract
|
||||
|
||||
export type EventFilter = {
|
||||
address?: string;
|
||||
topics?: Array<string>;
|
||||
// @TODO: Support OR-style topcis; backwards compatible to make this change
|
||||
//topics?: Array<string | Array<string>>
|
||||
};
|
||||
|
||||
// The (n + 1)th parameter passed to contract event callbacks
|
||||
export interface Event extends Log {
|
||||
args: Array<any>;
|
||||
decode: (data: string, topics?: Array<string>) => any;
|
||||
event: string;
|
||||
eventSignature: string;
|
||||
|
||||
removeListener: () => void;
|
||||
|
||||
getBlock: () => Promise<Block>;
|
||||
getTransaction: () => Promise<TransactionResponse>;
|
||||
getTransactionReceipt: () => Promise<TransactionReceipt>;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Provider
|
||||
|
||||
export type EventType = string | Array<string> | Filter;
|
||||
|
||||
export type Listener = (...args: Array<any>) => void;
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* Note: We use an abstract class so we can use instanceof to determine if an
|
||||
* object is a Provider.
|
||||
*/
|
||||
export abstract class MinimalProvider {
|
||||
abstract getNetwork(): Promise<Network>;
|
||||
|
||||
abstract getBlockNumber(): Promise<number>;
|
||||
abstract getGasPrice(): Promise<BigNumber>;
|
||||
|
||||
abstract getBalance(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<BigNumber>;
|
||||
abstract getTransactionCount(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<number>;
|
||||
abstract getCode(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string> ;
|
||||
abstract getStorageAt(addressOrName: string | Promise<string>, position: BigNumberish | Promise<BigNumberish>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string>;
|
||||
|
||||
abstract sendTransaction(signedTransaction: string | Promise<string>): Promise<TransactionResponse>;
|
||||
abstract call(transaction: TransactionRequest): Promise<string>;
|
||||
abstract estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
||||
|
||||
abstract getBlock(blockHashOrBlockTag: BlockTag | string | Promise<BlockTag | string>): Promise<Block>;
|
||||
abstract getTransaction(transactionHash: string): Promise<TransactionResponse>;
|
||||
abstract getTransactionReceipt(transactionHash: string): Promise<TransactionReceipt>;
|
||||
|
||||
abstract getLogs(filter: Filter): Promise<Array<Log>>;
|
||||
|
||||
abstract resolveName(name: string | Promise<string>): Promise<string>;
|
||||
abstract lookupAddress(address: string | Promise<string>): Promise<string>;
|
||||
|
||||
abstract on(eventName: EventType, listener: Listener): MinimalProvider;
|
||||
abstract once(eventName: EventType, listener: Listener): MinimalProvider;
|
||||
abstract listenerCount(eventName?: EventType): number;
|
||||
abstract listeners(eventName: EventType): Array<Listener>;
|
||||
abstract removeAllListeners(eventName: EventType): MinimalProvider;
|
||||
abstract removeListener(eventName: EventType, listener: Listener): MinimalProvider;
|
||||
|
||||
// @TODO: This *could* be implemented here, but would pull in events...
|
||||
abstract waitForTransaction(transactionHash: string, timeout?: number): Promise<TransactionReceipt>;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
// Signer
|
||||
|
||||
export type ProgressCallback = (percent: number) => void;
|
||||
|
||||
export type EncryptOptions = {
|
||||
iv?: Arrayish;
|
||||
entropy?: Arrayish;
|
||||
mnemonic?: string;
|
||||
path?: string;
|
||||
client?: string;
|
||||
salt?: Arrayish;
|
||||
uuid?: string;
|
||||
scrypt?: {
|
||||
N?: number;
|
||||
r?: number;
|
||||
p?: number;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signer
|
||||
*
|
||||
* Note: We use an abstract class so we can use instanceof to determine if an
|
||||
* object is a Signer.
|
||||
*/
|
||||
export abstract class Signer {
|
||||
provider?: MinimalProvider;
|
||||
|
||||
abstract getAddress(): Promise<string>
|
||||
|
||||
abstract signMessage(transaction: Arrayish | string): Promise<string>;
|
||||
abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||
}
|
||||
|
@ -111,6 +111,10 @@ export function parseUnits(value: string, unitType?: string | number): BigNumber
|
||||
// Remove commas
|
||||
var value = value.replace(/,/g,'');
|
||||
|
||||
if (unitInfo.decimals === 0) {
|
||||
return bigNumberify(value);
|
||||
}
|
||||
|
||||
// Is it negative?
|
||||
var negative = (value.substring(0, 1) === '-');
|
||||
if (negative) { value = value.substring(1); }
|
||||
|
@ -1,22 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
import { XMLHttpRequest } from 'xmlhttprequest';
|
||||
import { toUtf8Bytes } from './utf8';
|
||||
import { encode as base64Encode } from './base64';
|
||||
|
||||
export type ConnectionInfo = {
|
||||
url: string,
|
||||
user?: string,
|
||||
password?: string,
|
||||
allowInsecure?: boolean
|
||||
};
|
||||
import { encode as base64Encode } from './base64';
|
||||
import { toUtf8Bytes } from './utf8';
|
||||
|
||||
import { ConnectionInfo } from './types';
|
||||
export { ConnectionInfo };
|
||||
|
||||
import * as errors from './errors';
|
||||
|
||||
export type ProcessFunc = (value: any) => any;
|
||||
|
||||
type Header = { key: string, value: string };
|
||||
|
||||
export function fetchJson(connection: string | ConnectionInfo, json: string, processFunc: ProcessFunc): Promise<any> {
|
||||
export function fetchJson(connection: string | ConnectionInfo, json: string, processFunc: (value: any) => any): Promise<any> {
|
||||
let headers: Array<Header> = [ ];
|
||||
|
||||
let url: string = null;
|
||||
|
@ -4,6 +4,7 @@ import { Wallet } from './wallet';
|
||||
import * as HDNode from './hdnode';
|
||||
import { SigningKey } from './signing-key';
|
||||
|
||||
|
||||
export { HDNode, SigningKey, Wallet };
|
||||
|
||||
export default { HDNode, SigningKey, Wallet };
|
||||
|
@ -4,21 +4,17 @@ import aes from 'aes-js';
|
||||
import scrypt from 'scrypt-js';
|
||||
import uuid from 'uuid';
|
||||
|
||||
import { SigningKey } from './signing-key';
|
||||
import * as HDNode from './hdnode';
|
||||
|
||||
import { getAddress } from '../utils/address';
|
||||
import { arrayify, Arrayish, concat, hexlify } from '../utils/bytes';
|
||||
|
||||
import { pbkdf2 } from '../utils/pbkdf2';
|
||||
import { keccak256 } from '../utils/keccak256';
|
||||
import { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';
|
||||
import { randomBytes } from '../utils/random-bytes';
|
||||
|
||||
import { SigningKey } from './signing-key';
|
||||
import * as HDNode from './hdnode';
|
||||
|
||||
|
||||
export interface ProgressCallback {
|
||||
(percent: number): void
|
||||
}
|
||||
import { EncryptOptions, ProgressCallback } from '../utils/types';
|
||||
|
||||
function looseArrayify(hexString: string): Uint8Array {
|
||||
if (typeof(hexString) === 'string' && hexString.substring(0, 2) !== '0x') {
|
||||
@ -230,6 +226,7 @@ export function decrypt(json: string, password: Arrayish, progressCallback?: Pro
|
||||
return;
|
||||
}
|
||||
|
||||
if (progressCallback) { progressCallback(0); }
|
||||
scrypt(passwordBytes, salt, N, r, p, 64, function(error, progress, key) {
|
||||
if (error) {
|
||||
error.progress = progress;
|
||||
@ -288,21 +285,6 @@ export function decrypt(json: string, password: Arrayish, progressCallback?: Pro
|
||||
});
|
||||
}
|
||||
|
||||
export type EncryptOptions = {
|
||||
iv?: Arrayish;
|
||||
entropy?: Arrayish;
|
||||
mnemonic?: string;
|
||||
path?: string;
|
||||
client?: string;
|
||||
salt?: Arrayish;
|
||||
uuid?: string;
|
||||
scrypt?: {
|
||||
N?: number;
|
||||
r?: number;
|
||||
p?: number;
|
||||
}
|
||||
}
|
||||
|
||||
export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: EncryptOptions, progressCallback?: ProgressCallback): Promise<string> {
|
||||
|
||||
// the options are optional, so adjust the call as needed
|
||||
@ -382,6 +364,7 @@ export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish |
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (progressCallback) { progressCallback(0); }
|
||||
|
||||
// We take 64 bytes:
|
||||
// - 32 bytes As normal for the Web3 secret storage (derivedKey, macPrefix)
|
||||
|
@ -2,10 +2,9 @@
|
||||
|
||||
import { defaultPath, entropyToMnemonic, fromMnemonic, HDNode } from './hdnode';
|
||||
import * as secretStorage from './secret-storage';
|
||||
import { ProgressCallback } from './secret-storage';
|
||||
import { SigningKey } from './signing-key';
|
||||
|
||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from '../providers/provider';
|
||||
import { Provider } from '../providers/provider';
|
||||
import { Wordlist } from '../wordlists/wordlist';
|
||||
|
||||
import { BigNumber } from '../utils/bignumber';
|
||||
@ -17,17 +16,11 @@ import { randomBytes } from '../utils/random-bytes';
|
||||
import { recoverAddress } from '../utils/secp256k1';
|
||||
import { serialize as serializeTransaction } from '../utils/transaction';
|
||||
|
||||
import { BlockTag, ProgressCallback, Signer, TransactionRequest, TransactionResponse } from '../utils/types';
|
||||
export { BlockTag, ProgressCallback, Signer, TransactionRequest, TransactionResponse };
|
||||
|
||||
import * as errors from '../utils/errors';
|
||||
|
||||
export abstract class Signer {
|
||||
provider?: Provider;
|
||||
|
||||
abstract getAddress(): Promise<string>
|
||||
|
||||
abstract signMessage(transaction: Arrayish | string): Promise<string>;
|
||||
abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||
}
|
||||
|
||||
|
||||
export class Wallet extends Signer {
|
||||
|
||||
@ -171,7 +164,9 @@ export class Wallet extends Signer {
|
||||
static fromEncryptedJson(json: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet> {
|
||||
if (secretStorage.isCrowdsaleWallet(json)) {
|
||||
try {
|
||||
if (progressCallback) { progressCallback(0); }
|
||||
let privateKey = secretStorage.decryptCrowdsale(json, password);
|
||||
if (progressCallback) { progressCallback(1); }
|
||||
return Promise.resolve(new Wallet(privateKey));
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
|
Loading…
x
Reference in New Issue
Block a user