Add metacoin example project

This commit is contained in:
Leonid Logvinov
2018-03-28 11:05:36 +02:00
parent bc49dde4d5
commit 4d9029bb0e
82 changed files with 1209 additions and 732 deletions

View File

@@ -8,6 +8,7 @@ CHANGELOG
## v0.34.0 - _April 2, 2018_
* Fix the bug causing `zeroEx.exchange.fillOrdersUpToAsync` validation to fail if there were some extra orders passed (#470)
* Removed `ZeroExError.TransactionMiningTimeout` and moved it to '@0xproject/web3_wrapper' `Web3WrapperErrors.TransactionMiningTimeout` (#485)
* Remove automatic instantiation of `zeroEx.orderStateWatcher` (#488)
* Add `zeroEx.createOrderStateWatcher` to allow creating arbitrary number of OrderStateWatchers (#488)
* Added `stateLayer` setting to `OrderStateWatcherConfig` so OrderStateWatcher can be set to monitor different blockchain state layers (#488)

View File

@@ -90,7 +90,6 @@
"truffle-hdwallet-provider": "^0.0.3",
"tslint": "5.8.0",
"typedoc": "0xProject/typedoc",
"types-bn": "^0.0.1",
"typescript": "2.7.1",
"web3-provider-engine": "^13.0.1",
"webpack": "^3.1.0"

View File

@@ -58,7 +58,6 @@ export class ZeroEx {
*/
public proxy: TokenTransferProxyWrapper;
private _web3Wrapper: Web3Wrapper;
private _abiDecoder: AbiDecoder;
/**
* Verifies that the elliptic curve signature `signature` was generated
* by signing `data` with the private key corresponding to the `signerAddress` address.
@@ -167,21 +166,22 @@ export class ZeroEx {
]);
const artifactJSONs = _.values(artifacts);
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
this._abiDecoder = new AbiDecoder(abiArrays);
const defaults = {
gasPrice: config.gasPrice,
};
this._web3Wrapper = new Web3Wrapper(provider, defaults);
_.forEach(abiArrays, abi => {
this._web3Wrapper.abiDecoder.addABI(abi);
});
this.proxy = new TokenTransferProxyWrapper(
this._web3Wrapper,
config.networkId,
config.tokenTransferProxyContractAddress,
);
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this.proxy);
this.exchange = new ExchangeWrapper(
this._web3Wrapper,
config.networkId,
this._abiDecoder,
this.token,
config.exchangeContractAddress,
config.zrxContractAddress,
@@ -191,7 +191,7 @@ export class ZeroEx {
config.networkId,
config.tokenRegistryContractAddress,
);
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this.token);
}
/**
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
@@ -285,44 +285,12 @@ export class ZeroEx {
pollingIntervalMs = 1000,
timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> {
let timeoutExceeded = false;
if (timeoutMs) {
setTimeout(() => (timeoutExceeded = true), timeoutMs);
}
const txReceiptPromise = new Promise(
(resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => {
const intervalId = intervalUtils.setAsyncExcludingInterval(
async () => {
if (timeoutExceeded) {
intervalUtils.clearAsyncExcludingInterval(intervalId);
return reject(ZeroExError.TransactionMiningTimeout);
}
const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash);
if (!_.isNull(transactionReceipt)) {
intervalUtils.clearAsyncExcludingInterval(intervalId);
const logsWithDecodedArgs = _.map(
transactionReceipt.logs,
this._abiDecoder.tryToDecodeLogOrNoop.bind(this._abiDecoder),
);
const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = {
...transactionReceipt,
logs: logsWithDecodedArgs,
};
resolve(transactionReceiptWithDecodedLogArgs);
}
},
pollingIntervalMs,
(err: Error) => {
intervalUtils.clearAsyncExcludingInterval(intervalId);
reject(err);
},
);
},
const transactionReceiptWithDecodedLogs = await this._web3Wrapper.awaitTransactionMinedAsync(
txHash,
pollingIntervalMs,
timeoutMs,
);
const txReceipt = await txReceiptPromise;
return txReceipt;
return transactionReceiptWithDecodedLogs;
}
/**
* Instantiates and returns a new OrderStateWatcher instance.

View File

@@ -32,7 +32,6 @@ const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
export class ContractWrapper {
protected _web3Wrapper: Web3Wrapper;
protected _networkId: number;
private _abiDecoder?: AbiDecoder;
private _blockAndLogStreamerIfExists?: BlockAndLogStreamer;
private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer;
private _filters: { [filterToken: string]: FilterObject };
@@ -41,10 +40,9 @@ export class ContractWrapper {
};
private _onLogAddedSubscriptionToken: string | undefined;
private _onLogRemovedSubscriptionToken: string | undefined;
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
constructor(web3Wrapper: Web3Wrapper, networkId: number) {
this._web3Wrapper = web3Wrapper;
this._networkId = networkId;
this._abiDecoder = abiDecoder;
this._filters = {};
this._filterCallbacks = {};
this._blockAndLogStreamerIfExists = undefined;
@@ -102,10 +100,10 @@ export class ContractWrapper {
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
log: LogEntry,
): LogWithDecodedArgs<ArgsType> | RawLog {
if (_.isUndefined(this._abiDecoder)) {
if (_.isUndefined(this._web3Wrapper.abiDecoder)) {
throw new Error(InternalZeroExError.NoAbiDecoder);
}
const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log);
const logWithDecodedArgs = this._web3Wrapper.abiDecoder.tryToDecodeLogOrNoop(log);
return logWithDecodedArgs;
}
protected async _getContractAbiAndAddressFromArtifactsAsync(

View File

@@ -21,8 +21,8 @@ export class EtherTokenWrapper extends ContractWrapper {
[address: string]: EtherTokenContract;
} = {};
private _tokenWrapper: TokenWrapper;
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
super(web3Wrapper, networkId, abiDecoder);
constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenWrapper: TokenWrapper) {
super(web3Wrapper, networkId);
this._tokenWrapper = tokenWrapper;
}
/**

View File

@@ -87,12 +87,11 @@ export class ExchangeWrapper extends ContractWrapper {
constructor(
web3Wrapper: Web3Wrapper,
networkId: number,
abiDecoder: AbiDecoder,
tokenWrapper: TokenWrapper,
contractAddressIfExists?: string,
zrxContractAddressIfExists?: string,
) {
super(web3Wrapper, networkId, abiDecoder);
super(web3Wrapper, networkId);
this._tokenWrapper = tokenWrapper;
this._orderValidationUtils = new OrderValidationUtils(this);
this._contractAddressIfExists = contractAddressIfExists;

View File

@@ -22,13 +22,8 @@ export class TokenWrapper extends ContractWrapper {
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
private _tokenContractsByAddress: { [address: string]: TokenContract };
private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
constructor(
web3Wrapper: Web3Wrapper,
networkId: number,
abiDecoder: AbiDecoder,
tokenTransferProxyWrapper: TokenTransferProxyWrapper,
) {
super(web3Wrapper, networkId, abiDecoder);
constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenTransferProxyWrapper: TokenTransferProxyWrapper) {
super(web3Wrapper, networkId);
this._tokenContractsByAddress = {};
this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
}

View File

@@ -1,50 +1,14 @@
declare module 'web3_beta';
declare module 'chai-bignumber';
declare module 'dirty-chai';
declare module 'request-promise-native';
declare module 'web3-provider-engine';
declare module 'web3-provider-engine/subproviders/rpc';
declare module 'publish-release';
// semver-sort declarations
declare module 'semver-sort' {
const desc: (versions: string[]) => string[];
}
// HACK: In order to merge the bignumber declaration added by chai-bignumber to the chai Assertion
// interface we must use `namespace` as the Chai definitelyTyped definition does. Since we otherwise
// disallow `namespace`, we disable tslint for the following.
/* tslint:disable */
declare namespace Chai {
interface Assertion {
bignumber: Assertion;
// HACK: In order to comply with chai-as-promised we make eventually a `PromisedAssertion` not an `Assertion`
eventually: PromisedAssertion;
}
}
/* tslint:enable */
declare module '*.json' {
const json: any;
/* tslint:disable */
export default json;
/* tslint:enable */
}
declare module 'ethereumjs-abi' {
const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
}
// truffle-hdwallet-provider declarations
declare module 'truffle-hdwallet-provider' {
import { JSONRPCRequestPayload, JSONRPCResponsePayload } from '@0xproject/types';
import * as Web3 from 'web3';
class HDWalletProvider implements Web3.Provider {
constructor(mnemonic: string, rpcUrl: string);
public sendAsync(
payload: JSONRPCRequestPayload,
callback: (err: Error, result: JSONRPCResponsePayload) => void,
): void;
}
export = HDWalletProvider;
}

View File

@@ -1,23 +0,0 @@
import { BigNumber } from '@0xproject/utils';
// HACK: This module overrides the Chai namespace so that we can use BigNumber types inside.
// Source: https://github.com/Microsoft/TypeScript/issues/7352#issuecomment-191547232
declare global {
// HACK: In order to merge the bignumber declaration added by chai-bignumber to the chai Assertion
// interface we must use `namespace` as the Chai definitelyTyped definition does. Since we otherwise
// disallow `namespace`, we disable tslint for the following.
/* tslint:disable */
namespace Chai {
interface NumberComparer {
(value: number | BigNumber, message?: string): Assertion;
}
interface NumericComparison {
greaterThan: NumberComparer;
}
}
/* tslint:enable */
interface DecodedLogArg {
name: string;
value: string | BigNumber;
}
}

View File

@@ -69,7 +69,6 @@ export class OrderStateWatcher {
private _callbackIfExists?: OnOrderStateChangeCallback;
private _eventWatcher: EventWatcher;
private _web3Wrapper: Web3Wrapper;
private _abiDecoder: AbiDecoder;
private _expirationWatcher: ExpirationWatcher;
private _orderStateUtils: OrderStateUtils;
private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
@@ -78,12 +77,10 @@ export class OrderStateWatcher {
private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
constructor(
web3Wrapper: Web3Wrapper,
abiDecoder: AbiDecoder,
token: TokenWrapper,
exchange: ExchangeWrapper,
config?: OrderStateWatcherConfig,
) {
this._abiDecoder = abiDecoder;
this._web3Wrapper = web3Wrapper;
const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
const stateLayer =
@@ -230,7 +227,7 @@ export class OrderStateWatcher {
return;
}
const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined.
const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop<ContractEventArgs>(log);
const maybeDecodedLog = this._web3Wrapper.abiDecoder.tryToDecodeLogOrNoop<ContractEventArgs>(log);
const isLogDecoded = !_.isUndefined(((maybeDecodedLog as any) as LogWithDecodedArgs<ContractEventArgs>).event);
if (!isLogDecoded) {
return; // noop

View File

@@ -38,7 +38,6 @@ export enum ZeroExError {
NoNetworkId = 'NO_NETWORK_ID',
SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND',
SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
TransactionMiningTimeout = 'TRANSACTION_MINING_TIMEOUT',
}
export enum InternalZeroExError {

View File

@@ -1,13 +1,7 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "lib",
"noImplicitThis": false
"outDir": "lib"
},
"include": [
"./src/**/*",
"./test/**/*",
"../../node_modules/types-bn/index.d.ts",
"../../node_modules/types-ethereumjs-util/index.d.ts"
]
"include": ["./src/**/*", "./test/**/*"]
}