Refactoring.
This commit is contained in:
parent
c1b24e818c
commit
5da4917c27
465
dist/ethers.d.ts
vendored
465
dist/ethers.d.ts
vendored
@ -3,10 +3,8 @@ declare module "utils/keccak256" {
|
|||||||
export function keccak256(data: Arrayish): string;
|
export function keccak256(data: Arrayish): string;
|
||||||
}
|
}
|
||||||
declare module "utils/properties" {
|
declare module "utils/properties" {
|
||||||
export function defineReadOnly(object: any, name: any, value: any): void;
|
export function defineReadOnly(object: any, name: string, value: any): void;
|
||||||
export function defineFrozen(object: any, name: any, value: any): void;
|
export function defineFrozen(object: any, name: string, value: any): void;
|
||||||
export type DeferredSetter = (value: any) => void;
|
|
||||||
export function defineDeferredReadOnly(object: any, name: any, value: any): DeferredSetter;
|
|
||||||
export function resolveProperties(object: any): Promise<any>;
|
export function resolveProperties(object: any): Promise<any>;
|
||||||
export function shallowCopy(object: any): any;
|
export function shallowCopy(object: any): any;
|
||||||
export function jsonCopy(object: any): any;
|
export function jsonCopy(object: any): any;
|
||||||
@ -66,6 +64,7 @@ declare module "utils/bytes" {
|
|||||||
export function hexStripZeros(value: string): string;
|
export function hexStripZeros(value: string): string;
|
||||||
export function hexZeroPad(value: string, length: number): string;
|
export function hexZeroPad(value: string, length: number): string;
|
||||||
export function splitSignature(signature: Arrayish): Signature;
|
export function splitSignature(signature: Arrayish): Signature;
|
||||||
|
export function joinSignature(signature: Signature): string;
|
||||||
}
|
}
|
||||||
declare module "utils/bignumber" {
|
declare module "utils/bignumber" {
|
||||||
import { Arrayish } from "utils/bytes";
|
import { Arrayish } from "utils/bytes";
|
||||||
@ -167,15 +166,13 @@ declare module "contracts/interface" {
|
|||||||
import { BigNumber, BigNumberish } from "utils/bignumber";
|
import { BigNumber, BigNumberish } from "utils/bignumber";
|
||||||
export class Description {
|
export class Description {
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
readonly inputs: Array<ParamType>;
|
|
||||||
constructor(info: any);
|
constructor(info: any);
|
||||||
}
|
}
|
||||||
export class Indexed {
|
export class Indexed extends Description {
|
||||||
readonly type: string;
|
|
||||||
readonly hash: string;
|
readonly hash: string;
|
||||||
constructor(value: string);
|
|
||||||
}
|
}
|
||||||
export class DeployDescription extends Description {
|
export class DeployDescription extends Description {
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly payable: boolean;
|
readonly payable: boolean;
|
||||||
encode(bytecode: string, params: Array<any>): string;
|
encode(bytecode: string, params: Array<any>): string;
|
||||||
}
|
}
|
||||||
@ -183,25 +180,34 @@ declare module "contracts/interface" {
|
|||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly signature: string;
|
readonly signature: string;
|
||||||
readonly sighash: string;
|
readonly sighash: string;
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly outputs: Array<ParamType>;
|
readonly outputs: Array<ParamType>;
|
||||||
readonly payable: boolean;
|
readonly payable: boolean;
|
||||||
encode(params: Array<any>): string;
|
encode(params: Array<any>): string;
|
||||||
decode(data: string): any;
|
decode(data: string): any;
|
||||||
}
|
}
|
||||||
export type CallTransaction = {
|
|
||||||
args: Array<any>;
|
|
||||||
signature: string;
|
|
||||||
sighash: string;
|
|
||||||
decode: (data: string) => any;
|
|
||||||
value: BigNumber;
|
|
||||||
};
|
|
||||||
export class EventDescription extends Description {
|
export class EventDescription extends Description {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly signature: string;
|
readonly signature: string;
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly anonymous: boolean;
|
readonly anonymous: boolean;
|
||||||
readonly topic: string;
|
readonly topic: string;
|
||||||
decode(data: string, topics?: Array<string>): any;
|
decode(data: string, topics?: Array<string>): any;
|
||||||
}
|
}
|
||||||
|
class TransactionDescription extends Description {
|
||||||
|
readonly name: string;
|
||||||
|
readonly args: Array<any>;
|
||||||
|
readonly signature: string;
|
||||||
|
readonly sighash: string;
|
||||||
|
readonly decode: (data: string) => any;
|
||||||
|
readonly value: BigNumber;
|
||||||
|
}
|
||||||
|
class LogDescription extends Description {
|
||||||
|
readonly name: string;
|
||||||
|
readonly signature: string;
|
||||||
|
readonly topic: string;
|
||||||
|
readonly values: Array<any>;
|
||||||
|
}
|
||||||
export class Interface {
|
export class Interface {
|
||||||
readonly abi: Array<any>;
|
readonly abi: Array<any>;
|
||||||
readonly functions: Array<FunctionDescription>;
|
readonly functions: Array<FunctionDescription>;
|
||||||
@ -211,69 +217,105 @@ declare module "contracts/interface" {
|
|||||||
parseTransaction(tx: {
|
parseTransaction(tx: {
|
||||||
data: string;
|
data: string;
|
||||||
value?: BigNumberish;
|
value?: BigNumberish;
|
||||||
}): CallTransaction;
|
}): TransactionDescription;
|
||||||
|
parseLog(log: {
|
||||||
|
topics: Array<string>;
|
||||||
|
data: string;
|
||||||
|
}): LogDescription;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module "utils/namehash" {
|
declare module "wallet/words" {
|
||||||
export function namehash(name: string): string;
|
export function getWord(index: number): string;
|
||||||
|
export function getWordIndex(word: string): number;
|
||||||
}
|
}
|
||||||
declare module "providers/networks" {
|
declare module "utils/hmac" {
|
||||||
export type Network = {
|
import { Arrayish } from "utils/bytes";
|
||||||
name: string;
|
interface HashFunc {
|
||||||
chainId: number;
|
(): HashFunc;
|
||||||
ensAddress?: string;
|
update(chunk: Uint8Array): HashFunc;
|
||||||
};
|
digest(encoding: string): string;
|
||||||
export const networks: {
|
digest(): Uint8Array;
|
||||||
"unspecified": {
|
}
|
||||||
"chainId": number;
|
export interface HmacFunc extends HashFunc {
|
||||||
"name": string;
|
(hashFunc: HashFunc, key: Arrayish): HmacFunc;
|
||||||
};
|
}
|
||||||
"homestead": {
|
export function createSha256Hmac(key: Arrayish): HmacFunc;
|
||||||
"chainId": number;
|
export function createSha512Hmac(key: Arrayish): HmacFunc;
|
||||||
"ensAddress": string;
|
}
|
||||||
"name": string;
|
declare module "utils/pbkdf2" {
|
||||||
};
|
import { Arrayish } from "utils/bytes";
|
||||||
"mainnet": {
|
import { HmacFunc } from "utils/hmac";
|
||||||
"chainId": number;
|
export interface CreateHmacFunc {
|
||||||
"ensAddress": string;
|
(key: Arrayish): HmacFunc;
|
||||||
"name": string;
|
}
|
||||||
};
|
export function pbkdf2(password: Arrayish, salt: Arrayish, iterations: number, keylen: number, createHmac: CreateHmacFunc): Uint8Array;
|
||||||
"morden": {
|
}
|
||||||
"chainId": number;
|
declare module "utils/sha2" {
|
||||||
"name": string;
|
import { Arrayish } from "utils/bytes";
|
||||||
};
|
export function sha256(data: Arrayish): string;
|
||||||
"ropsten": {
|
export function sha512(data: Arrayish): string;
|
||||||
"chainId": number;
|
}
|
||||||
"ensAddress": string;
|
declare module "wallet/hdnode" {
|
||||||
"name": string;
|
import { Arrayish } from "utils/bytes";
|
||||||
};
|
import { KeyPair } from "utils/secp256k1";
|
||||||
"testnet": {
|
export const defaultPath = "m/44'/60'/0'/0/0";
|
||||||
"chainId": number;
|
export class HDNode {
|
||||||
"ensAddress": string;
|
private readonly keyPair;
|
||||||
"name": string;
|
readonly privateKey: string;
|
||||||
};
|
readonly publicKey: string;
|
||||||
"rinkeby": {
|
readonly mnemonic: string;
|
||||||
"chainId": number;
|
readonly path: string;
|
||||||
"name": string;
|
readonly chainCode: string;
|
||||||
};
|
readonly index: number;
|
||||||
"kovan": {
|
readonly depth: number;
|
||||||
"chainId": number;
|
constructor(keyPair: KeyPair, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string);
|
||||||
"name": string;
|
private _derive;
|
||||||
};
|
derivePath(path: string): HDNode;
|
||||||
"classic": {
|
}
|
||||||
"chainId": number;
|
export function fromMnemonic(mnemonic: string): HDNode;
|
||||||
"name": string;
|
export function fromSeed(seed: Arrayish): HDNode;
|
||||||
};
|
export function mnemonicToSeed(mnemonic: string, password?: string): string;
|
||||||
};
|
export function mnemonicToEntropy(mnemonic: string): string;
|
||||||
/**
|
export function entropyToMnemonic(entropy: Arrayish): string;
|
||||||
* getNetwork
|
export function isValidMnemonic(mnemonic: string): boolean;
|
||||||
*
|
}
|
||||||
* If the network is a the name of a common network, return that network.
|
declare module "utils/random-bytes" {
|
||||||
* Otherwise, if it is a network object, verify the chain ID is valid
|
export function randomBytes(length: number): Uint8Array;
|
||||||
* for that network. Otherwise, return the network.
|
}
|
||||||
*
|
declare module "wallet/signing-key" {
|
||||||
*/
|
import { Arrayish } from "utils/bytes";
|
||||||
export function getNetwork(network: Network | string | number): Network;
|
import { HDNode } from "wallet/hdnode";
|
||||||
|
import { Signature } from "utils/secp256k1";
|
||||||
|
export class SigningKey {
|
||||||
|
readonly privateKey: string;
|
||||||
|
readonly publicKey: string;
|
||||||
|
readonly address: string;
|
||||||
|
readonly mnemonic: string;
|
||||||
|
readonly path: string;
|
||||||
|
private readonly keyPair;
|
||||||
|
constructor(privateKey: Arrayish | HDNode);
|
||||||
|
signDigest(digest: Arrayish): Signature;
|
||||||
|
}
|
||||||
|
export function recoverAddress(digest: Arrayish, signature: Signature): string;
|
||||||
|
export function computeAddress(key: string): string;
|
||||||
|
}
|
||||||
|
declare module "wallet/secret-storage" {
|
||||||
|
import { Arrayish } from "utils/bytes";
|
||||||
|
import { SigningKey } from "wallet/signing-key";
|
||||||
|
export interface ProgressCallback {
|
||||||
|
(percent: number): void;
|
||||||
|
}
|
||||||
|
export function isCrowdsaleWallet(json: string): boolean;
|
||||||
|
export function isValidWallet(json: string): boolean;
|
||||||
|
export function decryptCrowdsale(json: string, password: Arrayish | string): SigningKey;
|
||||||
|
export function decrypt(json: string, password: any, progressCallback?: ProgressCallback): Promise<SigningKey>;
|
||||||
|
export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: any, progressCallback?: ProgressCallback): Promise<string>;
|
||||||
|
}
|
||||||
|
declare module "utils/hash" {
|
||||||
|
import { Arrayish } from "utils/bytes";
|
||||||
|
export function namehash(name: string): string;
|
||||||
|
export function id(text: string): string;
|
||||||
|
export function hashMessage(message: Arrayish | string): string;
|
||||||
}
|
}
|
||||||
declare module "utils/transaction" {
|
declare module "utils/transaction" {
|
||||||
import { BigNumber, BigNumberish } from "utils/bignumber";
|
import { BigNumber, BigNumberish } from "utils/bignumber";
|
||||||
@ -306,11 +348,68 @@ declare module "utils/transaction" {
|
|||||||
export function sign(transaction: UnsignedTransaction, signDigest: SignDigestFunc): string;
|
export function sign(transaction: UnsignedTransaction, signDigest: SignDigestFunc): string;
|
||||||
export function parse(rawTransaction: Arrayish): Transaction;
|
export function parse(rawTransaction: Arrayish): Transaction;
|
||||||
}
|
}
|
||||||
declare module "providers/provider" {
|
declare module "wallet/wallet" {
|
||||||
|
import { HDNode } from "wallet/hdnode";
|
||||||
|
import { ProgressCallback } from "wallet/secret-storage";
|
||||||
|
import { SigningKey } from "wallet/signing-key";
|
||||||
|
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from "providers/provider";
|
||||||
import { BigNumber, BigNumberish } from "utils/bignumber";
|
import { BigNumber, BigNumberish } from "utils/bignumber";
|
||||||
import { Arrayish } from "utils/bytes";
|
import { Arrayish } from "utils/bytes";
|
||||||
import { Network } from "providers/networks";
|
export abstract class Signer {
|
||||||
import { Transaction } from "utils/transaction";
|
provider?: Provider;
|
||||||
|
abstract getAddress(): Promise<string>;
|
||||||
|
abstract signMessage(transaction: Arrayish | string): Promise<string>;
|
||||||
|
abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
|
}
|
||||||
|
export class Wallet extends Signer {
|
||||||
|
readonly address: string;
|
||||||
|
readonly privateKey: string;
|
||||||
|
readonly provider: Provider;
|
||||||
|
private mnemonic;
|
||||||
|
private path;
|
||||||
|
private readonly signingKey;
|
||||||
|
defaultGasLimit: number;
|
||||||
|
constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider);
|
||||||
|
connect(provider: Provider): Wallet;
|
||||||
|
getAddress(): Promise<string>;
|
||||||
|
sign(transaction: TransactionRequest): Promise<string>;
|
||||||
|
signMessage(message: Arrayish | string): Promise<string>;
|
||||||
|
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
||||||
|
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
||||||
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
|
send(addressOrName: string, amountWei: BigNumberish, options: any): Promise<TransactionResponse>;
|
||||||
|
encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string>;
|
||||||
|
static createRandom(options: any): Wallet;
|
||||||
|
static isEncryptedWallet(json: string): boolean;
|
||||||
|
static fromEncryptedWallet(json: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet>;
|
||||||
|
static fromMnemonic(mnemonic: string, path?: string): Wallet;
|
||||||
|
static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback: ProgressCallback): Promise<Wallet>;
|
||||||
|
static verifyMessage(message: Arrayish | string, signature: string): string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare module "providers/networks" {
|
||||||
|
export type Network = {
|
||||||
|
name: string;
|
||||||
|
chainId: number;
|
||||||
|
ensAddress?: string;
|
||||||
|
};
|
||||||
|
export type Networkish = Network | string | number;
|
||||||
|
/**
|
||||||
|
* getNetwork
|
||||||
|
*
|
||||||
|
* If the network is a the name of a common network, return that network.
|
||||||
|
* Otherwise, if it is a network object, verify the chain ID is valid
|
||||||
|
* for that network. Otherwise, return the network.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function getNetwork(network: Networkish): Network;
|
||||||
|
}
|
||||||
|
declare module "providers/provider" {
|
||||||
|
import { Signer } from "wallet/wallet";
|
||||||
|
import { BigNumber, BigNumberish } from "utils/bignumber";
|
||||||
|
import { Arrayish } from "utils/bytes";
|
||||||
|
import { Network, Networkish } from "providers/networks";
|
||||||
|
import { SignDigestFunc, Transaction } from "utils/transaction";
|
||||||
export type BlockTag = string | number;
|
export type BlockTag = string | number;
|
||||||
export interface Block {
|
export interface Block {
|
||||||
hash: string;
|
hash: string;
|
||||||
@ -318,7 +417,7 @@ declare module "providers/provider" {
|
|||||||
number: number;
|
number: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
nonce: string;
|
nonce: string;
|
||||||
difficulty: string;
|
difficulty: number;
|
||||||
gasLimit: BigNumber;
|
gasLimit: BigNumber;
|
||||||
gasUsed: BigNumber;
|
gasUsed: BigNumber;
|
||||||
miner: string;
|
miner: string;
|
||||||
@ -373,6 +472,17 @@ declare module "providers/provider" {
|
|||||||
logIndex?: number;
|
logIndex?: number;
|
||||||
}
|
}
|
||||||
export function checkTransactionResponse(transaction: any): TransactionResponse;
|
export function checkTransactionResponse(transaction: any): TransactionResponse;
|
||||||
|
export class ProviderSigner extends Signer {
|
||||||
|
readonly provider: Provider;
|
||||||
|
readonly signDigest: SignDigestFunc;
|
||||||
|
private _addressPromise;
|
||||||
|
constructor(address: string | Promise<string>, signDigest: SignDigestFunc, provider: Provider);
|
||||||
|
getAddress(): Promise<string>;
|
||||||
|
signMessage(message: Arrayish | string): Promise<string>;
|
||||||
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
|
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
||||||
|
call(transaction: TransactionRequest): Promise<string>;
|
||||||
|
}
|
||||||
export class Provider {
|
export class Provider {
|
||||||
private _network;
|
private _network;
|
||||||
private _events;
|
private _events;
|
||||||
@ -391,7 +501,7 @@ declare module "providers/provider" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected ready: Promise<Network>;
|
protected ready: Promise<Network>;
|
||||||
constructor(network: string | Network);
|
constructor(network: Networkish | Promise<Network>);
|
||||||
private _doPoll;
|
private _doPoll;
|
||||||
resetEventsBlock(blockNumber: number): void;
|
resetEventsBlock(blockNumber: number): void;
|
||||||
readonly network: Network;
|
readonly network: Network;
|
||||||
@ -431,138 +541,6 @@ declare module "providers/provider" {
|
|||||||
removeListener(eventName: any, listener: any): Provider;
|
removeListener(eventName: any, listener: any): Provider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module "wallet/words" {
|
|
||||||
export function getWord(index: number): string;
|
|
||||||
export function getWordIndex(word: string): number;
|
|
||||||
}
|
|
||||||
declare module "utils/hmac" {
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
interface HashFunc {
|
|
||||||
(): HashFunc;
|
|
||||||
update(chunk: Uint8Array): HashFunc;
|
|
||||||
digest(encoding: string): string;
|
|
||||||
digest(): Uint8Array;
|
|
||||||
}
|
|
||||||
export interface HmacFunc extends HashFunc {
|
|
||||||
(hashFunc: HashFunc, key: Arrayish): HmacFunc;
|
|
||||||
}
|
|
||||||
export function createSha256Hmac(key: Arrayish): HmacFunc;
|
|
||||||
export function createSha512Hmac(key: Arrayish): HmacFunc;
|
|
||||||
}
|
|
||||||
declare module "utils/pbkdf2" {
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
import { HmacFunc } from "utils/hmac";
|
|
||||||
export interface CreateHmacFunc {
|
|
||||||
(key: Arrayish): HmacFunc;
|
|
||||||
}
|
|
||||||
export function pbkdf2(password: Arrayish, salt: Arrayish, iterations: number, keylen: number, createHmac: CreateHmacFunc): Uint8Array;
|
|
||||||
}
|
|
||||||
declare module "utils/sha2" {
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
export function sha256(data: Arrayish): string;
|
|
||||||
export function sha512(data: Arrayish): string;
|
|
||||||
}
|
|
||||||
declare module "wallet/hdnode" {
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
import { KeyPair } from "utils/secp256k1";
|
|
||||||
export class HDNode {
|
|
||||||
private readonly keyPair;
|
|
||||||
readonly privateKey: string;
|
|
||||||
readonly publicKey: string;
|
|
||||||
readonly mnemonic: string;
|
|
||||||
readonly path: string;
|
|
||||||
readonly chainCode: string;
|
|
||||||
readonly index: number;
|
|
||||||
readonly depth: number;
|
|
||||||
constructor(keyPair: KeyPair, chainCode: Uint8Array, index: number, depth: number, mnemonic: string, path: string);
|
|
||||||
private _derive;
|
|
||||||
derivePath(path: string): HDNode;
|
|
||||||
}
|
|
||||||
export function fromMnemonic(mnemonic: string): HDNode;
|
|
||||||
export function fromSeed(seed: Arrayish): HDNode;
|
|
||||||
export function mnemonicToSeed(mnemonic: string, password?: string): string;
|
|
||||||
export function mnemonicToEntropy(mnemonic: string): string;
|
|
||||||
export function entropyToMnemonic(entropy: Arrayish): string;
|
|
||||||
export function isValidMnemonic(mnemonic: string): boolean;
|
|
||||||
}
|
|
||||||
declare module "utils/random-bytes" {
|
|
||||||
export function randomBytes(length: number): Uint8Array;
|
|
||||||
}
|
|
||||||
declare module "wallet/signing-key" {
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
import { HDNode } from "wallet/hdnode";
|
|
||||||
import { Signature } from "utils/secp256k1";
|
|
||||||
export class SigningKey {
|
|
||||||
readonly privateKey: string;
|
|
||||||
readonly publicKey: string;
|
|
||||||
readonly address: string;
|
|
||||||
readonly mnemonic: string;
|
|
||||||
readonly path: string;
|
|
||||||
private readonly keyPair;
|
|
||||||
constructor(privateKey: Arrayish | HDNode);
|
|
||||||
signDigest(digest: Arrayish): Signature;
|
|
||||||
}
|
|
||||||
export function recoverAddress(digest: Arrayish, signature: Signature): string;
|
|
||||||
export function computeAddress(key: string): string;
|
|
||||||
}
|
|
||||||
declare module "wallet/secret-storage" {
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
import { SigningKey } from "wallet/signing-key";
|
|
||||||
export interface ProgressCallback {
|
|
||||||
(percent: number): void;
|
|
||||||
}
|
|
||||||
export function isCrowdsaleWallet(json: string): boolean;
|
|
||||||
export function isValidWallet(json: string): boolean;
|
|
||||||
export function decryptCrowdsale(json: string, password: Arrayish | string): SigningKey;
|
|
||||||
export function decrypt(json: string, password: any, progressCallback?: ProgressCallback): Promise<SigningKey>;
|
|
||||||
export function encrypt(privateKey: Arrayish | SigningKey, password: Arrayish | string, options?: any, progressCallback?: ProgressCallback): Promise<string>;
|
|
||||||
}
|
|
||||||
declare module "wallet/wallet" {
|
|
||||||
import { HDNode } from "wallet/hdnode";
|
|
||||||
import { ProgressCallback } from "wallet/secret-storage";
|
|
||||||
import { SigningKey } from "wallet/signing-key";
|
|
||||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from "providers/provider";
|
|
||||||
import { BigNumber, BigNumberish } from "utils/bignumber";
|
|
||||||
import { Arrayish } from "utils/bytes";
|
|
||||||
import { UnsignedTransaction } from "utils/transaction";
|
|
||||||
export interface Signer {
|
|
||||||
address?: string;
|
|
||||||
getAddress(): Promise<string>;
|
|
||||||
sendTransaction(transaction: UnsignedTransaction): Promise<TransactionResponse>;
|
|
||||||
provider: Provider;
|
|
||||||
sign(transaction: UnsignedTransaction): string;
|
|
||||||
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
|
||||||
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
|
||||||
getGasPrice(transaction?: TransactionRequest): Promise<BigNumber>;
|
|
||||||
}
|
|
||||||
export class Wallet implements Signer {
|
|
||||||
readonly address: string;
|
|
||||||
readonly privateKey: string;
|
|
||||||
private mnemonic;
|
|
||||||
private path;
|
|
||||||
private readonly signingKey;
|
|
||||||
provider: Provider;
|
|
||||||
defaultGasLimit: number;
|
|
||||||
constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider);
|
|
||||||
sign(transaction: UnsignedTransaction): string;
|
|
||||||
getAddress(): Promise<string>;
|
|
||||||
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
|
||||||
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
|
||||||
getGasPrice(): Promise<BigNumber>;
|
|
||||||
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
|
||||||
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
|
||||||
send(addressOrName: string, amountWei: BigNumberish, options: any): Promise<TransactionResponse>;
|
|
||||||
static hashMessage(message: Arrayish | string): string;
|
|
||||||
signMessage(message: Arrayish | string): string;
|
|
||||||
static verifyMessage(message: Arrayish | string, signature: string): string;
|
|
||||||
encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string>;
|
|
||||||
static createRandom(options: any): Wallet;
|
|
||||||
static isEncryptedWallet(json: string): boolean;
|
|
||||||
static fromEncryptedWallet(json: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet>;
|
|
||||||
static fromMnemonic(mnemonic: string, path?: string): Wallet;
|
|
||||||
static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback: ProgressCallback): Promise<Wallet>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
declare module "contracts/contract" {
|
declare module "contracts/contract" {
|
||||||
import { Interface } from "contracts/interface";
|
import { Interface } from "contracts/interface";
|
||||||
import { Provider, TransactionResponse } from "providers/provider";
|
import { Provider, TransactionResponse } from "providers/provider";
|
||||||
@ -613,11 +591,11 @@ declare module "utils/web" {
|
|||||||
}
|
}
|
||||||
declare module "providers/etherscan-provider" {
|
declare module "providers/etherscan-provider" {
|
||||||
import { Provider } from "providers/provider";
|
import { Provider } from "providers/provider";
|
||||||
import { Network } from "providers/networks";
|
import { Networkish } from "providers/networks";
|
||||||
export class EtherscanProvider extends Provider {
|
export class EtherscanProvider extends Provider {
|
||||||
readonly baseUrl: string;
|
readonly baseUrl: string;
|
||||||
readonly apiKey: string;
|
readonly apiKey: string;
|
||||||
constructor(network?: Network | string, apiKey?: string);
|
constructor(network?: Networkish, apiKey?: string);
|
||||||
perform(method: string, params: any): Promise<any>;
|
perform(method: string, params: any): Promise<any>;
|
||||||
getHistory(addressOrName: any, startBlock: any, endBlock: any): Promise<any[]>;
|
getHistory(addressOrName: any, startBlock: any, endBlock: any): Promise<any[]>;
|
||||||
}
|
}
|
||||||
@ -632,13 +610,14 @@ declare module "providers/fallback-provider" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module "providers/json-rpc-provider" {
|
declare module "providers/json-rpc-provider" {
|
||||||
import { Network } from "providers/networks";
|
import { Networkish } from "providers/networks";
|
||||||
import { BlockTag, Provider, TransactionRequest } from "providers/provider";
|
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from "providers/provider";
|
||||||
|
import { Signer } from "wallet/wallet";
|
||||||
import { BigNumber } from "utils/bignumber";
|
import { BigNumber } from "utils/bignumber";
|
||||||
import { Arrayish } from "utils/bytes";
|
import { Arrayish } from "utils/bytes";
|
||||||
import { ConnectionInfo } from "utils/web";
|
import { ConnectionInfo } from "utils/web";
|
||||||
export function hexlifyTransaction(transaction: TransactionRequest): any;
|
export function hexlifyTransaction(transaction: TransactionRequest): any;
|
||||||
export class JsonRpcSigner {
|
export class JsonRpcSigner extends Signer {
|
||||||
readonly provider: JsonRpcProvider;
|
readonly provider: JsonRpcProvider;
|
||||||
readonly _address: string;
|
readonly _address: string;
|
||||||
constructor(provider: JsonRpcProvider, address?: string);
|
constructor(provider: JsonRpcProvider, address?: string);
|
||||||
@ -646,14 +625,14 @@ declare module "providers/json-rpc-provider" {
|
|||||||
getAddress(): Promise<string>;
|
getAddress(): Promise<string>;
|
||||||
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
||||||
getTransactionCount(blockTag: any): Promise<number>;
|
getTransactionCount(blockTag: any): Promise<number>;
|
||||||
sendTransaction(transaction: TransactionRequest): Promise<any>;
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
signMessage(message: Arrayish | string): Promise<string>;
|
signMessage(message: Arrayish | string): Promise<string>;
|
||||||
unlock(password: any): Promise<boolean>;
|
unlock(password: any): Promise<boolean>;
|
||||||
}
|
}
|
||||||
export class JsonRpcProvider extends Provider {
|
export 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?: Networkish);
|
||||||
getSigner(address: string): JsonRpcSigner;
|
getSigner(address: string): JsonRpcSigner;
|
||||||
listAccounts(): Promise<Array<string>>;
|
listAccounts(): Promise<Array<string>>;
|
||||||
send(method: string, params: any): Promise<any>;
|
send(method: string, params: any): Promise<any>;
|
||||||
@ -662,19 +641,28 @@ declare module "providers/json-rpc-provider" {
|
|||||||
_stopPending(): void;
|
_stopPending(): void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
declare module "providers/ipc-provider" {
|
||||||
|
import { JsonRpcProvider } from "providers/json-rpc-provider";
|
||||||
|
import { Networkish } from "providers/networks";
|
||||||
|
export class IpcProvider extends JsonRpcProvider {
|
||||||
|
readonly path: string;
|
||||||
|
constructor(path: string, network?: Networkish);
|
||||||
|
send(method: string, params: any): Promise<any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
declare module "providers/infura-provider" {
|
declare module "providers/infura-provider" {
|
||||||
import { JsonRpcProvider, JsonRpcSigner } from "providers/json-rpc-provider";
|
import { JsonRpcProvider, JsonRpcSigner } from "providers/json-rpc-provider";
|
||||||
import { Network } from "providers/networks";
|
import { Networkish } from "providers/networks";
|
||||||
export class InfuraProvider extends JsonRpcProvider {
|
export class InfuraProvider extends JsonRpcProvider {
|
||||||
readonly apiAccessToken: string;
|
readonly apiAccessToken: string;
|
||||||
constructor(network?: Network | string, apiAccessToken?: string);
|
constructor(network?: Networkish, apiAccessToken?: string);
|
||||||
_startPending(): void;
|
_startPending(): void;
|
||||||
getSigner(address?: string): JsonRpcSigner;
|
getSigner(address?: string): JsonRpcSigner;
|
||||||
listAccounts(): Promise<Array<string>>;
|
listAccounts(): Promise<Array<string>>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module "providers/web3-provider" {
|
declare module "providers/web3-provider" {
|
||||||
import { Network } from "providers/networks";
|
import { Networkish } from "providers/networks";
|
||||||
import { JsonRpcProvider } from "providers/json-rpc-provider";
|
import { JsonRpcProvider } from "providers/json-rpc-provider";
|
||||||
export type Callback = (error: any, response: any) => void;
|
export type Callback = (error: any, response: any) => void;
|
||||||
export type AsyncProvider = {
|
export type AsyncProvider = {
|
||||||
@ -685,23 +673,21 @@ declare module "providers/web3-provider" {
|
|||||||
};
|
};
|
||||||
export class Web3Provider extends JsonRpcProvider {
|
export class Web3Provider extends JsonRpcProvider {
|
||||||
readonly _web3Provider: AsyncProvider;
|
readonly _web3Provider: AsyncProvider;
|
||||||
constructor(web3Provider: AsyncProvider, network?: Network | string);
|
constructor(web3Provider: AsyncProvider, network?: Networkish);
|
||||||
send(method: string, params: any): Promise<any>;
|
send(method: string, params: any): Promise<any>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module "providers/index" {
|
declare module "providers/index" {
|
||||||
import { Provider } from "providers/provider";
|
import { Provider, ProviderSigner } from "providers/provider";
|
||||||
import { Network } from "providers/networks";
|
import { Network } from "providers/networks";
|
||||||
import { EtherscanProvider } from "providers/etherscan-provider";
|
import { EtherscanProvider } from "providers/etherscan-provider";
|
||||||
import { FallbackProvider } from "providers/fallback-provider";
|
import { FallbackProvider } from "providers/fallback-provider";
|
||||||
|
import { IpcProvider } from "providers/ipc-provider";
|
||||||
import { InfuraProvider } from "providers/infura-provider";
|
import { InfuraProvider } from "providers/infura-provider";
|
||||||
import { JsonRpcProvider } from "providers/json-rpc-provider";
|
import { JsonRpcProvider } from "providers/json-rpc-provider";
|
||||||
import { Web3Provider } from "providers/web3-provider";
|
import { Web3Provider } from "providers/web3-provider";
|
||||||
function getDefaultProvider(network?: Network | string): FallbackProvider;
|
function getDefaultProvider(network?: Network | string): FallbackProvider;
|
||||||
export { Provider, getDefaultProvider, FallbackProvider, EtherscanProvider, InfuraProvider, JsonRpcProvider, Web3Provider, };
|
export { Provider, getDefaultProvider, ProviderSigner, FallbackProvider, EtherscanProvider, InfuraProvider, JsonRpcProvider, Web3Provider, IpcProvider };
|
||||||
}
|
|
||||||
declare module "utils/id" {
|
|
||||||
export function id(text: string): string;
|
|
||||||
}
|
}
|
||||||
declare module "utils/solidity" {
|
declare module "utils/solidity" {
|
||||||
export function pack(types: Array<string>, values: Array<any>): string;
|
export function pack(types: Array<string>, values: Array<any>): string;
|
||||||
@ -721,12 +707,12 @@ declare module "utils/index" {
|
|||||||
import * as base64 from "utils/base64";
|
import * as base64 from "utils/base64";
|
||||||
import * as bigNumber from "utils/bignumber";
|
import * as bigNumber from "utils/bignumber";
|
||||||
import * as bytes from "utils/bytes";
|
import * as bytes from "utils/bytes";
|
||||||
import { id } from "utils/id";
|
import { hashMessage, id, namehash } from "utils/hash";
|
||||||
import { keccak256 } from "utils/keccak256";
|
import { keccak256 } from "utils/keccak256";
|
||||||
import { namehash } from "utils/namehash";
|
|
||||||
import * as sha2 from "utils/sha2";
|
import * as sha2 from "utils/sha2";
|
||||||
import * as solidity from "utils/solidity";
|
import * as solidity from "utils/solidity";
|
||||||
import { randomBytes } from "utils/random-bytes";
|
import { randomBytes } from "utils/random-bytes";
|
||||||
|
import properties = require("utils/properties");
|
||||||
import * as RLP from "utils/rlp";
|
import * as RLP from "utils/rlp";
|
||||||
import * as utf8 from "utils/utf8";
|
import * as utf8 from "utils/utf8";
|
||||||
import * as units from "utils/units";
|
import * as units from "utils/units";
|
||||||
@ -738,6 +724,10 @@ declare module "utils/index" {
|
|||||||
parseSignature: typeof parseSignature;
|
parseSignature: typeof parseSignature;
|
||||||
RLP: typeof RLP;
|
RLP: typeof RLP;
|
||||||
fetchJson: typeof fetchJson;
|
fetchJson: typeof fetchJson;
|
||||||
|
defineReadOnly: typeof properties.defineReadOnly;
|
||||||
|
defineFrozen: typeof properties.defineFrozen;
|
||||||
|
resolveProperties: typeof properties.resolveProperties;
|
||||||
|
shallowCopy: typeof properties.shallowCopy;
|
||||||
etherSymbol: string;
|
etherSymbol: string;
|
||||||
arrayify: typeof bytes.arrayify;
|
arrayify: typeof bytes.arrayify;
|
||||||
concat: typeof bytes.concat;
|
concat: typeof bytes.concat;
|
||||||
@ -749,6 +739,7 @@ declare module "utils/index" {
|
|||||||
hexlify: typeof bytes.hexlify;
|
hexlify: typeof bytes.hexlify;
|
||||||
toUtf8Bytes: typeof utf8.toUtf8Bytes;
|
toUtf8Bytes: typeof utf8.toUtf8Bytes;
|
||||||
toUtf8String: typeof utf8.toUtf8String;
|
toUtf8String: typeof utf8.toUtf8String;
|
||||||
|
hashMessage: typeof hashMessage;
|
||||||
namehash: typeof namehash;
|
namehash: typeof namehash;
|
||||||
id: typeof id;
|
id: typeof id;
|
||||||
getAddress: typeof getAddress;
|
getAddress: typeof getAddress;
|
||||||
@ -765,6 +756,7 @@ declare module "utils/index" {
|
|||||||
solidityKeccak256: typeof solidity.keccak256;
|
solidityKeccak256: typeof solidity.keccak256;
|
||||||
soliditySha256: typeof solidity.sha256;
|
soliditySha256: typeof solidity.sha256;
|
||||||
splitSignature: typeof bytes.splitSignature;
|
splitSignature: typeof bytes.splitSignature;
|
||||||
|
joinSignature: typeof bytes.joinSignature;
|
||||||
parseTransaction: typeof parseTransaction;
|
parseTransaction: typeof parseTransaction;
|
||||||
};
|
};
|
||||||
export default _default;
|
export default _default;
|
||||||
@ -779,18 +771,9 @@ declare module "index" {
|
|||||||
import { Contract, Interface } from "contracts/index";
|
import { Contract, Interface } from "contracts/index";
|
||||||
import * as providers from "providers/index";
|
import * as providers from "providers/index";
|
||||||
import * as errors from "utils/errors";
|
import * as errors from "utils/errors";
|
||||||
import { networks } from "providers/networks";
|
import { getNetwork } from "providers/networks";
|
||||||
import utils from "utils/index";
|
import utils from "utils/index";
|
||||||
import { HDNode, SigningKey, Wallet } from "wallet/index";
|
import { HDNode, SigningKey, Wallet } from "wallet/index";
|
||||||
export { Wallet, HDNode, SigningKey, Contract, Interface, networks, providers, errors, utils, };
|
export { Wallet, HDNode, SigningKey, Contract, Interface, getNetwork, providers, errors, utils, };
|
||||||
}
|
|
||||||
declare module "providers/ipc-provider" {
|
|
||||||
import { JsonRpcProvider } from "providers/json-rpc-provider";
|
|
||||||
import { Network } from "providers/networks";
|
|
||||||
export class IpcProvider extends JsonRpcProvider {
|
|
||||||
readonly path: string;
|
|
||||||
constructor(path: string, network?: Network | string);
|
|
||||||
send(method: string, params: any): Promise<any>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//# sourceMappingURL=ethers.d.ts.map
|
//# sourceMappingURL=ethers.d.ts.map
|
1
dist/ethers.d.ts.map
vendored
Normal file
1
dist/ethers.d.ts.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1211
dist/ethers.js
vendored
1211
dist/ethers.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/ethers.min.js
vendored
2
dist/ethers.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/ethers.min.js.map
vendored
2
dist/ethers.min.js.map
vendored
File diff suppressed because one or more lines are too long
@ -32,6 +32,8 @@ var empty = "module.exports = {};";
|
|||||||
// @TODO: Use path construction instead of ../..
|
// @TODO: Use path construction instead of ../..
|
||||||
var brorand = "var randomBytes = require('../../src.ts/utils').randomBytes; module.exports = function(length) { return randomBytes(length); };";
|
var brorand = "var randomBytes = require('../../src.ts/utils').randomBytes; module.exports = function(length) { return randomBytes(length); };";
|
||||||
|
|
||||||
|
var process = "if (!global.setImmediate) { global.setImmedaite = setTimeout; };";
|
||||||
|
|
||||||
var transforms = {
|
var transforms = {
|
||||||
// 'ethers.js/package.json': JSON.stringify({ version: version }),
|
// 'ethers.js/package.json': JSON.stringify({ version: version }),
|
||||||
|
|
||||||
@ -57,6 +59,8 @@ var transforms = {
|
|||||||
|
|
||||||
// Used by sha3 if it exists; (so make it no exist)
|
// Used by sha3 if it exists; (so make it no exist)
|
||||||
// "process/.*": undef,
|
// "process/.*": undef,
|
||||||
|
"process/browser.js": process,
|
||||||
|
"timers-browserify/main.js": empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
function transformFile(path) {
|
function transformFile(path) {
|
||||||
@ -123,7 +127,7 @@ task("default", { filename: "ethers.js", debug: false, minify: false });
|
|||||||
// Creates dist/ethers-debug.js
|
// Creates dist/ethers-debug.js
|
||||||
//task("debug", { filename: "ethers-debug.js", debug: true, minify: false });
|
//task("debug", { filename: "ethers-debug.js", debug: true, minify: false });
|
||||||
|
|
||||||
// Creates dist/ethers.min/js
|
// Creates dist/ethers.min.js
|
||||||
task("minified", { filename: "ethers.min.js", debug: false, minify: true });
|
task("minified", { filename: "ethers.min.js", debug: false, minify: true });
|
||||||
|
|
||||||
|
|
||||||
@ -153,7 +157,7 @@ gulp.task("tests", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Crearte a single definition file in dist/
|
// Crearte a single definition file and its map as dist/ethers.d.ts[.map]
|
||||||
gulp.task("types", function() {
|
gulp.task("types", function() {
|
||||||
return ts.createProject("tsconfig.json")
|
return ts.createProject("tsconfig.json")
|
||||||
.src()
|
.src()
|
||||||
@ -167,5 +171,6 @@ gulp.task("types", function() {
|
|||||||
target: "es5"
|
target: "es5"
|
||||||
}))
|
}))
|
||||||
.dts
|
.dts
|
||||||
|
.pipe(sourcemaps.write('./'))
|
||||||
.pipe(gulp.dest("dist"))
|
.pipe(gulp.dest("dist"))
|
||||||
});
|
});
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
"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.ts": "./src.browser/random-bytes.ts",
|
"./src.ts/utils/random-bytes.ts": "./src.browser/random-bytes.ts",
|
||||||
"./providers/ipc-provider.js": "./utils/empty.js",
|
"./src.ts/providers/ipc-provider.ts": "./src.browser/empty.ts",
|
||||||
"xmlhttprequest": "./src.browser/xmlhttprequest.ts"
|
"xmlhttprequest": "./src.browser/xmlhttprequest.ts"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
6
src.browser/setimmediate.ts
Normal file
6
src.browser/setimmediate.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function setImmediate(func) {
|
||||||
|
setTimeout(func, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { setImmediate }
|
@ -9,7 +9,7 @@ import { getContractAddress } from '../utils/address';
|
|||||||
import { isHexString } from '../utils/bytes';
|
import { isHexString } from '../utils/bytes';
|
||||||
import { ParamType } from '../utils/abi-coder';
|
import { ParamType } from '../utils/abi-coder';
|
||||||
import { BigNumber, ConstantZero } from '../utils/bignumber';
|
import { BigNumber, ConstantZero } from '../utils/bignumber';
|
||||||
import { defineReadOnly, resolveProperties } from '../utils/properties';
|
import { defineReadOnly, shallowCopy } from '../utils/properties';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
|
|
||||||
@ -17,14 +17,8 @@ var allowedTransactionKeys = {
|
|||||||
data: true, from: true, gasLimit: true, gasPrice:true, nonce: true, to: true, value: true
|
data: true, from: true, gasLimit: true, gasPrice:true, nonce: true, to: true, value: true
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyObject(object) {
|
// Recursively replaces ENS names with promises to resolve the name and
|
||||||
var result = {};
|
// stalls until all promises have returned
|
||||||
for (var key in object) {
|
|
||||||
result[key] = object[key];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @TODO: Expand this to resolve any promises too
|
// @TODO: Expand this to resolve any promises too
|
||||||
function resolveAddresses(provider, value, paramType): Promise<any> {
|
function resolveAddresses(provider, value, paramType): Promise<any> {
|
||||||
if (Array.isArray(paramType)) {
|
if (Array.isArray(paramType)) {
|
||||||
@ -52,19 +46,20 @@ function resolveAddresses(provider, value, paramType): Promise<any> {
|
|||||||
return Promise.resolve(value);
|
return Promise.resolve(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type RunFunction = (...params: Array<any>) => Promise<any>;
|
type RunFunction = (...params: Array<any>) => Promise<any>;
|
||||||
|
|
||||||
function runMethod(contract: Contract, functionName: string, estimateOnly: boolean): RunFunction {
|
function runMethod(contract: Contract, functionName: string, estimateOnly: boolean): RunFunction {
|
||||||
let method = contract.interface.functions[functionName];
|
let method = contract.interface.functions[functionName];
|
||||||
return function(...params): Promise<any> {
|
return function(...params): Promise<any> {
|
||||||
var transaction: any = {}
|
var tx: any = {}
|
||||||
|
|
||||||
// If 1 extra parameter was passed in, it contains overrides
|
// If 1 extra parameter was passed in, it contains overrides
|
||||||
if (params.length === method.inputs.length + 1 && typeof(params[params.length - 1]) === 'object') {
|
if (params.length === method.inputs.length + 1 && typeof(params[params.length - 1]) === 'object') {
|
||||||
transaction = copyObject(params.pop());
|
tx = shallowCopy(params.pop());
|
||||||
|
|
||||||
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
|
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
|
||||||
for (var key in transaction) {
|
for (var key in tx) {
|
||||||
if (!allowedTransactionKeys[key]) {
|
if (!allowedTransactionKeys[key]) {
|
||||||
throw new Error('unknown transaction override ' + key);
|
throw new Error('unknown transaction override ' + key);
|
||||||
}
|
}
|
||||||
@ -77,16 +72,16 @@ function runMethod(contract: Contract, functionName: string, estimateOnly: boole
|
|||||||
|
|
||||||
// Check overrides make sense
|
// Check overrides make sense
|
||||||
['data', 'to'].forEach(function(key) {
|
['data', 'to'].forEach(function(key) {
|
||||||
if (transaction[key] != null) {
|
if (tx[key] != null) {
|
||||||
throw new Error('cannot override ' + key) ;
|
errors.throwError('cannot override ' + key, errors.UNSUPPORTED_OPERATION, { operation: key })
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send to the contract address
|
// Send to the contract address
|
||||||
transaction.to = contract.addressPromise;
|
tx.to = contract.addressPromise;
|
||||||
|
|
||||||
return resolveAddresses(contract.provider, params, method.inputs).then((params) => {
|
return resolveAddresses(contract.provider, params, method.inputs).then((params) => {
|
||||||
transaction.data = method.encode(params);
|
tx.data = method.encode(params);
|
||||||
if (method.type === 'call') {
|
if (method.type === 'call') {
|
||||||
|
|
||||||
// Call (constant functions) always cost 0 ether
|
// Call (constant functions) always cost 0 ether
|
||||||
@ -94,129 +89,74 @@ function runMethod(contract: Contract, functionName: string, estimateOnly: boole
|
|||||||
return Promise.resolve(ConstantZero);
|
return Promise.resolve(ConstantZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!contract.provider) {
|
||||||
|
errors.throwError('call (constant functions) require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'call' })
|
||||||
|
}
|
||||||
|
|
||||||
// Check overrides make sense
|
// Check overrides make sense
|
||||||
['gasLimit', 'gasPrice', 'value'].forEach(function(key) {
|
['gasLimit', 'gasPrice', 'value'].forEach(function(key) {
|
||||||
if (transaction[key] != null) {
|
if (tx[key] != null) {
|
||||||
throw new Error('call cannot override ' + key) ;
|
throw new Error('call cannot override ' + key) ;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (transaction.from == null && contract.signer) {
|
if (tx.from == null && contract.signer) {
|
||||||
if (contract.signer.address) {
|
tx.from = contract.signer.getAddress()
|
||||||
transaction.from = contract.signer.address;
|
|
||||||
} else if (contract.signer.getAddress) {
|
|
||||||
transaction.from = contract.signer.getAddress();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolveProperties(transaction).then((transaction) => {
|
return contract.provider.call(tx).then((value) => {
|
||||||
return contract.provider.call(transaction).then((value) => {
|
try {
|
||||||
try {
|
let result = method.decode(value);
|
||||||
let result = method.decode(value);
|
if (method.outputs.length === 1) {
|
||||||
if (method.outputs.length === 1) {
|
result = result[0];
|
||||||
result = result[0];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
if (value === '0x' && method.outputs.length > 0) {
|
|
||||||
errors.throwError('call exception', errors.CALL_EXCEPTION, {
|
|
||||||
address: contract.address,
|
|
||||||
method: method.signature,
|
|
||||||
value: params
|
|
||||||
});
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
});
|
return result;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (value === '0x' && method.outputs.length > 0) {
|
||||||
|
errors.throwError('call exception', errors.CALL_EXCEPTION, {
|
||||||
|
address: contract.address,
|
||||||
|
method: method.signature,
|
||||||
|
value: params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if (method.type === 'transaction') {
|
} else if (method.type === 'transaction') {
|
||||||
if (!contract.signer) { return Promise.reject(new Error('missing signer')); }
|
|
||||||
|
|
||||||
// Make sure they aren't overriding something they shouldn't
|
|
||||||
if (transaction.from != null) {
|
|
||||||
throw new Error('transaction cannot override from') ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only computing the transaction estimate
|
// Only computing the transaction estimate
|
||||||
if (estimateOnly) {
|
if (estimateOnly) {
|
||||||
if (contract.signer.estimateGas) {
|
if (!contract.provider) {
|
||||||
return contract.signer.estimateGas(transaction);
|
errors.throwError('estimate gas require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'estimateGas' })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contract.signer.address) {
|
if (tx.from == null && contract.signer) {
|
||||||
transaction.from = contract.signer.address;
|
tx.from = contract.signer.getAddress()
|
||||||
} else if (contract.signer.getAddress) {
|
|
||||||
transaction.from = contract.signer.getAddress();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolveProperties(transaction).then((transaction) => {
|
return contract.provider.estimateGas(tx);
|
||||||
return contract.provider.estimateGas(transaction);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the signer supports sendTrasaction, use it
|
if (!contract.signer) {
|
||||||
if (contract.signer.sendTransaction) {
|
errors.throwError('sending a transaction require a signer', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction' })
|
||||||
return contract.signer.sendTransaction(transaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contract.signer.sign) {
|
// Make sure they aren't overriding something they shouldn't
|
||||||
return Promise.reject(new Error('custom signer does not support signing'));
|
if (tx.from != null) {
|
||||||
|
errors.throwError('cannot override from in a transaction', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction' })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transaction.chainId == null) {
|
return contract.signer.sendTransaction(tx);
|
||||||
transaction.chainId = contract.provider.getNetwork().then((network) => {
|
|
||||||
return network.chainId;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transaction.gasLimit == null) {
|
|
||||||
if (contract.signer.estimateGas) {
|
|
||||||
transaction.gasLimit = contract.signer.estimateGas(transaction);
|
|
||||||
} else {
|
|
||||||
transaction.gasLimit = contract.provider.estimateGas(transaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!transaction.nonce) {
|
|
||||||
if (contract.signer.getTransactionCount) {
|
|
||||||
transaction.nonce = contract.signer.getTransactionCount();
|
|
||||||
} else if (contract.signer.address) {
|
|
||||||
transaction.nonce = contract.provider.getTransactionCount(contract.signer.address);
|
|
||||||
} else if (contract.signer.getAddress) {
|
|
||||||
transaction.nonce = contract.provider.getTransactionCount(contract.signer.getAddress());
|
|
||||||
} else {
|
|
||||||
throw new Error('cannot determine nonce');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!transaction.gasPrice) {
|
|
||||||
if (contract.signer.getGasPrice) {
|
|
||||||
transaction.gasPrice = contract.signer.getGasPrice(transaction);
|
|
||||||
} else {
|
|
||||||
transaction.gasPrice = contract.provider.getGasPrice();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolveProperties(transaction).then((transaction) => {
|
|
||||||
let signedTransaction = contract.signer.sign(transaction);
|
|
||||||
return contract.provider.sendTransaction(signedTransaction);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('invalid type - ' + method.type);
|
throw new Error('invalid type - ' + method.type);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
throw new Error('unsupport type - ' + method.type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSigner(value: any): value is Signer {
|
|
||||||
return (value && value.provider != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ContractEstimate = (...params: Array<any>) => Promise<BigNumber>;
|
export type ContractEstimate = (...params: Array<any>) => Promise<BigNumber>;
|
||||||
export type ContractFunction = (...params: Array<any>) => Promise<any>;
|
export type ContractFunction = (...params: Array<any>) => Promise<any>;
|
||||||
export type ContractEvent = (...params: Array<any>) => void;
|
export type ContractEvent = (...params: Array<any>) => void;
|
||||||
@ -229,6 +169,7 @@ export type Contractish = Array<string | ParamType> | Interface | string;
|
|||||||
export class Contract {
|
export class Contract {
|
||||||
readonly address: string;
|
readonly address: string;
|
||||||
readonly interface: Interface;
|
readonly interface: Interface;
|
||||||
|
|
||||||
readonly signer: Signer;
|
readonly signer: Signer;
|
||||||
readonly provider: Provider;
|
readonly provider: Provider;
|
||||||
|
|
||||||
@ -242,7 +183,8 @@ export class Contract {
|
|||||||
readonly deployTransaction: TransactionResponse;
|
readonly deployTransaction: TransactionResponse;
|
||||||
|
|
||||||
// https://github.com/Microsoft/TypeScript/issues/5453
|
// https://github.com/Microsoft/TypeScript/issues/5453
|
||||||
// Once this issue is resolved (there are open PR) we can do this nicer. :)
|
// 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: Contractish, signerOrProvider: Signer | Provider) {
|
||||||
errors.checkNew(this, Contract);
|
errors.checkNew(this, Contract);
|
||||||
@ -255,17 +197,16 @@ export class Contract {
|
|||||||
defineReadOnly(this, 'interface', new Interface(contractInterface));
|
defineReadOnly(this, 'interface', new Interface(contractInterface));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!signerOrProvider) { throw new Error('missing signer or provider'); }
|
if (signerOrProvider instanceof Signer) {
|
||||||
|
|
||||||
if (isSigner(signerOrProvider)) {
|
|
||||||
defineReadOnly(this, 'provider', signerOrProvider.provider);
|
defineReadOnly(this, 'provider', signerOrProvider.provider);
|
||||||
defineReadOnly(this, 'signer', signerOrProvider);
|
defineReadOnly(this, 'signer', signerOrProvider);
|
||||||
} else {
|
} else if (signerOrProvider instanceof Provider) {
|
||||||
defineReadOnly(this, 'provider', signerOrProvider);
|
defineReadOnly(this, 'provider', signerOrProvider);
|
||||||
defineReadOnly(this, 'signer', null);
|
defineReadOnly(this, 'signer', null);
|
||||||
|
} else {
|
||||||
|
errors.throwError('invalid signer or provider', errors.INVALID_ARGUMENT, { arg: 'signerOrProvider', value: signerOrProvider });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defineReadOnly(this, 'estimate', { });
|
defineReadOnly(this, 'estimate', { });
|
||||||
defineReadOnly(this, 'events', { });
|
defineReadOnly(this, 'events', { });
|
||||||
defineReadOnly(this, 'functions', { });
|
defineReadOnly(this, 'functions', { });
|
||||||
@ -277,8 +218,8 @@ export class Contract {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineReadOnly(this, 'address', addressOrName || null);
|
defineReadOnly(this, 'address', addressOrName);
|
||||||
defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName || null));
|
defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName));
|
||||||
|
|
||||||
Object.keys(this.interface.functions).forEach((name) => {
|
Object.keys(this.interface.functions).forEach((name) => {
|
||||||
var run = runMethod(this, name, false);
|
var run = runMethod(this, name, false);
|
||||||
@ -314,7 +255,7 @@ export class Contract {
|
|||||||
log.event = eventName;
|
log.event = eventName;
|
||||||
log.parse = eventInfo.parse;
|
log.parse = eventInfo.parse;
|
||||||
log.removeListener = function() {
|
log.removeListener = function() {
|
||||||
contract.provider.removeListener(eventInfo.topics, handleEvent);
|
contract.provider.removeListener([ eventInfo.topic ], handleEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.getBlock = function() { return contract.provider.getBlock(log.blockHash);; }
|
log.getBlock = function() { return contract.provider.getBlock(log.blockHash);; }
|
||||||
@ -337,11 +278,15 @@ export class Contract {
|
|||||||
set: function(value) {
|
set: function(value) {
|
||||||
if (!value) { value = null; }
|
if (!value) { value = null; }
|
||||||
|
|
||||||
|
if (!contract.provider) {
|
||||||
|
errors.throwError('events require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'events' })
|
||||||
|
}
|
||||||
|
|
||||||
if (!value && eventCallback) {
|
if (!value && eventCallback) {
|
||||||
contract.provider.removeListener(eventInfo.topics, handleEvent);
|
contract.provider.removeListener([ eventInfo.topic ], handleEvent);
|
||||||
|
|
||||||
} else if (value && !eventCallback) {
|
} else if (value && !eventCallback) {
|
||||||
contract.provider.on(eventInfo.topics, handleEvent);
|
contract.provider.on([ eventInfo.topic ], handleEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
eventCallback = value;
|
eventCallback = value;
|
||||||
@ -383,7 +328,7 @@ export class Contract {
|
|||||||
return this.signer.sendTransaction({
|
return this.signer.sendTransaction({
|
||||||
data: this.interface.deployFunction.encode(bytecode, args)
|
data: this.interface.deployFunction.encode(bytecode, args)
|
||||||
}).then((tx) => {
|
}).then((tx) => {
|
||||||
let contract = new Contract(getContractAddress(tx), this.interface, this.provider);
|
let contract = new Contract(getContractAddress(tx), this.interface, this.signer || this.provider);
|
||||||
defineReadOnly(contract, 'deployTransaction', tx);
|
defineReadOnly(contract, 'deployTransaction', tx);
|
||||||
return contract;
|
return contract;
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,6 @@ function parseParams(params: Array<ParamType>): { names: Array<any>, types: Arra
|
|||||||
|
|
||||||
export class Description {
|
export class Description {
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
readonly inputs: Array<ParamType>;
|
|
||||||
constructor(info: any) {
|
constructor(info: any) {
|
||||||
for (var key in info) {
|
for (var key in info) {
|
||||||
let value = info[key];
|
let value = info[key];
|
||||||
@ -55,51 +54,48 @@ export class Description {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @TOOD: Make this a description
|
// @TOOD: Make this a description
|
||||||
export class Indexed {
|
export class Indexed extends Description {
|
||||||
readonly type: string;
|
|
||||||
readonly hash: string;
|
readonly hash: string;
|
||||||
constructor(value: string) {
|
|
||||||
defineReadOnly(this, 'type', 'indexed');
|
|
||||||
defineReadOnly(this, 'hash', value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DeployDescription extends Description {
|
export class DeployDescription extends Description {
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly payable: boolean;
|
readonly payable: boolean;
|
||||||
|
|
||||||
encode(bytecode: string, params: Array<any>): string {
|
encode(bytecode: string, params: Array<any>): string {
|
||||||
if (!isHexString(bytecode)) {
|
if (!isHexString(bytecode)) {
|
||||||
errors.throwError('invalid contract bytecode', errors.INVALID_ARGUMENT, {
|
errors.throwError('invalid contract bytecode', errors.INVALID_ARGUMENT, {
|
||||||
arg: 'bytecode',
|
arg: 'bytecode',
|
||||||
type: typeof(bytecode),
|
type: typeof(bytecode),
|
||||||
value: bytecode
|
value: bytecode
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.length < this.inputs.length) {
|
if (params.length < this.inputs.length) {
|
||||||
errors.throwError('missing constructor argument', errors.MISSING_ARGUMENT, {
|
errors.throwError('missing constructor argument', errors.MISSING_ARGUMENT, {
|
||||||
arg: (this.inputs[params.length].name || 'unknown'),
|
arg: (this.inputs[params.length].name || 'unknown'),
|
||||||
count: params.length,
|
count: params.length,
|
||||||
expectedCount: this.inputs.length
|
expectedCount: this.inputs.length
|
||||||
});
|
});
|
||||||
} else if (params.length > this.inputs.length) {
|
|
||||||
errors.throwError('too many constructor arguments', errors.UNEXPECTED_ARGUMENT, {
|
|
||||||
count: params.length,
|
|
||||||
expectedCount: this.inputs.length
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
} else if (params.length > this.inputs.length) {
|
||||||
return (bytecode + defaultAbiCoder.encode(this.inputs, params).substring(2));
|
errors.throwError('too many constructor arguments', errors.UNEXPECTED_ARGUMENT, {
|
||||||
} catch (error) {
|
count: params.length,
|
||||||
errors.throwError('invalid constructor argument', errors.INVALID_ARGUMENT, {
|
expectedCount: this.inputs.length
|
||||||
arg: error.arg,
|
});
|
||||||
reason: error.reason,
|
}
|
||||||
value: error.value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
try {
|
||||||
|
return (bytecode + defaultAbiCoder.encode(this.inputs, params).substring(2));
|
||||||
|
} catch (error) {
|
||||||
|
errors.throwError('invalid constructor argument', errors.INVALID_ARGUMENT, {
|
||||||
|
arg: error.arg,
|
||||||
|
reason: error.reason,
|
||||||
|
value: error.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,68 +104,63 @@ export class FunctionDescription extends Description {
|
|||||||
readonly signature: string;
|
readonly signature: string;
|
||||||
readonly sighash: string;
|
readonly sighash: string;
|
||||||
|
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly outputs: Array<ParamType>;
|
readonly outputs: Array<ParamType>;
|
||||||
readonly payable: boolean;
|
readonly payable: boolean;
|
||||||
|
|
||||||
encode(params: Array<any>): string {
|
encode(params: Array<any>): string {
|
||||||
if (params.length < this.inputs.length) {
|
if (params.length < this.inputs.length) {
|
||||||
errors.throwError('missing input argument', errors.MISSING_ARGUMENT, {
|
errors.throwError('missing input argument', errors.MISSING_ARGUMENT, {
|
||||||
arg: (this.inputs[params.length].name || 'unknown'),
|
arg: (this.inputs[params.length].name || 'unknown'),
|
||||||
count: params.length,
|
count: params.length,
|
||||||
expectedCount: this.inputs.length,
|
expectedCount: this.inputs.length,
|
||||||
name: this.name
|
name: this.name
|
||||||
});
|
});
|
||||||
} else if (params.length > this.inputs.length) {
|
} else if (params.length > this.inputs.length) {
|
||||||
errors.throwError('too many input arguments', errors.UNEXPECTED_ARGUMENT, {
|
errors.throwError('too many input arguments', errors.UNEXPECTED_ARGUMENT, {
|
||||||
count: params.length,
|
count: params.length,
|
||||||
expectedCount: this.inputs.length
|
expectedCount: this.inputs.length
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this.sighash + defaultAbiCoder.encode(this.inputs, params).substring(2);
|
return this.sighash + defaultAbiCoder.encode(this.inputs, params).substring(2);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.throwError('invalid input argument', errors.INVALID_ARGUMENT, {
|
errors.throwError('invalid input argument', errors.INVALID_ARGUMENT, {
|
||||||
arg: error.arg,
|
arg: error.arg,
|
||||||
reason: error.reason,
|
reason: error.reason,
|
||||||
value: error.value
|
value: error.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
decode(data: string): any {
|
decode(data: string): any {
|
||||||
try {
|
try {
|
||||||
return defaultAbiCoder.decode(this.outputs, arrayify(data));
|
return defaultAbiCoder.decode(this.outputs, arrayify(data));
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
errors.throwError('invalid data for function output', errors.INVALID_ARGUMENT, {
|
errors.throwError('invalid data for function output', errors.INVALID_ARGUMENT, {
|
||||||
arg: 'data',
|
arg: 'data',
|
||||||
errorArg: error.arg,
|
errorArg: error.arg,
|
||||||
errorValue: error.value,
|
errorValue: error.value,
|
||||||
value: data,
|
value: data,
|
||||||
reason: error.reason
|
reason: error.reason
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: sub-class a description
|
class Result extends Description {
|
||||||
export type CallTransaction = {
|
[key: string]: any;
|
||||||
args: Array<any>,
|
[key: number]: any;
|
||||||
signature: string,
|
|
||||||
sighash: string,
|
|
||||||
decode: (data: string) => any,
|
|
||||||
value: BigNumber
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: Make this a description
|
|
||||||
function Result() {}
|
|
||||||
|
|
||||||
export class EventDescription extends Description {
|
export class EventDescription extends Description {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly signature: string;
|
readonly signature: string;
|
||||||
|
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly anonymous: boolean;
|
readonly anonymous: boolean;
|
||||||
readonly topic: string;
|
readonly topic: string;
|
||||||
|
|
||||||
@ -207,15 +198,15 @@ export class EventDescription extends Description {
|
|||||||
arrayify(data)
|
arrayify(data)
|
||||||
);
|
);
|
||||||
|
|
||||||
var result = new Result();
|
var result = new Result({});
|
||||||
var nonIndexedIndex = 0, indexedIndex = 0;
|
var nonIndexedIndex = 0, indexedIndex = 0;
|
||||||
this.inputs.forEach(function(input, index) {
|
this.inputs.forEach(function(input, index) {
|
||||||
if (input.indexed) {
|
if (input.indexed) {
|
||||||
if (topics == null) {
|
if (topics == null) {
|
||||||
result[index] = new Indexed(null);
|
result[index] = new Indexed({ type: 'indexed', hash: null });
|
||||||
|
|
||||||
} else if (inputDynamic[index]) {
|
} else if (inputDynamic[index]) {
|
||||||
result[index] = new Indexed(resultIndexed[indexedIndex++]);
|
result[index] = new Indexed({ type: 'indexed', hash: resultIndexed[indexedIndex++] });
|
||||||
} else {
|
} else {
|
||||||
result[index] = resultIndexed[indexedIndex++];
|
result[index] = resultIndexed[indexedIndex++];
|
||||||
}
|
}
|
||||||
@ -231,10 +222,22 @@ export class EventDescription extends Description {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO:
|
class TransactionDescription extends Description {
|
||||||
//export class Result {
|
readonly name: string;
|
||||||
// [prop: string]: any;
|
readonly args: Array<any>;
|
||||||
//}
|
readonly signature: string;
|
||||||
|
readonly sighash: string;
|
||||||
|
readonly decode: (data: string) => any;
|
||||||
|
readonly value: BigNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogDescription extends Description {
|
||||||
|
readonly name: string;
|
||||||
|
readonly signature: string;
|
||||||
|
readonly topic: string;
|
||||||
|
readonly values: Array<any>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function addMethod(method: any): void {
|
function addMethod(method: any): void {
|
||||||
switch (method.type) {
|
switch (method.type) {
|
||||||
@ -296,7 +299,7 @@ function addMethod(method: any): void {
|
|||||||
signature: signature,
|
signature: signature,
|
||||||
|
|
||||||
inputs: method.inputs,
|
inputs: method.inputs,
|
||||||
topics: [ keccak256(toUtf8Bytes(signature)) ],
|
topic: keccak256(toUtf8Bytes(signature)),
|
||||||
anonymous: (!!method.anonymous),
|
anonymous: (!!method.anonymous),
|
||||||
|
|
||||||
type: 'event'
|
type: 'event'
|
||||||
@ -374,25 +377,46 @@ export class Interface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parseTransaction(tx: { data: string, value?: BigNumberish }): CallTransaction {
|
parseTransaction(tx: { data: string, value?: BigNumberish }): TransactionDescription {
|
||||||
var sighash = tx.data.substring(0, 10).toLowerCase();
|
var sighash = tx.data.substring(0, 10).toLowerCase();
|
||||||
for (var name in this.functions) {
|
for (var name in this.functions) {
|
||||||
if (name.indexOf('(') === -1) { continue; }
|
if (name.indexOf('(') === -1) { continue; }
|
||||||
var func = this.functions[name];
|
var func = this.functions[name];
|
||||||
if (func.sighash === sighash) {
|
if (func.sighash === sighash) {
|
||||||
var result = defaultAbiCoder.decode(func.inputs, '0x' + tx.data.substring(10));
|
var result = defaultAbiCoder.decode(func.inputs, '0x' + tx.data.substring(10));
|
||||||
return {
|
return new TransactionDescription({
|
||||||
args: result,
|
args: result,
|
||||||
|
decode: func.decode,
|
||||||
|
name: name,
|
||||||
signature: func.signature,
|
signature: func.signature,
|
||||||
sighash: func.sighash,
|
sighash: func.sighash,
|
||||||
decode: func.decode,
|
type: 'transaction',
|
||||||
value: bigNumberify(tx.value || 0),
|
value: bigNumberify(tx.value || 0),
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO:
|
parseLog(log: { topics: Array<string>, data: string}): LogDescription {
|
||||||
//parseEvent(log: { }): Lo
|
for (var name in this.events) {
|
||||||
|
if (name.indexOf('(') === -1) { continue; }
|
||||||
|
var event = this.events[name];
|
||||||
|
if (event.anonymous) { continue; }
|
||||||
|
if (event.topic !== log.topics[0]) { continue; }
|
||||||
|
|
||||||
|
// @TODO: If anonymous, and the only method, and the input count matches, should we parse and return it?
|
||||||
|
|
||||||
|
return new LogDescription({
|
||||||
|
name: event.name,
|
||||||
|
signature: event.signature,
|
||||||
|
topic: event.topic,
|
||||||
|
type: 'log',
|
||||||
|
values: event.decode(log.data, log.topics)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +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 { getNetwork } from './providers/networks';
|
||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
import { HDNode, SigningKey, Wallet } from './wallet';
|
import { HDNode, SigningKey, Wallet } from './wallet';
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ export {
|
|||||||
Contract,
|
Contract,
|
||||||
Interface,
|
Interface,
|
||||||
|
|
||||||
networks,
|
getNetwork,
|
||||||
providers,
|
providers,
|
||||||
|
|
||||||
errors,
|
errors,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
import { checkTransactionResponse, Provider, TransactionRequest } from './provider';
|
import { checkTransactionResponse, Provider, TransactionRequest } from './provider';
|
||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
|
|
||||||
import { hexlify, hexStripZeros } from '../utils/bytes';
|
import { hexlify, hexStripZeros } from '../utils/bytes';
|
||||||
|
import { defineReadOnly } from '../utils/properties';
|
||||||
import { fetchJson } from '../utils/web';
|
import { fetchJson } from '../utils/web';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
@ -68,9 +69,8 @@ function checkLogTag(blockTag: string): number | "latest" {
|
|||||||
export class EtherscanProvider extends Provider{
|
export class EtherscanProvider extends Provider{
|
||||||
readonly baseUrl: string;
|
readonly baseUrl: string;
|
||||||
readonly apiKey: string;
|
readonly apiKey: string;
|
||||||
constructor(network?: Network | string, apiKey?: string) {
|
constructor(network?: Networkish, apiKey?: string) {
|
||||||
|
super(network);
|
||||||
super(network || 'homestead');
|
|
||||||
errors.checkNew(this, EtherscanProvider);
|
errors.checkNew(this, EtherscanProvider);
|
||||||
|
|
||||||
let name = 'invalid';
|
let name = 'invalid';
|
||||||
@ -94,8 +94,8 @@ export class EtherscanProvider extends Provider{
|
|||||||
throw new Error('unsupported network');
|
throw new Error('unsupported network');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.baseUrl = baseUrl;
|
defineReadOnly(this, 'baseUrl', baseUrl);
|
||||||
this.apiKey = apiKey;
|
defineReadOnly(this, 'apiKey', apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,28 +49,30 @@ export class FallbackProvider extends Provider {
|
|||||||
|
|
||||||
if (providers.length === 0) { throw new Error('no providers'); }
|
if (providers.length === 0) { throw new Error('no providers'); }
|
||||||
|
|
||||||
|
// All networks are ready, we can know the network for certain
|
||||||
let ready = checkNetworks(providers.map((p) => p.network));
|
let ready = checkNetworks(providers.map((p) => p.network));
|
||||||
if (ready) {
|
if (ready) {
|
||||||
super(providers[0].network);
|
super(providers[0].network);
|
||||||
errors.checkNew(this, FallbackProvider);
|
|
||||||
} else {
|
|
||||||
super(null);
|
|
||||||
errors.checkNew(this, FallbackProvider);
|
|
||||||
|
|
||||||
// We re-assign the ready function to make sure all networks actually match
|
} else {
|
||||||
this.ready = Promise.all(providers.map((p) => p.getNetwork())).then((networks) => {
|
// The network won't be known until all child providers know
|
||||||
|
let ready = Promise.all(providers.map((p) => p.getNetwork())).then((networks) => {
|
||||||
if (!checkNetworks(networks)) {
|
if (!checkNetworks(networks)) {
|
||||||
errors.throwError('getNetwork returned null', errors.UNKNOWN_ERROR, { })
|
errors.throwError('getNetwork returned null', errors.UNKNOWN_ERROR, { })
|
||||||
}
|
}
|
||||||
return networks[0];
|
return networks[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
super(ready);
|
||||||
}
|
}
|
||||||
|
errors.checkNew(this, FallbackProvider);
|
||||||
|
|
||||||
|
// Preserve a copy, so we don't get mutated
|
||||||
this._providers = providers.slice(0);
|
this._providers = providers.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
get providers() {
|
get providers() {
|
||||||
|
// Return a copy, so we don't get mutated
|
||||||
return this._providers.slice(0);
|
return this._providers.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { Provider } from './provider';
|
import { Provider, ProviderSigner } from './provider';
|
||||||
|
|
||||||
import { Network } from './networks';
|
import { Network } from './networks';
|
||||||
|
|
||||||
import { EtherscanProvider } from './etherscan-provider';
|
import { EtherscanProvider } from './etherscan-provider';
|
||||||
import { FallbackProvider } from './fallback-provider';
|
import { FallbackProvider } from './fallback-provider';
|
||||||
//import { IpcProvider } from './ipc-provider';
|
import { IpcProvider } from './ipc-provider';
|
||||||
import { InfuraProvider } from './infura-provider';
|
import { InfuraProvider } from './infura-provider';
|
||||||
import { JsonRpcProvider } from './json-rpc-provider';
|
import { JsonRpcProvider } from './json-rpc-provider';
|
||||||
import { Web3Provider } from './web3-provider';
|
import { Web3Provider } from './web3-provider';
|
||||||
@ -22,33 +22,14 @@ export {
|
|||||||
Provider,
|
Provider,
|
||||||
getDefaultProvider,
|
getDefaultProvider,
|
||||||
|
|
||||||
|
ProviderSigner,
|
||||||
|
|
||||||
FallbackProvider,
|
FallbackProvider,
|
||||||
|
|
||||||
EtherscanProvider,
|
EtherscanProvider,
|
||||||
InfuraProvider,
|
InfuraProvider,
|
||||||
JsonRpcProvider,
|
JsonRpcProvider,
|
||||||
Web3Provider,
|
Web3Provider,
|
||||||
|
|
||||||
|
IpcProvider
|
||||||
};
|
};
|
||||||
/*
|
|
||||||
var exports = {
|
|
||||||
EtherscanProvider: EtherscanProvider,
|
|
||||||
FallbackProvider: FallbackProvider,
|
|
||||||
InfuraProvider: InfuraProvider,
|
|
||||||
JsonRpcProvider: JsonRpcProvider,
|
|
||||||
Web3Provider: Web3Provider,
|
|
||||||
|
|
||||||
isProvider: Provider.isProvider,
|
|
||||||
|
|
||||||
networks: Provider.networks,
|
|
||||||
|
|
||||||
|
|
||||||
Provider: Provider,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Only available in node, so we do not include it in browsers
|
|
||||||
/*
|
|
||||||
if (IpcProvider) {
|
|
||||||
exports.IpcProvider = IpcProvider;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//module.exports = exports;
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';
|
import { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';
|
||||||
import { getNetwork, Network } from './networks';
|
import { getNetwork, Networkish } from './networks';
|
||||||
|
|
||||||
|
import { defineReadOnly } from '../utils/properties';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
|
|
||||||
export class InfuraProvider extends JsonRpcProvider {
|
export class InfuraProvider extends JsonRpcProvider {
|
||||||
readonly apiAccessToken: string;
|
readonly apiAccessToken: string;
|
||||||
|
|
||||||
constructor(network?: Network | string, apiAccessToken?: string) {
|
constructor(network?: Networkish, apiAccessToken?: string) {
|
||||||
|
network = getNetwork((network == null) ? 'homestead': network);
|
||||||
network = getNetwork(network || 'homestead');
|
|
||||||
|
|
||||||
var host = null;
|
var host = null;
|
||||||
switch(network.name) {
|
switch(network.name) {
|
||||||
@ -33,7 +34,7 @@ export class InfuraProvider extends JsonRpcProvider {
|
|||||||
super('https://' + host + '/' + (apiAccessToken || ''), network);
|
super('https://' + host + '/' + (apiAccessToken || ''), network);
|
||||||
errors.checkNew(this, InfuraProvider);
|
errors.checkNew(this, InfuraProvider);
|
||||||
|
|
||||||
this.apiAccessToken = (apiAccessToken || null);
|
defineReadOnly(this, 'apiAccessToken', apiAccessToken || null);
|
||||||
}
|
}
|
||||||
|
|
||||||
_startPending(): void {
|
_startPending(): void {
|
||||||
|
@ -2,13 +2,16 @@
|
|||||||
import net from 'net';
|
import net from 'net';
|
||||||
|
|
||||||
import { JsonRpcProvider } from './json-rpc-provider';
|
import { JsonRpcProvider } from './json-rpc-provider';
|
||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
|
|
||||||
|
import { defineReadOnly } from '../utils/properties';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
|
|
||||||
export class IpcProvider extends JsonRpcProvider {
|
export class IpcProvider extends JsonRpcProvider {
|
||||||
readonly path: string;
|
readonly path: string;
|
||||||
constructor(path: string, network?: Network | string) {
|
|
||||||
|
constructor(path: string, network?: Networkish) {
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
errors.throwError('missing path', errors.MISSING_ARGUMENT, { arg: 'path' });
|
errors.throwError('missing path', errors.MISSING_ARGUMENT, { arg: 'path' });
|
||||||
}
|
}
|
||||||
@ -16,7 +19,7 @@ export class IpcProvider extends JsonRpcProvider {
|
|||||||
super('ipc://' + path, network);
|
super('ipc://' + path, network);
|
||||||
errors.checkNew(this, IpcProvider);
|
errors.checkNew(this, IpcProvider);
|
||||||
|
|
||||||
this.path = path;
|
defineReadOnly(this, 'path', path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @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
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC
|
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC
|
||||||
|
|
||||||
import { getNetwork, Network } from './networks';
|
import { getNetwork, Network, Networkish } from './networks';
|
||||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from './provider';
|
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from './provider';
|
||||||
|
import { Signer } from '../wallet/wallet';
|
||||||
|
|
||||||
import { getAddress } from '../utils/address';
|
import { getAddress } from '../utils/address';
|
||||||
import { BigNumber } from '../utils/bignumber';
|
import { BigNumber } from '../utils/bignumber';
|
||||||
import { Arrayish, hexlify, hexStripZeros } from '../utils/bytes';
|
import { Arrayish, hexlify, hexStripZeros } from '../utils/bytes';
|
||||||
|
import { defineReadOnly, resolveProperties } from '../utils/properties';
|
||||||
import { toUtf8Bytes } from '../utils/utf8';
|
import { toUtf8Bytes } from '../utils/utf8';
|
||||||
import { ConnectionInfo, fetchJson } from '../utils/web';
|
import { ConnectionInfo, fetchJson } from '../utils/web';
|
||||||
|
|
||||||
@ -61,20 +63,19 @@ function getLowerCase(value: string): string {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class JsonRpcSigner {
|
export class JsonRpcSigner extends Signer {
|
||||||
readonly provider: JsonRpcProvider;
|
readonly provider: JsonRpcProvider;
|
||||||
readonly _address: string;
|
readonly _address: string;
|
||||||
// private _syncAddress: boolean;
|
|
||||||
|
|
||||||
constructor(provider: JsonRpcProvider, address?: string) {
|
constructor(provider: JsonRpcProvider, address?: string) {
|
||||||
|
super();
|
||||||
errors.checkNew(this, JsonRpcSigner);
|
errors.checkNew(this, JsonRpcSigner);
|
||||||
|
|
||||||
this.provider = provider;
|
defineReadOnly(this, 'provider', provider);
|
||||||
|
|
||||||
// Statically attach to a given address
|
// Statically attach to a given address
|
||||||
if (address) {
|
if (address) {
|
||||||
this._address = address;
|
defineReadOnly(this, '_address', address);
|
||||||
//this._syncAddress = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,41 +100,25 @@ export class JsonRpcSigner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getBalance(blockTag?: BlockTag): Promise<BigNumber> {
|
getBalance(blockTag?: BlockTag): Promise<BigNumber> {
|
||||||
return this.getAddress().then((address) => {
|
return this.provider.getBalance(this.getAddress(), blockTag);
|
||||||
return this.provider.getBalance(address, blockTag);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTransactionCount(blockTag): Promise<number> {
|
getTransactionCount(blockTag): Promise<number> {
|
||||||
return this.getAddress().then((address) => {
|
return this.provider.getTransactionCount(this.getAddress(), blockTag);
|
||||||
return this.provider.getTransactionCount(address, blockTag);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO:
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
||||||
//sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
let tx = hexlifyTransaction(transaction);
|
||||||
sendTransaction(transaction: TransactionRequest): Promise<any> {
|
|
||||||
transaction = hexlifyTransaction(transaction);
|
if (tx.from == null) {
|
||||||
return this.getAddress().then((address) => {
|
tx.from = this.getAddress().then((address) => {
|
||||||
transaction.from = address.toLowerCase();
|
if (!address) { return null; }
|
||||||
return this.provider.send('eth_sendTransaction', [ transaction ]).then((hash) => {
|
return address.toLowerCase();
|
||||||
// @TODO: Use secp256k1 to fill this in instead...
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
function check() {
|
|
||||||
this.provider.getTransaction(hash).then((transaction: TransactionResponse) => {
|
|
||||||
if (!transaction) {
|
|
||||||
setTimeout(check, 1000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transaction.wait = function(timeout?: number): Promise<TransactionResponse> {
|
|
||||||
return this.provider.waitForTransaction(hash, timeout);
|
|
||||||
};
|
|
||||||
resolve(transaction);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
check();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolveProperties(tx).then((tx) => {
|
||||||
|
return this.provider.send('eth_sendTransaction', [ transaction ]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +145,7 @@ export class JsonRpcProvider extends Provider {
|
|||||||
|
|
||||||
private _pendingFilter: Promise<number>;
|
private _pendingFilter: Promise<number>;
|
||||||
|
|
||||||
constructor(url?: ConnectionInfo | string, network?: Network | string) {
|
constructor(url?: ConnectionInfo | string, network?: Networkish) {
|
||||||
|
|
||||||
// One parameter, but it is a network name, so swap it with the URL
|
// One parameter, but it is a network name, so swap it with the URL
|
||||||
if (typeof(url) === 'string') {
|
if (typeof(url) === 'string') {
|
||||||
@ -170,7 +155,25 @@ export class JsonRpcProvider extends Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super(network);
|
if (network) {
|
||||||
|
// The network has been specified explicitly, we can use it
|
||||||
|
super(network);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// The network is unknown, query the JSON-RPC for it
|
||||||
|
let ready: Promise<Network> = new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.send('net_version', [ ]).then((result) => {
|
||||||
|
let chainId = parseInt(result);
|
||||||
|
|
||||||
|
resolve(getNetwork(chainId));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
super(ready);
|
||||||
|
}
|
||||||
|
|
||||||
errors.checkNew(this, JsonRpcProvider);
|
errors.checkNew(this, JsonRpcProvider);
|
||||||
|
|
||||||
// Default URL
|
// Default URL
|
||||||
@ -184,26 +187,6 @@ export class JsonRpcProvider extends Provider {
|
|||||||
this.connection = url;
|
this.connection = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The network is unknown, query the JSON-RPC for it
|
|
||||||
if (!this.network) {
|
|
||||||
this.ready = new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.send('net_version', [ ]).then((result) => {
|
|
||||||
let chainId = parseInt(result);
|
|
||||||
|
|
||||||
let network = getNetwork(chainId);
|
|
||||||
if (network) {
|
|
||||||
return resolve(network);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
name: 'custom',
|
|
||||||
chainId: chainId
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getSigner(address: string): JsonRpcSigner {
|
getSigner(address: string): JsonRpcSigner {
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"unspecified": {
|
|
||||||
"chainId": 0,
|
|
||||||
"name": "unspecified"
|
|
||||||
},
|
|
||||||
|
|
||||||
"homestead": {
|
|
||||||
"chainId": 1,
|
|
||||||
"ensAddress": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
|
||||||
"name": "homestead"
|
|
||||||
},
|
|
||||||
"mainnet": {
|
|
||||||
"chainId": 1,
|
|
||||||
"ensAddress": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
|
||||||
"name": "homestead"
|
|
||||||
},
|
|
||||||
|
|
||||||
"morden": {
|
|
||||||
"chainId": 2,
|
|
||||||
"name": "morden"
|
|
||||||
},
|
|
||||||
|
|
||||||
"ropsten": {
|
|
||||||
"chainId": 3,
|
|
||||||
"ensAddress": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
||||||
"name": "ropsten"
|
|
||||||
},
|
|
||||||
"testnet": {
|
|
||||||
"chainId": 3,
|
|
||||||
"ensAddress": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
||||||
"name": "ropsten"
|
|
||||||
},
|
|
||||||
|
|
||||||
"rinkeby": {
|
|
||||||
"chainId": 4,
|
|
||||||
"name": "rinkeby"
|
|
||||||
},
|
|
||||||
|
|
||||||
"kovan": {
|
|
||||||
"chainId": 42,
|
|
||||||
"name": "kovan"
|
|
||||||
},
|
|
||||||
|
|
||||||
"classic": {
|
|
||||||
"chainId": 61,
|
|
||||||
"name": "classic"
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,53 +8,47 @@ export type Network = {
|
|||||||
ensAddress?: string,
|
ensAddress?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: Make these all read-only with defineProperty
|
export type Networkish = Network | string | number;
|
||||||
export const networks = {
|
|
||||||
"unspecified": {
|
|
||||||
"chainId": 0,
|
const homestead = {
|
||||||
"name": "unspecified"
|
chainId: 1,
|
||||||
|
ensAddress: "0x314159265dd8dbb310642f98f50c066173c1259b",
|
||||||
|
name: "homestead"
|
||||||
|
};
|
||||||
|
|
||||||
|
const ropsten = {
|
||||||
|
chainId: 3,
|
||||||
|
ensAddress: "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
||||||
|
name: "ropsten"
|
||||||
|
};
|
||||||
|
|
||||||
|
const networks = {
|
||||||
|
unspecified: {
|
||||||
|
chainId: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
"homestead": {
|
homestead: homestead,
|
||||||
"chainId": 1,
|
mainnet: homestead,
|
||||||
"ensAddress": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
|
||||||
"name": "homestead"
|
morden: {
|
||||||
},
|
chainId: 2
|
||||||
"mainnet": {
|
|
||||||
"chainId": 1,
|
|
||||||
"ensAddress": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
|
||||||
"name": "homestead"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"morden": {
|
ropsten: ropsten,
|
||||||
"chainId": 2,
|
testnet: ropsten,
|
||||||
"name": "morden"
|
|
||||||
|
rinkeby: {
|
||||||
|
chainId: 4,
|
||||||
|
ensAddress: "0xe7410170f87102DF0055eB195163A03B7F2Bff4A"
|
||||||
},
|
},
|
||||||
|
|
||||||
"ropsten": {
|
kovan: {
|
||||||
"chainId": 3,
|
chainId: 42
|
||||||
"ensAddress": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
||||||
"name": "ropsten"
|
|
||||||
},
|
|
||||||
"testnet": {
|
|
||||||
"chainId": 3,
|
|
||||||
"ensAddress": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
||||||
"name": "ropsten"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"rinkeby": {
|
classic: {
|
||||||
"chainId": 4,
|
chainId: 61
|
||||||
"name": "rinkeby"
|
|
||||||
},
|
|
||||||
|
|
||||||
"kovan": {
|
|
||||||
"chainId": 42,
|
|
||||||
"name": "kovan"
|
|
||||||
},
|
|
||||||
|
|
||||||
"classic": {
|
|
||||||
"chainId": 61,
|
|
||||||
"name": "classic"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,39 +60,57 @@ export const networks = {
|
|||||||
* for that network. Otherwise, return the network.
|
* for that network. Otherwise, return the network.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export function getNetwork(network: Network | string | number): Network {
|
export function getNetwork(network: Networkish): Network {
|
||||||
// No network (null) or unspecified (chainId = 0)
|
// No network (null) or unspecified (chainId = 0)
|
||||||
if (!network) { return null; }
|
if (!network) { return null; }
|
||||||
|
|
||||||
if (typeof(network) === 'number') {
|
if (typeof(network) === 'number') {
|
||||||
for (var key in networks) {
|
for (var name in networks) {
|
||||||
let n = networks[key];
|
let n = networks[name];
|
||||||
if (n.chainId === network) {
|
if (n.chainId === network) {
|
||||||
return n;
|
return {
|
||||||
|
name: name,
|
||||||
|
chainId: n.chainId,
|
||||||
|
ensAddress: n.ensAddress
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return {
|
||||||
|
chainId: network,
|
||||||
|
name: 'unknown'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof(network) === 'string') {
|
if (typeof(network) === 'string') {
|
||||||
return networks[network] || null;
|
let n = networks[network];
|
||||||
|
if (n == null) { return null; }
|
||||||
|
return {
|
||||||
|
name: network,
|
||||||
|
chainId: n.chainId,
|
||||||
|
ensAddress: n.ensAddress
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let networkObj = networks[network.name];
|
let n = networks[network.name];
|
||||||
|
|
||||||
// Not a standard network; check that it is a valid network in general
|
// Not a standard network; check that it is a valid network in general
|
||||||
if (!networkObj) {
|
if (!n) {
|
||||||
if (typeof(network.chainId) !== 'number') {
|
if (typeof(n.chainId) !== 'number') {
|
||||||
errors.throwError('invalid network chainId', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
errors.throwError('invalid network chainId', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
||||||
}
|
}
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)
|
// Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)
|
||||||
if (network.chainId != 0 && network.chainId !== networkObj.chainId) {
|
if (network.chainId !== 0 && network.chainId !== n.chainId) {
|
||||||
errors.throwError('network chainId mismatch', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
errors.throwError('network chainId mismatch', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
||||||
}
|
}
|
||||||
|
|
||||||
return networkObj;
|
// Standard Network
|
||||||
|
return {
|
||||||
|
name: network.name,
|
||||||
|
chainId: n.chainId,
|
||||||
|
ensAddress: n.ensAddress
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,17 @@
|
|||||||
|
|
||||||
//import inherits = require('inherits');
|
//import inherits = require('inherits');
|
||||||
|
|
||||||
|
import { Signer } from '../wallet/wallet';
|
||||||
|
|
||||||
import { getAddress, getContractAddress } from '../utils/address';
|
import { getAddress, getContractAddress } from '../utils/address';
|
||||||
import { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber';
|
import { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber';
|
||||||
import { Arrayish, hexDataLength, hexDataSlice, hexlify, hexStripZeros, isHexString, stripZeros } from '../utils/bytes';
|
import { Arrayish, hexDataLength, hexDataSlice, hexlify, hexStripZeros, isHexString, joinSignature, stripZeros } from '../utils/bytes';
|
||||||
import { toUtf8String } from '../utils/utf8';
|
import { toUtf8String } from '../utils/utf8';
|
||||||
import { decode as rlpDecode, encode as rlpEncode } from '../utils/rlp';
|
import { decode as rlpDecode, encode as rlpEncode } from '../utils/rlp';
|
||||||
import { namehash } from '../utils/namehash';
|
import { hashMessage, namehash } from '../utils/hash';
|
||||||
import { getNetwork, Network } from './networks';
|
import { getNetwork, Network, Networkish } from './networks';
|
||||||
import { resolveProperties } from '../utils/properties';
|
import { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';
|
||||||
import { parse as parseTransaction, Transaction } from '../utils/transaction';
|
import { parse as parseTransaction, sign as signTransaction, SignDigestFunc, Transaction } from '../utils/transaction';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ export interface Block {
|
|||||||
|
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
nonce: string;
|
nonce: string;
|
||||||
difficulty: string;
|
difficulty: number;
|
||||||
|
|
||||||
gasLimit: BigNumber;
|
gasLimit: BigNumber;
|
||||||
gasUsed: BigNumber;
|
gasUsed: BigNumber;
|
||||||
@ -523,6 +525,11 @@ function getEventString(object) {
|
|||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
throw new Error();
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e.stack);
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error('invalid event - ' + object);
|
throw new Error('invalid event - ' + object);
|
||||||
}
|
}
|
||||||
@ -567,6 +574,84 @@ type Event = {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// @TODO: Perhaps allow a SignDigestAsyncFunc?
|
||||||
|
|
||||||
|
// Enable a simple signing function and provider to provide a full Signer
|
||||||
|
export class ProviderSigner extends Signer {
|
||||||
|
readonly provider: Provider;
|
||||||
|
readonly signDigest: SignDigestFunc;
|
||||||
|
|
||||||
|
private _addressPromise: Promise<string>;
|
||||||
|
|
||||||
|
constructor(address: string | Promise<string>, signDigest: SignDigestFunc, provider: Provider) {
|
||||||
|
super();
|
||||||
|
errors.checkNew(this, ProviderSigner);
|
||||||
|
defineReadOnly(this, '_addressPromise', Promise.resolve(address));
|
||||||
|
defineReadOnly(this, 'signDigest', signDigest);
|
||||||
|
defineReadOnly(this, 'provider', provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAddress(): Promise<string> {
|
||||||
|
return this._addressPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
signMessage(message: Arrayish | string): Promise<string> {
|
||||||
|
return Promise.resolve(joinSignature(this.signDigest(hashMessage(message))));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
||||||
|
transaction = shallowCopy(transaction);
|
||||||
|
|
||||||
|
if (transaction.chainId == null) {
|
||||||
|
transaction.chainId = this.provider.getNetwork().then((network) => {
|
||||||
|
return network.chainId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transaction.from == null) {
|
||||||
|
transaction.from = this.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transaction.gasLimit == null) {
|
||||||
|
transaction.gasLimit = this.provider.estimateGas(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transaction.gasPrice == null) {
|
||||||
|
transaction.gasPrice = this.provider.getGasPrice();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolveProperties(transaction).then((tx) => {
|
||||||
|
let signedTx = signTransaction(tx, this.signDigest);
|
||||||
|
return this._addressPromise.then((address) => {
|
||||||
|
if (parseTransaction(signedTx).from !== address) {
|
||||||
|
errors.throwError('signing address does not match expected address', errors.UNKNOWN_ERROR, { address: parseTransaction(signedTx).from, expectedAddress: address, signedTransaction: signedTx });
|
||||||
|
}
|
||||||
|
return this.provider.sendTransaction(signedTx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
estimateGas(transaction: TransactionRequest): Promise<BigNumber> {
|
||||||
|
transaction = shallowCopy(transaction);
|
||||||
|
|
||||||
|
if (transaction.from == null) {
|
||||||
|
transaction.from = this.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.provider.estimateGas(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
call(transaction: TransactionRequest): Promise<string> {
|
||||||
|
transaction = shallowCopy(transaction);
|
||||||
|
|
||||||
|
if (transaction.from == null) {
|
||||||
|
transaction.from = this.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.provider.call(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Provider {
|
export class Provider {
|
||||||
private _network: Network;
|
private _network: Network;
|
||||||
|
|
||||||
@ -594,19 +679,24 @@ export class Provider {
|
|||||||
*/
|
*/
|
||||||
protected ready: Promise<Network>;
|
protected ready: Promise<Network>;
|
||||||
|
|
||||||
constructor(network: string | Network) {
|
constructor(network: Networkish | Promise<Network>) {
|
||||||
errors.checkNew(this, Provider);
|
errors.checkNew(this, Provider);
|
||||||
|
|
||||||
network = getNetwork(network);
|
if (network instanceof Promise) {
|
||||||
|
defineReadOnly(this, 'ready', network.then((network) => {
|
||||||
if (network) {
|
defineReadOnly(this, '_network', network);
|
||||||
this._network = network;
|
return network;
|
||||||
// Sub-classes MAY re-assign a Promise if a standard network name is provided
|
}));
|
||||||
this.ready = Promise.resolve(this._network);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Sub-classes MUST re-assign a Promise to "ready" that returns a Network
|
let knownNetwork = getNetwork((network == null) ? 'homestead': network);
|
||||||
this.ready = new Promise((resolve, reject) => { });
|
if (knownNetwork) {
|
||||||
|
defineReadOnly(this, '_network', knownNetwork);
|
||||||
|
defineReadOnly(this, 'ready', Promise.resolve(this._network));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
errors.throwError('invalid network', errors.INVALID_ARGUMENT, { arg: 'network', value: network });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastBlockNumber = -2;
|
this._lastBlockNumber = -2;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
import { JsonRpcProvider } from './json-rpc-provider';
|
import { JsonRpcProvider } from './json-rpc-provider';
|
||||||
|
|
||||||
|
import { defineReadOnly } from '../utils/properties';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -24,7 +26,7 @@ export type AsyncProvider = {
|
|||||||
export class Web3Provider extends JsonRpcProvider {
|
export class Web3Provider extends JsonRpcProvider {
|
||||||
readonly _web3Provider: AsyncProvider;
|
readonly _web3Provider: AsyncProvider;
|
||||||
|
|
||||||
constructor(web3Provider: AsyncProvider, network?: Network | string) {
|
constructor(web3Provider: AsyncProvider, network?: Networkish) {
|
||||||
|
|
||||||
if (!web3Provider || !web3Provider.sendAsync) {
|
if (!web3Provider || !web3Provider.sendAsync) {
|
||||||
errors.throwError(
|
errors.throwError(
|
||||||
@ -40,7 +42,7 @@ export class Web3Provider extends JsonRpcProvider {
|
|||||||
super(url, network);
|
super(url, network);
|
||||||
errors.checkNew(this, Web3Provider);
|
errors.checkNew(this, Web3Provider);
|
||||||
|
|
||||||
this._web3Provider = web3Provider;
|
defineReadOnly(this, '_web3Provider', web3Provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
send(method: string, params: any): Promise<any> {
|
send(method: string, params: any): Promise<any> {
|
||||||
|
@ -259,3 +259,10 @@ export function splitSignature(signature: Arrayish): Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function joinSignature(signature: Signature): string {
|
||||||
|
return hexlify(concat([
|
||||||
|
hexZeroPad(signature.r, 32),
|
||||||
|
hexZeroPad(signature.s, 32),
|
||||||
|
(signature.recoveryParam ? '0x1c': '0x1b')
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { concat, hexlify } from './bytes';
|
import { Arrayish, concat, hexlify } from './bytes';
|
||||||
import { toUtf8Bytes } from './utf8';
|
import { toUtf8Bytes } from './utf8';
|
||||||
import { keccak256 } from './keccak256';
|
import { keccak256 } from './keccak256';
|
||||||
|
|
||||||
@ -32,3 +32,16 @@ export function namehash(name: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function id(text: string): string {
|
||||||
|
return keccak256(toUtf8Bytes(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hashMessage(message: Arrayish | string): string {
|
||||||
|
var payload = concat([
|
||||||
|
toUtf8Bytes('\x19Ethereum Signed Message:\n'),
|
||||||
|
toUtf8Bytes(String(message.length)),
|
||||||
|
((typeof(message) === 'string') ? toUtf8Bytes(message): message)
|
||||||
|
]);
|
||||||
|
return keccak256(payload);
|
||||||
|
}
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import { keccak256 } from './keccak256';
|
|
||||||
import { toUtf8Bytes } from './utf8';
|
|
||||||
|
|
||||||
export function id(text: string): string {
|
|
||||||
return keccak256(toUtf8Bytes(text));
|
|
||||||
}
|
|
@ -8,13 +8,12 @@ import { AbiCoder, defaultAbiCoder, parseSignature } from './abi-coder';
|
|||||||
import * as base64 from './base64';
|
import * as base64 from './base64';
|
||||||
import * as bigNumber from './bignumber';
|
import * as bigNumber from './bignumber';
|
||||||
import * as bytes from './bytes';
|
import * as bytes from './bytes';
|
||||||
import { id } from './id';
|
import { hashMessage, id, namehash } from './hash';
|
||||||
import { keccak256 } from './keccak256';
|
import { keccak256 } from './keccak256';
|
||||||
import { namehash } from './namehash';
|
|
||||||
import * as sha2 from './sha2';
|
import * as sha2 from './sha2';
|
||||||
import * as solidity from './solidity';
|
import * as solidity from './solidity';
|
||||||
import { randomBytes } from './random-bytes';
|
import { randomBytes } from './random-bytes';
|
||||||
//import properties = require('./properties');
|
import properties = require('./properties');
|
||||||
import * as RLP from './rlp';
|
import * as RLP from './rlp';
|
||||||
import * as utf8 from './utf8';
|
import * as utf8 from './utf8';
|
||||||
import * as units from './units';
|
import * as units from './units';
|
||||||
@ -30,7 +29,10 @@ export default {
|
|||||||
|
|
||||||
fetchJson: fetchJson,
|
fetchJson: fetchJson,
|
||||||
|
|
||||||
//defineProperty: properties.defineProperty,
|
defineReadOnly: properties.defineReadOnly,
|
||||||
|
defineFrozen: properties.defineFrozen,
|
||||||
|
resolveProperties: properties.resolveProperties,
|
||||||
|
shallowCopy: properties.shallowCopy,
|
||||||
|
|
||||||
// NFKD (decomposed)
|
// NFKD (decomposed)
|
||||||
//etherSymbol: '\uD835\uDF63',
|
//etherSymbol: '\uD835\uDF63',
|
||||||
@ -54,6 +56,7 @@ export default {
|
|||||||
toUtf8Bytes: utf8.toUtf8Bytes,
|
toUtf8Bytes: utf8.toUtf8Bytes,
|
||||||
toUtf8String: utf8.toUtf8String,
|
toUtf8String: utf8.toUtf8String,
|
||||||
|
|
||||||
|
hashMessage: hashMessage,
|
||||||
namehash: namehash,
|
namehash: namehash,
|
||||||
id: id,
|
id: id,
|
||||||
|
|
||||||
@ -77,6 +80,7 @@ export default {
|
|||||||
soliditySha256: solidity.sha256,
|
soliditySha256: solidity.sha256,
|
||||||
|
|
||||||
splitSignature: bytes.splitSignature,
|
splitSignature: bytes.splitSignature,
|
||||||
|
joinSignature: bytes.joinSignature,
|
||||||
|
|
||||||
parseTransaction: parseTransaction
|
parseTransaction: parseTransaction
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
export function defineReadOnly(object, name, value) {
|
export function defineReadOnly(object: any, name: string, value: any): void {
|
||||||
Object.defineProperty(object, name, {
|
Object.defineProperty(object, name, {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
value: value,
|
value: value,
|
||||||
@ -8,7 +8,7 @@ export function defineReadOnly(object, name, value) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defineFrozen(object, name, value) {
|
export function defineFrozen(object: any, name: string, value: any): void {
|
||||||
var frozen = JSON.stringify(value);
|
var frozen = JSON.stringify(value);
|
||||||
Object.defineProperty(object, name, {
|
Object.defineProperty(object, name, {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
@ -16,23 +16,7 @@ export function defineFrozen(object, name, value) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DeferredSetter = (value: any) => void;
|
export function resolveProperties(object: any): Promise<any> {
|
||||||
export function defineDeferredReadOnly(object, name, value): DeferredSetter {
|
|
||||||
var _value = value;
|
|
||||||
var setter = function(value: any): void {
|
|
||||||
_value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.defineProperty(object, name, {
|
|
||||||
enumerable: true,
|
|
||||||
get: function(): any { return _value; },
|
|
||||||
set: setter
|
|
||||||
});
|
|
||||||
|
|
||||||
return setter;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveProperties(object: any) {
|
|
||||||
let result: any = {};
|
let result: any = {};
|
||||||
|
|
||||||
let promises: Array<Promise<any>> = [];
|
let promises: Array<Promise<any>> = [];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getAddress } from './address';
|
import { getAddress } from './address';
|
||||||
import { arrayify, Arrayish, hexlify } from './bytes';
|
import { arrayify, Arrayish, hexlify, hexZeroPad } from './bytes';
|
||||||
import { keccak256 } from './keccak256';
|
import { keccak256 } from './keccak256';
|
||||||
import { defineReadOnly } from './properties';
|
import { defineReadOnly } from './properties';
|
||||||
|
|
||||||
@ -75,8 +75,8 @@ export class KeyPair {
|
|||||||
let signature = keyPair.sign(arrayify(digest), {canonical: true});
|
let signature = keyPair.sign(arrayify(digest), {canonical: true});
|
||||||
return {
|
return {
|
||||||
recoveryParam: signature.recoveryParam,
|
recoveryParam: signature.recoveryParam,
|
||||||
r: '0x' + signature.r.toString(16),
|
r: hexZeroPad('0x' + signature.r.toString(16), 32),
|
||||||
s: '0x' + signature.s.toString(16),
|
s: hexZeroPad('0x' + signature.s.toString(16), 32),
|
||||||
v: 27 + signature.recoveryParam
|
v: 27 + signature.recoveryParam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import { getAddress } from './address';
|
import { getAddress } from './address';
|
||||||
import { BigNumber, bigNumberify, BigNumberish,ConstantZero } from './bignumber';
|
import { BigNumber, bigNumberify, BigNumberish,ConstantZero } from './bignumber';
|
||||||
import { arrayify, Arrayish, hexlify, stripZeros, } from './bytes';
|
import { arrayify, Arrayish, hexlify, hexZeroPad, stripZeros, } from './bytes';
|
||||||
import { keccak256 } from './keccak256';
|
import { keccak256 } from './keccak256';
|
||||||
import { recoverAddress, Signature } from './secp256k1';
|
import { recoverAddress, Signature } from './secp256k1';
|
||||||
import * as RLP from './rlp';
|
import * as RLP from './rlp';
|
||||||
@ -110,8 +110,8 @@ export function sign(transaction: UnsignedTransaction, signDigest: SignDigestFun
|
|||||||
}
|
}
|
||||||
|
|
||||||
raw.push(hexlify(v));
|
raw.push(hexlify(v));
|
||||||
raw.push(signature.r);
|
raw.push(stripZeros(arrayify(signature.r)));
|
||||||
raw.push(signature.s);
|
raw.push(stripZeros(arrayify(signature.s)));
|
||||||
|
|
||||||
return RLP.encode(raw);
|
return RLP.encode(raw);
|
||||||
}
|
}
|
||||||
@ -136,8 +136,8 @@ export function parse(rawTransaction: Arrayish): Transaction {
|
|||||||
|
|
||||||
if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) {
|
if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) {
|
||||||
tx.v = bigNumberify(v).toNumber();
|
tx.v = bigNumberify(v).toNumber();
|
||||||
tx.r = signedTransaction[7];
|
tx.r = hexZeroPad(signedTransaction[7], 32);
|
||||||
tx.s = signedTransaction[8];
|
tx.s = hexZeroPad(signedTransaction[8], 32);
|
||||||
|
|
||||||
var chainId = (tx.v - 35) / 2;
|
var chainId = (tx.v - 35) / 2;
|
||||||
if (chainId < 0) { chainId = 0; }
|
if (chainId < 0) { chainId = 0; }
|
||||||
|
@ -30,6 +30,9 @@ function getLowerMask(bits: number): number {
|
|||||||
return (1 << bits) - 1;
|
return (1 << bits) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const defaultPath = "m/44'/60'/0'/0/0";
|
||||||
|
|
||||||
export class HDNode {
|
export class HDNode {
|
||||||
private readonly keyPair: KeyPair;
|
private readonly keyPair: KeyPair;
|
||||||
|
|
||||||
@ -254,3 +257,4 @@ export function isValidMnemonic(mnemonic: string): boolean {
|
|||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import scrypt from 'scrypt-js';
|
import scrypt from 'scrypt-js';
|
||||||
|
|
||||||
import { entropyToMnemonic, fromMnemonic, HDNode } from './hdnode';
|
import { defaultPath, entropyToMnemonic, fromMnemonic, HDNode } from './hdnode';
|
||||||
import * as secretStorage from './secret-storage';
|
import * as secretStorage from './secret-storage';
|
||||||
import { ProgressCallback } from './secret-storage';
|
import { ProgressCallback } from './secret-storage';
|
||||||
import { recoverAddress, SigningKey } from './signing-key';
|
import { recoverAddress, SigningKey } from './signing-key';
|
||||||
@ -10,11 +10,12 @@ import { recoverAddress, SigningKey } from './signing-key';
|
|||||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from '../providers/provider';
|
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from '../providers/provider';
|
||||||
|
|
||||||
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
||||||
import { arrayify, Arrayish, concat, hexlify, hexZeroPad } from '../utils/bytes';
|
import { arrayify, Arrayish, concat, hexlify, joinSignature } from '../utils/bytes';
|
||||||
|
import { hashMessage } from '../utils/hash';
|
||||||
import { keccak256 } from '../utils/keccak256';
|
import { keccak256 } from '../utils/keccak256';
|
||||||
import { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';
|
import { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';
|
||||||
import { randomBytes } from '../utils/random-bytes';
|
import { randomBytes } from '../utils/random-bytes';
|
||||||
import { sign as signTransaction, UnsignedTransaction } from '../utils/transaction';
|
import { sign as signTransaction } from '../utils/transaction';
|
||||||
import { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';
|
import { toUtf8Bytes, UnicodeNormalizationForm } from '../utils/utf8';
|
||||||
|
|
||||||
import * as errors from '../utils/errors';
|
import * as errors from '../utils/errors';
|
||||||
@ -25,71 +26,73 @@ import * as errors from '../utils/errors';
|
|||||||
console.log("Fix this! Setimmediate");
|
console.log("Fix this! Setimmediate");
|
||||||
//import _setimmediate = require('setimmediate');
|
//import _setimmediate = require('setimmediate');
|
||||||
|
|
||||||
export interface Signer {
|
export abstract class Signer {
|
||||||
// One of these MUST be specified
|
provider?: Provider;
|
||||||
address?: string;
|
|
||||||
getAddress(): Promise<string>
|
|
||||||
|
|
||||||
sendTransaction(transaction: UnsignedTransaction): Promise<TransactionResponse>;
|
abstract getAddress(): Promise<string>
|
||||||
|
|
||||||
// If sendTransaction is not implemented, the following MUST be
|
abstract signMessage(transaction: Arrayish | string): Promise<string>;
|
||||||
provider: Provider;
|
abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
sign(transaction: UnsignedTransaction): string;
|
|
||||||
|
|
||||||
// The following MAY be i,plemented
|
|
||||||
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
|
||||||
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
|
||||||
getGasPrice(transaction?: TransactionRequest): Promise<BigNumber>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: Move to HDNode
|
|
||||||
var defaultPath = "m/44'/60'/0'/0/0";
|
|
||||||
|
|
||||||
|
export class Wallet extends Signer {
|
||||||
|
|
||||||
export class Wallet implements Signer {
|
|
||||||
readonly address: string;
|
readonly address: string;
|
||||||
readonly privateKey: string;
|
readonly privateKey: string;
|
||||||
|
|
||||||
|
readonly provider: Provider;
|
||||||
|
|
||||||
|
|
||||||
private mnemonic: string;
|
private mnemonic: string;
|
||||||
private path: string;
|
private path: string;
|
||||||
|
|
||||||
private readonly signingKey: SigningKey;
|
private readonly signingKey: SigningKey;
|
||||||
|
|
||||||
provider: Provider;
|
|
||||||
|
|
||||||
//private _provider;
|
|
||||||
|
|
||||||
public defaultGasLimit: number = 1500000;
|
public defaultGasLimit: number = 1500000;
|
||||||
|
|
||||||
constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider) {
|
constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider) {
|
||||||
|
super();
|
||||||
errors.checkNew(this, Wallet);
|
errors.checkNew(this, Wallet);
|
||||||
|
|
||||||
// Make sure we have a valid signing key
|
// Make sure we have a valid signing key
|
||||||
if (privateKey instanceof SigningKey) {
|
if (privateKey instanceof SigningKey) {
|
||||||
this.signingKey = privateKey;
|
defineReadOnly(this, 'signingKey', privateKey);
|
||||||
if (this.signingKey.mnemonic) {
|
if (this.signingKey.mnemonic) {
|
||||||
defineReadOnly(this, 'mnemonic', privateKey.mnemonic);
|
defineReadOnly(this, 'mnemonic', privateKey.mnemonic);
|
||||||
defineReadOnly(this, 'path', privateKey.path);
|
defineReadOnly(this, 'path', privateKey.path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.signingKey = new SigningKey(privateKey);
|
defineReadOnly(this, 'signingKey', new SigningKey(privateKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
defineReadOnly(this, 'privateKey', this.signingKey.privateKey);
|
defineReadOnly(this, 'privateKey', this.signingKey.privateKey);
|
||||||
|
|
||||||
this.provider = provider;
|
defineReadOnly(this, 'provider', provider);
|
||||||
|
|
||||||
defineReadOnly(this, 'address', this.signingKey.address);
|
defineReadOnly(this, 'address', this.signingKey.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
sign(transaction: UnsignedTransaction): string {
|
connect(provider: Provider): Wallet {
|
||||||
return signTransaction(transaction, this.signingKey.signDigest.bind(this.signingKey));
|
return new Wallet(this.signingKey, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getAddress(): Promise<string> {
|
getAddress(): Promise<string> {
|
||||||
return Promise.resolve(this.address);
|
return Promise.resolve(this.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sign(transaction: TransactionRequest): Promise<string> {
|
||||||
|
return resolveProperties(transaction).then((tx) => {
|
||||||
|
return signTransaction(tx, this.signingKey.signDigest.bind(this.signingKey));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
signMessage(message: Arrayish | string): Promise<string> {
|
||||||
|
return Promise.resolve(joinSignature(this.signingKey.signDigest(hashMessage(message))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getBalance(blockTag?: BlockTag): Promise<BigNumber> {
|
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);
|
||||||
@ -100,26 +103,6 @@ export class Wallet implements Signer {
|
|||||||
return this.provider.getTransactionCount(this.address, blockTag);
|
return this.provider.getTransactionCount(this.address, blockTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
getGasPrice(): Promise<BigNumber> {
|
|
||||||
if (!this.provider) { throw new Error('missing provider'); }
|
|
||||||
|
|
||||||
return this.provider.getGasPrice();
|
|
||||||
}
|
|
||||||
|
|
||||||
estimateGas(transaction: TransactionRequest): Promise<BigNumber> {
|
|
||||||
if (!this.provider) { throw new Error('missing provider'); }
|
|
||||||
|
|
||||||
var calculate: TransactionRequest = {};
|
|
||||||
['from', 'to', 'data', 'value'].forEach(function(key) {
|
|
||||||
if (transaction[key] == null) { return; }
|
|
||||||
calculate[key] = transaction[key];
|
|
||||||
});
|
|
||||||
|
|
||||||
if (transaction.from == null) { calculate.from = this.address; }
|
|
||||||
|
|
||||||
return this.provider.estimateGas(calculate);
|
|
||||||
}
|
|
||||||
|
|
||||||
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
||||||
if (!this.provider) { throw new Error('missing provider'); }
|
if (!this.provider) { throw new Error('missing provider'); }
|
||||||
|
|
||||||
@ -134,11 +117,11 @@ export class Wallet implements Signer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx);
|
tx.gasLimit = this.provider.estimateGas(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.gasPrice == null) {
|
if (tx.gasPrice == null) {
|
||||||
tx.gasPrice = this.getGasPrice();
|
tx.gasPrice = this.provider.getGasPrice();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.nonce == null) {
|
if (tx.nonce == null) {
|
||||||
@ -169,41 +152,6 @@ export class Wallet implements Signer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static hashMessage(message: Arrayish | string): string {
|
|
||||||
var payload = concat([
|
|
||||||
toUtf8Bytes('\x19Ethereum Signed Message:\n'),
|
|
||||||
toUtf8Bytes(String(message.length)),
|
|
||||||
((typeof(message) === 'string') ? toUtf8Bytes(message): message)
|
|
||||||
]);
|
|
||||||
return keccak256(payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
signMessage(message: Arrayish | string): string {
|
|
||||||
var signingKey = new SigningKey(this.privateKey);
|
|
||||||
var sig = signingKey.signDigest(Wallet.hashMessage(message));
|
|
||||||
|
|
||||||
return (hexZeroPad(sig.r, 32) + hexZeroPad(sig.s, 32).substring(2) + (sig.recoveryParam ? '1c': '1b'));
|
|
||||||
}
|
|
||||||
|
|
||||||
static verifyMessage(message: Arrayish | string, signature: string): string {
|
|
||||||
signature = hexlify(signature);
|
|
||||||
if (signature.length != 132) { throw new Error('invalid signature'); }
|
|
||||||
var digest = Wallet.hashMessage(message);
|
|
||||||
|
|
||||||
var recoveryParam = parseInt(signature.substring(130), 16);
|
|
||||||
if (recoveryParam >= 27) { recoveryParam -= 27; }
|
|
||||||
if (recoveryParam < 0) { throw new Error('invalid signature'); }
|
|
||||||
|
|
||||||
return recoverAddress(
|
|
||||||
digest,
|
|
||||||
{
|
|
||||||
r: signature.substring(0, 66),
|
|
||||||
s: '0x' + signature.substring(66, 130),
|
|
||||||
recoveryParam: recoveryParam
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string> {
|
encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string> {
|
||||||
if (typeof(options) === 'function' && !progressCallback) {
|
if (typeof(options) === 'function' && !progressCallback) {
|
||||||
progressCallback = options;
|
progressCallback = options;
|
||||||
@ -323,4 +271,25 @@ export class Wallet implements Signer {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static verifyMessage(message: Arrayish | string, signature: string): string {
|
||||||
|
signature = hexlify(signature);
|
||||||
|
if (signature.length != 132) { throw new Error('invalid signature'); }
|
||||||
|
var digest = hashMessage(message);
|
||||||
|
|
||||||
|
var recoveryParam = parseInt(signature.substring(130), 16);
|
||||||
|
if (recoveryParam >= 27) { recoveryParam -= 27; }
|
||||||
|
if (recoveryParam < 0) { throw new Error('invalid signature'); }
|
||||||
|
|
||||||
|
return recoverAddress(
|
||||||
|
digest,
|
||||||
|
{
|
||||||
|
r: signature.substring(0, 66),
|
||||||
|
s: '0x' + signature.substring(66, 130),
|
||||||
|
recoveryParam: recoveryParam
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var interface_1 = require("./interface");
|
var interface_1 = require("./interface");
|
||||||
|
var provider_1 = require("../providers/provider");
|
||||||
|
var wallet_1 = require("../wallet/wallet");
|
||||||
var address_1 = require("../utils/address");
|
var address_1 = require("../utils/address");
|
||||||
var bytes_1 = require("../utils/bytes");
|
var bytes_1 = require("../utils/bytes");
|
||||||
var bignumber_1 = require("../utils/bignumber");
|
var bignumber_1 = require("../utils/bignumber");
|
||||||
@ -16,13 +18,8 @@ var errors = __importStar(require("../utils/errors"));
|
|||||||
var allowedTransactionKeys = {
|
var allowedTransactionKeys = {
|
||||||
data: true, from: true, gasLimit: true, gasPrice: true, nonce: true, to: true, value: true
|
data: true, from: true, gasLimit: true, gasPrice: true, nonce: true, to: true, value: true
|
||||||
};
|
};
|
||||||
function copyObject(object) {
|
// Recursively replaces ENS names with promises to resolve the name and
|
||||||
var result = {};
|
// stalls until all promises have returned
|
||||||
for (var key in object) {
|
|
||||||
result[key] = object[key];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// @TODO: Expand this to resolve any promises too
|
// @TODO: Expand this to resolve any promises too
|
||||||
function resolveAddresses(provider, value, paramType) {
|
function resolveAddresses(provider, value, paramType) {
|
||||||
if (Array.isArray(paramType)) {
|
if (Array.isArray(paramType)) {
|
||||||
@ -54,12 +51,12 @@ function runMethod(contract, functionName, estimateOnly) {
|
|||||||
for (var _i = 0; _i < arguments.length; _i++) {
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||||||
params[_i] = arguments[_i];
|
params[_i] = arguments[_i];
|
||||||
}
|
}
|
||||||
var transaction = {};
|
var tx = {};
|
||||||
// If 1 extra parameter was passed in, it contains overrides
|
// If 1 extra parameter was passed in, it contains overrides
|
||||||
if (params.length === method.inputs.length + 1 && typeof (params[params.length - 1]) === 'object') {
|
if (params.length === method.inputs.length + 1 && typeof (params[params.length - 1]) === 'object') {
|
||||||
transaction = copyObject(params.pop());
|
tx = properties_1.shallowCopy(params.pop());
|
||||||
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
|
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
|
||||||
for (var key in transaction) {
|
for (var key in tx) {
|
||||||
if (!allowedTransactionKeys[key]) {
|
if (!allowedTransactionKeys[key]) {
|
||||||
throw new Error('unknown transaction override ' + key);
|
throw new Error('unknown transaction override ' + key);
|
||||||
}
|
}
|
||||||
@ -70,137 +67,80 @@ function runMethod(contract, functionName, estimateOnly) {
|
|||||||
}
|
}
|
||||||
// Check overrides make sense
|
// Check overrides make sense
|
||||||
['data', 'to'].forEach(function (key) {
|
['data', 'to'].forEach(function (key) {
|
||||||
if (transaction[key] != null) {
|
if (tx[key] != null) {
|
||||||
throw new Error('cannot override ' + key);
|
errors.throwError('cannot override ' + key, errors.UNSUPPORTED_OPERATION, { operation: key });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Send to the contract address
|
// Send to the contract address
|
||||||
transaction.to = contract.addressPromise;
|
tx.to = contract.addressPromise;
|
||||||
return resolveAddresses(contract.provider, params, method.inputs).then(function (params) {
|
return resolveAddresses(contract.provider, params, method.inputs).then(function (params) {
|
||||||
transaction.data = method.encode(params);
|
tx.data = method.encode(params);
|
||||||
if (method.type === 'call') {
|
if (method.type === 'call') {
|
||||||
// Call (constant functions) always cost 0 ether
|
// Call (constant functions) always cost 0 ether
|
||||||
if (estimateOnly) {
|
if (estimateOnly) {
|
||||||
return Promise.resolve(bignumber_1.ConstantZero);
|
return Promise.resolve(bignumber_1.ConstantZero);
|
||||||
}
|
}
|
||||||
|
if (!contract.provider) {
|
||||||
|
errors.throwError('call (constant functions) require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'call' });
|
||||||
|
}
|
||||||
// Check overrides make sense
|
// Check overrides make sense
|
||||||
['gasLimit', 'gasPrice', 'value'].forEach(function (key) {
|
['gasLimit', 'gasPrice', 'value'].forEach(function (key) {
|
||||||
if (transaction[key] != null) {
|
if (tx[key] != null) {
|
||||||
throw new Error('call cannot override ' + key);
|
throw new Error('call cannot override ' + key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (transaction.from == null && contract.signer) {
|
if (tx.from == null && contract.signer) {
|
||||||
if (contract.signer.address) {
|
tx.from = contract.signer.getAddress();
|
||||||
transaction.from = contract.signer.address;
|
|
||||||
}
|
|
||||||
else if (contract.signer.getAddress) {
|
|
||||||
transaction.from = contract.signer.getAddress();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return properties_1.resolveProperties(transaction).then(function (transaction) {
|
return contract.provider.call(tx).then(function (value) {
|
||||||
return contract.provider.call(transaction).then(function (value) {
|
try {
|
||||||
try {
|
var result = method.decode(value);
|
||||||
var result = method.decode(value);
|
if (method.outputs.length === 1) {
|
||||||
if (method.outputs.length === 1) {
|
result = result[0];
|
||||||
result = result[0];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
return result;
|
||||||
if (value === '0x' && method.outputs.length > 0) {
|
}
|
||||||
errors.throwError('call exception', errors.CALL_EXCEPTION, {
|
catch (error) {
|
||||||
address: contract.address,
|
if (value === '0x' && method.outputs.length > 0) {
|
||||||
method: method.signature,
|
errors.throwError('call exception', errors.CALL_EXCEPTION, {
|
||||||
value: params
|
address: contract.address,
|
||||||
});
|
method: method.signature,
|
||||||
}
|
value: params
|
||||||
throw error;
|
});
|
||||||
}
|
}
|
||||||
});
|
throw error;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (method.type === 'transaction') {
|
else if (method.type === 'transaction') {
|
||||||
if (!contract.signer) {
|
|
||||||
return Promise.reject(new Error('missing signer'));
|
|
||||||
}
|
|
||||||
// Make sure they aren't overriding something they shouldn't
|
|
||||||
if (transaction.from != null) {
|
|
||||||
throw new Error('transaction cannot override from');
|
|
||||||
}
|
|
||||||
// Only computing the transaction estimate
|
// Only computing the transaction estimate
|
||||||
if (estimateOnly) {
|
if (estimateOnly) {
|
||||||
if (contract.signer.estimateGas) {
|
if (!contract.provider) {
|
||||||
return contract.signer.estimateGas(transaction);
|
errors.throwError('estimate gas require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'estimateGas' });
|
||||||
}
|
}
|
||||||
if (contract.signer.address) {
|
if (tx.from == null && contract.signer) {
|
||||||
transaction.from = contract.signer.address;
|
tx.from = contract.signer.getAddress();
|
||||||
}
|
}
|
||||||
else if (contract.signer.getAddress) {
|
return contract.provider.estimateGas(tx);
|
||||||
transaction.from = contract.signer.getAddress();
|
|
||||||
}
|
|
||||||
return properties_1.resolveProperties(transaction).then(function (transaction) {
|
|
||||||
return contract.provider.estimateGas(transaction);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// If the signer supports sendTrasaction, use it
|
if (!contract.signer) {
|
||||||
if (contract.signer.sendTransaction) {
|
errors.throwError('sending a transaction require a signer', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction' });
|
||||||
return contract.signer.sendTransaction(transaction);
|
|
||||||
}
|
}
|
||||||
if (!contract.signer.sign) {
|
// Make sure they aren't overriding something they shouldn't
|
||||||
return Promise.reject(new Error('custom signer does not support signing'));
|
if (tx.from != null) {
|
||||||
|
errors.throwError('cannot override from in a transaction', errors.UNSUPPORTED_OPERATION, { operation: 'sendTransaction' });
|
||||||
}
|
}
|
||||||
if (transaction.chainId == null) {
|
return contract.signer.sendTransaction(tx);
|
||||||
transaction.chainId = contract.provider.getNetwork().then(function (network) {
|
|
||||||
return network.chainId;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (transaction.gasLimit == null) {
|
|
||||||
if (contract.signer.estimateGas) {
|
|
||||||
transaction.gasLimit = contract.signer.estimateGas(transaction);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
transaction.gasLimit = contract.provider.estimateGas(transaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!transaction.nonce) {
|
|
||||||
if (contract.signer.getTransactionCount) {
|
|
||||||
transaction.nonce = contract.signer.getTransactionCount();
|
|
||||||
}
|
|
||||||
else if (contract.signer.address) {
|
|
||||||
transaction.nonce = contract.provider.getTransactionCount(contract.signer.address);
|
|
||||||
}
|
|
||||||
else if (contract.signer.getAddress) {
|
|
||||||
transaction.nonce = contract.provider.getTransactionCount(contract.signer.getAddress());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('cannot determine nonce');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!transaction.gasPrice) {
|
|
||||||
if (contract.signer.getGasPrice) {
|
|
||||||
transaction.gasPrice = contract.signer.getGasPrice(transaction);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
transaction.gasPrice = contract.provider.getGasPrice();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return properties_1.resolveProperties(transaction).then(function (transaction) {
|
|
||||||
var signedTransaction = contract.signer.sign(transaction);
|
|
||||||
return contract.provider.sendTransaction(signedTransaction);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
throw new Error('invalid type - ' + method.type);
|
throw new Error('invalid type - ' + method.type);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
throw new Error('unsupport type - ' + method.type);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function isSigner(value) {
|
|
||||||
return (value && value.provider != null);
|
|
||||||
}
|
|
||||||
var Contract = /** @class */ (function () {
|
var Contract = /** @class */ (function () {
|
||||||
// https://github.com/Microsoft/TypeScript/issues/5453
|
// https://github.com/Microsoft/TypeScript/issues/5453
|
||||||
// Once this issue is resolved (there are open PR) we can do this nicer. :)
|
// Once this issue is resolved (there are open PR) we can do this nicer
|
||||||
|
// by making addressOrName default to null for 2 operand calls. :)
|
||||||
function Contract(addressOrName, contractInterface, signerOrProvider) {
|
function Contract(addressOrName, contractInterface, signerOrProvider) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
errors.checkNew(this, Contract);
|
errors.checkNew(this, Contract);
|
||||||
@ -212,17 +152,17 @@ var Contract = /** @class */ (function () {
|
|||||||
else {
|
else {
|
||||||
properties_1.defineReadOnly(this, 'interface', new interface_1.Interface(contractInterface));
|
properties_1.defineReadOnly(this, 'interface', new interface_1.Interface(contractInterface));
|
||||||
}
|
}
|
||||||
if (!signerOrProvider) {
|
if (signerOrProvider instanceof wallet_1.Signer) {
|
||||||
throw new Error('missing signer or provider');
|
|
||||||
}
|
|
||||||
if (isSigner(signerOrProvider)) {
|
|
||||||
properties_1.defineReadOnly(this, 'provider', signerOrProvider.provider);
|
properties_1.defineReadOnly(this, 'provider', signerOrProvider.provider);
|
||||||
properties_1.defineReadOnly(this, 'signer', signerOrProvider);
|
properties_1.defineReadOnly(this, 'signer', signerOrProvider);
|
||||||
}
|
}
|
||||||
else {
|
else if (signerOrProvider instanceof provider_1.Provider) {
|
||||||
properties_1.defineReadOnly(this, 'provider', signerOrProvider);
|
properties_1.defineReadOnly(this, 'provider', signerOrProvider);
|
||||||
properties_1.defineReadOnly(this, 'signer', null);
|
properties_1.defineReadOnly(this, 'signer', null);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
errors.throwError('invalid signer or provider', errors.INVALID_ARGUMENT, { arg: 'signerOrProvider', value: signerOrProvider });
|
||||||
|
}
|
||||||
properties_1.defineReadOnly(this, 'estimate', {});
|
properties_1.defineReadOnly(this, 'estimate', {});
|
||||||
properties_1.defineReadOnly(this, 'events', {});
|
properties_1.defineReadOnly(this, 'events', {});
|
||||||
properties_1.defineReadOnly(this, 'functions', {});
|
properties_1.defineReadOnly(this, 'functions', {});
|
||||||
@ -232,8 +172,8 @@ var Contract = /** @class */ (function () {
|
|||||||
properties_1.defineReadOnly(this, 'addressPromise', Promise.resolve(null));
|
properties_1.defineReadOnly(this, 'addressPromise', Promise.resolve(null));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
properties_1.defineReadOnly(this, 'address', addressOrName || null);
|
properties_1.defineReadOnly(this, 'address', addressOrName);
|
||||||
properties_1.defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName || null));
|
properties_1.defineReadOnly(this, 'addressPromise', this.provider.resolveName(addressOrName));
|
||||||
Object.keys(this.interface.functions).forEach(function (name) {
|
Object.keys(this.interface.functions).forEach(function (name) {
|
||||||
var run = runMethod(_this, name, false);
|
var run = runMethod(_this, name, false);
|
||||||
if (_this[name] == null) {
|
if (_this[name] == null) {
|
||||||
@ -264,7 +204,7 @@ var Contract = /** @class */ (function () {
|
|||||||
log.event = eventName;
|
log.event = eventName;
|
||||||
log.parse = eventInfo.parse;
|
log.parse = eventInfo.parse;
|
||||||
log.removeListener = function () {
|
log.removeListener = function () {
|
||||||
contract.provider.removeListener(eventInfo.topics, handleEvent);
|
contract.provider.removeListener([eventInfo.topic], handleEvent);
|
||||||
};
|
};
|
||||||
log.getBlock = function () { return contract.provider.getBlock(log.blockHash); ; };
|
log.getBlock = function () { return contract.provider.getBlock(log.blockHash); ; };
|
||||||
log.getTransaction = function () { return contract.provider.getTransaction(log.transactionHash); };
|
log.getTransaction = function () { return contract.provider.getTransaction(log.transactionHash); };
|
||||||
@ -286,11 +226,14 @@ var Contract = /** @class */ (function () {
|
|||||||
if (!value) {
|
if (!value) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
|
if (!contract.provider) {
|
||||||
|
errors.throwError('events require a provider or a signer with a provider', errors.UNSUPPORTED_OPERATION, { operation: 'events' });
|
||||||
|
}
|
||||||
if (!value && eventCallback) {
|
if (!value && eventCallback) {
|
||||||
contract.provider.removeListener(eventInfo.topics, handleEvent);
|
contract.provider.removeListener([eventInfo.topic], handleEvent);
|
||||||
}
|
}
|
||||||
else if (value && !eventCallback) {
|
else if (value && !eventCallback) {
|
||||||
contract.provider.on(eventInfo.topics, handleEvent);
|
contract.provider.on([eventInfo.topic], handleEvent);
|
||||||
}
|
}
|
||||||
eventCallback = value;
|
eventCallback = value;
|
||||||
}
|
}
|
||||||
@ -328,7 +271,7 @@ var Contract = /** @class */ (function () {
|
|||||||
return this.signer.sendTransaction({
|
return this.signer.sendTransaction({
|
||||||
data: this.interface.deployFunction.encode(bytecode, args)
|
data: this.interface.deployFunction.encode(bytecode, args)
|
||||||
}).then(function (tx) {
|
}).then(function (tx) {
|
||||||
var contract = new Contract(address_1.getContractAddress(tx), _this.interface, _this.provider);
|
var contract = new Contract(address_1.getContractAddress(tx), _this.interface, _this.signer || _this.provider);
|
||||||
properties_1.defineReadOnly(contract, 'deployTransaction', tx);
|
properties_1.defineReadOnly(contract, 'deployTransaction', tx);
|
||||||
return contract;
|
return contract;
|
||||||
});
|
});
|
||||||
|
36
src/contracts/interface.d.ts
vendored
36
src/contracts/interface.d.ts
vendored
@ -2,15 +2,13 @@ import { ParamType } from '../utils/abi-coder';
|
|||||||
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
||||||
export declare class Description {
|
export declare class Description {
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
readonly inputs: Array<ParamType>;
|
|
||||||
constructor(info: any);
|
constructor(info: any);
|
||||||
}
|
}
|
||||||
export declare class Indexed {
|
export declare class Indexed extends Description {
|
||||||
readonly type: string;
|
|
||||||
readonly hash: string;
|
readonly hash: string;
|
||||||
constructor(value: string);
|
|
||||||
}
|
}
|
||||||
export declare class DeployDescription extends Description {
|
export declare class DeployDescription extends Description {
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly payable: boolean;
|
readonly payable: boolean;
|
||||||
encode(bytecode: string, params: Array<any>): string;
|
encode(bytecode: string, params: Array<any>): string;
|
||||||
}
|
}
|
||||||
@ -18,25 +16,34 @@ export declare class FunctionDescription extends Description {
|
|||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly signature: string;
|
readonly signature: string;
|
||||||
readonly sighash: string;
|
readonly sighash: string;
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly outputs: Array<ParamType>;
|
readonly outputs: Array<ParamType>;
|
||||||
readonly payable: boolean;
|
readonly payable: boolean;
|
||||||
encode(params: Array<any>): string;
|
encode(params: Array<any>): string;
|
||||||
decode(data: string): any;
|
decode(data: string): any;
|
||||||
}
|
}
|
||||||
export declare type CallTransaction = {
|
|
||||||
args: Array<any>;
|
|
||||||
signature: string;
|
|
||||||
sighash: string;
|
|
||||||
decode: (data: string) => any;
|
|
||||||
value: BigNumber;
|
|
||||||
};
|
|
||||||
export declare class EventDescription extends Description {
|
export declare class EventDescription extends Description {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly signature: string;
|
readonly signature: string;
|
||||||
|
readonly inputs: Array<ParamType>;
|
||||||
readonly anonymous: boolean;
|
readonly anonymous: boolean;
|
||||||
readonly topic: string;
|
readonly topic: string;
|
||||||
decode(data: string, topics?: Array<string>): any;
|
decode(data: string, topics?: Array<string>): any;
|
||||||
}
|
}
|
||||||
|
declare class TransactionDescription extends Description {
|
||||||
|
readonly name: string;
|
||||||
|
readonly args: Array<any>;
|
||||||
|
readonly signature: string;
|
||||||
|
readonly sighash: string;
|
||||||
|
readonly decode: (data: string) => any;
|
||||||
|
readonly value: BigNumber;
|
||||||
|
}
|
||||||
|
declare class LogDescription extends Description {
|
||||||
|
readonly name: string;
|
||||||
|
readonly signature: string;
|
||||||
|
readonly topic: string;
|
||||||
|
readonly values: Array<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>;
|
||||||
@ -46,5 +53,10 @@ export declare class Interface {
|
|||||||
parseTransaction(tx: {
|
parseTransaction(tx: {
|
||||||
data: string;
|
data: string;
|
||||||
value?: BigNumberish;
|
value?: BigNumberish;
|
||||||
}): CallTransaction;
|
}): TransactionDescription;
|
||||||
|
parseLog(log: {
|
||||||
|
topics: Array<string>;
|
||||||
|
data: string;
|
||||||
|
}): LogDescription;
|
||||||
}
|
}
|
||||||
|
export {};
|
||||||
|
@ -68,13 +68,13 @@ var Description = /** @class */ (function () {
|
|||||||
}());
|
}());
|
||||||
exports.Description = Description;
|
exports.Description = Description;
|
||||||
// @TOOD: Make this a description
|
// @TOOD: Make this a description
|
||||||
var Indexed = /** @class */ (function () {
|
var Indexed = /** @class */ (function (_super) {
|
||||||
function Indexed(value) {
|
__extends(Indexed, _super);
|
||||||
properties_1.defineReadOnly(this, 'type', 'indexed');
|
function Indexed() {
|
||||||
properties_1.defineReadOnly(this, 'hash', value);
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
}
|
}
|
||||||
return Indexed;
|
return Indexed;
|
||||||
}());
|
}(Description));
|
||||||
exports.Indexed = Indexed;
|
exports.Indexed = Indexed;
|
||||||
var DeployDescription = /** @class */ (function (_super) {
|
var DeployDescription = /** @class */ (function (_super) {
|
||||||
__extends(DeployDescription, _super);
|
__extends(DeployDescription, _super);
|
||||||
@ -166,8 +166,13 @@ var FunctionDescription = /** @class */ (function (_super) {
|
|||||||
return FunctionDescription;
|
return FunctionDescription;
|
||||||
}(Description));
|
}(Description));
|
||||||
exports.FunctionDescription = FunctionDescription;
|
exports.FunctionDescription = FunctionDescription;
|
||||||
// @TODO: Make this a description
|
var Result = /** @class */ (function (_super) {
|
||||||
function Result() { }
|
__extends(Result, _super);
|
||||||
|
function Result() {
|
||||||
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}(Description));
|
||||||
var EventDescription = /** @class */ (function (_super) {
|
var EventDescription = /** @class */ (function (_super) {
|
||||||
__extends(EventDescription, _super);
|
__extends(EventDescription, _super);
|
||||||
function EventDescription() {
|
function EventDescription() {
|
||||||
@ -200,15 +205,15 @@ var EventDescription = /** @class */ (function (_super) {
|
|||||||
var resultIndexed = abi_coder_1.defaultAbiCoder.decode(inputIndexed, bytes_1.concat(topics));
|
var resultIndexed = abi_coder_1.defaultAbiCoder.decode(inputIndexed, bytes_1.concat(topics));
|
||||||
}
|
}
|
||||||
var resultNonIndexed = abi_coder_1.defaultAbiCoder.decode(inputNonIndexed, bytes_1.arrayify(data));
|
var resultNonIndexed = abi_coder_1.defaultAbiCoder.decode(inputNonIndexed, bytes_1.arrayify(data));
|
||||||
var result = new Result();
|
var result = new Result({});
|
||||||
var nonIndexedIndex = 0, indexedIndex = 0;
|
var nonIndexedIndex = 0, indexedIndex = 0;
|
||||||
this.inputs.forEach(function (input, index) {
|
this.inputs.forEach(function (input, index) {
|
||||||
if (input.indexed) {
|
if (input.indexed) {
|
||||||
if (topics == null) {
|
if (topics == null) {
|
||||||
result[index] = new Indexed(null);
|
result[index] = new Indexed({ type: 'indexed', hash: null });
|
||||||
}
|
}
|
||||||
else if (inputDynamic[index]) {
|
else if (inputDynamic[index]) {
|
||||||
result[index] = new Indexed(resultIndexed[indexedIndex++]);
|
result[index] = new Indexed({ type: 'indexed', hash: resultIndexed[indexedIndex++] });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result[index] = resultIndexed[indexedIndex++];
|
result[index] = resultIndexed[indexedIndex++];
|
||||||
@ -227,10 +232,20 @@ var EventDescription = /** @class */ (function (_super) {
|
|||||||
return EventDescription;
|
return EventDescription;
|
||||||
}(Description));
|
}(Description));
|
||||||
exports.EventDescription = EventDescription;
|
exports.EventDescription = EventDescription;
|
||||||
// @TODO:
|
var TransactionDescription = /** @class */ (function (_super) {
|
||||||
//export class Result {
|
__extends(TransactionDescription, _super);
|
||||||
// [prop: string]: any;
|
function TransactionDescription() {
|
||||||
//}
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
return TransactionDescription;
|
||||||
|
}(Description));
|
||||||
|
var LogDescription = /** @class */ (function (_super) {
|
||||||
|
__extends(LogDescription, _super);
|
||||||
|
function LogDescription() {
|
||||||
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
return LogDescription;
|
||||||
|
}(Description));
|
||||||
function addMethod(method) {
|
function addMethod(method) {
|
||||||
switch (method.type) {
|
switch (method.type) {
|
||||||
case 'constructor': {
|
case 'constructor': {
|
||||||
@ -279,7 +294,7 @@ function addMethod(method) {
|
|||||||
name: method.name,
|
name: method.name,
|
||||||
signature: signature,
|
signature: signature,
|
||||||
inputs: method.inputs,
|
inputs: method.inputs,
|
||||||
topics: [keccak256_1.keccak256(utf8_1.toUtf8Bytes(signature))],
|
topic: keccak256_1.keccak256(utf8_1.toUtf8Bytes(signature)),
|
||||||
anonymous: (!!method.anonymous),
|
anonymous: (!!method.anonymous),
|
||||||
type: 'event'
|
type: 'event'
|
||||||
});
|
});
|
||||||
@ -346,17 +361,42 @@ var Interface = /** @class */ (function () {
|
|||||||
var func = this.functions[name];
|
var func = this.functions[name];
|
||||||
if (func.sighash === sighash) {
|
if (func.sighash === sighash) {
|
||||||
var result = abi_coder_1.defaultAbiCoder.decode(func.inputs, '0x' + tx.data.substring(10));
|
var result = abi_coder_1.defaultAbiCoder.decode(func.inputs, '0x' + tx.data.substring(10));
|
||||||
return {
|
return new TransactionDescription({
|
||||||
args: result,
|
args: result,
|
||||||
|
decode: func.decode,
|
||||||
|
name: name,
|
||||||
signature: func.signature,
|
signature: func.signature,
|
||||||
sighash: func.sighash,
|
sighash: func.sighash,
|
||||||
decode: func.decode,
|
type: 'transaction',
|
||||||
value: bignumber_1.bigNumberify(tx.value || 0),
|
value: bignumber_1.bigNumberify(tx.value || 0),
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
Interface.prototype.parseLog = function (log) {
|
||||||
|
for (var name in this.events) {
|
||||||
|
if (name.indexOf('(') === -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var event = this.events[name];
|
||||||
|
if (event.anonymous) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (event.topic !== log.topics[0]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// @TODO: If anonymous, and the only method, and the input count matches, should we parse and return it?
|
||||||
|
return new LogDescription({
|
||||||
|
name: event.name,
|
||||||
|
signature: event.signature,
|
||||||
|
topic: event.topic,
|
||||||
|
type: 'log',
|
||||||
|
values: event.decode(log.data, log.topics)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
return Interface;
|
return Interface;
|
||||||
}());
|
}());
|
||||||
exports.Interface = Interface;
|
exports.Interface = Interface;
|
||||||
|
4
src/index.d.ts
vendored
4
src/index.d.ts
vendored
@ -1,7 +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 { getNetwork } 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, networks, providers, errors, utils, };
|
export { Wallet, HDNode, SigningKey, Contract, Interface, getNetwork, providers, errors, utils, };
|
||||||
|
@ -18,7 +18,7 @@ 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");
|
var networks_1 = require("./providers/networks");
|
||||||
exports.networks = networks_1.networks;
|
exports.getNetwork = networks_1.getNetwork;
|
||||||
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");
|
||||||
|
4
src/providers/etherscan-provider.d.ts
vendored
4
src/providers/etherscan-provider.d.ts
vendored
@ -1,9 +1,9 @@
|
|||||||
import { Provider } from './provider';
|
import { Provider } from './provider';
|
||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
export declare class EtherscanProvider extends Provider {
|
export declare class EtherscanProvider extends Provider {
|
||||||
readonly baseUrl: string;
|
readonly baseUrl: string;
|
||||||
readonly apiKey: string;
|
readonly apiKey: string;
|
||||||
constructor(network?: Network | string, apiKey?: string);
|
constructor(network?: Networkish, apiKey?: string);
|
||||||
perform(method: string, params: any): Promise<any>;
|
perform(method: string, params: any): Promise<any>;
|
||||||
getHistory(addressOrName: any, startBlock: any, endBlock: any): Promise<any[]>;
|
getHistory(addressOrName: any, startBlock: any, endBlock: any): Promise<any[]>;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var provider_1 = require("./provider");
|
var provider_1 = require("./provider");
|
||||||
var bytes_1 = require("../utils/bytes");
|
var bytes_1 = require("../utils/bytes");
|
||||||
|
var properties_1 = require("../utils/properties");
|
||||||
var web_1 = require("../utils/web");
|
var web_1 = require("../utils/web");
|
||||||
var errors = __importStar(require("../utils/errors"));
|
var errors = __importStar(require("../utils/errors"));
|
||||||
// The transaction has already been sanitized by the calls in Provider
|
// The transaction has already been sanitized by the calls in Provider
|
||||||
@ -82,7 +83,7 @@ function checkLogTag(blockTag) {
|
|||||||
var EtherscanProvider = /** @class */ (function (_super) {
|
var EtherscanProvider = /** @class */ (function (_super) {
|
||||||
__extends(EtherscanProvider, _super);
|
__extends(EtherscanProvider, _super);
|
||||||
function EtherscanProvider(network, apiKey) {
|
function EtherscanProvider(network, apiKey) {
|
||||||
var _this = _super.call(this, network || 'homestead') || this;
|
var _this = _super.call(this, network) || this;
|
||||||
errors.checkNew(_this, EtherscanProvider);
|
errors.checkNew(_this, EtherscanProvider);
|
||||||
var name = 'invalid';
|
var name = 'invalid';
|
||||||
if (_this.network) {
|
if (_this.network) {
|
||||||
@ -105,8 +106,8 @@ var EtherscanProvider = /** @class */ (function (_super) {
|
|||||||
default:
|
default:
|
||||||
throw new Error('unsupported network');
|
throw new Error('unsupported network');
|
||||||
}
|
}
|
||||||
_this.baseUrl = baseUrl;
|
properties_1.defineReadOnly(_this, 'baseUrl', baseUrl);
|
||||||
_this.apiKey = apiKey;
|
properties_1.defineReadOnly(_this, 'apiKey', apiKey);
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
EtherscanProvider.prototype.perform = function (method, params) {
|
EtherscanProvider.prototype.perform = function (method, params) {
|
||||||
|
@ -54,27 +54,29 @@ var FallbackProvider = /** @class */ (function (_super) {
|
|||||||
if (providers.length === 0) {
|
if (providers.length === 0) {
|
||||||
throw new Error('no providers');
|
throw new Error('no providers');
|
||||||
}
|
}
|
||||||
|
// All networks are ready, we can know the network for certain
|
||||||
var ready = checkNetworks(providers.map(function (p) { return p.network; }));
|
var ready = checkNetworks(providers.map(function (p) { return p.network; }));
|
||||||
if (ready) {
|
if (ready) {
|
||||||
_this = _super.call(this, providers[0].network) || this;
|
_this = _super.call(this, providers[0].network) || this;
|
||||||
errors.checkNew(_this, FallbackProvider);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this = _super.call(this, null) || this;
|
// The network won't be known until all child providers know
|
||||||
errors.checkNew(_this, FallbackProvider);
|
var ready_1 = Promise.all(providers.map(function (p) { return p.getNetwork(); })).then(function (networks) {
|
||||||
// We re-assign the ready function to make sure all networks actually match
|
|
||||||
_this.ready = Promise.all(providers.map(function (p) { return p.getNetwork(); })).then(function (networks) {
|
|
||||||
if (!checkNetworks(networks)) {
|
if (!checkNetworks(networks)) {
|
||||||
errors.throwError('getNetwork returned null', errors.UNKNOWN_ERROR, {});
|
errors.throwError('getNetwork returned null', errors.UNKNOWN_ERROR, {});
|
||||||
}
|
}
|
||||||
return networks[0];
|
return networks[0];
|
||||||
});
|
});
|
||||||
|
_this = _super.call(this, ready_1) || this;
|
||||||
}
|
}
|
||||||
|
errors.checkNew(_this, FallbackProvider);
|
||||||
|
// Preserve a copy, so we don't get mutated
|
||||||
_this._providers = providers.slice(0);
|
_this._providers = providers.slice(0);
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
Object.defineProperty(FallbackProvider.prototype, "providers", {
|
Object.defineProperty(FallbackProvider.prototype, "providers", {
|
||||||
get: function () {
|
get: function () {
|
||||||
|
// Return a copy, so we don't get mutated
|
||||||
return this._providers.slice(0);
|
return this._providers.slice(0);
|
||||||
},
|
},
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
|
5
src/providers/index.d.ts
vendored
5
src/providers/index.d.ts
vendored
@ -1,9 +1,10 @@
|
|||||||
import { Provider } from './provider';
|
import { Provider, ProviderSigner } from './provider';
|
||||||
import { Network } from './networks';
|
import { Network } from './networks';
|
||||||
import { EtherscanProvider } from './etherscan-provider';
|
import { EtherscanProvider } from './etherscan-provider';
|
||||||
import { FallbackProvider } from './fallback-provider';
|
import { FallbackProvider } from './fallback-provider';
|
||||||
|
import { IpcProvider } from './ipc-provider';
|
||||||
import { InfuraProvider } from './infura-provider';
|
import { InfuraProvider } from './infura-provider';
|
||||||
import { JsonRpcProvider } from './json-rpc-provider';
|
import { JsonRpcProvider } from './json-rpc-provider';
|
||||||
import { Web3Provider } from './web3-provider';
|
import { Web3Provider } from './web3-provider';
|
||||||
declare function getDefaultProvider(network?: Network | string): FallbackProvider;
|
declare function getDefaultProvider(network?: Network | string): FallbackProvider;
|
||||||
export { Provider, getDefaultProvider, FallbackProvider, EtherscanProvider, InfuraProvider, JsonRpcProvider, Web3Provider, };
|
export { Provider, getDefaultProvider, ProviderSigner, FallbackProvider, EtherscanProvider, InfuraProvider, JsonRpcProvider, Web3Provider, IpcProvider };
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var provider_1 = require("./provider");
|
var provider_1 = require("./provider");
|
||||||
exports.Provider = provider_1.Provider;
|
exports.Provider = provider_1.Provider;
|
||||||
|
exports.ProviderSigner = provider_1.ProviderSigner;
|
||||||
var etherscan_provider_1 = require("./etherscan-provider");
|
var etherscan_provider_1 = require("./etherscan-provider");
|
||||||
exports.EtherscanProvider = etherscan_provider_1.EtherscanProvider;
|
exports.EtherscanProvider = etherscan_provider_1.EtherscanProvider;
|
||||||
var fallback_provider_1 = require("./fallback-provider");
|
var fallback_provider_1 = require("./fallback-provider");
|
||||||
exports.FallbackProvider = fallback_provider_1.FallbackProvider;
|
exports.FallbackProvider = fallback_provider_1.FallbackProvider;
|
||||||
//import { IpcProvider } from './ipc-provider';
|
var ipc_provider_1 = require("./ipc-provider");
|
||||||
|
exports.IpcProvider = ipc_provider_1.IpcProvider;
|
||||||
var infura_provider_1 = require("./infura-provider");
|
var infura_provider_1 = require("./infura-provider");
|
||||||
exports.InfuraProvider = infura_provider_1.InfuraProvider;
|
exports.InfuraProvider = infura_provider_1.InfuraProvider;
|
||||||
var json_rpc_provider_1 = require("./json-rpc-provider");
|
var json_rpc_provider_1 = require("./json-rpc-provider");
|
||||||
|
4
src/providers/infura-provider.d.ts
vendored
4
src/providers/infura-provider.d.ts
vendored
@ -1,8 +1,8 @@
|
|||||||
import { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';
|
import { JsonRpcProvider, JsonRpcSigner } from './json-rpc-provider';
|
||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
export declare class InfuraProvider extends JsonRpcProvider {
|
export declare class InfuraProvider extends JsonRpcProvider {
|
||||||
readonly apiAccessToken: string;
|
readonly apiAccessToken: string;
|
||||||
constructor(network?: Network | string, apiAccessToken?: string);
|
constructor(network?: Networkish, apiAccessToken?: string);
|
||||||
_startPending(): void;
|
_startPending(): void;
|
||||||
getSigner(address?: string): JsonRpcSigner;
|
getSigner(address?: string): JsonRpcSigner;
|
||||||
listAccounts(): Promise<Array<string>>;
|
listAccounts(): Promise<Array<string>>;
|
||||||
|
@ -19,12 +19,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var json_rpc_provider_1 = require("./json-rpc-provider");
|
var json_rpc_provider_1 = require("./json-rpc-provider");
|
||||||
var networks_1 = require("./networks");
|
var networks_1 = require("./networks");
|
||||||
|
var properties_1 = require("../utils/properties");
|
||||||
var errors = __importStar(require("../utils/errors"));
|
var errors = __importStar(require("../utils/errors"));
|
||||||
var InfuraProvider = /** @class */ (function (_super) {
|
var InfuraProvider = /** @class */ (function (_super) {
|
||||||
__extends(InfuraProvider, _super);
|
__extends(InfuraProvider, _super);
|
||||||
function InfuraProvider(network, apiAccessToken) {
|
function InfuraProvider(network, apiAccessToken) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
network = networks_1.getNetwork(network || 'homestead');
|
network = networks_1.getNetwork((network == null) ? 'homestead' : network);
|
||||||
var host = null;
|
var host = null;
|
||||||
switch (network.name) {
|
switch (network.name) {
|
||||||
case 'homestead':
|
case 'homestead':
|
||||||
@ -44,7 +45,7 @@ var InfuraProvider = /** @class */ (function (_super) {
|
|||||||
}
|
}
|
||||||
_this = _super.call(this, 'https://' + host + '/' + (apiAccessToken || ''), network) || this;
|
_this = _super.call(this, 'https://' + host + '/' + (apiAccessToken || ''), network) || this;
|
||||||
errors.checkNew(_this, InfuraProvider);
|
errors.checkNew(_this, InfuraProvider);
|
||||||
_this.apiAccessToken = (apiAccessToken || null);
|
properties_1.defineReadOnly(_this, 'apiAccessToken', apiAccessToken || null);
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
InfuraProvider.prototype._startPending = function () {
|
InfuraProvider.prototype._startPending = function () {
|
||||||
|
4
src/providers/ipc-provider.d.ts
vendored
4
src/providers/ipc-provider.d.ts
vendored
@ -1,7 +1,7 @@
|
|||||||
import { JsonRpcProvider } from './json-rpc-provider';
|
import { JsonRpcProvider } from './json-rpc-provider';
|
||||||
import { Network } from './networks';
|
import { Networkish } 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?: Networkish);
|
||||||
send(method: string, params: any): Promise<any>;
|
send(method: string, params: any): Promise<any>;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var net_1 = __importDefault(require("net"));
|
var net_1 = __importDefault(require("net"));
|
||||||
var json_rpc_provider_1 = require("./json-rpc-provider");
|
var json_rpc_provider_1 = require("./json-rpc-provider");
|
||||||
|
var properties_1 = require("../utils/properties");
|
||||||
var errors = __importStar(require("../utils/errors"));
|
var errors = __importStar(require("../utils/errors"));
|
||||||
var IpcProvider = /** @class */ (function (_super) {
|
var IpcProvider = /** @class */ (function (_super) {
|
||||||
__extends(IpcProvider, _super);
|
__extends(IpcProvider, _super);
|
||||||
@ -32,7 +33,7 @@ var IpcProvider = /** @class */ (function (_super) {
|
|||||||
}
|
}
|
||||||
_this = _super.call(this, 'ipc://' + path, network) || this;
|
_this = _super.call(this, 'ipc://' + path, network) || this;
|
||||||
errors.checkNew(_this, IpcProvider);
|
errors.checkNew(_this, IpcProvider);
|
||||||
_this.path = path;
|
properties_1.defineReadOnly(_this, 'path', path);
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
// @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
|
||||||
|
11
src/providers/json-rpc-provider.d.ts
vendored
11
src/providers/json-rpc-provider.d.ts
vendored
@ -1,10 +1,11 @@
|
|||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
import { BlockTag, Provider, TransactionRequest } from './provider';
|
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from './provider';
|
||||||
|
import { Signer } from '../wallet/wallet';
|
||||||
import { BigNumber } from '../utils/bignumber';
|
import { BigNumber } from '../utils/bignumber';
|
||||||
import { Arrayish } from '../utils/bytes';
|
import { Arrayish } from '../utils/bytes';
|
||||||
import { ConnectionInfo } from '../utils/web';
|
import { ConnectionInfo } from '../utils/web';
|
||||||
export declare function hexlifyTransaction(transaction: TransactionRequest): any;
|
export declare function hexlifyTransaction(transaction: TransactionRequest): any;
|
||||||
export declare class JsonRpcSigner {
|
export declare class JsonRpcSigner extends Signer {
|
||||||
readonly provider: JsonRpcProvider;
|
readonly provider: JsonRpcProvider;
|
||||||
readonly _address: string;
|
readonly _address: string;
|
||||||
constructor(provider: JsonRpcProvider, address?: string);
|
constructor(provider: JsonRpcProvider, address?: string);
|
||||||
@ -12,14 +13,14 @@ export declare class JsonRpcSigner {
|
|||||||
getAddress(): Promise<string>;
|
getAddress(): Promise<string>;
|
||||||
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
||||||
getTransactionCount(blockTag: any): Promise<number>;
|
getTransactionCount(blockTag: any): Promise<number>;
|
||||||
sendTransaction(transaction: TransactionRequest): Promise<any>;
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
signMessage(message: Arrayish | string): Promise<string>;
|
signMessage(message: Arrayish | string): Promise<string>;
|
||||||
unlock(password: any): Promise<boolean>;
|
unlock(password: any): Promise<boolean>;
|
||||||
}
|
}
|
||||||
export declare class JsonRpcProvider extends Provider {
|
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?: Networkish);
|
||||||
getSigner(address: string): JsonRpcSigner;
|
getSigner(address: string): JsonRpcSigner;
|
||||||
listAccounts(): Promise<Array<string>>;
|
listAccounts(): Promise<Array<string>>;
|
||||||
send(method: string, params: any): Promise<any>;
|
send(method: string, params: any): Promise<any>;
|
||||||
|
@ -20,8 +20,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC
|
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC
|
||||||
var networks_1 = require("./networks");
|
var networks_1 = require("./networks");
|
||||||
var provider_1 = require("./provider");
|
var provider_1 = require("./provider");
|
||||||
|
var wallet_1 = require("../wallet/wallet");
|
||||||
var address_1 = require("../utils/address");
|
var address_1 = require("../utils/address");
|
||||||
var bytes_1 = require("../utils/bytes");
|
var bytes_1 = require("../utils/bytes");
|
||||||
|
var properties_1 = require("../utils/properties");
|
||||||
var utf8_1 = require("../utils/utf8");
|
var utf8_1 = require("../utils/utf8");
|
||||||
var web_1 = require("../utils/web");
|
var web_1 = require("../utils/web");
|
||||||
var errors = __importStar(require("../utils/errors"));
|
var errors = __importStar(require("../utils/errors"));
|
||||||
@ -74,16 +76,17 @@ function getLowerCase(value) {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
var JsonRpcSigner = /** @class */ (function () {
|
var JsonRpcSigner = /** @class */ (function (_super) {
|
||||||
// private _syncAddress: boolean;
|
__extends(JsonRpcSigner, _super);
|
||||||
function JsonRpcSigner(provider, address) {
|
function JsonRpcSigner(provider, address) {
|
||||||
errors.checkNew(this, JsonRpcSigner);
|
var _this = _super.call(this) || this;
|
||||||
this.provider = provider;
|
errors.checkNew(_this, JsonRpcSigner);
|
||||||
|
properties_1.defineReadOnly(_this, 'provider', provider);
|
||||||
// Statically attach to a given address
|
// Statically attach to a given address
|
||||||
if (address) {
|
if (address) {
|
||||||
this._address = address;
|
properties_1.defineReadOnly(_this, '_address', address);
|
||||||
//this._syncAddress = true;
|
|
||||||
}
|
}
|
||||||
|
return _this;
|
||||||
}
|
}
|
||||||
Object.defineProperty(JsonRpcSigner.prototype, "address", {
|
Object.defineProperty(JsonRpcSigner.prototype, "address", {
|
||||||
get: function () {
|
get: function () {
|
||||||
@ -107,42 +110,24 @@ var JsonRpcSigner = /** @class */ (function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
JsonRpcSigner.prototype.getBalance = function (blockTag) {
|
JsonRpcSigner.prototype.getBalance = function (blockTag) {
|
||||||
var _this = this;
|
return this.provider.getBalance(this.getAddress(), blockTag);
|
||||||
return this.getAddress().then(function (address) {
|
|
||||||
return _this.provider.getBalance(address, blockTag);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
JsonRpcSigner.prototype.getTransactionCount = function (blockTag) {
|
JsonRpcSigner.prototype.getTransactionCount = function (blockTag) {
|
||||||
var _this = this;
|
return this.provider.getTransactionCount(this.getAddress(), blockTag);
|
||||||
return this.getAddress().then(function (address) {
|
|
||||||
return _this.provider.getTransactionCount(address, blockTag);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
// @TODO:
|
|
||||||
//sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
|
||||||
JsonRpcSigner.prototype.sendTransaction = function (transaction) {
|
JsonRpcSigner.prototype.sendTransaction = function (transaction) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
transaction = hexlifyTransaction(transaction);
|
var tx = hexlifyTransaction(transaction);
|
||||||
return this.getAddress().then(function (address) {
|
if (tx.from == null) {
|
||||||
transaction.from = address.toLowerCase();
|
tx.from = this.getAddress().then(function (address) {
|
||||||
return _this.provider.send('eth_sendTransaction', [transaction]).then(function (hash) {
|
if (!address) {
|
||||||
// @TODO: Use secp256k1 to fill this in instead...
|
return null;
|
||||||
return new Promise(function (resolve, reject) {
|
}
|
||||||
function check() {
|
return address.toLowerCase();
|
||||||
this.provider.getTransaction(hash).then(function (transaction) {
|
|
||||||
if (!transaction) {
|
|
||||||
setTimeout(check, 1000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transaction.wait = function (timeout) {
|
|
||||||
return this.provider.waitForTransaction(hash, timeout);
|
|
||||||
};
|
|
||||||
resolve(transaction);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
check();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
return properties_1.resolveProperties(tx).then(function (tx) {
|
||||||
|
return _this.provider.send('eth_sendTransaction', [transaction]);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
JsonRpcSigner.prototype.signMessage = function (message) {
|
JsonRpcSigner.prototype.signMessage = function (message) {
|
||||||
@ -160,7 +145,7 @@ var JsonRpcSigner = /** @class */ (function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
return JsonRpcSigner;
|
return JsonRpcSigner;
|
||||||
}());
|
}(wallet_1.Signer));
|
||||||
exports.JsonRpcSigner = JsonRpcSigner;
|
exports.JsonRpcSigner = JsonRpcSigner;
|
||||||
var JsonRpcProvider = /** @class */ (function (_super) {
|
var JsonRpcProvider = /** @class */ (function (_super) {
|
||||||
__extends(JsonRpcProvider, _super);
|
__extends(JsonRpcProvider, _super);
|
||||||
@ -173,7 +158,22 @@ var JsonRpcProvider = /** @class */ (function (_super) {
|
|||||||
url = null;
|
url = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_this = _super.call(this, network) || this;
|
if (network) {
|
||||||
|
// The network has been specified explicitly, we can use it
|
||||||
|
_this = _super.call(this, network) || this;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The network is unknown, query the JSON-RPC for it
|
||||||
|
var ready = new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(function () {
|
||||||
|
_this.send('net_version', []).then(function (result) {
|
||||||
|
var chainId = parseInt(result);
|
||||||
|
resolve(networks_1.getNetwork(chainId));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_this = _super.call(this, ready) || this;
|
||||||
|
}
|
||||||
errors.checkNew(_this, JsonRpcProvider);
|
errors.checkNew(_this, JsonRpcProvider);
|
||||||
// Default URL
|
// Default URL
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@ -187,24 +187,6 @@ var JsonRpcProvider = /** @class */ (function (_super) {
|
|||||||
else {
|
else {
|
||||||
_this.connection = url;
|
_this.connection = url;
|
||||||
}
|
}
|
||||||
// The network is unknown, query the JSON-RPC for it
|
|
||||||
if (!_this.network) {
|
|
||||||
_this.ready = new Promise(function (resolve, reject) {
|
|
||||||
setTimeout(function () {
|
|
||||||
_this.send('net_version', []).then(function (result) {
|
|
||||||
var chainId = parseInt(result);
|
|
||||||
var network = networks_1.getNetwork(chainId);
|
|
||||||
if (network) {
|
|
||||||
return resolve(network);
|
|
||||||
}
|
|
||||||
resolve({
|
|
||||||
name: 'custom',
|
|
||||||
chainId: chainId
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
JsonRpcProvider.prototype.getSigner = function (address) {
|
JsonRpcProvider.prototype.getSigner = function (address) {
|
||||||
|
45
src/providers/networks.d.ts
vendored
45
src/providers/networks.d.ts
vendored
@ -3,48 +3,7 @@ export declare type Network = {
|
|||||||
chainId: number;
|
chainId: number;
|
||||||
ensAddress?: string;
|
ensAddress?: string;
|
||||||
};
|
};
|
||||||
export declare const networks: {
|
export declare type Networkish = Network | string | number;
|
||||||
"unspecified": {
|
|
||||||
"chainId": number;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"homestead": {
|
|
||||||
"chainId": number;
|
|
||||||
"ensAddress": string;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"mainnet": {
|
|
||||||
"chainId": number;
|
|
||||||
"ensAddress": string;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"morden": {
|
|
||||||
"chainId": number;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"ropsten": {
|
|
||||||
"chainId": number;
|
|
||||||
"ensAddress": string;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"testnet": {
|
|
||||||
"chainId": number;
|
|
||||||
"ensAddress": string;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"rinkeby": {
|
|
||||||
"chainId": number;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"kovan": {
|
|
||||||
"chainId": number;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
"classic": {
|
|
||||||
"chainId": number;
|
|
||||||
"name": string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* getNetwork
|
* getNetwork
|
||||||
*
|
*
|
||||||
@ -53,4 +12,4 @@ export declare const networks: {
|
|||||||
* for that network. Otherwise, return the network.
|
* for that network. Otherwise, return the network.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export declare function getNetwork(network: Network | string | number): Network;
|
export declare function getNetwork(network: Networkish): Network;
|
||||||
|
@ -8,47 +8,36 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var errors = __importStar(require("../utils/errors"));
|
var errors = __importStar(require("../utils/errors"));
|
||||||
// @TODO: Make these all read-only with defineProperty
|
var homestead = {
|
||||||
exports.networks = {
|
chainId: 1,
|
||||||
"unspecified": {
|
ensAddress: "0x314159265dd8dbb310642f98f50c066173c1259b",
|
||||||
"chainId": 0,
|
name: "homestead"
|
||||||
"name": "unspecified"
|
};
|
||||||
|
var ropsten = {
|
||||||
|
chainId: 3,
|
||||||
|
ensAddress: "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
||||||
|
name: "ropsten"
|
||||||
|
};
|
||||||
|
var networks = {
|
||||||
|
unspecified: {
|
||||||
|
chainId: 0
|
||||||
},
|
},
|
||||||
"homestead": {
|
homestead: homestead,
|
||||||
"chainId": 1,
|
mainnet: homestead,
|
||||||
"ensAddress": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
morden: {
|
||||||
"name": "homestead"
|
chainId: 2
|
||||||
},
|
},
|
||||||
"mainnet": {
|
ropsten: ropsten,
|
||||||
"chainId": 1,
|
testnet: ropsten,
|
||||||
"ensAddress": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
rinkeby: {
|
||||||
"name": "homestead"
|
chainId: 4,
|
||||||
|
ensAddress: "0xe7410170f87102DF0055eB195163A03B7F2Bff4A"
|
||||||
},
|
},
|
||||||
"morden": {
|
kovan: {
|
||||||
"chainId": 2,
|
chainId: 42
|
||||||
"name": "morden"
|
|
||||||
},
|
},
|
||||||
"ropsten": {
|
classic: {
|
||||||
"chainId": 3,
|
chainId: 61
|
||||||
"ensAddress": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
||||||
"name": "ropsten"
|
|
||||||
},
|
|
||||||
"testnet": {
|
|
||||||
"chainId": 3,
|
|
||||||
"ensAddress": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
||||||
"name": "ropsten"
|
|
||||||
},
|
|
||||||
"rinkeby": {
|
|
||||||
"chainId": 4,
|
|
||||||
"name": "rinkeby"
|
|
||||||
},
|
|
||||||
"kovan": {
|
|
||||||
"chainId": 42,
|
|
||||||
"name": "kovan"
|
|
||||||
},
|
|
||||||
"classic": {
|
|
||||||
"chainId": 61,
|
|
||||||
"name": "classic"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@ -65,29 +54,49 @@ function getNetwork(network) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (typeof (network) === 'number') {
|
if (typeof (network) === 'number') {
|
||||||
for (var key in exports.networks) {
|
for (var name in networks) {
|
||||||
var n = exports.networks[key];
|
var n_1 = networks[name];
|
||||||
if (n.chainId === network) {
|
if (n_1.chainId === network) {
|
||||||
return n;
|
return {
|
||||||
|
name: name,
|
||||||
|
chainId: n_1.chainId,
|
||||||
|
ensAddress: n_1.ensAddress
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return {
|
||||||
|
chainId: network,
|
||||||
|
name: 'unknown'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (typeof (network) === 'string') {
|
if (typeof (network) === 'string') {
|
||||||
return exports.networks[network] || null;
|
var n_2 = networks[network];
|
||||||
|
if (n_2 == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: network,
|
||||||
|
chainId: n_2.chainId,
|
||||||
|
ensAddress: n_2.ensAddress
|
||||||
|
};
|
||||||
}
|
}
|
||||||
var networkObj = exports.networks[network.name];
|
var n = networks[network.name];
|
||||||
// Not a standard network; check that it is a valid network in general
|
// Not a standard network; check that it is a valid network in general
|
||||||
if (!networkObj) {
|
if (!n) {
|
||||||
if (typeof (network.chainId) !== 'number') {
|
if (typeof (n.chainId) !== 'number') {
|
||||||
errors.throwError('invalid network chainId', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
errors.throwError('invalid network chainId', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
||||||
}
|
}
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
// Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)
|
// Make sure the chainId matches the expected network chainId (or is 0; disable EIP-155)
|
||||||
if (network.chainId != 0 && network.chainId !== networkObj.chainId) {
|
if (network.chainId !== 0 && network.chainId !== n.chainId) {
|
||||||
errors.throwError('network chainId mismatch', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
errors.throwError('network chainId mismatch', errors.INVALID_ARGUMENT, { name: 'network', value: network });
|
||||||
}
|
}
|
||||||
return networkObj;
|
// Standard Network
|
||||||
|
return {
|
||||||
|
name: network.name,
|
||||||
|
chainId: n.chainId,
|
||||||
|
ensAddress: n.ensAddress
|
||||||
|
};
|
||||||
}
|
}
|
||||||
exports.getNetwork = getNetwork;
|
exports.getNetwork = getNetwork;
|
||||||
|
20
src/providers/provider.d.ts
vendored
20
src/providers/provider.d.ts
vendored
@ -1,7 +1,8 @@
|
|||||||
|
import { Signer } from '../wallet/wallet';
|
||||||
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
||||||
import { Arrayish } from '../utils/bytes';
|
import { Arrayish } from '../utils/bytes';
|
||||||
import { Network } from './networks';
|
import { Network, Networkish } from './networks';
|
||||||
import { Transaction } from '../utils/transaction';
|
import { SignDigestFunc, Transaction } from '../utils/transaction';
|
||||||
export declare type BlockTag = string | number;
|
export declare type BlockTag = string | number;
|
||||||
export interface Block {
|
export interface Block {
|
||||||
hash: string;
|
hash: string;
|
||||||
@ -9,7 +10,7 @@ export interface Block {
|
|||||||
number: number;
|
number: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
nonce: string;
|
nonce: string;
|
||||||
difficulty: string;
|
difficulty: number;
|
||||||
gasLimit: BigNumber;
|
gasLimit: BigNumber;
|
||||||
gasUsed: BigNumber;
|
gasUsed: BigNumber;
|
||||||
miner: string;
|
miner: string;
|
||||||
@ -64,6 +65,17 @@ export interface Log {
|
|||||||
logIndex?: number;
|
logIndex?: number;
|
||||||
}
|
}
|
||||||
export declare function checkTransactionResponse(transaction: any): TransactionResponse;
|
export declare function checkTransactionResponse(transaction: any): TransactionResponse;
|
||||||
|
export declare class ProviderSigner extends Signer {
|
||||||
|
readonly provider: Provider;
|
||||||
|
readonly signDigest: SignDigestFunc;
|
||||||
|
private _addressPromise;
|
||||||
|
constructor(address: string | Promise<string>, signDigest: SignDigestFunc, provider: Provider);
|
||||||
|
getAddress(): Promise<string>;
|
||||||
|
signMessage(message: Arrayish | string): Promise<string>;
|
||||||
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
|
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
||||||
|
call(transaction: TransactionRequest): Promise<string>;
|
||||||
|
}
|
||||||
export declare class Provider {
|
export declare class Provider {
|
||||||
private _network;
|
private _network;
|
||||||
private _events;
|
private _events;
|
||||||
@ -82,7 +94,7 @@ export declare class Provider {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected ready: Promise<Network>;
|
protected ready: Promise<Network>;
|
||||||
constructor(network: string | Network);
|
constructor(network: Networkish | Promise<Network>);
|
||||||
private _doPoll;
|
private _doPoll;
|
||||||
resetEventsBlock(blockNumber: number): void;
|
resetEventsBlock(blockNumber: number): void;
|
||||||
readonly network: Network;
|
readonly network: Network;
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||||
|
return function (d, b) {
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
if (mod && mod.__esModule) return mod;
|
if (mod && mod.__esModule) return mod;
|
||||||
var result = {};
|
var result = {};
|
||||||
@ -8,12 +18,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
//import inherits = require('inherits');
|
//import inherits = require('inherits');
|
||||||
|
var wallet_1 = require("../wallet/wallet");
|
||||||
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 bytes_1 = require("../utils/bytes");
|
var bytes_1 = require("../utils/bytes");
|
||||||
var utf8_1 = require("../utils/utf8");
|
var utf8_1 = require("../utils/utf8");
|
||||||
var rlp_1 = require("../utils/rlp");
|
var rlp_1 = require("../utils/rlp");
|
||||||
var namehash_1 = require("../utils/namehash");
|
var hash_1 = require("../utils/hash");
|
||||||
var networks_1 = require("./networks");
|
var networks_1 = require("./networks");
|
||||||
var properties_1 = require("../utils/properties");
|
var properties_1 = require("../utils/properties");
|
||||||
var transaction_1 = require("../utils/transaction");
|
var transaction_1 = require("../utils/transaction");
|
||||||
@ -389,6 +400,12 @@ function getEventString(object) {
|
|||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e.stack);
|
||||||
|
}
|
||||||
throw new Error('invalid event - ' + object);
|
throw new Error('invalid event - ' + object);
|
||||||
}
|
}
|
||||||
function parseEventString(string) {
|
function parseEventString(string) {
|
||||||
@ -430,18 +447,87 @@ type Event = {
|
|||||||
type: string,
|
type: string,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
// @TODO: Perhaps allow a SignDigestAsyncFunc?
|
||||||
|
// Enable a simple signing function and provider to provide a full Signer
|
||||||
|
var ProviderSigner = /** @class */ (function (_super) {
|
||||||
|
__extends(ProviderSigner, _super);
|
||||||
|
function ProviderSigner(address, signDigest, provider) {
|
||||||
|
var _this = _super.call(this) || this;
|
||||||
|
errors.checkNew(_this, ProviderSigner);
|
||||||
|
properties_1.defineReadOnly(_this, '_addressPromise', Promise.resolve(address));
|
||||||
|
properties_1.defineReadOnly(_this, 'signDigest', signDigest);
|
||||||
|
properties_1.defineReadOnly(_this, 'provider', provider);
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
ProviderSigner.prototype.getAddress = function () {
|
||||||
|
return this._addressPromise;
|
||||||
|
};
|
||||||
|
ProviderSigner.prototype.signMessage = function (message) {
|
||||||
|
return Promise.resolve(bytes_1.joinSignature(this.signDigest(hash_1.hashMessage(message))));
|
||||||
|
};
|
||||||
|
ProviderSigner.prototype.sendTransaction = function (transaction) {
|
||||||
|
var _this = this;
|
||||||
|
transaction = properties_1.shallowCopy(transaction);
|
||||||
|
if (transaction.chainId == null) {
|
||||||
|
transaction.chainId = this.provider.getNetwork().then(function (network) {
|
||||||
|
return network.chainId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (transaction.from == null) {
|
||||||
|
transaction.from = this.getAddress();
|
||||||
|
}
|
||||||
|
if (transaction.gasLimit == null) {
|
||||||
|
transaction.gasLimit = this.provider.estimateGas(transaction);
|
||||||
|
}
|
||||||
|
if (transaction.gasPrice == null) {
|
||||||
|
transaction.gasPrice = this.provider.getGasPrice();
|
||||||
|
}
|
||||||
|
return properties_1.resolveProperties(transaction).then(function (tx) {
|
||||||
|
var signedTx = transaction_1.sign(tx, _this.signDigest);
|
||||||
|
return _this._addressPromise.then(function (address) {
|
||||||
|
if (transaction_1.parse(signedTx).from !== address) {
|
||||||
|
errors.throwError('signing address does not match expected address', errors.UNKNOWN_ERROR, { address: transaction_1.parse(signedTx).from, expectedAddress: address, signedTransaction: signedTx });
|
||||||
|
}
|
||||||
|
return _this.provider.sendTransaction(signedTx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
ProviderSigner.prototype.estimateGas = function (transaction) {
|
||||||
|
transaction = properties_1.shallowCopy(transaction);
|
||||||
|
if (transaction.from == null) {
|
||||||
|
transaction.from = this.getAddress();
|
||||||
|
}
|
||||||
|
return this.provider.estimateGas(transaction);
|
||||||
|
};
|
||||||
|
ProviderSigner.prototype.call = function (transaction) {
|
||||||
|
transaction = properties_1.shallowCopy(transaction);
|
||||||
|
if (transaction.from == null) {
|
||||||
|
transaction.from = this.getAddress();
|
||||||
|
}
|
||||||
|
return this.provider.call(transaction);
|
||||||
|
};
|
||||||
|
return ProviderSigner;
|
||||||
|
}(wallet_1.Signer));
|
||||||
|
exports.ProviderSigner = ProviderSigner;
|
||||||
var Provider = /** @class */ (function () {
|
var Provider = /** @class */ (function () {
|
||||||
function Provider(network) {
|
function Provider(network) {
|
||||||
|
var _this = this;
|
||||||
errors.checkNew(this, Provider);
|
errors.checkNew(this, Provider);
|
||||||
network = networks_1.getNetwork(network);
|
if (network instanceof Promise) {
|
||||||
if (network) {
|
properties_1.defineReadOnly(this, 'ready', network.then(function (network) {
|
||||||
this._network = network;
|
properties_1.defineReadOnly(_this, '_network', network);
|
||||||
// Sub-classes MAY re-assign a Promise if a standard network name is provided
|
return network;
|
||||||
this.ready = Promise.resolve(this._network);
|
}));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Sub-classes MUST re-assign a Promise to "ready" that returns a Network
|
var knownNetwork = networks_1.getNetwork((network == null) ? 'homestead' : network);
|
||||||
this.ready = new Promise(function (resolve, reject) { });
|
if (knownNetwork) {
|
||||||
|
properties_1.defineReadOnly(this, '_network', knownNetwork);
|
||||||
|
properties_1.defineReadOnly(this, 'ready', Promise.resolve(this._network));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errors.throwError('invalid network', errors.INVALID_ARGUMENT, { arg: 'network', value: network });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this._lastBlockNumber = -2;
|
this._lastBlockNumber = -2;
|
||||||
// Balances being watched for changes
|
// Balances being watched for changes
|
||||||
@ -873,7 +959,7 @@ var Provider = /** @class */ (function () {
|
|||||||
errors.throwError('network does support ENS', errors.UNSUPPORTED_OPERATION, { operation: 'ENS', network: network.name });
|
errors.throwError('network does support ENS', errors.UNSUPPORTED_OPERATION, { operation: 'ENS', network: network.name });
|
||||||
}
|
}
|
||||||
// keccak256('resolver(bytes32)')
|
// keccak256('resolver(bytes32)')
|
||||||
var data = '0x0178b8bf' + namehash_1.namehash(name).substring(2);
|
var data = '0x0178b8bf' + hash_1.namehash(name).substring(2);
|
||||||
var transaction = { to: network.ensAddress, data: data };
|
var transaction = { to: network.ensAddress, data: data };
|
||||||
return _this.call(transaction).then(function (data) {
|
return _this.call(transaction).then(function (data) {
|
||||||
// extract the address from the data
|
// extract the address from the data
|
||||||
@ -898,7 +984,7 @@ var Provider = /** @class */ (function () {
|
|||||||
}
|
}
|
||||||
catch (error) { }
|
catch (error) { }
|
||||||
var self = this;
|
var self = this;
|
||||||
var nodeHash = namehash_1.namehash(name);
|
var nodeHash = hash_1.namehash(name);
|
||||||
// Get the addr from the resovler
|
// Get the addr from the resovler
|
||||||
return this._getResolver(name).then(function (resolverAddress) {
|
return this._getResolver(name).then(function (resolverAddress) {
|
||||||
// keccak256('addr(bytes32)')
|
// keccak256('addr(bytes32)')
|
||||||
@ -926,7 +1012,7 @@ var Provider = /** @class */ (function () {
|
|||||||
}
|
}
|
||||||
address = address_1.getAddress(address);
|
address = address_1.getAddress(address);
|
||||||
var name = address.substring(2) + '.addr.reverse';
|
var name = address.substring(2) + '.addr.reverse';
|
||||||
var nodehash = namehash_1.namehash(name);
|
var nodehash = hash_1.namehash(name);
|
||||||
var self = this;
|
var self = this;
|
||||||
return this._getResolver(name).then(function (resolverAddress) {
|
return this._getResolver(name).then(function (resolverAddress) {
|
||||||
if (!resolverAddress) {
|
if (!resolverAddress) {
|
||||||
|
4
src/providers/web3-provider.d.ts
vendored
4
src/providers/web3-provider.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
import { Network } from './networks';
|
import { Networkish } from './networks';
|
||||||
import { JsonRpcProvider } from './json-rpc-provider';
|
import { JsonRpcProvider } from './json-rpc-provider';
|
||||||
export declare type Callback = (error: any, response: any) => void;
|
export declare type Callback = (error: any, response: any) => void;
|
||||||
export declare type AsyncProvider = {
|
export declare type AsyncProvider = {
|
||||||
@ -9,6 +9,6 @@ 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?: Networkish);
|
||||||
send(method: string, params: any): Promise<any>;
|
send(method: string, params: any): Promise<any>;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
var json_rpc_provider_1 = require("./json-rpc-provider");
|
var json_rpc_provider_1 = require("./json-rpc-provider");
|
||||||
|
var properties_1 = require("../utils/properties");
|
||||||
var errors = __importStar(require("../utils/errors"));
|
var errors = __importStar(require("../utils/errors"));
|
||||||
var Web3Provider = /** @class */ (function (_super) {
|
var Web3Provider = /** @class */ (function (_super) {
|
||||||
__extends(Web3Provider, _super);
|
__extends(Web3Provider, _super);
|
||||||
@ -30,7 +31,7 @@ var Web3Provider = /** @class */ (function (_super) {
|
|||||||
var url = web3Provider.host || web3Provider.path || 'unknown';
|
var url = web3Provider.host || web3Provider.path || 'unknown';
|
||||||
_this = _super.call(this, url, network) || this;
|
_this = _super.call(this, url, network) || this;
|
||||||
errors.checkNew(_this, Web3Provider);
|
errors.checkNew(_this, Web3Provider);
|
||||||
_this._web3Provider = web3Provider;
|
properties_1.defineReadOnly(_this, '_web3Provider', web3Provider);
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
Web3Provider.prototype.send = function (method, params) {
|
Web3Provider.prototype.send = function (method, params) {
|
||||||
|
1
src/utils/bytes.d.ts
vendored
1
src/utils/bytes.d.ts
vendored
@ -17,3 +17,4 @@ export declare function hexDataSlice(data: string, offset: number, length?: numb
|
|||||||
export declare function hexStripZeros(value: string): string;
|
export declare function hexStripZeros(value: string): string;
|
||||||
export declare function hexZeroPad(value: string, length: number): string;
|
export declare function hexZeroPad(value: string, length: number): string;
|
||||||
export declare function splitSignature(signature: Arrayish): Signature;
|
export declare function splitSignature(signature: Arrayish): Signature;
|
||||||
|
export declare function joinSignature(signature: Signature): string;
|
||||||
|
@ -224,3 +224,11 @@ function splitSignature(signature) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.splitSignature = splitSignature;
|
exports.splitSignature = splitSignature;
|
||||||
|
function joinSignature(signature) {
|
||||||
|
return hexlify(concat([
|
||||||
|
hexZeroPad(signature.r, 32),
|
||||||
|
hexZeroPad(signature.s, 32),
|
||||||
|
(signature.recoveryParam ? '0x1c' : '0x1b')
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
exports.joinSignature = joinSignature;
|
||||||
|
4
src/utils/hash.d.ts
vendored
Normal file
4
src/utils/hash.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Arrayish } from './bytes';
|
||||||
|
export declare function namehash(name: string): string;
|
||||||
|
export declare function id(text: string): string;
|
||||||
|
export declare function hashMessage(message: Arrayish | string): string;
|
40
src/utils/hash.js
Normal file
40
src/utils/hash.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
'use strict';
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
var bytes_1 = require("./bytes");
|
||||||
|
var utf8_1 = require("./utf8");
|
||||||
|
var keccak256_1 = require("./keccak256");
|
||||||
|
var Zeros = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
var Partition = new RegExp("^((.*)\\.)?([^.]+)$");
|
||||||
|
var UseSTD3ASCIIRules = new RegExp("^[a-z0-9.-]*$");
|
||||||
|
function namehash(name) {
|
||||||
|
name = name.toLowerCase();
|
||||||
|
// Supporting the full UTF-8 space requires additional (and large)
|
||||||
|
// libraries, so for now we simply do not support them.
|
||||||
|
// It should be fairly easy in the future to support systems with
|
||||||
|
// String.normalize, but that is future work.
|
||||||
|
if (!name.match(UseSTD3ASCIIRules)) {
|
||||||
|
throw new Error('contains invalid UseSTD3ASCIIRules characters');
|
||||||
|
}
|
||||||
|
var result = Zeros;
|
||||||
|
while (name.length) {
|
||||||
|
var partition = name.match(Partition);
|
||||||
|
var label = utf8_1.toUtf8Bytes(partition[3]);
|
||||||
|
result = keccak256_1.keccak256(bytes_1.concat([result, keccak256_1.keccak256(label)]));
|
||||||
|
name = partition[2] || '';
|
||||||
|
}
|
||||||
|
return bytes_1.hexlify(result);
|
||||||
|
}
|
||||||
|
exports.namehash = namehash;
|
||||||
|
function id(text) {
|
||||||
|
return keccak256_1.keccak256(utf8_1.toUtf8Bytes(text));
|
||||||
|
}
|
||||||
|
exports.id = id;
|
||||||
|
function hashMessage(message) {
|
||||||
|
var payload = bytes_1.concat([
|
||||||
|
utf8_1.toUtf8Bytes('\x19Ethereum Signed Message:\n'),
|
||||||
|
utf8_1.toUtf8Bytes(String(message.length)),
|
||||||
|
((typeof (message) === 'string') ? utf8_1.toUtf8Bytes(message) : message)
|
||||||
|
]);
|
||||||
|
return keccak256_1.keccak256(payload);
|
||||||
|
}
|
||||||
|
exports.hashMessage = hashMessage;
|
10
src/utils/index.d.ts
vendored
10
src/utils/index.d.ts
vendored
@ -3,12 +3,12 @@ import { AbiCoder, parseSignature } from './abi-coder';
|
|||||||
import * as base64 from './base64';
|
import * as base64 from './base64';
|
||||||
import * as bigNumber from './bignumber';
|
import * as bigNumber from './bignumber';
|
||||||
import * as bytes from './bytes';
|
import * as bytes from './bytes';
|
||||||
import { id } from './id';
|
import { hashMessage, id, namehash } from './hash';
|
||||||
import { keccak256 } from './keccak256';
|
import { keccak256 } from './keccak256';
|
||||||
import { namehash } from './namehash';
|
|
||||||
import * as sha2 from './sha2';
|
import * as sha2 from './sha2';
|
||||||
import * as solidity from './solidity';
|
import * as solidity from './solidity';
|
||||||
import { randomBytes } from './random-bytes';
|
import { randomBytes } from './random-bytes';
|
||||||
|
import properties = require('./properties');
|
||||||
import * as RLP from './rlp';
|
import * as RLP from './rlp';
|
||||||
import * as utf8 from './utf8';
|
import * as utf8 from './utf8';
|
||||||
import * as units from './units';
|
import * as units from './units';
|
||||||
@ -20,6 +20,10 @@ declare const _default: {
|
|||||||
parseSignature: typeof parseSignature;
|
parseSignature: typeof parseSignature;
|
||||||
RLP: typeof RLP;
|
RLP: typeof RLP;
|
||||||
fetchJson: typeof fetchJson;
|
fetchJson: typeof fetchJson;
|
||||||
|
defineReadOnly: typeof properties.defineReadOnly;
|
||||||
|
defineFrozen: typeof properties.defineFrozen;
|
||||||
|
resolveProperties: typeof properties.resolveProperties;
|
||||||
|
shallowCopy: typeof properties.shallowCopy;
|
||||||
etherSymbol: string;
|
etherSymbol: string;
|
||||||
arrayify: typeof bytes.arrayify;
|
arrayify: typeof bytes.arrayify;
|
||||||
concat: typeof bytes.concat;
|
concat: typeof bytes.concat;
|
||||||
@ -31,6 +35,7 @@ declare const _default: {
|
|||||||
hexlify: typeof bytes.hexlify;
|
hexlify: typeof bytes.hexlify;
|
||||||
toUtf8Bytes: typeof utf8.toUtf8Bytes;
|
toUtf8Bytes: typeof utf8.toUtf8Bytes;
|
||||||
toUtf8String: typeof utf8.toUtf8String;
|
toUtf8String: typeof utf8.toUtf8String;
|
||||||
|
hashMessage: typeof hashMessage;
|
||||||
namehash: typeof namehash;
|
namehash: typeof namehash;
|
||||||
id: typeof id;
|
id: typeof id;
|
||||||
getAddress: typeof getAddress;
|
getAddress: typeof getAddress;
|
||||||
@ -47,6 +52,7 @@ declare const _default: {
|
|||||||
solidityKeccak256: typeof solidity.keccak256;
|
solidityKeccak256: typeof solidity.keccak256;
|
||||||
soliditySha256: typeof solidity.sha256;
|
soliditySha256: typeof solidity.sha256;
|
||||||
splitSignature: typeof bytes.splitSignature;
|
splitSignature: typeof bytes.splitSignature;
|
||||||
|
joinSignature: typeof bytes.joinSignature;
|
||||||
parseTransaction: typeof parseTransaction;
|
parseTransaction: typeof parseTransaction;
|
||||||
};
|
};
|
||||||
export default _default;
|
export default _default;
|
||||||
|
@ -14,13 +14,12 @@ var abi_coder_1 = require("./abi-coder");
|
|||||||
var base64 = __importStar(require("./base64"));
|
var base64 = __importStar(require("./base64"));
|
||||||
var bigNumber = __importStar(require("./bignumber"));
|
var bigNumber = __importStar(require("./bignumber"));
|
||||||
var bytes = __importStar(require("./bytes"));
|
var bytes = __importStar(require("./bytes"));
|
||||||
var id_1 = require("./id");
|
var hash_1 = require("./hash");
|
||||||
var keccak256_1 = require("./keccak256");
|
var keccak256_1 = require("./keccak256");
|
||||||
var namehash_1 = require("./namehash");
|
|
||||||
var sha2 = __importStar(require("./sha2"));
|
var sha2 = __importStar(require("./sha2"));
|
||||||
var solidity = __importStar(require("./solidity"));
|
var solidity = __importStar(require("./solidity"));
|
||||||
var random_bytes_1 = require("./random-bytes");
|
var random_bytes_1 = require("./random-bytes");
|
||||||
//import properties = require('./properties');
|
var properties = require("./properties");
|
||||||
var RLP = __importStar(require("./rlp"));
|
var RLP = __importStar(require("./rlp"));
|
||||||
var utf8 = __importStar(require("./utf8"));
|
var utf8 = __importStar(require("./utf8"));
|
||||||
var units = __importStar(require("./units"));
|
var units = __importStar(require("./units"));
|
||||||
@ -32,7 +31,10 @@ exports.default = {
|
|||||||
parseSignature: abi_coder_1.parseSignature,
|
parseSignature: abi_coder_1.parseSignature,
|
||||||
RLP: RLP,
|
RLP: RLP,
|
||||||
fetchJson: web_1.fetchJson,
|
fetchJson: web_1.fetchJson,
|
||||||
//defineProperty: properties.defineProperty,
|
defineReadOnly: properties.defineReadOnly,
|
||||||
|
defineFrozen: properties.defineFrozen,
|
||||||
|
resolveProperties: properties.resolveProperties,
|
||||||
|
shallowCopy: properties.shallowCopy,
|
||||||
// NFKD (decomposed)
|
// NFKD (decomposed)
|
||||||
//etherSymbol: '\uD835\uDF63',
|
//etherSymbol: '\uD835\uDF63',
|
||||||
// NFKC (composed)
|
// NFKC (composed)
|
||||||
@ -47,8 +49,9 @@ exports.default = {
|
|||||||
hexlify: bytes.hexlify,
|
hexlify: bytes.hexlify,
|
||||||
toUtf8Bytes: utf8.toUtf8Bytes,
|
toUtf8Bytes: utf8.toUtf8Bytes,
|
||||||
toUtf8String: utf8.toUtf8String,
|
toUtf8String: utf8.toUtf8String,
|
||||||
namehash: namehash_1.namehash,
|
hashMessage: hash_1.hashMessage,
|
||||||
id: id_1.id,
|
namehash: hash_1.namehash,
|
||||||
|
id: hash_1.id,
|
||||||
getAddress: address_1.getAddress,
|
getAddress: address_1.getAddress,
|
||||||
getIcapAddress: address_1.getIcapAddress,
|
getIcapAddress: address_1.getIcapAddress,
|
||||||
getContractAddress: address_1.getContractAddress,
|
getContractAddress: address_1.getContractAddress,
|
||||||
@ -63,5 +66,6 @@ exports.default = {
|
|||||||
solidityKeccak256: solidity.keccak256,
|
solidityKeccak256: solidity.keccak256,
|
||||||
soliditySha256: solidity.sha256,
|
soliditySha256: solidity.sha256,
|
||||||
splitSignature: bytes.splitSignature,
|
splitSignature: bytes.splitSignature,
|
||||||
|
joinSignature: bytes.joinSignature,
|
||||||
parseTransaction: transaction_1.parse
|
parseTransaction: transaction_1.parse
|
||||||
};
|
};
|
||||||
|
0
src/utils/messages.d.ts
vendored
Normal file
0
src/utils/messages.d.ts
vendored
Normal file
31
src/utils/messages.js
Normal file
31
src/utils/messages.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
import { Arrayish, concat } from './bytes';
|
||||||
|
export function hashMessage(message: Arrayish | string): string {
|
||||||
|
var payload = concat([
|
||||||
|
toUtf8Bytes('\x19Ethereum Signed Message:\n'),
|
||||||
|
toUtf8Bytes(String(message.length)),
|
||||||
|
((typeof(message) === 'string') ? toUtf8Bytes(message): message)
|
||||||
|
]);
|
||||||
|
return keccak256(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export verifyMessage(message: Arrayish | string, signature: string): string {
|
||||||
|
signature = hexlify(signature);
|
||||||
|
if (signature.length != 132) { throw new Error('invalid signature'); }
|
||||||
|
var digest = Wallet.hashMessage(message);
|
||||||
|
|
||||||
|
var recoveryParam = parseInt(signature.substring(130), 16);
|
||||||
|
if (recoveryParam >= 27) { recoveryParam -= 27; }
|
||||||
|
if (recoveryParam < 0) { throw new Error('invalid signature'); }
|
||||||
|
|
||||||
|
return recoverAddress(
|
||||||
|
digest,
|
||||||
|
{
|
||||||
|
r: signature.substring(0, 66),
|
||||||
|
s: '0x' + signature.substring(66, 130),
|
||||||
|
recoveryParam: recoveryParam
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
6
src/utils/properties.d.ts
vendored
6
src/utils/properties.d.ts
vendored
@ -1,7 +1,5 @@
|
|||||||
export declare function defineReadOnly(object: any, name: any, value: any): void;
|
export declare function defineReadOnly(object: any, name: string, value: any): void;
|
||||||
export declare function defineFrozen(object: any, name: any, value: any): void;
|
export declare function defineFrozen(object: any, name: string, value: any): void;
|
||||||
export declare type DeferredSetter = (value: any) => void;
|
|
||||||
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 shallowCopy(object: any): any;
|
||||||
export declare function jsonCopy(object: any): any;
|
export declare function jsonCopy(object: any): any;
|
||||||
|
@ -16,19 +16,6 @@ function defineFrozen(object, name, value) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.defineFrozen = defineFrozen;
|
exports.defineFrozen = defineFrozen;
|
||||||
function defineDeferredReadOnly(object, name, value) {
|
|
||||||
var _value = value;
|
|
||||||
var setter = function (value) {
|
|
||||||
_value = value;
|
|
||||||
};
|
|
||||||
Object.defineProperty(object, name, {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return _value; },
|
|
||||||
set: setter
|
|
||||||
});
|
|
||||||
return setter;
|
|
||||||
}
|
|
||||||
exports.defineDeferredReadOnly = defineDeferredReadOnly;
|
|
||||||
function resolveProperties(object) {
|
function resolveProperties(object) {
|
||||||
var result = {};
|
var result = {};
|
||||||
var promises = [];
|
var promises = [];
|
||||||
|
@ -28,8 +28,8 @@ var KeyPair = /** @class */ (function () {
|
|||||||
var signature = keyPair.sign(bytes_1.arrayify(digest), { canonical: true });
|
var signature = keyPair.sign(bytes_1.arrayify(digest), { canonical: true });
|
||||||
return {
|
return {
|
||||||
recoveryParam: signature.recoveryParam,
|
recoveryParam: signature.recoveryParam,
|
||||||
r: '0x' + signature.r.toString(16),
|
r: bytes_1.hexZeroPad('0x' + signature.r.toString(16), 32),
|
||||||
s: '0x' + signature.s.toString(16),
|
s: bytes_1.hexZeroPad('0x' + signature.s.toString(16), 32),
|
||||||
v: 27 + signature.recoveryParam
|
v: 27 + signature.recoveryParam
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -72,8 +72,8 @@ function sign(transaction, signDigest) {
|
|||||||
v += transaction.chainId * 2 + 8;
|
v += transaction.chainId * 2 + 8;
|
||||||
}
|
}
|
||||||
raw.push(bytes_1.hexlify(v));
|
raw.push(bytes_1.hexlify(v));
|
||||||
raw.push(signature.r);
|
raw.push(bytes_1.stripZeros(bytes_1.arrayify(signature.r)));
|
||||||
raw.push(signature.s);
|
raw.push(bytes_1.stripZeros(bytes_1.arrayify(signature.s)));
|
||||||
return RLP.encode(raw);
|
return RLP.encode(raw);
|
||||||
}
|
}
|
||||||
exports.sign = sign;
|
exports.sign = sign;
|
||||||
@ -96,8 +96,8 @@ function parse(rawTransaction) {
|
|||||||
var s = bytes_1.arrayify(signedTransaction[8]);
|
var s = bytes_1.arrayify(signedTransaction[8]);
|
||||||
if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) {
|
if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) {
|
||||||
tx.v = bignumber_1.bigNumberify(v).toNumber();
|
tx.v = bignumber_1.bigNumberify(v).toNumber();
|
||||||
tx.r = signedTransaction[7];
|
tx.r = bytes_1.hexZeroPad(signedTransaction[7], 32);
|
||||||
tx.s = signedTransaction[8];
|
tx.s = bytes_1.hexZeroPad(signedTransaction[8], 32);
|
||||||
var chainId = (tx.v - 35) / 2;
|
var chainId = (tx.v - 35) / 2;
|
||||||
if (chainId < 0) {
|
if (chainId < 0) {
|
||||||
chainId = 0;
|
chainId = 0;
|
||||||
|
1
src/wallet/hdnode.d.ts
vendored
1
src/wallet/hdnode.d.ts
vendored
@ -1,5 +1,6 @@
|
|||||||
import { Arrayish } from '../utils/bytes';
|
import { Arrayish } from '../utils/bytes';
|
||||||
import { KeyPair } from '../utils/secp256k1';
|
import { KeyPair } from '../utils/secp256k1';
|
||||||
|
export declare const defaultPath = "m/44'/60'/0'/0/0";
|
||||||
export declare class HDNode {
|
export declare class HDNode {
|
||||||
private readonly keyPair;
|
private readonly keyPair;
|
||||||
readonly privateKey: string;
|
readonly privateKey: string;
|
||||||
|
@ -29,6 +29,7 @@ function getUpperMask(bits) {
|
|||||||
function getLowerMask(bits) {
|
function getLowerMask(bits) {
|
||||||
return (1 << bits) - 1;
|
return (1 << bits) - 1;
|
||||||
}
|
}
|
||||||
|
exports.defaultPath = "m/44'/60'/0'/0/0";
|
||||||
var HDNode = /** @class */ (function () {
|
var HDNode = /** @class */ (function () {
|
||||||
// @TODO: Private constructor?
|
// @TODO: Private constructor?
|
||||||
function HDNode(keyPair, chainCode, index, depth, mnemonic, path) {
|
function HDNode(keyPair, chainCode, index, depth, mnemonic, path) {
|
||||||
|
29
src/wallet/wallet.d.ts
vendored
29
src/wallet/wallet.d.ts
vendored
@ -4,41 +4,34 @@ import { SigningKey } from './signing-key';
|
|||||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from '../providers/provider';
|
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from '../providers/provider';
|
||||||
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
import { BigNumber, BigNumberish } from '../utils/bignumber';
|
||||||
import { Arrayish } from '../utils/bytes';
|
import { Arrayish } from '../utils/bytes';
|
||||||
import { UnsignedTransaction } from '../utils/transaction';
|
export declare abstract class Signer {
|
||||||
export interface Signer {
|
provider?: Provider;
|
||||||
address?: string;
|
abstract getAddress(): Promise<string>;
|
||||||
getAddress(): Promise<string>;
|
abstract signMessage(transaction: Arrayish | string): Promise<string>;
|
||||||
sendTransaction(transaction: UnsignedTransaction): Promise<TransactionResponse>;
|
abstract sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
provider: Provider;
|
|
||||||
sign(transaction: UnsignedTransaction): string;
|
|
||||||
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
|
||||||
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
|
||||||
getGasPrice(transaction?: TransactionRequest): Promise<BigNumber>;
|
|
||||||
}
|
}
|
||||||
export declare class Wallet implements Signer {
|
export declare class Wallet extends Signer {
|
||||||
readonly address: string;
|
readonly address: string;
|
||||||
readonly privateKey: string;
|
readonly privateKey: string;
|
||||||
|
readonly provider: Provider;
|
||||||
private mnemonic;
|
private mnemonic;
|
||||||
private path;
|
private path;
|
||||||
private readonly signingKey;
|
private readonly signingKey;
|
||||||
provider: Provider;
|
|
||||||
defaultGasLimit: number;
|
defaultGasLimit: number;
|
||||||
constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider);
|
constructor(privateKey: SigningKey | HDNode | Arrayish, provider?: Provider);
|
||||||
sign(transaction: UnsignedTransaction): string;
|
connect(provider: Provider): Wallet;
|
||||||
getAddress(): Promise<string>;
|
getAddress(): Promise<string>;
|
||||||
|
sign(transaction: TransactionRequest): Promise<string>;
|
||||||
|
signMessage(message: Arrayish | string): Promise<string>;
|
||||||
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
getBalance(blockTag?: BlockTag): Promise<BigNumber>;
|
||||||
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
getTransactionCount(blockTag?: BlockTag): Promise<number>;
|
||||||
getGasPrice(): Promise<BigNumber>;
|
|
||||||
estimateGas(transaction: TransactionRequest): Promise<BigNumber>;
|
|
||||||
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>;
|
||||||
send(addressOrName: string, amountWei: BigNumberish, options: any): Promise<TransactionResponse>;
|
send(addressOrName: string, amountWei: BigNumberish, options: any): Promise<TransactionResponse>;
|
||||||
static hashMessage(message: Arrayish | string): string;
|
|
||||||
signMessage(message: Arrayish | string): string;
|
|
||||||
static verifyMessage(message: Arrayish | string, signature: string): string;
|
|
||||||
encrypt(password: Arrayish | string, options: any, progressCallback: ProgressCallback): Promise<string>;
|
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: string, password: Arrayish, progressCallback: ProgressCallback): Promise<Wallet>;
|
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: ProgressCallback): Promise<Wallet>;
|
static fromBrainWallet(username: Arrayish | string, password: Arrayish | string, progressCallback: ProgressCallback): Promise<Wallet>;
|
||||||
|
static verifyMessage(message: Arrayish | string, signature: string): string;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||||
|
return function (d, b) {
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
@ -15,6 +25,7 @@ var hdnode_1 = require("./hdnode");
|
|||||||
var secretStorage = __importStar(require("./secret-storage"));
|
var secretStorage = __importStar(require("./secret-storage"));
|
||||||
var signing_key_1 = require("./signing-key");
|
var signing_key_1 = require("./signing-key");
|
||||||
var bytes_1 = require("../utils/bytes");
|
var bytes_1 = require("../utils/bytes");
|
||||||
|
var hash_1 = require("../utils/hash");
|
||||||
var keccak256_1 = require("../utils/keccak256");
|
var keccak256_1 = require("../utils/keccak256");
|
||||||
var properties_1 = require("../utils/properties");
|
var properties_1 = require("../utils/properties");
|
||||||
var random_bytes_1 = require("../utils/random-bytes");
|
var random_bytes_1 = require("../utils/random-bytes");
|
||||||
@ -24,34 +35,50 @@ var errors = __importStar(require("../utils/errors"));
|
|||||||
// 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");
|
||||||
// @TODO: Move to HDNode
|
//import _setimmediate = require('setimmediate');
|
||||||
var defaultPath = "m/44'/60'/0'/0/0";
|
var Signer = /** @class */ (function () {
|
||||||
var Wallet = /** @class */ (function () {
|
function Signer() {
|
||||||
|
}
|
||||||
|
return Signer;
|
||||||
|
}());
|
||||||
|
exports.Signer = Signer;
|
||||||
|
var Wallet = /** @class */ (function (_super) {
|
||||||
|
__extends(Wallet, _super);
|
||||||
function Wallet(privateKey, provider) {
|
function Wallet(privateKey, provider) {
|
||||||
//private _provider;
|
var _this = _super.call(this) || this;
|
||||||
this.defaultGasLimit = 1500000;
|
_this.defaultGasLimit = 1500000;
|
||||||
errors.checkNew(this, Wallet);
|
errors.checkNew(_this, Wallet);
|
||||||
// Make sure we have a valid signing key
|
// Make sure we have a valid signing key
|
||||||
if (privateKey instanceof signing_key_1.SigningKey) {
|
if (privateKey instanceof signing_key_1.SigningKey) {
|
||||||
this.signingKey = privateKey;
|
properties_1.defineReadOnly(_this, 'signingKey', privateKey);
|
||||||
if (this.signingKey.mnemonic) {
|
if (_this.signingKey.mnemonic) {
|
||||||
properties_1.defineReadOnly(this, 'mnemonic', privateKey.mnemonic);
|
properties_1.defineReadOnly(_this, 'mnemonic', privateKey.mnemonic);
|
||||||
properties_1.defineReadOnly(this, 'path', privateKey.path);
|
properties_1.defineReadOnly(_this, 'path', privateKey.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.signingKey = new signing_key_1.SigningKey(privateKey);
|
properties_1.defineReadOnly(_this, 'signingKey', new signing_key_1.SigningKey(privateKey));
|
||||||
}
|
}
|
||||||
properties_1.defineReadOnly(this, 'privateKey', this.signingKey.privateKey);
|
properties_1.defineReadOnly(_this, 'privateKey', _this.signingKey.privateKey);
|
||||||
this.provider = provider;
|
properties_1.defineReadOnly(_this, 'provider', provider);
|
||||||
properties_1.defineReadOnly(this, 'address', this.signingKey.address);
|
properties_1.defineReadOnly(_this, 'address', _this.signingKey.address);
|
||||||
|
return _this;
|
||||||
}
|
}
|
||||||
Wallet.prototype.sign = function (transaction) {
|
Wallet.prototype.connect = function (provider) {
|
||||||
return transaction_1.sign(transaction, this.signingKey.signDigest.bind(this.signingKey));
|
return new Wallet(this.signingKey, provider);
|
||||||
};
|
};
|
||||||
Wallet.prototype.getAddress = function () {
|
Wallet.prototype.getAddress = function () {
|
||||||
return Promise.resolve(this.address);
|
return Promise.resolve(this.address);
|
||||||
};
|
};
|
||||||
|
Wallet.prototype.sign = function (transaction) {
|
||||||
|
var _this = this;
|
||||||
|
return properties_1.resolveProperties(transaction).then(function (tx) {
|
||||||
|
return transaction_1.sign(tx, _this.signingKey.signDigest.bind(_this.signingKey));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Wallet.prototype.signMessage = function (message) {
|
||||||
|
return Promise.resolve(bytes_1.joinSignature(this.signingKey.signDigest(hash_1.hashMessage(message))));
|
||||||
|
};
|
||||||
Wallet.prototype.getBalance = function (blockTag) {
|
Wallet.prototype.getBalance = function (blockTag) {
|
||||||
if (!this.provider) {
|
if (!this.provider) {
|
||||||
throw new Error('missing provider');
|
throw new Error('missing provider');
|
||||||
@ -64,28 +91,6 @@ var Wallet = /** @class */ (function () {
|
|||||||
}
|
}
|
||||||
return this.provider.getTransactionCount(this.address, blockTag);
|
return this.provider.getTransactionCount(this.address, blockTag);
|
||||||
};
|
};
|
||||||
Wallet.prototype.getGasPrice = function () {
|
|
||||||
if (!this.provider) {
|
|
||||||
throw new Error('missing provider');
|
|
||||||
}
|
|
||||||
return this.provider.getGasPrice();
|
|
||||||
};
|
|
||||||
Wallet.prototype.estimateGas = function (transaction) {
|
|
||||||
if (!this.provider) {
|
|
||||||
throw new Error('missing provider');
|
|
||||||
}
|
|
||||||
var calculate = {};
|
|
||||||
['from', 'to', 'data', 'value'].forEach(function (key) {
|
|
||||||
if (transaction[key] == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
calculate[key] = transaction[key];
|
|
||||||
});
|
|
||||||
if (transaction.from == null) {
|
|
||||||
calculate.from = this.address;
|
|
||||||
}
|
|
||||||
return this.provider.estimateGas(calculate);
|
|
||||||
};
|
|
||||||
Wallet.prototype.sendTransaction = function (transaction) {
|
Wallet.prototype.sendTransaction = function (transaction) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
if (!this.provider) {
|
if (!this.provider) {
|
||||||
@ -99,10 +104,10 @@ var Wallet = /** @class */ (function () {
|
|||||||
tx.to = this.provider.resolveName(tx.to);
|
tx.to = this.provider.resolveName(tx.to);
|
||||||
}
|
}
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx);
|
tx.gasLimit = this.provider.estimateGas(tx);
|
||||||
}
|
}
|
||||||
if (tx.gasPrice == null) {
|
if (tx.gasPrice == null) {
|
||||||
tx.gasPrice = this.getGasPrice();
|
tx.gasPrice = this.provider.getGasPrice();
|
||||||
}
|
}
|
||||||
if (tx.nonce == null) {
|
if (tx.nonce == null) {
|
||||||
tx.nonce = this.getTransactionCount();
|
tx.nonce = this.getTransactionCount();
|
||||||
@ -127,38 +132,6 @@ var Wallet = /** @class */ (function () {
|
|||||||
value: amountWei,
|
value: amountWei,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Wallet.hashMessage = function (message) {
|
|
||||||
var payload = bytes_1.concat([
|
|
||||||
utf8_1.toUtf8Bytes('\x19Ethereum Signed Message:\n'),
|
|
||||||
utf8_1.toUtf8Bytes(String(message.length)),
|
|
||||||
((typeof (message) === 'string') ? utf8_1.toUtf8Bytes(message) : message)
|
|
||||||
]);
|
|
||||||
return keccak256_1.keccak256(payload);
|
|
||||||
};
|
|
||||||
Wallet.prototype.signMessage = function (message) {
|
|
||||||
var signingKey = new signing_key_1.SigningKey(this.privateKey);
|
|
||||||
var sig = signingKey.signDigest(Wallet.hashMessage(message));
|
|
||||||
return (bytes_1.hexZeroPad(sig.r, 32) + bytes_1.hexZeroPad(sig.s, 32).substring(2) + (sig.recoveryParam ? '1c' : '1b'));
|
|
||||||
};
|
|
||||||
Wallet.verifyMessage = function (message, signature) {
|
|
||||||
signature = bytes_1.hexlify(signature);
|
|
||||||
if (signature.length != 132) {
|
|
||||||
throw new Error('invalid signature');
|
|
||||||
}
|
|
||||||
var digest = Wallet.hashMessage(message);
|
|
||||||
var recoveryParam = parseInt(signature.substring(130), 16);
|
|
||||||
if (recoveryParam >= 27) {
|
|
||||||
recoveryParam -= 27;
|
|
||||||
}
|
|
||||||
if (recoveryParam < 0) {
|
|
||||||
throw new Error('invalid signature');
|
|
||||||
}
|
|
||||||
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) {
|
||||||
progressCallback = options;
|
progressCallback = options;
|
||||||
@ -232,7 +205,7 @@ var Wallet = /** @class */ (function () {
|
|||||||
};
|
};
|
||||||
Wallet.fromMnemonic = function (mnemonic, path) {
|
Wallet.fromMnemonic = function (mnemonic, path) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
path = defaultPath;
|
path = hdnode_1.defaultPath;
|
||||||
}
|
}
|
||||||
return new Wallet(hdnode_1.fromMnemonic(mnemonic).derivePath(path));
|
return new Wallet(hdnode_1.fromMnemonic(mnemonic).derivePath(path));
|
||||||
};
|
};
|
||||||
@ -266,6 +239,25 @@ var Wallet = /** @class */ (function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Wallet.verifyMessage = function (message, signature) {
|
||||||
|
signature = bytes_1.hexlify(signature);
|
||||||
|
if (signature.length != 132) {
|
||||||
|
throw new Error('invalid signature');
|
||||||
|
}
|
||||||
|
var digest = hash_1.hashMessage(message);
|
||||||
|
var recoveryParam = parseInt(signature.substring(130), 16);
|
||||||
|
if (recoveryParam >= 27) {
|
||||||
|
recoveryParam -= 27;
|
||||||
|
}
|
||||||
|
if (recoveryParam < 0) {
|
||||||
|
throw new Error('invalid signature');
|
||||||
|
}
|
||||||
|
return signing_key_1.recoverAddress(digest, {
|
||||||
|
r: signature.substring(0, 66),
|
||||||
|
s: '0x' + signature.substring(66, 130),
|
||||||
|
recoveryParam: recoveryParam
|
||||||
|
});
|
||||||
|
};
|
||||||
return Wallet;
|
return Wallet;
|
||||||
}());
|
}(Signer));
|
||||||
exports.Wallet = Wallet;
|
exports.Wallet = Wallet;
|
||||||
|
@ -85,7 +85,7 @@ describe('Test Transaction Signing and Parsing', function() {
|
|||||||
|
|
||||||
var tests = utils.loadTests('transactions');
|
var tests = utils.loadTests('transactions');
|
||||||
tests.forEach(function(test) {
|
tests.forEach(function(test) {
|
||||||
it(('parses and signs transaction - ' + test.name), function() {
|
it(('parses and signs transaction - ' + test.name), async function() {
|
||||||
var wallet = new Wallet(test.privateKey);
|
var wallet = new Wallet(test.privateKey);
|
||||||
|
|
||||||
var transaction = {};
|
var transaction = {};
|
||||||
@ -133,9 +133,8 @@ describe('Test Transaction Signing and Parsing', function() {
|
|||||||
|
|
||||||
assert.equal(parsedTransaction.chainId, 0, 'parsed chainId');
|
assert.equal(parsedTransaction.chainId, 0, 'parsed chainId');
|
||||||
|
|
||||||
var signedTransaction = wallet.sign(transaction);
|
var signedTransaction = await wallet.sign(transaction);
|
||||||
assert.equal(signedTransaction, test.signedTransaction,
|
assert.equal(signedTransaction, test.signedTransaction, 'signed transaction');
|
||||||
'signed transaction');
|
|
||||||
|
|
||||||
// EIP155
|
// EIP155
|
||||||
|
|
||||||
@ -152,9 +151,8 @@ describe('Test Transaction Signing and Parsing', function() {
|
|||||||
'eip155 parsed chainId');
|
'eip155 parsed chainId');
|
||||||
|
|
||||||
transaction.chainId = 5;
|
transaction.chainId = 5;
|
||||||
var signedTransactionChainId5 = wallet.sign(transaction);
|
var signedTransactionChainId5 = await wallet.sign(transaction);
|
||||||
assert.equal(signedTransactionChainId5, test.signedTransactionChainId5,
|
assert.equal(signedTransactionChainId5, test.signedTransactionChainId5, 'eip155 signed transaction');
|
||||||
'eip155 signed transaction');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -202,8 +200,9 @@ describe('Test Signing Messages', function() {
|
|||||||
it(('signs a message "' + test.name + '"'), function() {
|
it(('signs a message "' + test.name + '"'), function() {
|
||||||
this.timeout(1000000);
|
this.timeout(1000000);
|
||||||
var wallet = new Wallet(test.privateKey);
|
var wallet = new Wallet(test.privateKey);
|
||||||
var signature = wallet.signMessage(test.message);
|
return wallet.signMessage(test.message).then(function(signature) {
|
||||||
assert.equal(signature, test.signature, 'computes message signature');
|
assert.equal(signature, test.signature, 'computes message signature');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -218,7 +217,7 @@ describe('Test Signing Messages', function() {
|
|||||||
tests.forEach(function(test) {
|
tests.forEach(function(test) {
|
||||||
it(('hashes a message "' + test.name + '"'), function() {
|
it(('hashes a message "' + test.name + '"'), function() {
|
||||||
this.timeout(1000000);
|
this.timeout(1000000);
|
||||||
var hash = Wallet.hashMessage(test.message);
|
var hash = ethers.utils.hashMessage(test.message);
|
||||||
assert.equal(hash, test.messageHash, 'calculates message hash');
|
assert.equal(hash, test.messageHash, 'calculates message hash');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user