aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contract-wrappers
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contract-wrappers')
-rw-r--r--packages/contract-wrappers/CHANGELOG.json34
-rw-r--r--packages/contract-wrappers/CHANGELOG.md13
-rw-r--r--packages/contract-wrappers/package.json34
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts43
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts17
-rw-r--r--packages/contract-wrappers/src/utils/constants.ts2
-rw-r--r--packages/contract-wrappers/src/utils/utils.ts6
-rw-r--r--packages/contract-wrappers/test/subscription_test.ts2
8 files changed, 121 insertions, 30 deletions
diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json
index a9e631157..8863f61f4 100644
--- a/packages/contract-wrappers/CHANGELOG.json
+++ b/packages/contract-wrappers/CHANGELOG.json
@@ -1,5 +1,39 @@
[
{
+ "version": "2.0.0",
+ "changes": [
+ {
+ "note":
+ "Fixes dropped events in subscriptions by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too.",
+ "pr": 1080
+ },
+ {
+ "note":
+ "Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it",
+ "pr": 1080
+ }
+ ],
+ "timestamp": 1537907159
+ },
+ {
+ "version": "1.0.5",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ],
+ "timestamp": 1537875740
+ },
+ {
+ "version": "1.0.4",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ],
+ "timestamp": 1537541580
+ },
+ {
"version": "1.0.3",
"changes": [
{
diff --git a/packages/contract-wrappers/CHANGELOG.md b/packages/contract-wrappers/CHANGELOG.md
index 69561213e..41e5645a3 100644
--- a/packages/contract-wrappers/CHANGELOG.md
+++ b/packages/contract-wrappers/CHANGELOG.md
@@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.0.0 - _September 25, 2018_
+
+ * Fixes dropped events in subscriptions by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too. (#1080)
+ * Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it (#1080)
+
+## v1.0.5 - _September 25, 2018_
+
+ * Dependencies updated
+
+## v1.0.4 - _September 21, 2018_
+
+ * Dependencies updated
+
## v1.0.3 - _September 19, 2018_
* Drastically reduce the bundle size by removing unused parts of included contract artifacts.
diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json
index 0d830f6c2..e30bf079c 100644
--- a/packages/contract-wrappers/package.json
+++ b/packages/contract-wrappers/package.json
@@ -1,6 +1,6 @@
{
"name": "@0xproject/contract-wrappers",
- "version": "1.0.3",
+ "version": "2.0.0",
"description": "Smart TS wrappers for 0x smart contracts",
"keywords": [
"0xproject",
@@ -41,14 +41,14 @@
"node": ">=6.0.0"
},
"devDependencies": {
- "@0xproject/abi-gen": "^1.0.8",
- "@0xproject/dev-utils": "^1.0.7",
- "@0xproject/migrations": "^1.0.9",
- "@0xproject/subproviders": "^2.0.2",
+ "@0xproject/abi-gen": "^1.0.11",
+ "@0xproject/dev-utils": "^1.0.10",
+ "@0xproject/migrations": "^1.0.12",
+ "@0xproject/subproviders": "^2.0.5",
"@0xproject/tslint-config": "^1.0.7",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
- "@types/node": "^8.0.53",
+ "@types/node": "*",
"@types/sinon": "^2.2.2",
"@types/uuid": "^3.4.2",
"@types/web3-provider-engine": "^14.0.0",
@@ -72,17 +72,17 @@
"web3-provider-engine": "14.0.6"
},
"dependencies": {
- "@0xproject/assert": "^1.0.8",
- "@0xproject/base-contract": "^2.0.2",
- "@0xproject/fill-scenarios": "^1.0.2",
- "@0xproject/json-schemas": "^1.0.1",
- "@0xproject/order-utils": "^1.0.2",
- "@0xproject/types": "^1.0.1",
- "@0xproject/typescript-typings": "^2.0.0",
- "@0xproject/utils": "^1.0.8",
- "@0xproject/web3-wrapper": "^2.0.2",
- "ethereum-types": "^1.0.6",
- "ethereumjs-blockstream": "5.0.0",
+ "@0xproject/assert": "^1.0.11",
+ "@0xproject/base-contract": "^2.0.5",
+ "@0xproject/fill-scenarios": "^1.0.5",
+ "@0xproject/json-schemas": "^1.0.4",
+ "@0xproject/order-utils": "^1.0.5",
+ "@0xproject/types": "^1.1.1",
+ "@0xproject/typescript-typings": "^2.0.2",
+ "@0xproject/utils": "^1.0.11",
+ "@0xproject/web3-wrapper": "^3.0.1",
+ "ethereum-types": "^1.0.8",
+ "ethereumjs-blockstream": "6.0.0",
"ethereumjs-util": "^5.1.1",
"ethers": "^4.0.0-beta.14",
"js-sha3": "^0.7.0",
diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
index 19de17c0a..f7a89e3be 100644
--- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
@@ -1,5 +1,5 @@
import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils';
-import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper';
import {
BlockParamLiteral,
ContractAbi,
@@ -8,6 +8,7 @@ import {
LogEntry,
LogWithDecodedArgs,
RawLog,
+ RawLogEntry,
} from 'ethereum-types';
import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream';
import * as _ from 'lodash';
@@ -157,7 +158,8 @@ export abstract class ContractWrapper {
return addressIfExists;
}
}
- private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: boolean, log: LogEntry): void {
+ private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: boolean, rawLog: RawLogEntry): void {
+ const log: LogEntry = marshaller.unmarshalLog(rawLog);
_.forEach(this._filters, (filter: FilterObject, filterToken: string) => {
if (filterUtils.matchesFilter(log, filter)) {
const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs<ArgsType>;
@@ -174,8 +176,8 @@ export abstract class ContractWrapper {
throw new Error(ContractWrappersError.SubscriptionAlreadyPresent);
}
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
- this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
- this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
+ this._blockstreamGetBlockOrNullAsync.bind(this),
+ this._blockstreamGetLogsAsync.bind(this),
ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose),
);
const catchAllLogFilter = {};
@@ -194,6 +196,32 @@ export abstract class ContractWrapper {
this._onLogStateChanged.bind(this, isRemoved),
);
}
+ // This method only exists in order to comply with the expected interface of Blockstream's constructor
+ private async _blockstreamGetBlockOrNullAsync(hash: string): Promise<Block | null> {
+ const shouldIncludeTransactionData = false;
+ const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({
+ method: 'eth_getBlockByHash',
+ params: [hash, shouldIncludeTransactionData],
+ });
+ return blockOrNull;
+ }
+ // This method only exists in order to comply with the expected interface of Blockstream's constructor
+ private async _blockstreamGetLatestBlockOrNullAsync(): Promise<Block | null> {
+ const shouldIncludeTransactionData = false;
+ const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({
+ method: 'eth_getBlockByNumber',
+ params: [BlockParamLiteral.Latest, shouldIncludeTransactionData],
+ });
+ return blockOrNull;
+ }
+ // This method only exists in order to comply with the expected interface of Blockstream's constructor
+ private async _blockstreamGetLogsAsync(filterOptions: FilterObject): Promise<RawLogEntry[]> {
+ const logs = await this._web3Wrapper.sendRawPayloadAsync<RawLogEntry[]>({
+ method: 'eth_getLogs',
+ params: [filterOptions],
+ });
+ return logs as RawLogEntry[];
+ }
// HACK: This should be a package-scoped method (which doesn't exist in TS)
// We don't want this method available in the public interface for all classes
// who inherit from ContractWrapper, and it is only used by the internal implementation
@@ -212,11 +240,14 @@ export abstract class ContractWrapper {
delete this._blockAndLogStreamerIfExists;
}
private async _reconcileBlockAsync(): Promise<void> {
- const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest);
+ const latestBlockOrNull = await this._blockstreamGetLatestBlockOrNullAsync();
+ if (_.isNull(latestBlockOrNull)) {
+ return; // noop
+ }
// We need to coerce to Block type cause Web3.Block includes types for mempool blocks
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
- await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
+ await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull);
}
}
}
diff --git a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts
index 13ef0fe01..906222731 100644
--- a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts
@@ -12,6 +12,7 @@ import { TransactionOpts } from '../types';
import { assert } from '../utils/assert';
import { calldataOptimizationUtils } from '../utils/calldata_optimization_utils';
import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
import { ContractWrapper } from './contract_wrapper';
import { ForwarderContract } from './generated/forwarder';
@@ -57,7 +58,7 @@ export class ForwarderWrapper extends ContractWrapper {
takerAddress: string,
ethAmount: BigNumber,
signedFeeOrders: SignedOrder[] = [],
- feePercentage: BigNumber = constants.ZERO_AMOUNT,
+ feePercentage: number = 0,
feeRecipientAddress: string = constants.NULL_ADDRESS,
txOpts: TransactionOpts = {},
): Promise<string> {
@@ -66,7 +67,7 @@ export class ForwarderWrapper extends ContractWrapper {
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
assert.isBigNumber('ethAmount', ethAmount);
assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema);
- assert.isBigNumber('feePercentage', feePercentage);
+ assert.isNumber('feePercentage', feePercentage);
assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress);
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
// other assertions
@@ -76,6 +77,8 @@ export class ForwarderWrapper extends ContractWrapper {
this.getZRXTokenAddress(),
this.getEtherTokenAddress(),
);
+ // format feePercentage
+ const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage);
// lowercase input addresses
const normalizedTakerAddress = takerAddress.toLowerCase();
const normalizedFeeRecipientAddress = feeRecipientAddress.toLowerCase();
@@ -89,7 +92,7 @@ export class ForwarderWrapper extends ContractWrapper {
_.map(optimizedMarketOrders, order => order.signature),
optimizedFeeOrders,
_.map(optimizedFeeOrders, order => order.signature),
- feePercentage,
+ formattedFeePercentage,
feeRecipientAddress,
{
value: ethAmount,
@@ -124,7 +127,7 @@ export class ForwarderWrapper extends ContractWrapper {
takerAddress: string,
ethAmount: BigNumber,
signedFeeOrders: SignedOrder[] = [],
- feePercentage: BigNumber = constants.ZERO_AMOUNT,
+ feePercentage: number = 0,
feeRecipientAddress: string = constants.NULL_ADDRESS,
txOpts: TransactionOpts = {},
): Promise<string> {
@@ -134,7 +137,7 @@ export class ForwarderWrapper extends ContractWrapper {
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
assert.isBigNumber('ethAmount', ethAmount);
assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema);
- assert.isBigNumber('feePercentage', feePercentage);
+ assert.isNumber('feePercentage', feePercentage);
assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress);
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
// other assertions
@@ -144,6 +147,8 @@ export class ForwarderWrapper extends ContractWrapper {
this.getZRXTokenAddress(),
this.getEtherTokenAddress(),
);
+ // format feePercentage
+ const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage);
// lowercase input addresses
const normalizedTakerAddress = takerAddress.toLowerCase();
const normalizedFeeRecipientAddress = feeRecipientAddress.toLowerCase();
@@ -158,7 +163,7 @@ export class ForwarderWrapper extends ContractWrapper {
_.map(optimizedMarketOrders, order => order.signature),
optimizedFeeOrders,
_.map(optimizedFeeOrders, order => order.signature),
- feePercentage,
+ formattedFeePercentage,
feeRecipientAddress,
{
value: ethAmount,
diff --git a/packages/contract-wrappers/src/utils/constants.ts b/packages/contract-wrappers/src/utils/constants.ts
index 2df11538c..78441decf 100644
--- a/packages/contract-wrappers/src/utils/constants.ts
+++ b/packages/contract-wrappers/src/utils/constants.ts
@@ -12,4 +12,6 @@ export const constants = {
UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
ZERO_AMOUNT: new BigNumber(0),
+ ONE_AMOUNT: new BigNumber(1),
+ ETHER_TOKEN_DECIMALS: 18,
};
diff --git a/packages/contract-wrappers/src/utils/utils.ts b/packages/contract-wrappers/src/utils/utils.ts
index 689a7ee0a..f7949ec34 100644
--- a/packages/contract-wrappers/src/utils/utils.ts
+++ b/packages/contract-wrappers/src/utils/utils.ts
@@ -1,4 +1,7 @@
import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+
+import { constants } from './constants';
export const utils = {
getCurrentUnixTimestampSec(): BigNumber {
@@ -8,4 +11,7 @@ export const utils = {
getCurrentUnixTimestampMs(): BigNumber {
return new BigNumber(Date.now());
},
+ numberPercentageToEtherTokenAmountPercentage(percentage: number): BigNumber {
+ return Web3Wrapper.toBaseUnitAmount(constants.ONE_AMOUNT, constants.ETHER_TOKEN_DECIMALS).mul(percentage);
+ },
};
diff --git a/packages/contract-wrappers/test/subscription_test.ts b/packages/contract-wrappers/test/subscription_test.ts
index 81b9012bd..68ef7225e 100644
--- a/packages/contract-wrappers/test/subscription_test.ts
+++ b/packages/contract-wrappers/test/subscription_test.ts
@@ -61,7 +61,7 @@ describe('SubscriptionTest', () => {
callback,
);
stubs = [
- Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(
+ Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockIfExistsAsync').throws(
new Error('JSON RPC error'),
),
];