Merge branch 'development' into fix/refactorDocs
* development: (30 commits) Export TransactionOpts type Make website private Publish Update CHANGELOG Change interval to 1h Rename Add ifExists to cleanupJobInterval Add a cleanup job to an order watcher Improve the comment Add CHANGELOG comment Add a HACK comment Normalise subprovider names Remove a comment Fix a typo Pin testrpc version Remove gas params from tests Add fake gas estimate suprovider for tests Revert "Fix website linter errors" Fix website linter errors Fix tests ... # Conflicts: # packages/website/ts/utils/constants.ts
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
vx.x.x
|
v0.27.1 - _November 28, 2017_
|
||||||
|
------------------------
|
||||||
|
* Export `TransactionOpts` type
|
||||||
|
|
||||||
|
v0.27.0 - _November 28, 2017_
|
||||||
------------------------
|
------------------------
|
||||||
* Make `ZeroExConfig` required parameter of `ZeroEx` constructor (#233)
|
* Make `ZeroExConfig` required parameter of `ZeroEx` constructor (#233)
|
||||||
* Add a required property `networkId` to `ZeroExConfig` (#233)
|
* Add a required property `networkId` to `ZeroExConfig` (#233)
|
||||||
@@ -8,9 +12,11 @@ vx.x.x
|
|||||||
* Remove `ZeroExError.ContractNotFound` and replace it with contract-specific errors (#233)
|
* Remove `ZeroExError.ContractNotFound` and replace it with contract-specific errors (#233)
|
||||||
* Make `DecodedLogEvent<A>` contain `LogWithDecodedArgs<A>` under log key instead of merging it in like web3 does (#234)
|
* Make `DecodedLogEvent<A>` contain `LogWithDecodedArgs<A>` under log key instead of merging it in like web3 does (#234)
|
||||||
* Rename `removed` to `isRemoved` in `DecodedLogEvent<A>` (#234)
|
* Rename `removed` to `isRemoved` in `DecodedLogEvent<A>` (#234)
|
||||||
|
* Add config allowing to specify gasPrice and gasLimit for every transaction sending method (#235)
|
||||||
|
* All transaction sending methods now call `estimateGas` if no gas amount was supplied (#235)
|
||||||
* Modify order validation methods to validate against the `latest` block, not against the `pending` block (#236)
|
* Modify order validation methods to validate against the `latest` block, not against the `pending` block (#236)
|
||||||
|
|
||||||
v0.26.0
|
v0.26.0 - _November 21, 2017_
|
||||||
------------------------
|
------------------------
|
||||||
* Add post-formatter for logs converting `blockNumber`, `logIndex`, `transactionIndex` from hexes to numbers (#231)
|
* Add post-formatter for logs converting `blockNumber`, `logIndex`, `transactionIndex` from hexes to numbers (#231)
|
||||||
* Remove support for Async callback types when used in Subscribe functions (#222)
|
* Remove support for Async callback types when used in Subscribe functions (#222)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "0x.js",
|
"name": "0x.js",
|
||||||
"version": "0.26.1",
|
"version": "0.27.0",
|
||||||
"description": "A javascript library for interacting with the 0x protocol",
|
"description": "A javascript library for interacting with the 0x protocol",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"0x.js",
|
"0x.js",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.1.1",
|
"@0xproject/tslint-config": "^0.2.0",
|
||||||
"@types/bintrees": "^1.0.2",
|
"@types/bintrees": "^1.0.2",
|
||||||
"@types/jsonschema": "^1.1.1",
|
"@types/jsonschema": "^1.1.1",
|
||||||
"@types/lodash": "^4.14.64",
|
"@types/lodash": "^4.14.64",
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"copyfiles": "^1.2.0",
|
"copyfiles": "^1.2.0",
|
||||||
"coveralls": "^3.0.0",
|
"coveralls": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"ethereumjs-testrpc": "4.0.1",
|
"ethereumjs-testrpc": "6.0.3",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"mocha": "^4.0.0",
|
"mocha": "^4.0.0",
|
||||||
"npm-run-all": "^4.0.2",
|
"npm-run-all": "^4.0.2",
|
||||||
@@ -83,8 +83,8 @@
|
|||||||
"webpack": "^3.1.0"
|
"webpack": "^3.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0xproject/assert": "^0.0.5",
|
"@0xproject/assert": "^0.0.6",
|
||||||
"@0xproject/json-schemas": "^0.6.8",
|
"@0xproject/json-schemas": "^0.6.9",
|
||||||
"bignumber.js": "~4.1.0",
|
"bignumber.js": "~4.1.0",
|
||||||
"bintrees": "^1.0.2",
|
"bintrees": "^1.0.2",
|
||||||
"bn.js": "4.11.8",
|
"bn.js": "4.11.8",
|
||||||
|
@@ -5,6 +5,10 @@ import * as Web3 from 'web3';
|
|||||||
|
|
||||||
import {AbiType} from './types';
|
import {AbiType} from './types';
|
||||||
|
|
||||||
|
// HACK: Gas estimates on testrpc don't take into account gas refunds.
|
||||||
|
// Our calls can trigger max 8 gas refunds for SSTORE per transaction for 15k gas each which gives 120k.
|
||||||
|
const GAS_MARGIN = 120000;
|
||||||
|
|
||||||
export class Contract implements Web3.ContractInstance {
|
export class Contract implements Web3.ContractInstance {
|
||||||
public address: string;
|
public address: string;
|
||||||
public abi: Web3.ContractAbi;
|
public abi: Web3.ContractAbi;
|
||||||
@@ -34,9 +38,10 @@ export class Contract implements Web3.ContractInstance {
|
|||||||
} else {
|
} else {
|
||||||
const cbStyleFunction = this.contract[functionAbi.name];
|
const cbStyleFunction = this.contract[functionAbi.name];
|
||||||
const cbStyleEstimateGasFunction = this.contract[functionAbi.name].estimateGas;
|
const cbStyleEstimateGasFunction = this.contract[functionAbi.name].estimateGas;
|
||||||
|
const estimateGasAsync = promisify(cbStyleEstimateGasFunction, this.contract);
|
||||||
this[functionAbi.name] = {
|
this[functionAbi.name] = {
|
||||||
estimateGasAsync: promisify(cbStyleEstimateGasFunction, this.contract),
|
estimateGasAsync,
|
||||||
sendTransactionAsync: this.promisifyWithDefaultParams(cbStyleFunction),
|
sendTransactionAsync: this.promisifyWithDefaultParams(cbStyleFunction, estimateGasAsync),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -47,28 +52,40 @@ export class Contract implements Web3.ContractInstance {
|
|||||||
this[eventAbi.name] = this.contract[eventAbi.name];
|
this[eventAbi.name] = this.contract[eventAbi.name];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> {
|
private promisifyWithDefaultParams(
|
||||||
|
web3CbStyleFunction: (...args: any[]) => void,
|
||||||
|
estimateGasAsync: (...args: any[]) => Promise<number>,
|
||||||
|
): (...args: any[]) => Promise<any> {
|
||||||
const promisifiedWithDefaultParams = async (...args: any[]) => {
|
const promisifiedWithDefaultParams = async (...args: any[]) => {
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise(async (resolve, reject) => {
|
||||||
const lastArg = args[args.length - 1];
|
const lastArg = args[args.length - 1];
|
||||||
let txData: Partial<Web3.TxData> = {};
|
let txData: Partial<Web3.TxData> = {};
|
||||||
if (this.isTxData(lastArg)) {
|
if (!_.isUndefined(lastArg) && this.isTxData(lastArg)) {
|
||||||
txData = args.pop();
|
txData = args.pop();
|
||||||
}
|
}
|
||||||
|
// Gas amount sourced with the following priorities:
|
||||||
|
// 1. Optional param passed in to public method call
|
||||||
|
// 2. Global config passed in at library instantiation
|
||||||
|
// 3. Gas estimate calculation + safety margin
|
||||||
|
const removeUndefinedProperties = _.pickBy;
|
||||||
txData = {
|
txData = {
|
||||||
...this.defaults,
|
...removeUndefinedProperties(this.defaults),
|
||||||
...txData,
|
...removeUndefinedProperties(txData),
|
||||||
};
|
};
|
||||||
const callback = (err: Error, data: any) => {
|
if (_.isUndefined(txData.gas)) {
|
||||||
if (_.isNull(err)) {
|
try {
|
||||||
resolve(data);
|
const estimatedGas = await estimateGasAsync.apply(this.contract, [...args, txData]);
|
||||||
} else {
|
const gas = estimatedGas + GAS_MARGIN;
|
||||||
|
txData.gas = gas;
|
||||||
|
} catch (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
const callback = (err: Error, data: any) => _.isNull(err) ? resolve(data) : reject(err);
|
||||||
args.push(txData);
|
args.push(txData);
|
||||||
args.push(callback);
|
args.push(callback);
|
||||||
fn.apply(this.contract, args);
|
web3CbStyleFunction.apply(this.contract, args);
|
||||||
});
|
});
|
||||||
return promise;
|
return promise;
|
||||||
};
|
};
|
||||||
|
@@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {artifacts} from '../artifacts';
|
import {artifacts} from '../artifacts';
|
||||||
import {EtherTokenContract, ZeroExError} from '../types';
|
import {EtherTokenContract, TransactionOpts, ZeroExError} from '../types';
|
||||||
import {assert} from '../utils/assert';
|
import {assert} from '../utils/assert';
|
||||||
import {Web3Wrapper} from '../web3_wrapper';
|
import {Web3Wrapper} from '../web3_wrapper';
|
||||||
|
|
||||||
@@ -27,10 +27,13 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* to the depositor address. These wrapped ETH tokens can be used in 0x trades and are redeemable for 1-to-1
|
* to the depositor address. These wrapped ETH tokens can be used in 0x trades and are redeemable for 1-to-1
|
||||||
* for ETH.
|
* for ETH.
|
||||||
* @param amountInWei Amount of ETH in Wei the caller wishes to deposit.
|
* @param amountInWei Amount of ETH in Wei the caller wishes to deposit.
|
||||||
* @param depositor The hex encoded user Ethereum address that would like to make the deposit.
|
* @param depositor The hex encoded user Ethereum address that would like to make the deposit.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async depositAsync(amountInWei: BigNumber, depositor: string): Promise<string> {
|
public async depositAsync(
|
||||||
|
amountInWei: BigNumber, depositor: string, txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
||||||
|
|
||||||
@@ -41,6 +44,8 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
const txHash = await wethContract.deposit.sendTransactionAsync({
|
const txHash = await wethContract.deposit.sendTransactionAsync({
|
||||||
from: depositor,
|
from: depositor,
|
||||||
value: amountInWei,
|
value: amountInWei,
|
||||||
|
gas: txOpts.gasLimit,
|
||||||
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -49,9 +54,12 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* equivalent number of wrapped ETH tokens.
|
* equivalent number of wrapped ETH tokens.
|
||||||
* @param amountInWei Amount of ETH in Wei the caller wishes to withdraw.
|
* @param amountInWei Amount of ETH in Wei the caller wishes to withdraw.
|
||||||
* @param withdrawer The hex encoded user Ethereum address that would like to make the withdrawl.
|
* @param withdrawer The hex encoded user Ethereum address that would like to make the withdrawl.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async withdrawAsync(amountInWei: BigNumber, withdrawer: string): Promise<string> {
|
public async withdrawAsync(
|
||||||
|
amountInWei: BigNumber, withdrawer: string, txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
||||||
|
|
||||||
@@ -62,6 +70,8 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
const wethContract = await this._getEtherTokenContractAsync();
|
const wethContract = await this._getEtherTokenContractAsync();
|
||||||
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
|
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
|
||||||
from: withdrawer,
|
from: withdrawer,
|
||||||
|
gas: txOpts.gasLimit,
|
||||||
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
|
@@ -169,16 +169,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
@@ -188,18 +188,6 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
||||||
|
|
||||||
const gas = await exchangeInstance.fillOrder.estimateGasAsync(
|
|
||||||
orderAddresses,
|
|
||||||
orderValues,
|
|
||||||
fillTakerTokenAmount,
|
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance,
|
|
||||||
signedOrder.ecSignature.v,
|
|
||||||
signedOrder.ecSignature.r,
|
|
||||||
signedOrder.ecSignature.s,
|
|
||||||
{
|
|
||||||
from: takerAddress,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
|
const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@@ -210,7 +198,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
signedOrder.ecSignature.s,
|
signedOrder.ecSignature.s,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
@@ -236,7 +225,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
public async fillOrdersUpToAsync(signedOrders: SignedOrder[], fillTakerTokenAmount: BigNumber,
|
public async fillOrdersUpToAsync(signedOrders: SignedOrder[], fillTakerTokenAmount: BigNumber,
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
|
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
|
||||||
const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress);
|
const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress);
|
||||||
assert.hasAtMostOneUniqueValue(takerTokenAddresses,
|
assert.hasAtMostOneUniqueValue(takerTokenAddresses,
|
||||||
@@ -248,9 +237,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
@@ -278,18 +267,6 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const gas = await exchangeInstance.fillOrdersUpTo.estimateGasAsync(
|
|
||||||
orderAddressesArray,
|
|
||||||
orderValuesArray,
|
|
||||||
fillTakerTokenAmount,
|
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance,
|
|
||||||
vArray,
|
|
||||||
rArray,
|
|
||||||
sArray,
|
|
||||||
{
|
|
||||||
from: takerAddress,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync(
|
const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync(
|
||||||
orderAddressesArray,
|
orderAddressesArray,
|
||||||
orderValuesArray,
|
orderValuesArray,
|
||||||
@@ -300,7 +277,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
sArray,
|
sArray,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
@@ -328,7 +306,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
public async batchFillOrdersAsync(orderFillRequests: OrderFillRequest[],
|
public async batchFillOrdersAsync(orderFillRequests: OrderFillRequest[],
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderFillRequests,
|
orderFillRequests,
|
||||||
@@ -338,9 +316,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
@@ -370,18 +348,6 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const gas = await exchangeInstance.batchFillOrders.estimateGasAsync(
|
|
||||||
orderAddressesArray,
|
|
||||||
orderValuesArray,
|
|
||||||
fillTakerTokenAmounts,
|
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance,
|
|
||||||
vArray,
|
|
||||||
rArray,
|
|
||||||
sArray,
|
|
||||||
{
|
|
||||||
from: takerAddress,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
|
||||||
orderAddressesArray,
|
orderAddressesArray,
|
||||||
orderValuesArray,
|
orderValuesArray,
|
||||||
@@ -392,7 +358,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
sArray,
|
sArray,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
@@ -411,16 +378,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
@decorators.contractCallErrorHandler
|
@decorators.contractCallErrorHandler
|
||||||
public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
@@ -429,18 +396,6 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
||||||
|
|
||||||
const gas = await exchangeInstance.fillOrKillOrder.estimateGasAsync(
|
|
||||||
orderAddresses,
|
|
||||||
orderValues,
|
|
||||||
fillTakerTokenAmount,
|
|
||||||
signedOrder.ecSignature.v,
|
|
||||||
signedOrder.ecSignature.r,
|
|
||||||
signedOrder.ecSignature.s,
|
|
||||||
{
|
|
||||||
from: takerAddress,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
|
const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@@ -450,7 +405,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
signedOrder.ecSignature.s,
|
signedOrder.ecSignature.s,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
@@ -467,7 +423,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
@decorators.contractCallErrorHandler
|
@decorators.contractCallErrorHandler
|
||||||
public async batchFillOrKillAsync(orderFillRequests: OrderFillRequest[],
|
public async batchFillOrKillAsync(orderFillRequests: OrderFillRequest[],
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('orderFillRequests', orderFillRequests,
|
assert.doesConformToSchema('orderFillRequests', orderFillRequests,
|
||||||
schemas.orderFillRequestsSchema);
|
schemas.orderFillRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
@@ -482,9 +438,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
@@ -509,18 +465,6 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
||||||
const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] =
|
const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] =
|
||||||
_.unzip<any>(orderAddressesValuesAndTakerTokenFillAmounts);
|
_.unzip<any>(orderAddressesValuesAndTakerTokenFillAmounts);
|
||||||
|
|
||||||
const gas = await exchangeInstance.batchFillOrKillOrders.estimateGasAsync(
|
|
||||||
orderAddresses,
|
|
||||||
orderValues,
|
|
||||||
fillTakerTokenAmounts,
|
|
||||||
vParams,
|
|
||||||
rParams,
|
|
||||||
sParams,
|
|
||||||
{
|
|
||||||
from: takerAddress,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@@ -530,7 +474,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
sParams,
|
sParams,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
@@ -546,16 +491,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
@decorators.contractCallErrorHandler
|
@decorators.contractCallErrorHandler
|
||||||
public async cancelOrderAsync(order: Order|SignedOrder,
|
public async cancelOrderAsync(order: Order|SignedOrder,
|
||||||
cancelTakerTokenAmount: BigNumber,
|
cancelTakerTokenAmount: BigNumber,
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const orderHash = utils.getOrderHashHex(order);
|
const orderHash = utils.getOrderHashHex(order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
@@ -564,21 +509,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
||||||
const gas = await exchangeInstance.cancelOrder.estimateGasAsync(
|
|
||||||
orderAddresses,
|
|
||||||
orderValues,
|
|
||||||
cancelTakerTokenAmount,
|
|
||||||
{
|
|
||||||
from: order.maker,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
|
const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
cancelTakerTokenAmount,
|
cancelTakerTokenAmount,
|
||||||
{
|
{
|
||||||
from: order.maker,
|
from: order.maker,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
@@ -593,7 +531,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
@decorators.contractCallErrorHandler
|
@decorators.contractCallErrorHandler
|
||||||
public async batchCancelOrdersAsync(orderCancellationRequests: OrderCancellationRequest[],
|
public async batchCancelOrdersAsync(orderCancellationRequests: OrderCancellationRequest[],
|
||||||
orderTransactionOpts?: OrderTransactionOpts): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
||||||
assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests,
|
assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests,
|
||||||
schemas.orderCancellationRequestsSchema);
|
schemas.orderCancellationRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
@@ -606,9 +544,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
||||||
const maker = makers[0];
|
const maker = makers[0];
|
||||||
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
SHOULD_VALIDATE_BY_DEFAULT :
|
||||||
orderTransactionOpts.shouldValidate;
|
orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
for (const orderCancellationRequest of orderCancellationRequests) {
|
for (const orderCancellationRequest of orderCancellationRequests) {
|
||||||
const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
|
const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
|
||||||
@@ -633,21 +571,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
||||||
const [orderAddresses, orderValues, cancelTakerTokenAmounts] =
|
const [orderAddresses, orderValues, cancelTakerTokenAmounts] =
|
||||||
_.unzip<any>(orderAddressesValuesAndTakerTokenCancelAmounts);
|
_.unzip<any>(orderAddressesValuesAndTakerTokenCancelAmounts);
|
||||||
const gas = await exchangeInstance.batchCancelOrders.estimateGasAsync(
|
|
||||||
orderAddresses,
|
|
||||||
orderValues,
|
|
||||||
cancelTakerTokenAmounts,
|
|
||||||
{
|
|
||||||
from: maker,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
cancelTakerTokenAmounts,
|
cancelTakerTokenAmounts,
|
||||||
{
|
{
|
||||||
from: maker,
|
from: maker,
|
||||||
gas,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
|
@@ -12,6 +12,7 @@ import {
|
|||||||
TokenContract,
|
TokenContract,
|
||||||
TokenContractEventArgs,
|
TokenContractEventArgs,
|
||||||
TokenEvents,
|
TokenEvents,
|
||||||
|
TransactionOpts,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {AbiDecoder} from '../utils/abi_decoder';
|
import {AbiDecoder} from '../utils/abi_decoder';
|
||||||
@@ -66,24 +67,21 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* for spenderAddress.
|
* for spenderAddress.
|
||||||
* @param spenderAddress The hex encoded user Ethereum address who will be able to spend the set allowance.
|
* @param spenderAddress The hex encoded user Ethereum address who will be able to spend the set allowance.
|
||||||
* @param amountInBaseUnits The allowance amount you would like to set.
|
* @param amountInBaseUnits The allowance amount you would like to set.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string,
|
public async setAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string,
|
||||||
amountInBaseUnits: BigNumber): Promise<string> {
|
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
||||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
||||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const tokenContract = await this._getTokenContractAsync(tokenAddress);
|
const tokenContract = await this._getTokenContractAsync(tokenAddress);
|
||||||
// Hack: for some reason default estimated gas amount causes `base fee exceeds gas limit` exception
|
|
||||||
// on testrpc. Probably related to https://github.com/ethereumjs/testrpc/issues/294
|
|
||||||
// TODO: Debug issue in testrpc and submit a PR, then remove this hack
|
|
||||||
const networkId = this._web3Wrapper.getNetworkId();
|
|
||||||
const gas = networkId === constants.TESTRPC_NETWORK_ID ? ALLOWANCE_TO_ZERO_GAS_AMOUNT : undefined;
|
|
||||||
const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
|
const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
|
||||||
from: ownerAddress,
|
from: ownerAddress,
|
||||||
gas,
|
gas: txOpts.gasLimit,
|
||||||
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -96,12 +94,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param ownerAddress The hex encoded user Ethereum address who would like to set an allowance
|
* @param ownerAddress The hex encoded user Ethereum address who would like to set an allowance
|
||||||
* for spenderAddress.
|
* for spenderAddress.
|
||||||
* @param spenderAddress The hex encoded user Ethereum address who will be able to spend the set allowance.
|
* @param spenderAddress The hex encoded user Ethereum address who will be able to spend the set allowance.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setUnlimitedAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async setUnlimitedAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
||||||
spenderAddress: string): Promise<string> {
|
spenderAddress: string, txOpts: TransactionOpts = {}): Promise<string> {
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, spenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
tokenAddress, ownerAddress, spenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -147,16 +146,19 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param ownerAddress The hex encoded user Ethereum address who is setting an allowance
|
* @param ownerAddress The hex encoded user Ethereum address who is setting an allowance
|
||||||
* for the Proxy contract.
|
* for the Proxy contract.
|
||||||
* @param amountInBaseUnits The allowance amount specified in baseUnits.
|
* @param amountInBaseUnits The allowance amount specified in baseUnits.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setProxyAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async setProxyAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
||||||
amountInBaseUnits: BigNumber): Promise<string> {
|
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||||
const txHash = await this.setAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits);
|
const txHash = await this.setAllowanceAsync(
|
||||||
|
tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits, txOpts,
|
||||||
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -167,11 +169,14 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed.
|
* @param tokenAddress The hex encoded contract Ethereum address where the ERC20 token is deployed.
|
||||||
* @param ownerAddress The hex encoded user Ethereum address who is setting an allowance
|
* @param ownerAddress The hex encoded user Ethereum address who is setting an allowance
|
||||||
* for the Proxy contract.
|
* for the Proxy contract.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setUnlimitedProxyAllowanceAsync(tokenAddress: string, ownerAddress: string): Promise<string> {
|
public async setUnlimitedProxyAllowanceAsync(
|
||||||
|
tokenAddress: string, ownerAddress: string, txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
const txHash = await this.setProxyAllowanceAsync(
|
const txHash = await this.setProxyAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
tokenAddress, ownerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -181,10 +186,11 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param fromAddress The hex encoded user Ethereum address that will send the funds.
|
* @param fromAddress The hex encoded user Ethereum address that will send the funds.
|
||||||
* @param toAddress The hex encoded user Ethereum address that will receive the funds.
|
* @param toAddress The hex encoded user Ethereum address that will receive the funds.
|
||||||
* @param amountInBaseUnits The amount (specified in baseUnits) of the token to transfer.
|
* @param amountInBaseUnits The amount (specified in baseUnits) of the token to transfer.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async transferAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
public async transferAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
||||||
amountInBaseUnits: BigNumber): Promise<string> {
|
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
@@ -199,6 +205,8 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
|
|
||||||
const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
|
const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
|
||||||
from: fromAddress,
|
from: fromAddress,
|
||||||
|
gas: txOpts.gasLimit,
|
||||||
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -213,10 +221,11 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* `fromAddress` must have set an allowance to the `senderAddress`
|
* `fromAddress` must have set an allowance to the `senderAddress`
|
||||||
* before this call.
|
* before this call.
|
||||||
* @param amountInBaseUnits The amount (specified in baseUnits) of the token to transfer.
|
* @param amountInBaseUnits The amount (specified in baseUnits) of the token to transfer.
|
||||||
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async transferFromAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
public async transferFromAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
||||||
senderAddress: string, amountInBaseUnits: BigNumber):
|
senderAddress: string, amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}):
|
||||||
Promise<string> {
|
Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
assert.isETHAddressHex('fromAddress', fromAddress);
|
||||||
@@ -240,6 +249,8 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
fromAddress, toAddress, amountInBaseUnits,
|
fromAddress, toAddress, amountInBaseUnits,
|
||||||
{
|
{
|
||||||
from: senderAddress,
|
from: senderAddress,
|
||||||
|
gas: txOpts.gasLimit,
|
||||||
|
gasPrice: txOpts.gasPrice,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
|
@@ -32,6 +32,7 @@ export {
|
|||||||
LogWithDecodedArgs,
|
LogWithDecodedArgs,
|
||||||
MethodOpts,
|
MethodOpts,
|
||||||
OrderTransactionOpts,
|
OrderTransactionOpts,
|
||||||
|
TransactionOpts,
|
||||||
FilterObject,
|
FilterObject,
|
||||||
LogEvent,
|
LogEvent,
|
||||||
DecodedLogEvent,
|
DecodedLogEvent,
|
||||||
|
@@ -50,6 +50,8 @@ interface OrderStateByOrderHash {
|
|||||||
[orderHash: string]: OrderState;
|
[orderHash: string]: OrderState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes all the functionality related to watching a set of orders
|
* This class includes all the functionality related to watching a set of orders
|
||||||
* for potential changes in order validity/fillability. The orderWatcher notifies
|
* for potential changes in order validity/fillability. The orderWatcher notifies
|
||||||
@@ -68,6 +70,8 @@ export class OrderStateWatcher {
|
|||||||
private _orderStateUtils: OrderStateUtils;
|
private _orderStateUtils: OrderStateUtils;
|
||||||
private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
|
private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
|
||||||
private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
|
private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
|
||||||
|
private _cleanupJobInterval: number;
|
||||||
|
private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
|
||||||
constructor(
|
constructor(
|
||||||
web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper,
|
web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper,
|
||||||
config?: OrderStateWatcherConfig,
|
config?: OrderStateWatcherConfig,
|
||||||
@@ -92,6 +96,9 @@ export class OrderStateWatcher {
|
|||||||
this._expirationWatcher = new ExpirationWatcher(
|
this._expirationWatcher = new ExpirationWatcher(
|
||||||
expirationMarginIfExistsMs, orderExpirationCheckingIntervalMsIfExists,
|
expirationMarginIfExistsMs, orderExpirationCheckingIntervalMsIfExists,
|
||||||
);
|
);
|
||||||
|
this._cleanupJobInterval = _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs) ?
|
||||||
|
DEFAULT_CLEANUP_JOB_INTERVAL_MS :
|
||||||
|
config.cleanupJobIntervalMs;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Add an order to the orderStateWatcher. Before the order is added, it's
|
* Add an order to the orderStateWatcher. Before the order is added, it's
|
||||||
@@ -139,12 +146,15 @@ export class OrderStateWatcher {
|
|||||||
this._callbackIfExists = callback;
|
this._callbackIfExists = callback;
|
||||||
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
||||||
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
||||||
|
this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||||
|
this._cleanupAsync.bind(this), this._cleanupJobInterval,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Ends an orderStateWatcher subscription.
|
* Ends an orderStateWatcher subscription.
|
||||||
*/
|
*/
|
||||||
public unsubscribe(): void {
|
public unsubscribe(): void {
|
||||||
if (_.isUndefined(this._callbackIfExists)) {
|
if (_.isUndefined(this._callbackIfExists) || _.isUndefined(this._cleanupJobIntervalIdIfExists)) {
|
||||||
throw new Error(ZeroExError.SubscriptionNotFound);
|
throw new Error(ZeroExError.SubscriptionNotFound);
|
||||||
}
|
}
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteAll();
|
this._balanceAndProxyAllowanceLazyStore.deleteAll();
|
||||||
@@ -152,6 +162,34 @@ export class OrderStateWatcher {
|
|||||||
delete this._callbackIfExists;
|
delete this._callbackIfExists;
|
||||||
this._eventWatcher.unsubscribe();
|
this._eventWatcher.unsubscribe();
|
||||||
this._expirationWatcher.unsubscribe();
|
this._expirationWatcher.unsubscribe();
|
||||||
|
intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists);
|
||||||
|
}
|
||||||
|
private async _cleanupAsync(): Promise<void> {
|
||||||
|
for (const orderHash of _.keys(this._orderByOrderHash)) {
|
||||||
|
this._cleanupOrderRelatedState(orderHash);
|
||||||
|
await this._emitRevalidateOrdersAsync([orderHash]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private _cleanupOrderRelatedState(orderHash: string): void {
|
||||||
|
const signedOrder = this._orderByOrderHash[orderHash];
|
||||||
|
|
||||||
|
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(orderHash);
|
||||||
|
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(orderHash);
|
||||||
|
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.makerTokenAddress, signedOrder.maker);
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.makerTokenAddress, signedOrder.maker);
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.takerTokenAddress, signedOrder.taker);
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.takerTokenAddress, signedOrder.taker);
|
||||||
|
|
||||||
|
const zrxTokenAddress = this._getZRXTokenAddress();
|
||||||
|
if (!signedOrder.makerFee.isZero()) {
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.maker);
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.maker);
|
||||||
|
}
|
||||||
|
if (!signedOrder.takerFee.isZero()) {
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.taker);
|
||||||
|
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.taker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private _onOrderExpired(orderHash: string): void {
|
private _onOrderExpired(orderHash: string): void {
|
||||||
const orderState: OrderState = {
|
const orderState: OrderState = {
|
||||||
@@ -266,8 +304,7 @@ export class OrderStateWatcher {
|
|||||||
this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress] = new Set();
|
this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress] = new Set();
|
||||||
}
|
}
|
||||||
this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress].add(orderHash);
|
this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress].add(orderHash);
|
||||||
const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper;
|
const zrxTokenAddress = this._getZRXTokenAddress();
|
||||||
const zrxTokenAddress = exchange.getZRXTokenAddress();
|
|
||||||
if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
|
if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
|
||||||
this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
|
this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
|
||||||
}
|
}
|
||||||
@@ -282,4 +319,9 @@ export class OrderStateWatcher {
|
|||||||
delete this._dependentOrderHashes[makerAddress];
|
delete this._dependentOrderHashes[makerAddress];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private _getZRXTokenAddress(): string {
|
||||||
|
const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper;
|
||||||
|
const zrxTokenAddress = exchange.getZRXTokenAddress();
|
||||||
|
return zrxTokenAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -332,6 +332,7 @@ export interface TxOpts {
|
|||||||
from: string;
|
from: string;
|
||||||
gas?: number;
|
gas?: number;
|
||||||
value?: BigNumber;
|
value?: BigNumber;
|
||||||
|
gasPrice?: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TokenAddressBySymbol {
|
export interface TokenAddressBySymbol {
|
||||||
@@ -406,11 +407,13 @@ export interface JSONRPCPayload {
|
|||||||
* eventPollingIntervalMs: How often to poll the Ethereum node for new events. Defaults: 200
|
* eventPollingIntervalMs: How often to poll the Ethereum node for new events. Defaults: 200
|
||||||
* expirationMarginMs: Amount of time before order expiry that you'd like to be notified
|
* expirationMarginMs: Amount of time before order expiry that you'd like to be notified
|
||||||
* of an orders expiration. Defaults: 0
|
* of an orders expiration. Defaults: 0
|
||||||
|
* cleanupJobIntervalMs: How often to run a cleanup job which revalidates all the orders. Defaults: 1h
|
||||||
*/
|
*/
|
||||||
export interface OrderStateWatcherConfig {
|
export interface OrderStateWatcherConfig {
|
||||||
orderExpirationCheckingIntervalMs?: number;
|
orderExpirationCheckingIntervalMs?: number;
|
||||||
eventPollingIntervalMs?: number;
|
eventPollingIntervalMs?: number;
|
||||||
expirationMarginMs?: number;
|
expirationMarginMs?: number;
|
||||||
|
cleanupJobIntervalMs?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -482,11 +485,20 @@ export interface MethodOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shouldValidate: Flag indicating whether the library should make attempts to validate a transaction before
|
* gasPrice: Gas price in Wei to use for a transaction
|
||||||
* broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc.
|
* gasLimit: The amount of gas to send with a transaction
|
||||||
*/
|
*/
|
||||||
export interface OrderTransactionOpts {
|
export interface TransactionOpts {
|
||||||
shouldValidate: boolean;
|
gasPrice?: BigNumber;
|
||||||
|
gasLimit?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shouldValidate: Flag indicating whether the library should make attempts to validate a transaction before
|
||||||
|
* broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc. Default: true
|
||||||
|
*/
|
||||||
|
export interface OrderTransactionOpts extends TransactionOpts {
|
||||||
|
shouldValidate?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FilterObject = Web3.FilterObject;
|
export type FilterObject = Web3.FilterObject;
|
||||||
|
@@ -18,7 +18,7 @@ const blockchainLifecycle = new BlockchainLifecycle();
|
|||||||
// a small amount of ETH will be used to pay this gas cost. We therefore check that the difference between
|
// a small amount of ETH will be used to pay this gas cost. We therefore check that the difference between
|
||||||
// the expected balance and actual balance (given the amount of ETH deposited), only deviates by the amount
|
// the expected balance and actual balance (given the amount of ETH deposited), only deviates by the amount
|
||||||
// required to pay gas costs.
|
// required to pay gas costs.
|
||||||
const MAX_REASONABLE_GAS_COST_IN_WEI = 62237;
|
const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
|
||||||
|
|
||||||
describe('EtherTokenWrapper', () => {
|
describe('EtherTokenWrapper', () => {
|
||||||
let web3: Web3;
|
let web3: Web3;
|
||||||
|
@@ -8,4 +8,5 @@ export const constants = {
|
|||||||
KOVAN_RPC_URL: 'https://kovan.infura.io',
|
KOVAN_RPC_URL: 'https://kovan.infura.io',
|
||||||
ROPSTEN_RPC_URL: 'https://ropsten.infura.io',
|
ROPSTEN_RPC_URL: 'https://ropsten.infura.io',
|
||||||
ZRX_DECIMALS: 18,
|
ZRX_DECIMALS: 18,
|
||||||
|
GAS_ESTIMATE: 500000,
|
||||||
};
|
};
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import {JSONRPCPayload} from '../types';
|
import {JSONRPCPayload} from '../../../src/types';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class implements the web3-provider-engine subprovider interface and returns
|
* This class implements the web3-provider-engine subprovider interface and returns
|
||||||
* that the provider has no addresses when queried.
|
* that the provider has no addresses when queried.
|
||||||
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||||
*/
|
*/
|
||||||
export class EmptyWalletSubProvider {
|
export class EmptyWalletSubprovider {
|
||||||
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
||||||
// tslint:disable-next-line:prefer-function-over-method
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
|
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
|
@@ -0,0 +1,34 @@
|
|||||||
|
import {JSONRPCPayload} from '../../../src/types';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This class implements the web3-provider-engine subprovider interface and returns
|
||||||
|
* the constant gas estimate when queried.
|
||||||
|
* HACK: We need this so that our tests don't use testrpc gas estimation which sometimes kills the node.
|
||||||
|
* Source: https://github.com/trufflesuite/ganache-cli/issues/417
|
||||||
|
* Source: https://github.com/trufflesuite/ganache-cli/issues/437
|
||||||
|
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||||
|
*/
|
||||||
|
export class FakeGasEstimateSubprovider {
|
||||||
|
private constantGasAmount: number;
|
||||||
|
constructor(constantGasAmount: number) {
|
||||||
|
this.constantGasAmount = constantGasAmount;
|
||||||
|
}
|
||||||
|
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
||||||
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
|
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
|
||||||
|
switch (payload.method) {
|
||||||
|
case 'eth_estimateGas':
|
||||||
|
end(null, this.constantGasAmount);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Required to implement this method despite not needing it for this subprovider
|
||||||
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
|
public setEngine(engine: any) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
}
|
@@ -7,7 +7,8 @@ import * as Web3 from 'web3';
|
|||||||
import ProviderEngine = require('web3-provider-engine');
|
import ProviderEngine = require('web3-provider-engine');
|
||||||
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
||||||
|
|
||||||
import {EmptyWalletSubProvider} from '../../src/subproviders/empty_wallet_subprovider';
|
import {EmptyWalletSubprovider} from './subproviders/empty_wallet_subprovider';
|
||||||
|
import {FakeGasEstimateSubprovider} from './subproviders/fake_gas_estimate_subprovider';
|
||||||
|
|
||||||
import {constants} from './constants';
|
import {constants} from './constants';
|
||||||
|
|
||||||
@@ -22,8 +23,9 @@ export const web3Factory = {
|
|||||||
const provider = new ProviderEngine();
|
const provider = new ProviderEngine();
|
||||||
const rpcUrl = `http://${constants.RPC_HOST}:${constants.RPC_PORT}`;
|
const rpcUrl = `http://${constants.RPC_HOST}:${constants.RPC_PORT}`;
|
||||||
if (!hasAddresses) {
|
if (!hasAddresses) {
|
||||||
provider.addProvider(new EmptyWalletSubProvider());
|
provider.addProvider(new EmptyWalletSubprovider());
|
||||||
}
|
}
|
||||||
|
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
|
||||||
provider.addProvider(new RpcSubprovider({
|
provider.addProvider(new RpcSubprovider({
|
||||||
rpcUrl,
|
rpcUrl,
|
||||||
}));
|
}));
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/assert",
|
"name": "@0xproject/assert",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"description": "Provides a standard way of performing type and schema validation across 0x projects",
|
"description": "Provides a standard way of performing type and schema validation across 0x projects",
|
||||||
"main": "lib/src/index.js",
|
"main": "lib/src/index.js",
|
||||||
"types": "lib/src/index.d.ts",
|
"types": "lib/src/index.d.ts",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
|
"homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.1.1",
|
"@0xproject/tslint-config": "^0.2.0",
|
||||||
"@types/lodash": "^4.14.78",
|
"@types/lodash": "^4.14.78",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
"@types/valid-url": "^1.0.2",
|
"@types/valid-url": "^1.0.2",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"typescript": "^2.4.2"
|
"typescript": "^2.4.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0xproject/json-schemas": "^0.6.8",
|
"@0xproject/json-schemas": "^0.6.9",
|
||||||
"bignumber.js": "~4.1.0",
|
"bignumber.js": "~4.1.0",
|
||||||
"ethereum-address": "^0.0.4",
|
"ethereum-address": "^0.0.4",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/connect",
|
"name": "@0xproject/connect",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"description": "A javascript library for interacting with the standard relayer api",
|
"description": "A javascript library for interacting with the standard relayer api",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"connect",
|
"connect",
|
||||||
@@ -36,9 +36,9 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
|
"homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"0x.js": "^0.26.1",
|
"0x.js": "^0.27.0",
|
||||||
"@0xproject/assert": "^0.0.5",
|
"@0xproject/assert": "^0.0.6",
|
||||||
"@0xproject/json-schemas": "^0.6.8",
|
"@0xproject/json-schemas": "^0.6.9",
|
||||||
"bignumber.js": "~4.1.0",
|
"bignumber.js": "~4.1.0",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
"websocket": "^1.0.25"
|
"websocket": "^1.0.25"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.1.1",
|
"@0xproject/tslint-config": "^0.2.0",
|
||||||
"@types/fetch-mock": "^5.12.1",
|
"@types/fetch-mock": "^5.12.1",
|
||||||
"@types/lodash": "^4.14.77",
|
"@types/lodash": "^4.14.77",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/json-schemas",
|
"name": "@0xproject/json-schemas",
|
||||||
"version": "0.6.8",
|
"version": "0.6.9",
|
||||||
"description": "0x-related json schemas",
|
"description": "0x-related json schemas",
|
||||||
"main": "lib/src/index.js",
|
"main": "lib/src/index.js",
|
||||||
"types": "lib/src/index.d.ts",
|
"types": "lib/src/index.d.ts",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"lodash.values": "^4.3.0"
|
"lodash.values": "^4.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.1.1",
|
"@0xproject/tslint-config": "^0.2.0",
|
||||||
"@types/lodash.foreach": "^4.5.3",
|
"@types/lodash.foreach": "^4.5.3",
|
||||||
"@types/lodash.values": "^4.3.3",
|
"@types/lodash.values": "^4.3.3",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/tslint-config",
|
"name": "@0xproject/tslint-config",
|
||||||
"version": "0.1.1",
|
"version": "0.2.0",
|
||||||
"description": "Lint rules related to 0xProject for TSLint",
|
"description": "Lint rules related to 0xProject for TSLint",
|
||||||
"main": "tslint.json",
|
"main": "tslint.json",
|
||||||
"files": [
|
"files": [
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "website",
|
"name": "website",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
"description": "Website and 0x portal dapp",
|
"description": "Website and 0x portal dapp",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "NODE_ENV=production webpack; exit 0;",
|
"build": "NODE_ENV=production webpack; exit 0;",
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
"author": "Fabio Berger",
|
"author": "Fabio Berger",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"0x.js": "^0.26.0",
|
"0x.js": "^0.27.0",
|
||||||
"accounting": "^0.4.1",
|
"accounting": "^0.4.1",
|
||||||
"basscss": "^8.0.3",
|
"basscss": "^8.0.3",
|
||||||
"bignumber.js": "~4.1.0",
|
"bignumber.js": "~4.1.0",
|
||||||
|
@@ -116,6 +116,7 @@ const docsInfoConfig: DocsInfoConfig = {
|
|||||||
'MethodOpts',
|
'MethodOpts',
|
||||||
'ValidateOrderFillableOpts',
|
'ValidateOrderFillableOpts',
|
||||||
'OrderTransactionOpts',
|
'OrderTransactionOpts',
|
||||||
|
'TransactionOpts',
|
||||||
'ContractEventArg',
|
'ContractEventArg',
|
||||||
'LogEvent',
|
'LogEvent',
|
||||||
'LogEntry',
|
'LogEntry',
|
||||||
|
14
yarn.lock
14
yarn.lock
@@ -6,6 +6,10 @@
|
|||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/accounting/-/accounting-0.4.1.tgz#865d9f5694fd7c438fba34eb4bc82eec6f34cdd5"
|
resolved "https://registry.yarnpkg.com/@types/accounting/-/accounting-0.4.1.tgz#865d9f5694fd7c438fba34eb4bc82eec6f34cdd5"
|
||||||
|
|
||||||
|
"@types/bintrees@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/bintrees/-/bintrees-1.0.2.tgz#0dfdce4eeebdf90427bd35b0e79dc248b3d157a6"
|
||||||
|
|
||||||
"@types/dateformat@^1.0.1":
|
"@types/dateformat@^1.0.1":
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-1.0.1.tgz#2e5b235c8c55652c4fec284506d2a36fe65fe87e"
|
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-1.0.1.tgz#2e5b235c8c55652c4fec284506d2a36fe65fe87e"
|
||||||
@@ -18,10 +22,6 @@
|
|||||||
version "5.12.2"
|
version "5.12.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/fetch-mock/-/fetch-mock-5.12.2.tgz#8c96517ff74303031c65c5da2d99858e34c844d2"
|
resolved "https://registry.yarnpkg.com/@types/fetch-mock/-/fetch-mock-5.12.2.tgz#8c96517ff74303031c65c5da2d99858e34c844d2"
|
||||||
|
|
||||||
"@types/bintrees@^1.0.2":
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/bintrees/-/bintrees-1.0.2.tgz#0dfdce4eeebdf90427bd35b0e79dc248b3d157a6"
|
|
||||||
|
|
||||||
"@types/fs-extra@^4.0.0":
|
"@types/fs-extra@^4.0.0":
|
||||||
version "4.0.5"
|
version "4.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.5.tgz#8aa6033c0e87c653b09a6711686916864b48ec9e"
|
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.5.tgz#8aa6033c0e87c653b09a6711686916864b48ec9e"
|
||||||
@@ -2888,9 +2888,9 @@ ethereumjs-blockstream@^2.0.6:
|
|||||||
source-map-support "0.4.14"
|
source-map-support "0.4.14"
|
||||||
uuid "3.0.1"
|
uuid "3.0.1"
|
||||||
|
|
||||||
ethereumjs-testrpc@4.0.1:
|
ethereumjs-testrpc@6.0.3:
|
||||||
version "4.0.1"
|
version "6.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/ethereumjs-testrpc/-/ethereumjs-testrpc-4.0.1.tgz#af23babff4c36008418bc6de4c80f81606896cad"
|
resolved "https://registry.yarnpkg.com/ethereumjs-testrpc/-/ethereumjs-testrpc-6.0.3.tgz#7a0b87bf3670f92f607f98fa6a78801d9741b124"
|
||||||
dependencies:
|
dependencies:
|
||||||
webpack "^3.0.0"
|
webpack "^3.0.0"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user