merge v2-prototype
This commit is contained in:
@@ -30,8 +30,8 @@ const schemaErrorTransformer = (error: Error) => {
|
|||||||
*/
|
*/
|
||||||
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||||
const asyncErrorHandlingDecorator = (
|
const asyncErrorHandlingDecorator = (
|
||||||
target: object,
|
_target: object,
|
||||||
key: string | symbol,
|
_key: string | symbol,
|
||||||
descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
||||||
) => {
|
) => {
|
||||||
const originalMethod = descriptor.value as AsyncMethod;
|
const originalMethod = descriptor.value as AsyncMethod;
|
||||||
@@ -57,8 +57,8 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
|||||||
|
|
||||||
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||||
const syncErrorHandlingDecorator = (
|
const syncErrorHandlingDecorator = (
|
||||||
target: object,
|
_target: object,
|
||||||
key: string | symbol,
|
_key: string | symbol,
|
||||||
descriptor: TypedPropertyDescriptor<SyncMethod>,
|
descriptor: TypedPropertyDescriptor<SyncMethod>,
|
||||||
) => {
|
) => {
|
||||||
const originalMethod = descriptor.value as SyncMethod;
|
const originalMethod = descriptor.value as SyncMethod;
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { BlockParamLiteral, ExchangeContractErrs } from '@0xproject/types';
|
import { ExchangeContractErrs } from '@0xproject/types';
|
||||||
import { BigNumber } from '@0xproject/utils';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
|
||||||
import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
|
import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
|
||||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
|
||||||
import { TradeSide, TransferType } from '../types';
|
import { TradeSide, TransferType } from '../types';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ export const filterUtils = {
|
|||||||
blockRange?: BlockRange,
|
blockRange?: BlockRange,
|
||||||
): FilterObject {
|
): FilterObject {
|
||||||
const eventAbi = _.find(abi, { name: eventName }) as EventAbi;
|
const eventAbi = _.find(abi, { name: eventName }) as EventAbi;
|
||||||
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName);
|
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi);
|
||||||
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
||||||
const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues);
|
const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues);
|
||||||
const topics = [topicForEventSignature, ...topicsForIndexedArgs];
|
const topics = [topicForEventSignature, ...topicsForIndexedArgs];
|
||||||
@@ -46,7 +46,7 @@ export const filterUtils = {
|
|||||||
}
|
}
|
||||||
return filter;
|
return filter;
|
||||||
},
|
},
|
||||||
getEventSignatureFromAbiByName(eventAbi: EventAbi, eventName: ContractEvents): string {
|
getEventSignatureFromAbiByName(eventAbi: EventAbi): string {
|
||||||
const types = _.map(eventAbi.inputs, 'type');
|
const types = _.map(eventAbi.inputs, 'type');
|
||||||
const signature = `${eventAbi.name}(${types.join(',')})`;
|
const signature = `${eventAbi.name}(${types.join(',')})`;
|
||||||
return signature;
|
return signature;
|
||||||
|
@@ -277,7 +277,7 @@ describe('EtherTokenWrapper', () => {
|
|||||||
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
(_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -307,7 +307,7 @@ describe('EtherTokenWrapper', () => {
|
|||||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
(_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@@ -999,7 +999,7 @@ describe('ExchangeWrapper', () => {
|
|||||||
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
|
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||||
(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
(_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -1024,7 +1024,7 @@ describe('ExchangeWrapper', () => {
|
|||||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||||
(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
(_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@@ -80,7 +80,7 @@ describe('SubscriptionTest', () => {
|
|||||||
});
|
});
|
||||||
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
const callback = (_err: Error | null, _logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
||||||
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
stubs = [
|
stubs = [
|
||||||
Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(
|
Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(
|
||||||
|
@@ -484,7 +484,7 @@ describe('TokenWrapper', () => {
|
|||||||
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
|
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
(_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -508,7 +508,7 @@ describe('TokenWrapper', () => {
|
|||||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
(_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@@ -5,7 +5,7 @@ import * as chai from 'chai';
|
|||||||
|
|
||||||
import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mixin_authorizable';
|
import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mixin_authorizable';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||||
@@ -44,7 +44,7 @@ describe('Authorizable', () => {
|
|||||||
});
|
});
|
||||||
describe('addAuthorizedAddress', () => {
|
describe('addAuthorizedAddress', () => {
|
||||||
it('should throw if not called by owner', async () => {
|
it('should throw if not called by owner', async () => {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }),
|
authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }),
|
||||||
RevertReason.OnlyContractOwner,
|
RevertReason.OnlyContractOwner,
|
||||||
);
|
);
|
||||||
@@ -62,7 +62,7 @@ describe('Authorizable', () => {
|
|||||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||||
RevertReason.TargetAlreadyAuthorized,
|
RevertReason.TargetAlreadyAuthorized,
|
||||||
);
|
);
|
||||||
@@ -75,7 +75,7 @@ describe('Authorizable', () => {
|
|||||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
||||||
from: notOwner,
|
from: notOwner,
|
||||||
}),
|
}),
|
||||||
@@ -99,7 +99,7 @@ describe('Authorizable', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
@@ -115,7 +115,7 @@ describe('Authorizable', () => {
|
|||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
||||||
from: notOwner,
|
from: notOwner,
|
||||||
}),
|
}),
|
||||||
@@ -128,7 +128,7 @@ describe('Authorizable', () => {
|
|||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const index = new BigNumber(1);
|
const index = new BigNumber(1);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
@@ -137,7 +137,7 @@ describe('Authorizable', () => {
|
|||||||
});
|
});
|
||||||
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
@@ -156,7 +156,7 @@ describe('Authorizable', () => {
|
|||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const address1Index = new BigNumber(0);
|
const address1Index = new BigNumber(0);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, {
|
authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
|
@@ -17,7 +17,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr
|
|||||||
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
||||||
import { IAssetProxyContract } from '../../generated_contract_wrappers/i_asset_proxy';
|
import { IAssetProxyContract } from '../../generated_contract_wrappers/i_asset_proxy';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||||
@@ -184,7 +184,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
// Perform a transfer; expect this to fail.
|
// Perform a transfer; expect this to fail.
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
await expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc20Proxy.address,
|
to: erc20Proxy.address,
|
||||||
data,
|
data,
|
||||||
@@ -205,7 +205,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
await expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc20Proxy.address,
|
to: erc20Proxy.address,
|
||||||
data,
|
data,
|
||||||
@@ -344,7 +344,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
erc20Proxy.address, // the ERC20 proxy does not have an ERC721 receiver
|
erc20Proxy.address, // the ERC20 proxy does not have an ERC721 receiver
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc721Proxy.address,
|
to: erc721Proxy.address,
|
||||||
data,
|
data,
|
||||||
@@ -369,7 +369,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc721Proxy.address,
|
to: erc721Proxy.address,
|
||||||
data,
|
data,
|
||||||
@@ -393,7 +393,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc721Proxy.address,
|
to: erc721Proxy.address,
|
||||||
data,
|
data,
|
||||||
@@ -421,7 +421,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc721Proxy.address,
|
to: erc721Proxy.address,
|
||||||
data,
|
data,
|
||||||
@@ -442,7 +442,7 @@ describe('Asset Transfer Proxies', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
web3Wrapper.sendTransactionAsync({
|
web3Wrapper.sendTransactionAsync({
|
||||||
to: erc721Proxy.address,
|
to: erc721Proxy.address,
|
||||||
data,
|
data,
|
||||||
|
@@ -14,7 +14,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr
|
|||||||
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
||||||
import { CancelContractEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
import { CancelContractEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||||
@@ -144,7 +144,7 @@ describe('Exchange core', () => {
|
|||||||
const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
|
const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
|
||||||
const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
|
const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
|
||||||
signedOrder.signature = invalidSigHex;
|
signedOrder.signature = invalidSigHex;
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
||||||
RevertReason.InvalidOrderSignature,
|
RevertReason.InvalidOrderSignature,
|
||||||
);
|
);
|
||||||
@@ -153,7 +153,7 @@ describe('Exchange core', () => {
|
|||||||
it('should throw if no value is filled', async () => {
|
it('should throw if no value is filled', async () => {
|
||||||
signedOrder = orderFactory.newSignedOrder();
|
signedOrder = orderFactory.newSignedOrder();
|
||||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -167,7 +167,7 @@ describe('Exchange core', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if not sent by maker', async () => {
|
it('should throw if not sent by maker', async () => {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress),
|
exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress),
|
||||||
RevertReason.InvalidMaker,
|
RevertReason.InvalidMaker,
|
||||||
);
|
);
|
||||||
@@ -178,7 +178,7 @@ describe('Exchange core', () => {
|
|||||||
makerAssetAmount: new BigNumber(0),
|
makerAssetAmount: new BigNumber(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -189,7 +189,7 @@ describe('Exchange core', () => {
|
|||||||
takerAssetAmount: new BigNumber(0),
|
takerAssetAmount: new BigNumber(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -197,7 +197,7 @@ describe('Exchange core', () => {
|
|||||||
|
|
||||||
it('should be able to cancel a full order', async () => {
|
it('should be able to cancel a full order', async () => {
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||||
}),
|
}),
|
||||||
@@ -222,7 +222,7 @@ describe('Exchange core', () => {
|
|||||||
|
|
||||||
it('should throw if already cancelled', async () => {
|
it('should throw if already cancelled', async () => {
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -232,7 +232,7 @@ describe('Exchange core', () => {
|
|||||||
signedOrder = orderFactory.newSignedOrder({
|
signedOrder = orderFactory.newSignedOrder({
|
||||||
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||||
});
|
});
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -250,7 +250,7 @@ describe('Exchange core', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fillTakerAssetAmount2 = new BigNumber(1);
|
const fillTakerAssetAmount2 = new BigNumber(1);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||||
takerAssetFillAmount: fillTakerAssetAmount2,
|
takerAssetFillAmount: fillTakerAssetAmount2,
|
||||||
}),
|
}),
|
||||||
@@ -264,7 +264,7 @@ describe('Exchange core', () => {
|
|||||||
const orderEpoch = new BigNumber(1);
|
const orderEpoch = new BigNumber(1);
|
||||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||||
const lesserOrderEpoch = new BigNumber(0);
|
const lesserOrderEpoch = new BigNumber(0);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress),
|
exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress),
|
||||||
RevertReason.InvalidNewOrderEpoch,
|
RevertReason.InvalidNewOrderEpoch,
|
||||||
);
|
);
|
||||||
@@ -273,7 +273,7 @@ describe('Exchange core', () => {
|
|||||||
it('should fail to set orderEpoch equal to existing orderEpoch', async () => {
|
it('should fail to set orderEpoch equal to existing orderEpoch', async () => {
|
||||||
const orderEpoch = new BigNumber(1);
|
const orderEpoch = new BigNumber(1);
|
||||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress),
|
exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress),
|
||||||
RevertReason.InvalidNewOrderEpoch,
|
RevertReason.InvalidNewOrderEpoch,
|
||||||
);
|
);
|
||||||
@@ -363,7 +363,7 @@ describe('Exchange core', () => {
|
|||||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||||
RevertReason.TransferFailed,
|
RevertReason.TransferFailed,
|
||||||
);
|
);
|
||||||
@@ -386,7 +386,7 @@ describe('Exchange core', () => {
|
|||||||
expect(initialOwnerTakerAsset).to.be.bignumber.not.equal(takerAddress);
|
expect(initialOwnerTakerAsset).to.be.bignumber.not.equal(takerAddress);
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||||
RevertReason.TransferFailed,
|
RevertReason.TransferFailed,
|
||||||
);
|
);
|
||||||
@@ -409,7 +409,7 @@ describe('Exchange core', () => {
|
|||||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||||
RevertReason.InvalidAmount,
|
RevertReason.InvalidAmount,
|
||||||
);
|
);
|
||||||
@@ -432,7 +432,7 @@ describe('Exchange core', () => {
|
|||||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||||
RevertReason.InvalidAmount,
|
RevertReason.InvalidAmount,
|
||||||
);
|
);
|
||||||
@@ -449,7 +449,7 @@ describe('Exchange core', () => {
|
|||||||
});
|
});
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||||
RevertReason.RoundingError,
|
RevertReason.RoundingError,
|
||||||
);
|
);
|
||||||
@@ -475,7 +475,7 @@ describe('Exchange core', () => {
|
|||||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||||
RevertReason.LengthGreaterThan131Required,
|
RevertReason.LengthGreaterThan131Required,
|
||||||
);
|
);
|
||||||
|
@@ -14,7 +14,7 @@ import {
|
|||||||
TestAssetProxyDispatcherContract,
|
TestAssetProxyDispatcherContract,
|
||||||
} from '../../generated_contract_wrappers/test_asset_proxy_dispatcher';
|
} from '../../generated_contract_wrappers/test_asset_proxy_dispatcher';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||||
@@ -129,7 +129,7 @@ describe('AssetProxyDispatcher', () => {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
);
|
);
|
||||||
// Register new ERC20 Transfer Proxy contract
|
// Register new ERC20 Transfer Proxy contract
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(newErc20TransferProxy.address, {
|
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(newErc20TransferProxy.address, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
@@ -138,7 +138,7 @@ describe('AssetProxyDispatcher', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if requesting address is not owner', async () => {
|
it('should throw if requesting address is not owner', async () => {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: notOwner }),
|
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: notOwner }),
|
||||||
RevertReason.OnlyContractOwner,
|
RevertReason.OnlyContractOwner,
|
||||||
);
|
);
|
||||||
@@ -210,7 +210,7 @@ describe('AssetProxyDispatcher', () => {
|
|||||||
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address);
|
||||||
// Perform a transfer from makerAddress to takerAddress
|
// Perform a transfer from makerAddress to takerAddress
|
||||||
const amount = new BigNumber(10);
|
const amount = new BigNumber(10);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync(
|
assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync(
|
||||||
encodedAssetData,
|
encodedAssetData,
|
||||||
makerAddress,
|
makerAddress,
|
||||||
|
@@ -12,7 +12,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr
|
|||||||
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
||||||
import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||||
@@ -602,7 +602,7 @@ describe('matchOrders', () => {
|
|||||||
// Cancel left order
|
// Cancel left order
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress);
|
||||||
// Match orders
|
// Match orders
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -627,7 +627,7 @@ describe('matchOrders', () => {
|
|||||||
// Cancel right order
|
// Cancel right order
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress);
|
||||||
// Match orders
|
// Match orders
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -650,7 +650,7 @@ describe('matchOrders', () => {
|
|||||||
feeRecipientAddress: feeRecipientAddressRight,
|
feeRecipientAddress: feeRecipientAddressRight,
|
||||||
});
|
});
|
||||||
// Match orders
|
// Match orders
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||||
RevertReason.NegativeSpreadRequired,
|
RevertReason.NegativeSpreadRequired,
|
||||||
);
|
);
|
||||||
@@ -673,7 +673,7 @@ describe('matchOrders', () => {
|
|||||||
feeRecipientAddress: feeRecipientAddressRight,
|
feeRecipientAddress: feeRecipientAddressRight,
|
||||||
});
|
});
|
||||||
// Match orders
|
// Match orders
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||||
// We are assuming assetData fields of the right order are the
|
// We are assuming assetData fields of the right order are the
|
||||||
// reverse of the left order, rather than checking equality. This
|
// reverse of the left order, rather than checking equality. This
|
||||||
@@ -702,7 +702,7 @@ describe('matchOrders', () => {
|
|||||||
feeRecipientAddress: feeRecipientAddressRight,
|
feeRecipientAddress: feeRecipientAddressRight,
|
||||||
});
|
});
|
||||||
// Match orders
|
// Match orders
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||||
RevertReason.InvalidOrderSignature,
|
RevertReason.InvalidOrderSignature,
|
||||||
);
|
);
|
||||||
|
@@ -13,7 +13,7 @@ import { TestValidatorContract } from '../../generated_contract_wrappers/test_va
|
|||||||
import { TestWalletContract } from '../../generated_contract_wrappers/test_wallet';
|
import { TestWalletContract } from '../../generated_contract_wrappers/test_wallet';
|
||||||
import { addressUtils } from '../utils/address_utils';
|
import { addressUtils } from '../utils/address_utils';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertOrOtherErrorAsync } from '../utils/assertions';
|
import { expectContractCallFailed } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { LogDecoder } from '../utils/log_decoder';
|
import { LogDecoder } from '../utils/log_decoder';
|
||||||
@@ -101,7 +101,7 @@ describe('MixinSignatureValidator', () => {
|
|||||||
it('should revert when signature is empty', async () => {
|
it('should revert when signature is empty', async () => {
|
||||||
const emptySignature = '0x';
|
const emptySignature = '0x';
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
signatureValidator.publicIsValidSignature.callAsync(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
signedOrder.makerAddress,
|
signedOrder.makerAddress,
|
||||||
@@ -115,7 +115,7 @@ describe('MixinSignatureValidator', () => {
|
|||||||
const unsupportedSignatureType = SignatureType.NSignatureTypes;
|
const unsupportedSignatureType = SignatureType.NSignatureTypes;
|
||||||
const unsupportedSignatureHex = `0x${unsupportedSignatureType}`;
|
const unsupportedSignatureHex = `0x${unsupportedSignatureType}`;
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
signatureValidator.publicIsValidSignature.callAsync(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
signedOrder.makerAddress,
|
signedOrder.makerAddress,
|
||||||
@@ -128,7 +128,7 @@ describe('MixinSignatureValidator', () => {
|
|||||||
it('should revert when SignatureType=Illegal', async () => {
|
it('should revert when SignatureType=Illegal', async () => {
|
||||||
const unsupportedSignatureHex = `0x${SignatureType.Illegal}`;
|
const unsupportedSignatureHex = `0x${SignatureType.Illegal}`;
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
signatureValidator.publicIsValidSignature.callAsync(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
signedOrder.makerAddress,
|
signedOrder.makerAddress,
|
||||||
@@ -155,7 +155,7 @@ describe('MixinSignatureValidator', () => {
|
|||||||
const signatureBuffer = Buffer.concat([fillerData, signatureType]);
|
const signatureBuffer = Buffer.concat([fillerData, signatureType]);
|
||||||
const signatureHex = ethUtil.bufferToHex(signatureBuffer);
|
const signatureHex = ethUtil.bufferToHex(signatureBuffer);
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
signatureValidator.publicIsValidSignature.callAsync(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
signedOrder.makerAddress,
|
signedOrder.makerAddress,
|
||||||
|
@@ -11,7 +11,7 @@ import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
|||||||
import { ExchangeWrapperContract } from '../../generated_contract_wrappers/exchange_wrapper';
|
import { ExchangeWrapperContract } from '../../generated_contract_wrappers/exchange_wrapper';
|
||||||
import { WhitelistContract } from '../../generated_contract_wrappers/whitelist';
|
import { WhitelistContract } from '../../generated_contract_wrappers/whitelist';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||||
@@ -134,7 +134,7 @@ describe('Exchange transactions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if not called by specified sender', async () => {
|
it('should throw if not called by specified sender', async () => {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.executeTransactionAsync(signedTx, takerAddress),
|
exchangeWrapper.executeTransactionAsync(signedTx, takerAddress),
|
||||||
RevertReason.FailedExecution,
|
RevertReason.FailedExecution,
|
||||||
);
|
);
|
||||||
@@ -177,7 +177,7 @@ describe('Exchange transactions', () => {
|
|||||||
|
|
||||||
it('should throw if the a 0x transaction with the same transactionHash has already been executed', async () => {
|
it('should throw if the a 0x transaction with the same transactionHash has already been executed', async () => {
|
||||||
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.executeTransactionAsync(signedTx, senderAddress),
|
exchangeWrapper.executeTransactionAsync(signedTx, senderAddress),
|
||||||
RevertReason.InvalidTxHash,
|
RevertReason.InvalidTxHash,
|
||||||
);
|
);
|
||||||
@@ -197,7 +197,7 @@ describe('Exchange transactions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if not called by specified sender', async () => {
|
it('should throw if not called by specified sender', async () => {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.executeTransactionAsync(signedTx, makerAddress),
|
exchangeWrapper.executeTransactionAsync(signedTx, makerAddress),
|
||||||
RevertReason.FailedExecution,
|
RevertReason.FailedExecution,
|
||||||
);
|
);
|
||||||
@@ -205,7 +205,7 @@ describe('Exchange transactions', () => {
|
|||||||
|
|
||||||
it('should cancel the order when signed by maker and called by sender', async () => {
|
it('should cancel the order when signed by maker and called by sender', async () => {
|
||||||
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, senderAddress),
|
exchangeWrapper.fillOrderAsync(signedOrder, senderAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -250,7 +250,7 @@ describe('Exchange transactions', () => {
|
|||||||
signedOrder.signature,
|
signedOrder.signature,
|
||||||
);
|
);
|
||||||
const signedFillTx = takerTransactionFactory.newSignedTransaction(fillData);
|
const signedFillTx = takerTransactionFactory.newSignedTransaction(fillData);
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapperContract.fillOrder.sendTransactionAsync(
|
exchangeWrapperContract.fillOrder.sendTransactionAsync(
|
||||||
orderWithoutExchangeAddress,
|
orderWithoutExchangeAddress,
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
@@ -370,7 +370,7 @@ describe('Exchange transactions', () => {
|
|||||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
const salt = generatePseudoRandomSalt();
|
const salt = generatePseudoRandomSalt();
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||||
orderWithoutExchangeAddress,
|
orderWithoutExchangeAddress,
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
@@ -392,7 +392,7 @@ describe('Exchange transactions', () => {
|
|||||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
const salt = generatePseudoRandomSalt();
|
const salt = generatePseudoRandomSalt();
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||||
orderWithoutExchangeAddress,
|
orderWithoutExchangeAddress,
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
|
@@ -12,7 +12,7 @@ import { ERC20ProxyContract } from '../../generated_contract_wrappers/e_r_c20_pr
|
|||||||
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
import { ERC721ProxyContract } from '../../generated_contract_wrappers/e_r_c721_proxy';
|
||||||
import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
import { ERC20Wrapper } from '../utils/erc20_wrapper';
|
||||||
@@ -174,7 +174,7 @@ describe('Exchange wrappers', () => {
|
|||||||
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
||||||
RevertReason.OrderUnfillable,
|
RevertReason.OrderUnfillable,
|
||||||
);
|
);
|
||||||
@@ -187,7 +187,7 @@ describe('Exchange wrappers', () => {
|
|||||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
||||||
RevertReason.CompleteFillFailed,
|
RevertReason.CompleteFillFailed,
|
||||||
);
|
);
|
||||||
@@ -500,7 +500,7 @@ describe('Exchange wrappers', () => {
|
|||||||
|
|
||||||
await exchangeWrapper.fillOrKillOrderAsync(signedOrders[0], takerAddress);
|
await exchangeWrapper.fillOrKillOrderAsync(signedOrders[0], takerAddress);
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, {
|
exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmounts,
|
takerAssetFillAmounts,
|
||||||
}),
|
}),
|
||||||
@@ -703,7 +703,7 @@ describe('Exchange wrappers', () => {
|
|||||||
orderFactory.newSignedOrder(),
|
orderFactory.newSignedOrder(),
|
||||||
];
|
];
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
||||||
}),
|
}),
|
||||||
@@ -921,7 +921,7 @@ describe('Exchange wrappers', () => {
|
|||||||
orderFactory.newSignedOrder(),
|
orderFactory.newSignedOrder(),
|
||||||
];
|
];
|
||||||
|
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
||||||
makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
||||||
}),
|
}),
|
||||||
|
@@ -9,7 +9,7 @@ import * as _ from 'lodash';
|
|||||||
|
|
||||||
import { TestLibBytesContract } from '../../generated_contract_wrappers/test_lib_bytes';
|
import { TestLibBytesContract } from '../../generated_contract_wrappers/test_lib_bytes';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertOrOtherErrorAsync } from '../utils/assertions';
|
import { expectContractCallFailed } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||||
@@ -100,7 +100,7 @@ describe('LibBytes', () => {
|
|||||||
|
|
||||||
describe('popLastByte', () => {
|
describe('popLastByte', () => {
|
||||||
it('should revert if length is 0', async () => {
|
it('should revert if length is 0', async () => {
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicPopLastByte.callAsync(constants.NULL_BYTES),
|
libBytes.publicPopLastByte.callAsync(constants.NULL_BYTES),
|
||||||
RevertReason.LibBytesGreaterThanZeroLengthRequired,
|
RevertReason.LibBytesGreaterThanZeroLengthRequired,
|
||||||
);
|
);
|
||||||
@@ -116,7 +116,7 @@ describe('LibBytes', () => {
|
|||||||
|
|
||||||
describe('popLast20Bytes', () => {
|
describe('popLast20Bytes', () => {
|
||||||
it('should revert if length is less than 20', async () => {
|
it('should revert if length is less than 20', async () => {
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicPopLast20Bytes.callAsync(byteArrayShorterThan20Bytes),
|
libBytes.publicPopLast20Bytes.callAsync(byteArrayShorterThan20Bytes),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -184,7 +184,7 @@ describe('LibBytes', () => {
|
|||||||
|
|
||||||
describe('deepCopyBytes', () => {
|
describe('deepCopyBytes', () => {
|
||||||
it('should revert if dest is shorter than source', async () => {
|
it('should revert if dest is shorter than source', async () => {
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicDeepCopyBytes.callAsync(byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes),
|
libBytes.publicDeepCopyBytes.callAsync(byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes),
|
||||||
RevertReason.LibBytesGreaterOrEqualToSourceBytesLengthRequired,
|
RevertReason.LibBytesGreaterOrEqualToSourceBytesLengthRequired,
|
||||||
);
|
);
|
||||||
@@ -237,7 +237,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the byte array is too short to hold an address', async () => {
|
it('should fail if the byte array is too short to hold an address', async () => {
|
||||||
const shortByteArray = '0xabcdef';
|
const shortByteArray = '0xabcdef';
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadAddress.callAsync(shortByteArray, offset),
|
libBytes.publicReadAddress.callAsync(shortByteArray, offset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -245,7 +245,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => {
|
||||||
const byteArray = testAddress;
|
const byteArray = testAddress;
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadAddress.callAsync(byteArray, badOffset),
|
libBytes.publicReadAddress.callAsync(byteArray, badOffset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -281,7 +281,7 @@ describe('LibBytes', () => {
|
|||||||
});
|
});
|
||||||
it('should fail if the byte array is too short to hold an address', async () => {
|
it('should fail if the byte array is too short to hold an address', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteAddress.callAsync(byteArrayShorterThan20Bytes, offset, testAddress),
|
libBytes.publicWriteAddress.callAsync(byteArrayShorterThan20Bytes, offset, testAddress),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -289,7 +289,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => {
|
||||||
const byteArray = byteArrayLongerThan32Bytes;
|
const byteArray = byteArrayLongerThan32Bytes;
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteAddress.callAsync(byteArray, badOffset, testAddress),
|
libBytes.publicWriteAddress.callAsync(byteArray, badOffset, testAddress),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -313,14 +313,14 @@ describe('LibBytes', () => {
|
|||||||
});
|
});
|
||||||
it('should fail if the byte array is too short to hold a bytes32', async () => {
|
it('should fail if the byte array is too short to hold a bytes32', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytes32.callAsync(byteArrayShorterThan32Bytes, offset),
|
libBytes.publicReadBytes32.callAsync(byteArrayShorterThan32Bytes, offset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => {
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytes32.callAsync(testBytes32, badOffset),
|
libBytes.publicReadBytes32.callAsync(testBytes32, badOffset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -356,7 +356,7 @@ describe('LibBytes', () => {
|
|||||||
});
|
});
|
||||||
it('should fail if the byte array is too short to hold a bytes32', async () => {
|
it('should fail if the byte array is too short to hold a bytes32', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteBytes32.callAsync(byteArrayShorterThan32Bytes, offset, testBytes32),
|
libBytes.publicWriteBytes32.callAsync(byteArrayShorterThan32Bytes, offset, testBytes32),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -364,7 +364,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => {
|
||||||
const byteArray = byteArrayLongerThan32Bytes;
|
const byteArray = byteArrayLongerThan32Bytes;
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteBytes32.callAsync(byteArray, badOffset, testBytes32),
|
libBytes.publicWriteBytes32.callAsync(byteArray, badOffset, testBytes32),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -392,7 +392,7 @@ describe('LibBytes', () => {
|
|||||||
});
|
});
|
||||||
it('should fail if the byte array is too short to hold a uint256', async () => {
|
it('should fail if the byte array is too short to hold a uint256', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadUint256.callAsync(byteArrayShorterThan32Bytes, offset),
|
libBytes.publicReadUint256.callAsync(byteArrayShorterThan32Bytes, offset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -402,7 +402,7 @@ describe('LibBytes', () => {
|
|||||||
const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256);
|
const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256);
|
||||||
const byteArray = ethUtil.bufferToHex(testUint256AsBuffer);
|
const byteArray = ethUtil.bufferToHex(testUint256AsBuffer);
|
||||||
const badOffset = new BigNumber(testUint256AsBuffer.byteLength);
|
const badOffset = new BigNumber(testUint256AsBuffer.byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadUint256.callAsync(byteArray, badOffset),
|
libBytes.publicReadUint256.callAsync(byteArray, badOffset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -442,7 +442,7 @@ describe('LibBytes', () => {
|
|||||||
});
|
});
|
||||||
it('should fail if the byte array is too short to hold a uint256', async () => {
|
it('should fail if the byte array is too short to hold a uint256', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteUint256.callAsync(byteArrayShorterThan32Bytes, offset, testUint256),
|
libBytes.publicWriteUint256.callAsync(byteArrayShorterThan32Bytes, offset, testUint256),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -450,7 +450,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => {
|
||||||
const byteArray = byteArrayLongerThan32Bytes;
|
const byteArray = byteArrayLongerThan32Bytes;
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteUint256.callAsync(byteArray, badOffset, testUint256),
|
libBytes.publicWriteUint256.callAsync(byteArray, badOffset, testUint256),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -461,7 +461,7 @@ describe('LibBytes', () => {
|
|||||||
// AssertionError: expected promise to be rejected with an error including 'revert' but it was fulfilled with '0x08c379a0'
|
// AssertionError: expected promise to be rejected with an error including 'revert' but it was fulfilled with '0x08c379a0'
|
||||||
it('should revert if byte array has a length < 4', async () => {
|
it('should revert if byte array has a length < 4', async () => {
|
||||||
const byteArrayLessThan4Bytes = '0x010101';
|
const byteArrayLessThan4Bytes = '0x010101';
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)),
|
libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo4LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo4LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -516,28 +516,28 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the byte array is too short to hold the length of a nested byte array', async () => {
|
it('should fail if the byte array is too short to hold the length of a nested byte array', async () => {
|
||||||
// The length of the nested array is 32 bytes. By storing less than 32 bytes, a length cannot be read.
|
// The length of the nested array is 32 bytes. By storing less than 32 bytes, a length cannot be read.
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, offset),
|
libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, offset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should fail if we store a nested byte array length, without a nested byte array', async () => {
|
it('should fail if we store a nested byte array length, without a nested byte array', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytesWithLength.callAsync(testBytes32, offset),
|
libBytes.publicReadBytesWithLength.callAsync(testBytes32, offset),
|
||||||
RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => {
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, badOffset),
|
libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, badOffset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => {
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicReadBytesWithLength.callAsync(testBytes32, badOffset),
|
libBytes.publicReadBytesWithLength.callAsync(testBytes32, badOffset),
|
||||||
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
RevertReason.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||||
);
|
);
|
||||||
@@ -649,7 +649,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the byte array is too short to hold the length of a nested byte array', async () => {
|
it('should fail if the byte array is too short to hold the length of a nested byte array', async () => {
|
||||||
const offset = new BigNumber(0);
|
const offset = new BigNumber(0);
|
||||||
const emptyByteArray = ethUtil.bufferToHex(new Buffer(1));
|
const emptyByteArray = ethUtil.bufferToHex(new Buffer(1));
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, offset, longData),
|
libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, offset, longData),
|
||||||
RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
||||||
);
|
);
|
||||||
@@ -657,7 +657,7 @@ describe('LibBytes', () => {
|
|||||||
it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array)', async () => {
|
it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array)', async () => {
|
||||||
const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength));
|
const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength));
|
||||||
const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength);
|
const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, badOffset, shortData),
|
libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, badOffset, shortData),
|
||||||
RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
||||||
);
|
);
|
||||||
|
@@ -14,8 +14,9 @@ import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mix
|
|||||||
import { TestAssetProxyOwnerContract } from '../../generated_contract_wrappers/test_asset_proxy_owner';
|
import { TestAssetProxyOwnerContract } from '../../generated_contract_wrappers/test_asset_proxy_owner';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import {
|
import {
|
||||||
expectRevertOrAlwaysFailingTransactionAsync,
|
expectContractCallFailedWithoutReasonAsync,
|
||||||
expectRevertOrContractCallFailedAsync,
|
expectContractCreationFailedWithoutReason,
|
||||||
|
expectTransactionFailedWithoutReasonAsync,
|
||||||
} from '../utils/assertions';
|
} from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
@@ -108,7 +109,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
});
|
});
|
||||||
it('should throw if a null address is included in assetProxyContracts', async () => {
|
it('should throw if a null address is included in assetProxyContracts', async () => {
|
||||||
const assetProxyContractAddresses = [erc20Proxy.address, constants.NULL_ADDRESS];
|
const assetProxyContractAddresses = [erc20Proxy.address, constants.NULL_ADDRESS];
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectContractCreationFailedWithoutReason(
|
||||||
AssetProxyOwnerContract.deployFrom0xArtifactAsync(
|
AssetProxyOwnerContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.AssetProxyOwner,
|
artifacts.AssetProxyOwner,
|
||||||
provider,
|
provider,
|
||||||
@@ -150,7 +151,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
describe('registerAssetProxy', () => {
|
describe('registerAssetProxy', () => {
|
||||||
it('should throw if not called by multisig', async () => {
|
it('should throw if not called by multisig', async () => {
|
||||||
const isRegistered = true;
|
const isRegistered = true;
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, isRegistered, {
|
testAssetProxyOwner.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, isRegistered, {
|
||||||
from: owners[0],
|
from: owners[0],
|
||||||
}),
|
}),
|
||||||
@@ -277,7 +278,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
);
|
);
|
||||||
const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
||||||
const txId = log.args.transactionId;
|
const txId = log.args.transactionId;
|
||||||
return expectRevertOrContractCallFailedAsync(
|
return expectContractCallFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId),
|
testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -312,7 +313,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
);
|
);
|
||||||
const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
||||||
const txId = log.args.transactionId;
|
const txId = log.args.transactionId;
|
||||||
return expectRevertOrContractCallFailedAsync(
|
return expectContractCallFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId),
|
testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -332,7 +333,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
||||||
const txId = log.args.transactionId;
|
const txId = log.args.transactionId;
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
||||||
from: owners[1],
|
from: owners[1],
|
||||||
}),
|
}),
|
||||||
@@ -354,7 +355,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
|
|
||||||
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
|
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
||||||
from: owners[1],
|
from: owners[1],
|
||||||
}),
|
}),
|
||||||
@@ -376,7 +377,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
|
|
||||||
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
|
await multiSigWrapper.confirmTransactionAsync(txId, owners[1]);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
||||||
from: owners[1],
|
from: owners[1],
|
||||||
}),
|
}),
|
||||||
@@ -433,7 +434,7 @@ describe('AssetProxyOwner', () => {
|
|||||||
const isExecuted = tx[3];
|
const isExecuted = tx[3];
|
||||||
expect(isExecuted).to.equal(true);
|
expect(isExecuted).to.equal(true);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
|
||||||
from: owners[1],
|
from: owners[1],
|
||||||
}),
|
}),
|
||||||
|
@@ -8,7 +8,7 @@ import {
|
|||||||
SubmissionContractEventArgs,
|
SubmissionContractEventArgs,
|
||||||
} from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock';
|
} from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectTransactionFailedWithoutReasonAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { increaseTimeAndMineBlockAsync } from '../utils/increase_time';
|
import { increaseTimeAndMineBlockAsync } from '../utils/increase_time';
|
||||||
@@ -67,7 +67,7 @@ describe('MultiSigWalletWithTimeLock', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when not called by wallet', async () => {
|
it('should throw when not called by wallet', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
multiSig.changeTimeLock.sendTransactionAsync(SECONDS_TIME_LOCKED, { from: owners[0] }),
|
multiSig.changeTimeLock.sendTransactionAsync(SECONDS_TIME_LOCKED, { from: owners[0] }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -78,7 +78,7 @@ describe('MultiSigWalletWithTimeLock', () => {
|
|||||||
const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]);
|
const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]);
|
||||||
const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>;
|
||||||
const txId = log.args.transactionId;
|
const txId = log.args.transactionId;
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }),
|
multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -147,7 +147,7 @@ describe('MultiSigWalletWithTimeLock', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if it has enough confirmations but is not past the time lock', async () => {
|
it('should throw if it has enough confirmations but is not past the time lock', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }),
|
multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -7,7 +7,7 @@ import * as _ from 'lodash';
|
|||||||
import { TokenRegistryContract } from '../generated_contract_wrappers/token_registry';
|
import { TokenRegistryContract } from '../generated_contract_wrappers/token_registry';
|
||||||
|
|
||||||
import { artifacts } from './utils/artifacts';
|
import { artifacts } from './utils/artifacts';
|
||||||
import { expectRevertOrAlwaysFailingTransactionAsync } from './utils/assertions';
|
import { expectTransactionFailedWithoutReasonAsync } from './utils/assertions';
|
||||||
import { chaiSetup } from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import { constants } from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import { TokenRegWrapper } from './utils/token_registry_wrapper';
|
import { TokenRegWrapper } from './utils/token_registry_wrapper';
|
||||||
@@ -75,7 +75,7 @@ describe('TokenRegistry', () => {
|
|||||||
|
|
||||||
describe('addToken', () => {
|
describe('addToken', () => {
|
||||||
it('should throw when not called by owner', async () => {
|
it('should throw when not called by owner', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(tokenRegWrapper.addTokenAsync(token1, notOwner));
|
return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(token1, notOwner));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add token metadata when called by owner', async () => {
|
it('should add token metadata when called by owner', async () => {
|
||||||
@@ -87,20 +87,18 @@ describe('TokenRegistry', () => {
|
|||||||
it('should throw if token already exists', async () => {
|
it('should throw if token already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token1, owner);
|
await tokenRegWrapper.addTokenAsync(token1, owner);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(tokenRegWrapper.addTokenAsync(token1, owner));
|
return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(token1, owner));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if token address is null', async () => {
|
it('should throw if token address is null', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(tokenRegWrapper.addTokenAsync(nullToken, owner));
|
return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(nullToken, owner));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if name already exists', async () => {
|
it('should throw if name already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token1, owner);
|
await tokenRegWrapper.addTokenAsync(token1, owner);
|
||||||
const duplicateNameToken = _.assign({}, token2, { name: token1.name });
|
const duplicateNameToken = _.assign({}, token2, { name: token1.name });
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner));
|
||||||
tokenRegWrapper.addTokenAsync(duplicateNameToken, owner),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if symbol already exists', async () => {
|
it('should throw if symbol already exists', async () => {
|
||||||
@@ -109,7 +107,7 @@ describe('TokenRegistry', () => {
|
|||||||
symbol: token1.symbol,
|
symbol: token1.symbol,
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner),
|
tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -136,7 +134,7 @@ describe('TokenRegistry', () => {
|
|||||||
|
|
||||||
describe('setTokenName', () => {
|
describe('setTokenName', () => {
|
||||||
it('should throw when not called by owner', async () => {
|
it('should throw when not called by owner', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: notOwner }),
|
tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: notOwner }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -162,13 +160,13 @@ describe('TokenRegistry', () => {
|
|||||||
it('should throw if the name already exists', async () => {
|
it('should throw if the name already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token2, owner);
|
await tokenRegWrapper.addTokenAsync(token2, owner);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: owner }),
|
tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: owner }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if token does not exist', async () => {
|
it('should throw if token does not exist', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.setTokenName.sendTransactionAsync(nullToken.address, token2.name, { from: owner }),
|
tokenReg.setTokenName.sendTransactionAsync(nullToken.address, token2.name, { from: owner }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -176,7 +174,7 @@ describe('TokenRegistry', () => {
|
|||||||
|
|
||||||
describe('setTokenSymbol', () => {
|
describe('setTokenSymbol', () => {
|
||||||
it('should throw when not called by owner', async () => {
|
it('should throw when not called by owner', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, {
|
tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, {
|
||||||
from: notOwner,
|
from: notOwner,
|
||||||
}),
|
}),
|
||||||
@@ -202,7 +200,7 @@ describe('TokenRegistry', () => {
|
|||||||
it('should throw if the symbol already exists', async () => {
|
it('should throw if the symbol already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token2, owner);
|
await tokenRegWrapper.addTokenAsync(token2, owner);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, {
|
tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
@@ -210,7 +208,7 @@ describe('TokenRegistry', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if token does not exist', async () => {
|
it('should throw if token does not exist', async () => {
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.setTokenSymbol.sendTransactionAsync(nullToken.address, token2.symbol, {
|
tokenReg.setTokenSymbol.sendTransactionAsync(nullToken.address, token2.symbol, {
|
||||||
from: owner,
|
from: owner,
|
||||||
}),
|
}),
|
||||||
@@ -221,7 +219,7 @@ describe('TokenRegistry', () => {
|
|||||||
describe('removeToken', () => {
|
describe('removeToken', () => {
|
||||||
it('should throw if not called by owner', async () => {
|
it('should throw if not called by owner', async () => {
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.removeToken.sendTransactionAsync(token1.address, index, { from: notOwner }),
|
tokenReg.removeToken.sendTransactionAsync(token1.address, index, { from: notOwner }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -240,7 +238,7 @@ describe('TokenRegistry', () => {
|
|||||||
|
|
||||||
it('should throw if token does not exist', async () => {
|
it('should throw if token does not exist', async () => {
|
||||||
const index = new BigNumber(0);
|
const index = new BigNumber(0);
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.removeToken.sendTransactionAsync(nullToken.address, index, { from: owner }),
|
tokenReg.removeToken.sendTransactionAsync(nullToken.address, index, { from: owner }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -248,7 +246,7 @@ describe('TokenRegistry', () => {
|
|||||||
it('should throw if token at given index does not match address', async () => {
|
it('should throw if token at given index does not match address', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token2, owner);
|
await tokenRegWrapper.addTokenAsync(token2, owner);
|
||||||
const incorrectIndex = new BigNumber(0);
|
const incorrectIndex = new BigNumber(0);
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
tokenReg.removeToken.sendTransactionAsync(token2.address, incorrectIndex, { from: owner }),
|
tokenReg.removeToken.sendTransactionAsync(token2.address, incorrectIndex, { from: owner }),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -5,7 +5,7 @@ import * as chai from 'chai';
|
|||||||
|
|
||||||
import { WETH9Contract } from '../../generated_contract_wrappers/weth9';
|
import { WETH9Contract } from '../../generated_contract_wrappers/weth9';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectInsufficientFundsAsync, expectRevertOrAlwaysFailingTransactionAsync } from '../utils/assertions';
|
import { expectInsufficientFundsAsync, expectTransactionFailedWithoutReasonAsync } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||||
@@ -74,7 +74,7 @@ describe('EtherToken', () => {
|
|||||||
const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
|
const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
|
||||||
const ethTokensToWithdraw = initEthTokenBalance.plus(1);
|
const ethTokensToWithdraw = initEthTokenBalance.plus(1);
|
||||||
|
|
||||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedWithoutReasonAsync(
|
||||||
etherToken.withdraw.sendTransactionAsync(ethTokensToWithdraw),
|
etherToken.withdraw.sendTransactionAsync(ethTokensToWithdraw),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -5,7 +5,7 @@ import * as chai from 'chai';
|
|||||||
|
|
||||||
import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token';
|
import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token';
|
||||||
import { artifacts } from '../utils/artifacts';
|
import { artifacts } from '../utils/artifacts';
|
||||||
import { expectRevertOrOtherErrorAsync } from '../utils/assertions';
|
import { expectContractCallFailed } from '../utils/assertions';
|
||||||
import { chaiSetup } from '../utils/chai_setup';
|
import { chaiSetup } from '../utils/chai_setup';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
|
||||||
@@ -54,7 +54,7 @@ describe('UnlimitedAllowanceToken', () => {
|
|||||||
it('should throw if owner has insufficient balance', async () => {
|
it('should throw if owner has insufficient balance', async () => {
|
||||||
const ownerBalance = await token.balanceOf.callAsync(owner);
|
const ownerBalance = await token.balanceOf.callAsync(owner);
|
||||||
const amountToTransfer = ownerBalance.plus(1);
|
const amountToTransfer = ownerBalance.plus(1);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
token.transfer.callAsync(spender, amountToTransfer, { from: owner }),
|
token.transfer.callAsync(spender, amountToTransfer, { from: owner }),
|
||||||
RevertReason.Erc20InsufficientBalance,
|
RevertReason.Erc20InsufficientBalance,
|
||||||
);
|
);
|
||||||
@@ -93,7 +93,7 @@ describe('UnlimitedAllowanceToken', () => {
|
|||||||
await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner }),
|
await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner }),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
||||||
from: spender,
|
from: spender,
|
||||||
}),
|
}),
|
||||||
@@ -109,7 +109,7 @@ describe('UnlimitedAllowanceToken', () => {
|
|||||||
const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
|
const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
|
||||||
expect(isSpenderAllowanceInsufficient).to.be.true();
|
expect(isSpenderAllowanceInsufficient).to.be.true();
|
||||||
|
|
||||||
return expectRevertOrOtherErrorAsync(
|
return expectContractCallFailed(
|
||||||
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
||||||
from: spender,
|
from: spender,
|
||||||
}),
|
}),
|
||||||
|
@@ -1,108 +1,159 @@
|
|||||||
import { RevertReason } from '@0xproject/types';
|
import { RevertReason } from '@0xproject/types';
|
||||||
|
import { logUtils } from '@0xproject/utils';
|
||||||
|
import { NodeType } from '@0xproject/web3-wrapper';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import { TransactionReceipt, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
import { TransactionReceipt, TransactionReceiptStatus, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { constants } from './constants';
|
|
||||||
import { web3Wrapper } from './web3_wrapper';
|
import { web3Wrapper } from './web3_wrapper';
|
||||||
|
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
|
||||||
function _expectEitherErrorAsync<T>(p: Promise<T>, error1: string, error2: string): PromiseLike<void> {
|
let nodeType: NodeType | undefined;
|
||||||
return expect(p)
|
|
||||||
.to.be.rejected()
|
// Represents the return value of a `sendTransaction` call. The Promise should
|
||||||
.then(e => {
|
// resolve with either a transaction receipt or a transaction hash.
|
||||||
expect(e).to.satisfy(
|
export type sendTransactionResult = Promise<TransactionReceipt | TransactionReceiptWithDecodedLogs | string>;
|
||||||
(err: Error) => _.includes(err.message, error1) || _.includes(err.message, error2),
|
|
||||||
`expected promise to reject with error message that includes "${error1}" or "${error2}", but got: ` +
|
async function _getGanacheOrGethError(ganacheError: string, gethError: string): Promise<string> {
|
||||||
`"${e.message}"\n`,
|
if (_.isUndefined(nodeType)) {
|
||||||
);
|
nodeType = await web3Wrapper.getNodeTypeAsync();
|
||||||
});
|
}
|
||||||
|
switch (nodeType) {
|
||||||
|
case NodeType.Ganache:
|
||||||
|
return ganacheError;
|
||||||
|
case NodeType.Geth:
|
||||||
|
return gethError;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown node type: ${nodeType}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _getInsufficientFundsErrorMessageAsync(): Promise<string> {
|
||||||
|
return _getGanacheOrGethError("sender doesn't have enough funds", 'insufficient funds');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _getTransactionFailedErrorMessageAsync(): Promise<string> {
|
||||||
|
return _getGanacheOrGethError('revert', 'always failing transaction');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _getContractCallFailedErrorMessageAsync(): Promise<string> {
|
||||||
|
return _getGanacheOrGethError('revert', 'Contract call failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rejects if the given Promise does not reject with an error indicating
|
* Rejects if the given Promise does not reject with an error indicating
|
||||||
* insufficient funds.
|
* insufficient funds.
|
||||||
* @param p the Promise which is expected to reject
|
* @param p a promise resulting from a contract call or sendTransaction call.
|
||||||
* @returns a new Promise which will reject if the conditions are not met and
|
* @returns a new Promise which will reject if the conditions are not met and
|
||||||
* otherwise resolve with no value.
|
* otherwise resolve with no value.
|
||||||
*/
|
*/
|
||||||
export function expectInsufficientFundsAsync<T>(p: Promise<T>): PromiseLike<void> {
|
export async function expectInsufficientFundsAsync<T>(p: Promise<T>): Promise<void> {
|
||||||
return _expectEitherErrorAsync(p, 'insufficient funds', "sender doesn't have enough funds");
|
const errMessage = await _getInsufficientFundsErrorMessageAsync();
|
||||||
|
return expect(p).to.be.rejectedWith(errMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rejects if the given Promise does not reject with a "revert" error or the
|
* Resolves if the the sendTransaction call fails with the given revert reason.
|
||||||
* given otherError.
|
* However, since Geth does not support revert reasons for sendTransaction, this
|
||||||
* @param p the Promise which is expected to reject
|
* falls back to expectTransactionFailedWithoutReasonAsync if the backing
|
||||||
* @param otherError the other error which is accepted as a valid reject error.
|
* Ethereum node is Geth.
|
||||||
* @returns a new Promise which will reject if the conditions are not met and
|
* @param p a Promise resulting from a sendTransaction call
|
||||||
* otherwise resolve with no value.
|
|
||||||
*/
|
|
||||||
export function expectRevertOrOtherErrorAsync<T>(p: Promise<T>, otherError: string): PromiseLike<void> {
|
|
||||||
return _expectEitherErrorAsync(p, constants.REVERT, otherError);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rejects if the given Promise does not reject with a "revert" or "always
|
|
||||||
* failing transaction" error.
|
|
||||||
* @param p the Promise which is expected to reject
|
|
||||||
* @returns a new Promise which will reject if the conditions are not met and
|
|
||||||
* otherwise resolve with no value.
|
|
||||||
*/
|
|
||||||
export function expectRevertOrAlwaysFailingTransactionAsync<T>(p: Promise<T>): PromiseLike<void> {
|
|
||||||
return expectRevertOrOtherErrorAsync(p, 'always failing transaction');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rejects if at least one the following conditions is not met:
|
|
||||||
* 1) The given Promise rejects with the given revert reason.
|
|
||||||
* 2) The given Promise rejects with an error containing "always failing transaction"
|
|
||||||
* 3) The given Promise fulfills with a txReceipt that has a status of 0 or '0', indicating the transaction failed.
|
|
||||||
* 4) The given Promise fulfills with a txHash and corresponding txReceipt has a status of 0 or '0'.
|
|
||||||
* @param p the Promise which is expected to reject
|
|
||||||
* @param reason a specific revert reason
|
* @param reason a specific revert reason
|
||||||
* @returns a new Promise which will reject if the conditions are not met and
|
* @returns a new Promise which will reject if the conditions are not met and
|
||||||
* otherwise resolve with no value.
|
* otherwise resolve with no value.
|
||||||
*/
|
*/
|
||||||
export async function expectRevertReasonOrAlwaysFailingTransactionAsync(
|
export async function expectTransactionFailedAsync(p: sendTransactionResult, reason: RevertReason): Promise<void> {
|
||||||
p: Promise<string | TransactionReceiptWithDecodedLogs | TransactionReceipt>,
|
// HACK(albrow): This dummy `catch` should not be necessary, but if you
|
||||||
reason: RevertReason,
|
// remove it, there is an uncaught exception and the Node process will
|
||||||
): Promise<void> {
|
// forcibly exit. It's possible this is a false positive in
|
||||||
|
// make-promises-safe.
|
||||||
|
p.catch(e => {
|
||||||
|
_.noop(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_.isUndefined(nodeType)) {
|
||||||
|
nodeType = await web3Wrapper.getNodeTypeAsync();
|
||||||
|
}
|
||||||
|
switch (nodeType) {
|
||||||
|
case NodeType.Ganache:
|
||||||
|
return expect(p).to.be.rejectedWith(reason);
|
||||||
|
case NodeType.Geth:
|
||||||
|
logUtils.warn(
|
||||||
|
'WARNING: Geth does not support revert reasons for sendTransaction. This test will pass if the transaction fails for any reason.',
|
||||||
|
);
|
||||||
|
return expectTransactionFailedWithoutReasonAsync(p);
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown node type: ${nodeType}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves if the transaction fails without a revert reason, or if the
|
||||||
|
* corresponding transactionReceipt has a status of 0 or '0', indicating
|
||||||
|
* failure.
|
||||||
|
* @param p a Promise resulting from a sendTransaction call
|
||||||
|
* @returns a new Promise which will reject if the conditions are not met and
|
||||||
|
* otherwise resolve with no value.
|
||||||
|
*/
|
||||||
|
export async function expectTransactionFailedWithoutReasonAsync(p: sendTransactionResult): Promise<void> {
|
||||||
return p
|
return p
|
||||||
.then(async result => {
|
.then(async result => {
|
||||||
let txReceiptStatus: string | 0 | 1 | null;
|
let txReceiptStatus: TransactionReceiptStatus;
|
||||||
if (typeof result === 'string') {
|
if (_.isString(result)) {
|
||||||
// Result is a txHash. We need to make a web3 call to get the receipt.
|
// Result is a txHash. We need to make a web3 call to get the
|
||||||
|
// receipt, then get the status from the receipt.
|
||||||
const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(result);
|
const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(result);
|
||||||
txReceiptStatus = txReceipt.status;
|
txReceiptStatus = txReceipt.status;
|
||||||
} else if ('status' in result) {
|
} else if ('status' in result) {
|
||||||
// Result is a TransactionReceiptWithDecodedLogs or TransactionReceipt
|
// Result is a transaction receipt, so we can get the status
|
||||||
// and status is a field of result.
|
// directly.
|
||||||
txReceiptStatus = result.status;
|
txReceiptStatus = result.status;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unexpected result type');
|
throw new Error('Unexpected result type: ' + typeof result);
|
||||||
}
|
}
|
||||||
expect(_.toString(txReceiptStatus)).to.equal(
|
expect(_.toString(txReceiptStatus)).to.equal(
|
||||||
'0',
|
'0',
|
||||||
'transactionReceipt had a non-zero status, indicating success',
|
'Expected transaction to fail but receipt had a non-zero status, indicating success',
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(async err => {
|
||||||
expect(err.message).to.satisfy(
|
// If the promise rejects, we expect a specific error message,
|
||||||
(msg: string) => _.includes(msg, reason) || _.includes(msg, 'always failing transaction'),
|
// depending on the backing Ethereum node type.
|
||||||
`Expected ${reason} or 'always failing transaction' but error message was ${err.message}`,
|
const errMessage = await _getTransactionFailedErrorMessageAsync();
|
||||||
);
|
expect(err.message).to.include(errMessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rejects if the given Promise does not reject with a "revert" or "Contract
|
* Resolves if the the contract call fails with the given revert reason.
|
||||||
* call failed" error.
|
* @param p a Promise resulting from a contract call
|
||||||
* @param p the Promise which is expected to reject
|
* @param reason a specific revert reason
|
||||||
* @returns a new Promise which will reject if the conditions are not met and
|
* @returns a new Promise which will reject if the conditions are not met and
|
||||||
* otherwise resolve with no value.
|
* otherwise resolve with no value.
|
||||||
*/
|
*/
|
||||||
export function expectRevertOrContractCallFailedAsync<T>(p: Promise<T>): PromiseLike<void> {
|
export async function expectContractCallFailed<T>(p: Promise<T>, reason: RevertReason): Promise<void> {
|
||||||
return expectRevertOrOtherErrorAsync<T>(p, 'Contract call failed');
|
return expect(p).to.be.rejectedWith(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves if the contract call fails without a revert reason.
|
||||||
|
* @param p a Promise resulting from a contract call
|
||||||
|
* @returns a new Promise which will reject if the conditions are not met and
|
||||||
|
* otherwise resolve with no value.
|
||||||
|
*/
|
||||||
|
export async function expectContractCallFailedWithoutReasonAsync<T>(p: Promise<T>): Promise<void> {
|
||||||
|
const errMessage = await _getContractCallFailedErrorMessageAsync();
|
||||||
|
return expect(p).to.be.rejectedWith(errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves if the contract creation/deployment fails without a revert reason.
|
||||||
|
* @param p a Promise resulting from a contract creation/deployment
|
||||||
|
* @returns a new Promise which will reject if the conditions are not met and
|
||||||
|
* otherwise resolve with no value.
|
||||||
|
*/
|
||||||
|
export async function expectContractCreationFailedWithoutReason<T>(p: Promise<T>): Promise<void> {
|
||||||
|
const errMessage = await _getTransactionFailedErrorMessageAsync();
|
||||||
|
return expect(p).to.be.rejectedWith(errMessage);
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@ const TESTRPC_PRIVATE_KEYS_STRINGS = [
|
|||||||
|
|
||||||
export const constants = {
|
export const constants = {
|
||||||
INVALID_OPCODE: 'invalid opcode',
|
INVALID_OPCODE: 'invalid opcode',
|
||||||
REVERT: 'revert',
|
|
||||||
TESTRPC_NETWORK_ID: 50,
|
TESTRPC_NETWORK_ID: 50,
|
||||||
// Note(albrow): In practice V8 and most other engines limit the minimum
|
// Note(albrow): In practice V8 and most other engines limit the minimum
|
||||||
// interval for setInterval to 10ms. We still set it to 0 here in order to
|
// interval for setInterval to 10ms. We still set it to 0 here in order to
|
||||||
|
@@ -17,7 +17,7 @@ import 'make-promises-safe';
|
|||||||
import { ExchangeContract, FillContractEventArgs } from '../../generated_contract_wrappers/exchange';
|
import { ExchangeContract, FillContractEventArgs } from '../../generated_contract_wrappers/exchange';
|
||||||
|
|
||||||
import { artifacts } from './artifacts';
|
import { artifacts } from './artifacts';
|
||||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from './assertions';
|
import { expectTransactionFailedAsync } from './assertions';
|
||||||
import { AssetWrapper } from './asset_wrapper';
|
import { AssetWrapper } from './asset_wrapper';
|
||||||
import { chaiSetup } from './chai_setup';
|
import { chaiSetup } from './chai_setup';
|
||||||
import { constants } from './constants';
|
import { constants } from './constants';
|
||||||
@@ -418,7 +418,7 @@ export class CoreCombinatorialUtils {
|
|||||||
fillRevertReasonIfExists: RevertReason | undefined,
|
fillRevertReasonIfExists: RevertReason | undefined,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!_.isUndefined(fillRevertReasonIfExists)) {
|
if (!_.isUndefined(fillRevertReasonIfExists)) {
|
||||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
return expectTransactionFailedAsync(
|
||||||
this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount }),
|
this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount }),
|
||||||
fillRevertReasonIfExists,
|
fillRevertReasonIfExists,
|
||||||
);
|
);
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
import { logUtils } from '@0xproject/utils';
|
import { logUtils } from '@0xproject/utils';
|
||||||
import { uniqueVersionIds, Web3Wrapper } from '@0xproject/web3-wrapper';
|
import { NodeType, Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import { includes } from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
enum NodeType {
|
|
||||||
Geth = 'GETH',
|
|
||||||
Ganache = 'GANACHE',
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK(albrow): 🐉 We have to do this so that debug.setHead works correctly.
|
// HACK(albrow): 🐉 We have to do this so that debug.setHead works correctly.
|
||||||
// (Geth does not seem to like debug.setHead(0), so by sending some transactions
|
// (Geth does not seem to like debug.setHead(0), so by sending some transactions
|
||||||
@@ -18,6 +13,7 @@ export class BlockchainLifecycle {
|
|||||||
private _web3Wrapper: Web3Wrapper;
|
private _web3Wrapper: Web3Wrapper;
|
||||||
private _snapshotIdsStack: number[];
|
private _snapshotIdsStack: number[];
|
||||||
private _addresses: string[] = [];
|
private _addresses: string[] = [];
|
||||||
|
private _nodeType: NodeType | undefined;
|
||||||
constructor(web3Wrapper: Web3Wrapper) {
|
constructor(web3Wrapper: Web3Wrapper) {
|
||||||
this._web3Wrapper = web3Wrapper;
|
this._web3Wrapper = web3Wrapper;
|
||||||
this._snapshotIdsStack = [];
|
this._snapshotIdsStack = [];
|
||||||
@@ -61,16 +57,6 @@ export class BlockchainLifecycle {
|
|||||||
throw new Error(`Unknown node type: ${nodeType}`);
|
throw new Error(`Unknown node type: ${nodeType}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async _getNodeTypeAsync(): Promise<NodeType> {
|
|
||||||
const version = await this._web3Wrapper.getNodeVersionAsync();
|
|
||||||
if (includes(version, uniqueVersionIds.geth)) {
|
|
||||||
return NodeType.Geth;
|
|
||||||
} else if (includes(version, uniqueVersionIds.ganache)) {
|
|
||||||
return NodeType.Ganache;
|
|
||||||
} else {
|
|
||||||
throw new Error(`Unknown client version: ${version}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private async _mineMinimumBlocksAsync(): Promise<void> {
|
private async _mineMinimumBlocksAsync(): Promise<void> {
|
||||||
logUtils.warn('WARNING: minimum block number for tests not met. Mining additional blocks...');
|
logUtils.warn('WARNING: minimum block number for tests not met. Mining additional blocks...');
|
||||||
if (this._addresses.length === 0) {
|
if (this._addresses.length === 0) {
|
||||||
@@ -92,4 +78,10 @@ export class BlockchainLifecycle {
|
|||||||
}
|
}
|
||||||
logUtils.warn('Done mining the minimum number of blocks.');
|
logUtils.warn('Done mining the minimum number of blocks.');
|
||||||
}
|
}
|
||||||
|
private async _getNodeTypeAsync(): Promise<NodeType> {
|
||||||
|
if (_.isUndefined(this._nodeType)) {
|
||||||
|
this._nodeType = await this._web3Wrapper.getNodeTypeAsync();
|
||||||
|
}
|
||||||
|
return this._nodeType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Add `TraceParams` interface for `debug_traceTransaction` parameters",
|
"note": "Add `TraceParams` interface for `debug_traceTransaction` parameters",
|
||||||
"pr": 675
|
"pr": 675
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `TransactionReceiptStatus` type",
|
||||||
|
"pr": 812
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@@ -215,6 +215,8 @@ export interface TxDataPayable extends TxData {
|
|||||||
value?: BigNumber;
|
value?: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TransactionReceiptStatus = null | string | 0 | 1;
|
||||||
|
|
||||||
export interface TransactionReceipt {
|
export interface TransactionReceipt {
|
||||||
blockHash: string;
|
blockHash: string;
|
||||||
blockNumber: number;
|
blockNumber: number;
|
||||||
@@ -222,7 +224,7 @@ export interface TransactionReceipt {
|
|||||||
transactionIndex: number;
|
transactionIndex: number;
|
||||||
from: string;
|
from: string;
|
||||||
to: string;
|
to: string;
|
||||||
status: null | string | 0 | 1;
|
status: TransactionReceiptStatus;
|
||||||
cumulativeGasUsed: number;
|
cumulativeGasUsed: number;
|
||||||
gasUsed: number;
|
gasUsed: number;
|
||||||
contractAddress: string | null;
|
contractAddress: string | null;
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -1,7 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
BalanceAndProxyAllowanceLazyStore,
|
BalanceAndProxyAllowanceLazyStore,
|
||||||
ContractWrappers,
|
ContractWrappers,
|
||||||
|
LogCancelContractEventArgs,
|
||||||
|
LogFillContractEventArgs,
|
||||||
OrderFilledCancelledLazyStore,
|
OrderFilledCancelledLazyStore,
|
||||||
|
WithdrawalContractEventArgs,
|
||||||
} from '@0xproject/contract-wrappers';
|
} from '@0xproject/contract-wrappers';
|
||||||
import { schemas } from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import { getOrderHashHex, OrderStateUtils } from '@0xproject/order-utils';
|
import { getOrderHashHex, OrderStateUtils } from '@0xproject/order-utils';
|
||||||
@@ -23,14 +26,8 @@ import {
|
|||||||
DepositContractEventArgs,
|
DepositContractEventArgs,
|
||||||
EtherTokenContractEventArgs,
|
EtherTokenContractEventArgs,
|
||||||
EtherTokenEvents,
|
EtherTokenEvents,
|
||||||
WithdrawalContractEventArgs,
|
|
||||||
} from '../generated_contract_wrappers/ether_token';
|
} from '../generated_contract_wrappers/ether_token';
|
||||||
import {
|
import { ExchangeContractEventArgs, ExchangeEvents } from '../generated_contract_wrappers/exchange';
|
||||||
ExchangeContractEventArgs,
|
|
||||||
ExchangeEvents,
|
|
||||||
LogCancelContractEventArgs,
|
|
||||||
LogFillContractEventArgs,
|
|
||||||
} from '../generated_contract_wrappers/exchange';
|
|
||||||
import {
|
import {
|
||||||
ApprovalContractEventArgs,
|
ApprovalContractEventArgs,
|
||||||
TokenContractEventArgs,
|
TokenContractEventArgs,
|
||||||
@@ -301,6 +298,7 @@ export class OrderWatcher {
|
|||||||
}
|
}
|
||||||
case EtherTokenEvents.Withdrawal: {
|
case EtherTokenEvents.Withdrawal: {
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
|
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||||
const args = decodedLog.args as WithdrawalContractEventArgs;
|
const args = decodedLog.args as WithdrawalContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
@@ -317,6 +315,7 @@ export class OrderWatcher {
|
|||||||
}
|
}
|
||||||
case ExchangeEvents.LogFill: {
|
case ExchangeEvents.LogFill: {
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
|
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||||
const args = decodedLog.args as LogFillContractEventArgs;
|
const args = decodedLog.args as LogFillContractEventArgs;
|
||||||
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash);
|
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
@@ -329,6 +328,7 @@ export class OrderWatcher {
|
|||||||
}
|
}
|
||||||
case ExchangeEvents.LogCancel: {
|
case ExchangeEvents.LogCancel: {
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
|
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||||
const args = decodedLog.args as LogCancelContractEventArgs;
|
const args = decodedLog.args as LogCancelContractEventArgs;
|
||||||
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash);
|
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
|
@@ -1,4 +1,12 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "0.11.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `EthLightwalletSubprovider`"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1529397769,
|
"timestamp": 1529397769,
|
||||||
"version": "0.10.4",
|
"version": "0.10.4",
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0xproject/assert": "^0.2.12",
|
"@0xproject/assert": "^0.2.12",
|
||||||
"@0xproject/types": "^0.8.1",
|
"@0xproject/types": "^1.0.0",
|
||||||
"@0xproject/web3-wrapper": "^0.7.1",
|
"@0xproject/web3-wrapper": "^0.7.1",
|
||||||
"@0xproject/typescript-typings": "^0.4.2",
|
"@0xproject/typescript-typings": "^0.4.2",
|
||||||
"@0xproject/utils": "^0.7.1",
|
"@0xproject/utils": "^0.7.1",
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
"ethereum-types": "^0.0.2",
|
"ethereum-types": "^0.0.2",
|
||||||
"bip39": "^2.5.0",
|
"bip39": "^2.5.0",
|
||||||
"bn.js": "^4.11.8",
|
"bn.js": "^4.11.8",
|
||||||
|
"eth-lightwallet": "^3.0.1",
|
||||||
"ethereumjs-tx": "^1.3.5",
|
"ethereumjs-tx": "^1.3.5",
|
||||||
"ethereumjs-util": "^5.1.1",
|
"ethereumjs-util": "^5.1.1",
|
||||||
"ganache-core": "0xProject/ganache-core",
|
"ganache-core": "0xProject/ganache-core",
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
"@types/node": "^8.0.53",
|
"@types/node": "^8.0.53",
|
||||||
|
"@types/sinon": "^2.2.2",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"copyfiles": "^1.2.0",
|
"copyfiles": "^1.2.0",
|
||||||
@@ -78,6 +80,7 @@
|
|||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"nyc": "^11.0.1",
|
"nyc": "^11.0.1",
|
||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
|
"sinon": "^4.0.0",
|
||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"typedoc": "0xProject/typedoc",
|
"typedoc": "0xProject/typedoc",
|
||||||
"typescript": "2.7.1",
|
"typescript": "2.7.1",
|
||||||
|
5
packages/subproviders/src/globals.d.ts
vendored
5
packages/subproviders/src/globals.d.ts
vendored
@@ -1,8 +1,3 @@
|
|||||||
// tslint:disable:max-classes-per-file
|
|
||||||
// tslint:disable:class-name
|
|
||||||
// tslint:disable:async-suffix
|
|
||||||
// tslint:disable:completed-docs
|
|
||||||
|
|
||||||
declare module '*.json' {
|
declare module '*.json' {
|
||||||
const json: any;
|
const json: any;
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
@@ -15,6 +15,7 @@ export { Subprovider } from './subproviders/subprovider';
|
|||||||
export { NonceTrackerSubprovider } from './subproviders/nonce_tracker';
|
export { NonceTrackerSubprovider } from './subproviders/nonce_tracker';
|
||||||
export { PrivateKeyWalletSubprovider } from './subproviders/private_key_wallet';
|
export { PrivateKeyWalletSubprovider } from './subproviders/private_key_wallet';
|
||||||
export { MnemonicWalletSubprovider } from './subproviders/mnemonic_wallet';
|
export { MnemonicWalletSubprovider } from './subproviders/mnemonic_wallet';
|
||||||
|
export { EthLightwalletSubprovider } from './subproviders/eth_lightwallet_subprovider';
|
||||||
export {
|
export {
|
||||||
Callback,
|
Callback,
|
||||||
ErrorCallback,
|
ErrorCallback,
|
||||||
|
@@ -0,0 +1,68 @@
|
|||||||
|
import * as lightwallet from 'eth-lightwallet';
|
||||||
|
|
||||||
|
import { PartialTxParams } from '../types';
|
||||||
|
|
||||||
|
import { BaseWalletSubprovider } from './base_wallet_subprovider';
|
||||||
|
import { PrivateKeyWalletSubprovider } from './private_key_wallet';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This class implements the web3-provider-engine subprovider interface and forwards
|
||||||
|
* requests involving user accounts and signing operations to eth-lightwallet
|
||||||
|
*
|
||||||
|
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||||
|
*/
|
||||||
|
export class EthLightwalletSubprovider extends BaseWalletSubprovider {
|
||||||
|
private _keystore: lightwallet.keystore;
|
||||||
|
private _pwDerivedKey: Uint8Array;
|
||||||
|
constructor(keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) {
|
||||||
|
super();
|
||||||
|
this._keystore = keystore;
|
||||||
|
this._pwDerivedKey = pwDerivedKey;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Retrieve the accounts associated with the eth-lightwallet instance.
|
||||||
|
* This method is implicitly called when issuing a `eth_accounts` JSON RPC request
|
||||||
|
* via your providerEngine instance.
|
||||||
|
*
|
||||||
|
* @return An array of accounts
|
||||||
|
*/
|
||||||
|
public async getAccountsAsync(): Promise<string[]> {
|
||||||
|
const accounts = this._keystore.getAddresses();
|
||||||
|
return accounts;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Signs a transaction with the account specificed by the `from` field in txParams.
|
||||||
|
* If you've added this Subprovider to your app's provider, you can simply send
|
||||||
|
* an `eth_sendTransaction` JSON RPC request, and this method will be called auto-magically.
|
||||||
|
* If you are not using this via a ProviderEngine instance, you can call it directly.
|
||||||
|
* @param txParams Parameters of the transaction to sign
|
||||||
|
* @return Signed transaction hex string
|
||||||
|
*/
|
||||||
|
public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
|
||||||
|
// Lightwallet loses the chain id information when hex encoding the transaction
|
||||||
|
// this results in a different signature on certain networks. PrivateKeyWallet
|
||||||
|
// respects this as it uses the parameters passed in
|
||||||
|
let privKey = this._keystore.exportPrivateKey(txParams.from, this._pwDerivedKey);
|
||||||
|
const privKeyWallet = new PrivateKeyWalletSubprovider(privKey);
|
||||||
|
privKey = '';
|
||||||
|
const privKeySignature = await privKeyWallet.signTransactionAsync(txParams);
|
||||||
|
return privKeySignature;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sign a personal Ethereum signed message. The signing account will be the account
|
||||||
|
* associated with the provided address.
|
||||||
|
* If you've added the MnemonicWalletSubprovider to your app's provider, you can simply send an `eth_sign`
|
||||||
|
* or `personal_sign` JSON RPC request, and this method will be called auto-magically.
|
||||||
|
* If you are not using this via a ProviderEngine instance, you can call it directly.
|
||||||
|
* @param data Hex string message to sign
|
||||||
|
* @param address Address of the account to sign with
|
||||||
|
* @return Signature hex string (order: rsv)
|
||||||
|
*/
|
||||||
|
public async signPersonalMessageAsync(data: string, address: string): Promise<string> {
|
||||||
|
let privKey = this._keystore.exportPrivateKey(address, this._pwDerivedKey);
|
||||||
|
const privKeyWallet = new PrivateKeyWalletSubprovider(privKey);
|
||||||
|
privKey = '';
|
||||||
|
const result = privKeyWallet.signPersonalMessageAsync(data, address);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,167 @@
|
|||||||
|
import * as chai from 'chai';
|
||||||
|
import * as lightwallet from 'eth-lightwallet';
|
||||||
|
import { JSONRPCResponsePayload } from 'ethereum-types';
|
||||||
|
import * as ethUtils from 'ethereumjs-util';
|
||||||
|
import Web3ProviderEngine = require('web3-provider-engine');
|
||||||
|
|
||||||
|
import { EthLightwalletSubprovider } from '../../src';
|
||||||
|
import { DoneCallback } from '../../src/types';
|
||||||
|
import { chaiSetup } from '../chai_setup';
|
||||||
|
import { fixtureData } from '../utils/fixture_data';
|
||||||
|
import { ganacheSubprovider } from '../utils/ganache_subprovider';
|
||||||
|
import { reportCallbackErrors } from '../utils/report_callback_errors';
|
||||||
|
|
||||||
|
chaiSetup.configure();
|
||||||
|
const expect = chai.expect;
|
||||||
|
|
||||||
|
const DEFAULT_NUM_ACCOUNTS = 10;
|
||||||
|
const PASSWORD = 'supersecretpassword99';
|
||||||
|
const SALT = 'kvODghzs7Ff1uqHyI0P3wI4Hso4w4iWT2e9qmrWz0y4';
|
||||||
|
|
||||||
|
describe('EthLightwalletSubprovider', () => {
|
||||||
|
let ethLightwalletSubprovider: EthLightwalletSubprovider;
|
||||||
|
before(async () => {
|
||||||
|
const options = {
|
||||||
|
password: PASSWORD,
|
||||||
|
seedPhrase: fixtureData.TEST_RPC_MNEMONIC,
|
||||||
|
salt: SALT,
|
||||||
|
hdPathString: fixtureData.TESTRPC_BASE_DERIVATION_PATH,
|
||||||
|
};
|
||||||
|
const createVaultAsync = async (vaultOptions: lightwallet.VaultOptions) => {
|
||||||
|
return new Promise<lightwallet.keystore>(resolve => {
|
||||||
|
lightwallet.keystore.createVault(vaultOptions, (err: Error, vaultKeystore) => {
|
||||||
|
if (err) {
|
||||||
|
throw new Error(`Failed to createVault: ${err}`);
|
||||||
|
}
|
||||||
|
resolve(vaultKeystore);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const deriveKeyFromPasswordAsync = async (vaultKeystore: lightwallet.keystore) => {
|
||||||
|
return new Promise<Uint8Array>(resolve => {
|
||||||
|
vaultKeystore.keyFromPassword(PASSWORD, (err: Error, passwordDerivedKey: Uint8Array) => {
|
||||||
|
if (err) {
|
||||||
|
throw new Error(`Failed to get key from password: ${err}`);
|
||||||
|
}
|
||||||
|
resolve(passwordDerivedKey);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const keystore: lightwallet.keystore = await createVaultAsync(options);
|
||||||
|
const pwDerivedKey: Uint8Array = await deriveKeyFromPasswordAsync(keystore);
|
||||||
|
|
||||||
|
// Generate 10 addresses
|
||||||
|
keystore.generateNewAddress(pwDerivedKey, DEFAULT_NUM_ACCOUNTS);
|
||||||
|
|
||||||
|
ethLightwalletSubprovider = new EthLightwalletSubprovider(keystore, pwDerivedKey);
|
||||||
|
});
|
||||||
|
describe('direct method calls', () => {
|
||||||
|
describe('success cases', () => {
|
||||||
|
it('returns a list of accounts', async () => {
|
||||||
|
const accounts = await ethLightwalletSubprovider.getAccountsAsync();
|
||||||
|
expect(accounts[0]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_0);
|
||||||
|
expect(accounts[1]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_1);
|
||||||
|
expect(accounts.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
|
||||||
|
});
|
||||||
|
it('signs a personal message hash', async () => {
|
||||||
|
const accounts = await ethLightwalletSubprovider.getAccountsAsync();
|
||||||
|
const signingAccount = accounts[0];
|
||||||
|
const data = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING));
|
||||||
|
const ecSignatureHex = await ethLightwalletSubprovider.signPersonalMessageAsync(data, signingAccount);
|
||||||
|
expect(ecSignatureHex).to.be.equal(fixtureData.PERSONAL_MESSAGE_SIGNED_RESULT);
|
||||||
|
});
|
||||||
|
it('signs a transaction', async () => {
|
||||||
|
const txHex = await ethLightwalletSubprovider.signTransactionAsync(fixtureData.TX_DATA);
|
||||||
|
expect(txHex).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('calls through a provider', () => {
|
||||||
|
let provider: Web3ProviderEngine;
|
||||||
|
before(() => {
|
||||||
|
provider = new Web3ProviderEngine();
|
||||||
|
provider.addProvider(ethLightwalletSubprovider);
|
||||||
|
provider.addProvider(ganacheSubprovider);
|
||||||
|
provider.start();
|
||||||
|
});
|
||||||
|
describe('success cases', () => {
|
||||||
|
it('returns a list of accounts', (done: DoneCallback) => {
|
||||||
|
const payload = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'eth_accounts',
|
||||||
|
params: [],
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
|
||||||
|
expect(err).to.be.a('null');
|
||||||
|
expect(response.result[0]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_0);
|
||||||
|
expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
provider.sendAsync(payload, callback);
|
||||||
|
});
|
||||||
|
it('signs a personal message hash with eth_sign', (done: DoneCallback) => {
|
||||||
|
const data = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING));
|
||||||
|
const account = fixtureData.TEST_RPC_ACCOUNT_0;
|
||||||
|
const payload = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'eth_sign',
|
||||||
|
params: [account, data],
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
|
||||||
|
expect(err).to.be.a('null');
|
||||||
|
expect(response.result).to.be.equal(fixtureData.PERSONAL_MESSAGE_SIGNED_RESULT);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
provider.sendAsync(payload, callback);
|
||||||
|
});
|
||||||
|
it('signs a transaction', (done: DoneCallback) => {
|
||||||
|
const payload = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'eth_signTransaction',
|
||||||
|
params: [fixtureData.TX_DATA],
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
|
||||||
|
expect(err).to.be.a('null');
|
||||||
|
expect(response.result.raw).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
provider.sendAsync(payload, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('failure cases', () => {
|
||||||
|
it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => {
|
||||||
|
const nonHexMessage = 'hello world';
|
||||||
|
const payload = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'eth_sign',
|
||||||
|
params: [fixtureData.TEST_RPC_ACCOUNT_0, nonHexMessage],
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
const callback = reportCallbackErrors(done)((err: Error, _response: JSONRPCResponsePayload) => {
|
||||||
|
expect(err).to.not.be.a('null');
|
||||||
|
expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
provider.sendAsync(payload, callback);
|
||||||
|
});
|
||||||
|
it('should throw if `data` param not hex when calling personal_sign', (done: DoneCallback) => {
|
||||||
|
const nonHexMessage = 'hello world';
|
||||||
|
const payload = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'personal_sign',
|
||||||
|
params: [nonHexMessage, fixtureData.TEST_RPC_ACCOUNT_0],
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
const callback = reportCallbackErrors(done)((err: Error, _response: JSONRPCResponsePayload) => {
|
||||||
|
expect(err).to.not.be.a('null');
|
||||||
|
expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
provider.sendAsync(payload, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -60,6 +60,20 @@ describe('PrivateKeyWalletSubprovider', () => {
|
|||||||
});
|
});
|
||||||
provider.sendAsync(payload, callback);
|
provider.sendAsync(payload, callback);
|
||||||
});
|
});
|
||||||
|
it('signs a transaction', (done: DoneCallback) => {
|
||||||
|
const payload = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'eth_signTransaction',
|
||||||
|
params: [fixtureData.TX_DATA],
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
|
||||||
|
expect(err).to.be.a('null');
|
||||||
|
expect(response.result.raw).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
provider.sendAsync(payload, callback);
|
||||||
|
});
|
||||||
it('signs a personal message with eth_sign', (done: DoneCallback) => {
|
it('signs a personal message with eth_sign', (done: DoneCallback) => {
|
||||||
const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING));
|
const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING));
|
||||||
const payload = {
|
const payload = {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { DoneCallback } from '@0xproject/types';
|
import { DoneCallback } from '@0xproject/types';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import { JSONRPCResponsePayload } from 'ethereum-types';
|
import { JSONRPCResponsePayload } from 'ethereum-types';
|
||||||
|
import * as Sinon from 'sinon';
|
||||||
import Web3ProviderEngine = require('web3-provider-engine');
|
import Web3ProviderEngine = require('web3-provider-engine');
|
||||||
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
||||||
|
|
||||||
@@ -41,6 +42,9 @@ describe('RedundantSubprovider', () => {
|
|||||||
const nonExistentSubprovider = new RpcSubprovider({
|
const nonExistentSubprovider = new RpcSubprovider({
|
||||||
rpcUrl: 'http://does-not-exist:3000',
|
rpcUrl: 'http://does-not-exist:3000',
|
||||||
});
|
});
|
||||||
|
const handleRequestStub = Sinon.stub(nonExistentSubprovider, 'handleRequest').throws(
|
||||||
|
new Error('REQUEST_FAILED'),
|
||||||
|
);
|
||||||
const subproviders = [nonExistentSubprovider as Subprovider, ganacheSubprovider];
|
const subproviders = [nonExistentSubprovider as Subprovider, ganacheSubprovider];
|
||||||
const redundantSubprovider = new RedundantSubprovider(subproviders);
|
const redundantSubprovider = new RedundantSubprovider(subproviders);
|
||||||
provider.addProvider(redundantSubprovider);
|
provider.addProvider(redundantSubprovider);
|
||||||
@@ -55,6 +59,7 @@ describe('RedundantSubprovider', () => {
|
|||||||
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
|
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
|
||||||
expect(err).to.be.a('null');
|
expect(err).to.be.a('null');
|
||||||
expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
|
expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
|
||||||
|
handleRequestStub.restore();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
provider.sendAsync(payload, callback);
|
provider.sendAsync(payload, callback);
|
||||||
|
@@ -4,6 +4,9 @@
|
|||||||
"changes": [
|
"changes": [
|
||||||
{
|
{
|
||||||
"notes": "Updated types for V2 of 0x protocol"
|
"notes": "Updated types for V2 of 0x protocol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `ECSignatureBuffer`"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@@ -48,6 +48,12 @@ export interface ECSignature {
|
|||||||
s: string;
|
s: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ECSignatureBuffer {
|
||||||
|
v: number;
|
||||||
|
r: Buffer;
|
||||||
|
s: Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validator signature components
|
* Validator signature components
|
||||||
*/
|
*/
|
||||||
|
@@ -2,6 +2,10 @@
|
|||||||
{
|
{
|
||||||
"version": "0.4.2",
|
"version": "0.4.2",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add types for `eth-lightwallet`",
|
||||||
|
"pr": 775
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"note": "Improve 'web3-provider-engine' typings",
|
"note": "Improve 'web3-provider-engine' typings",
|
||||||
"pr": 768
|
"pr": 768
|
||||||
|
50
packages/typescript-typings/types/eth-lightwallet/index.d.ts
vendored
Normal file
50
packages/typescript-typings/types/eth-lightwallet/index.d.ts
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// eth-lightwallet declarations
|
||||||
|
declare module 'eth-lightwallet' {
|
||||||
|
import { ECSignatureBuffer } from '@0xproject/types';
|
||||||
|
|
||||||
|
// tslint:disable-next-line:class-name
|
||||||
|
export class signing {
|
||||||
|
public static signTx(
|
||||||
|
keystore: keystore,
|
||||||
|
pwDerivedKey: Uint8Array,
|
||||||
|
rawTx: string,
|
||||||
|
signingAddress: string,
|
||||||
|
): string;
|
||||||
|
public static signMsg(
|
||||||
|
keystore: keystore,
|
||||||
|
pwDerivedKey: Uint8Array,
|
||||||
|
rawMsg: string,
|
||||||
|
signingAddress: string,
|
||||||
|
): ECSignatureBuffer;
|
||||||
|
public static signMsgHash(
|
||||||
|
keystore: keystore,
|
||||||
|
pwDerivedKey: Uint8Array,
|
||||||
|
msgHash: string,
|
||||||
|
signingAddress: string,
|
||||||
|
): ECSignatureBuffer;
|
||||||
|
public static concatSig(signature: any): string;
|
||||||
|
}
|
||||||
|
// tslint:disable-next-line:class-name
|
||||||
|
export class keystore {
|
||||||
|
public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore;
|
||||||
|
public static generateRandomSeed(): string;
|
||||||
|
public static isSeedValid(seed: string): boolean;
|
||||||
|
public static deserialize(keystore: string): keystore;
|
||||||
|
public serialize(): string;
|
||||||
|
public keyFromPassword(
|
||||||
|
password: string,
|
||||||
|
callback?: (error: Error, pwDerivedKey: Uint8Array) => void,
|
||||||
|
): Uint8Array;
|
||||||
|
public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean;
|
||||||
|
public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void;
|
||||||
|
public getSeed(pwDerivedKey: Uint8Array): string;
|
||||||
|
public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string;
|
||||||
|
public getAddresses(): string[];
|
||||||
|
}
|
||||||
|
interface VaultOptions {
|
||||||
|
password: string;
|
||||||
|
seedPhrase: string;
|
||||||
|
salt?: string;
|
||||||
|
hdPathString: string;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,14 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1529397769,
|
||||||
|
"version": "0.7.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `getNodeTypeAsync` method",
|
||||||
|
"pr": 812
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1529397769,
|
"timestamp": 1529397769,
|
||||||
"version": "0.7.1",
|
"version": "0.7.1",
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
export { Web3Wrapper, uniqueVersionIds } from './web3_wrapper';
|
export { Web3Wrapper, uniqueVersionIds, NodeType } from './web3_wrapper';
|
||||||
export { Web3WrapperErrors } from './types';
|
export { Web3WrapperErrors } from './types';
|
||||||
|
@@ -31,6 +31,12 @@ export const uniqueVersionIds = {
|
|||||||
ganache: 'EthereumJS TestRPC',
|
ganache: 'EthereumJS TestRPC',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NodeType represents the type of the backing Ethereum node.
|
||||||
|
export enum NodeType {
|
||||||
|
Geth = 'GETH',
|
||||||
|
Ganache = 'GANACHE',
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around the Web3.js 0.x library that provides a consistent, clean promise-based interface.
|
* A wrapper around the Web3.js 0.x library that provides a consistent, clean promise-based interface.
|
||||||
*/
|
*/
|
||||||
@@ -489,6 +495,20 @@ export class Web3Wrapper {
|
|||||||
public async setHeadAsync(blockNumber: number): Promise<void> {
|
public async setHeadAsync(blockNumber: number): Promise<void> {
|
||||||
await this._sendRawPayloadAsync<void>({ method: 'debug_setHead', params: [this._web3.toHex(blockNumber)] });
|
await this._sendRawPayloadAsync<void>({ method: 'debug_setHead', params: [this._web3.toHex(blockNumber)] });
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Returns either NodeType.Geth or NodeType.Ganache depending on the type of
|
||||||
|
* the backing Ethereum node. Throws for any other type of node.
|
||||||
|
*/
|
||||||
|
public async getNodeTypeAsync(): Promise<NodeType> {
|
||||||
|
const version = await this.getNodeVersionAsync();
|
||||||
|
if (_.includes(version, uniqueVersionIds.geth)) {
|
||||||
|
return NodeType.Geth;
|
||||||
|
} else if (_.includes(version, uniqueVersionIds.ganache)) {
|
||||||
|
return NodeType.Ganache;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unknown client version: ${version}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
private async _sendRawPayloadAsync<A>(payload: Partial<JSONRPCRequestPayload>): Promise<A> {
|
private async _sendRawPayloadAsync<A>(payload: Partial<JSONRPCRequestPayload>): Promise<A> {
|
||||||
const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
|
const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
|
||||||
const payloadWithDefaults = {
|
const payloadWithDefaults = {
|
||||||
|
@@ -70,7 +70,18 @@
|
|||||||
})(document, 'script', 'twitter-wjs');
|
})(document, 'script', 'twitter-wjs');
|
||||||
</script>
|
</script>
|
||||||
<!-- End Twitter SDK -->
|
<!-- End Twitter SDK -->
|
||||||
|
<!-- Hotjar Tracking Code for https://0xproject.com/ -->
|
||||||
|
<script>
|
||||||
|
(function (h, o, t, j, a, r) {
|
||||||
|
h.hj = h.hj || function () { (h.hj.q = h.hj.q || []).push(arguments) };
|
||||||
|
h._hjSettings = { hjid: 935597, hjsv: 6 };
|
||||||
|
a = o.getElementsByTagName('head')[0];
|
||||||
|
r = o.createElement('script'); r.async = 1;
|
||||||
|
r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
|
||||||
|
a.appendChild(r);
|
||||||
|
})(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
|
||||||
|
</script>
|
||||||
|
<!-- End Hotjar Tracking Code -->
|
||||||
<!-- Main -->
|
<!-- Main -->
|
||||||
<script type="text/javascript" crossorigin="anonymous" src="/bundle.js" charset="utf-8"></script>
|
<script type="text/javascript" crossorigin="anonymous" src="/bundle.js" charset="utf-8"></script>
|
||||||
</body>
|
</body>
|
||||||
|
@@ -39,7 +39,7 @@ export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
|
|||||||
borderRadius,
|
borderRadius,
|
||||||
}) => (
|
}) => (
|
||||||
<Island borderRadius={borderRadius}>
|
<Island borderRadius={borderRadius}>
|
||||||
<Container paddingRight="30px" paddingLeft="30px" maxWidth={350} paddingTop="15px" paddingBottom="15px">
|
<Container paddingRight="30px" paddingLeft="30px" paddingTop="15px" paddingBottom="15px">
|
||||||
<div className="flex flex-column">
|
<div className="flex flex-column">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<Title>{title}</Title>
|
<Title>{title}</Title>
|
||||||
|
@@ -6,13 +6,29 @@ import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboardi
|
|||||||
import { Animation } from 'ts/components/ui/animation';
|
import { Animation } from 'ts/components/ui/animation';
|
||||||
import { Container } from 'ts/components/ui/container';
|
import { Container } from 'ts/components/ui/container';
|
||||||
import { Overlay } from 'ts/components/ui/overlay';
|
import { Overlay } from 'ts/components/ui/overlay';
|
||||||
|
import { PointerDirection } from 'ts/components/ui/pointer';
|
||||||
import { zIndex } from 'ts/style/z_index';
|
import { zIndex } from 'ts/style/z_index';
|
||||||
|
|
||||||
export interface Step {
|
export interface FixedPositionSettings {
|
||||||
|
type: 'fixed';
|
||||||
|
top?: string;
|
||||||
|
bottom?: string;
|
||||||
|
left?: string;
|
||||||
|
right?: string;
|
||||||
|
pointerDirection?: PointerDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TargetPositionSettings {
|
||||||
|
type: 'target';
|
||||||
target: string;
|
target: string;
|
||||||
|
placement: Placement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Step {
|
||||||
|
// Provide either a CSS selector, or fixed position settings. Only applies to desktop.
|
||||||
|
position: TargetPositionSettings | FixedPositionSettings;
|
||||||
title?: string;
|
title?: string;
|
||||||
content: React.ReactNode;
|
content: React.ReactNode;
|
||||||
placement?: Placement;
|
|
||||||
shouldHideBackButton?: boolean;
|
shouldHideBackButton?: boolean;
|
||||||
shouldHideNextButton?: boolean;
|
shouldHideNextButton?: boolean;
|
||||||
continueButtonDisplay?: ContinueButtonDisplay;
|
continueButtonDisplay?: ContinueButtonDisplay;
|
||||||
@@ -40,18 +56,30 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let onboardingElement = null;
|
let onboardingElement = null;
|
||||||
|
const currentStep = this._getCurrentStep();
|
||||||
if (this.props.isMobile) {
|
if (this.props.isMobile) {
|
||||||
onboardingElement = <Animation type="easeUpFromBottom">{this._renderOnboardignCard()}</Animation>;
|
onboardingElement = <Animation type="easeUpFromBottom">{this._renderOnboardingCard()}</Animation>;
|
||||||
} else {
|
} else if (currentStep.position.type === 'target') {
|
||||||
|
const { placement, target } = currentStep.position;
|
||||||
onboardingElement = (
|
onboardingElement = (
|
||||||
<Popper
|
<Popper referenceElement={document.querySelector(target)} placement={placement} positionFixed={true}>
|
||||||
referenceElement={this._getElementForStep()}
|
|
||||||
placement={this._getCurrentStep().placement}
|
|
||||||
positionFixed={true}
|
|
||||||
>
|
|
||||||
{this._renderPopperChildren.bind(this)}
|
{this._renderPopperChildren.bind(this)}
|
||||||
</Popper>
|
</Popper>
|
||||||
);
|
);
|
||||||
|
} else if (currentStep.position.type === 'fixed') {
|
||||||
|
const { top, right, bottom, left, pointerDirection } = currentStep.position;
|
||||||
|
onboardingElement = (
|
||||||
|
<Container
|
||||||
|
position="fixed"
|
||||||
|
zIndex={zIndex.aboveOverlay}
|
||||||
|
top={top}
|
||||||
|
right={right}
|
||||||
|
bottom={bottom}
|
||||||
|
left={left}
|
||||||
|
>
|
||||||
|
{this._renderToolTip(pointerDirection)}
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (this.props.disableOverlay) {
|
if (this.props.disableOverlay) {
|
||||||
return onboardingElement;
|
return onboardingElement;
|
||||||
@@ -63,9 +91,6 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
private _getElementForStep(): Element {
|
|
||||||
return document.querySelector(this._getCurrentStep().target);
|
|
||||||
}
|
|
||||||
private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode {
|
private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode {
|
||||||
const customStyles = { zIndex: zIndex.aboveOverlay };
|
const customStyles = { zIndex: zIndex.aboveOverlay };
|
||||||
// On re-render, we want to re-center the popper.
|
// On re-render, we want to re-center the popper.
|
||||||
@@ -76,7 +101,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
private _renderToolTip(): React.ReactNode {
|
private _renderToolTip(pointerDirection?: PointerDirection): React.ReactNode {
|
||||||
const { steps, stepIndex } = this.props;
|
const { steps, stepIndex } = this.props;
|
||||||
const step = steps[stepIndex];
|
const step = steps[stepIndex];
|
||||||
const isLastStep = steps.length - 1 === stepIndex;
|
const isLastStep = steps.length - 1 === stepIndex;
|
||||||
@@ -94,12 +119,13 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
continueButtonDisplay={step.continueButtonDisplay}
|
continueButtonDisplay={step.continueButtonDisplay}
|
||||||
continueButtonText={step.continueButtonText}
|
continueButtonText={step.continueButtonText}
|
||||||
onContinueButtonClick={step.onContinueButtonClick}
|
onContinueButtonClick={step.onContinueButtonClick}
|
||||||
|
pointerDirection={pointerDirection}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderOnboardignCard(): React.ReactNode {
|
private _renderOnboardingCard(): React.ReactNode {
|
||||||
const { steps, stepIndex } = this.props;
|
const { steps, stepIndex } = this.props;
|
||||||
const step = steps[stepIndex];
|
const step = steps[stepIndex];
|
||||||
const isLastStep = steps.length - 1 === stepIndex;
|
const isLastStep = steps.length - 1 === stepIndex;
|
||||||
|
@@ -9,7 +9,12 @@ import { AddEthOnboardingStep } from 'ts/components/onboarding/add_eth_onboardin
|
|||||||
import { CongratsOnboardingStep } from 'ts/components/onboarding/congrats_onboarding_step';
|
import { CongratsOnboardingStep } from 'ts/components/onboarding/congrats_onboarding_step';
|
||||||
import { InstallWalletOnboardingStep } from 'ts/components/onboarding/install_wallet_onboarding_step';
|
import { InstallWalletOnboardingStep } from 'ts/components/onboarding/install_wallet_onboarding_step';
|
||||||
import { IntroOnboardingStep } from 'ts/components/onboarding/intro_onboarding_step';
|
import { IntroOnboardingStep } from 'ts/components/onboarding/intro_onboarding_step';
|
||||||
import { OnboardingFlow, Step } from 'ts/components/onboarding/onboarding_flow';
|
import {
|
||||||
|
FixedPositionSettings,
|
||||||
|
OnboardingFlow,
|
||||||
|
Step,
|
||||||
|
TargetPositionSettings,
|
||||||
|
} from 'ts/components/onboarding/onboarding_flow';
|
||||||
import { SetAllowancesOnboardingStep } from 'ts/components/onboarding/set_allowances_onboarding_step';
|
import { SetAllowancesOnboardingStep } from 'ts/components/onboarding/set_allowances_onboarding_step';
|
||||||
import { UnlockWalletOnboardingStep } from 'ts/components/onboarding/unlock_wallet_onboarding_step';
|
import { UnlockWalletOnboardingStep } from 'ts/components/onboarding/unlock_wallet_onboarding_step';
|
||||||
import {
|
import {
|
||||||
@@ -45,8 +50,6 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
private _unlisten: () => void;
|
private _unlisten: () => void;
|
||||||
public componentDidMount(): void {
|
public componentDidMount(): void {
|
||||||
this._adjustStepIfShould();
|
this._adjustStepIfShould();
|
||||||
// Wait until the step is adjusted to decide whether we should show onboarding.
|
|
||||||
setTimeout(this._autoStartOnboardingIfShould.bind(this), 1000);
|
|
||||||
// If there is a route change, just close onboarding.
|
// If there is a route change, just close onboarding.
|
||||||
this._unlisten = this.props.history.listen(() => this.props.updateIsRunning(false));
|
this._unlisten = this.props.history.listen(() => this.props.updateIsRunning(false));
|
||||||
}
|
}
|
||||||
@@ -61,6 +64,9 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
document.querySelector('.wallet').scrollIntoView();
|
document.querySelector('.wallet').scrollIntoView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!prevProps.blockchainIsLoaded && this.props.blockchainIsLoaded) {
|
||||||
|
this._autoStartOnboardingIfShould();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
@@ -76,56 +82,61 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
private _getSteps(): Step[] {
|
private _getSteps(): Step[] {
|
||||||
|
const nextToWalletPosition: TargetPositionSettings = {
|
||||||
|
type: 'target',
|
||||||
|
target: '.wallet',
|
||||||
|
placement: 'right',
|
||||||
|
};
|
||||||
|
const underMetamaskExtension: FixedPositionSettings = {
|
||||||
|
type: 'fixed',
|
||||||
|
top: '30px',
|
||||||
|
right: '10px',
|
||||||
|
pointerDirection: 'top',
|
||||||
|
};
|
||||||
const steps: Step[] = [
|
const steps: Step[] = [
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: '0x Ecosystem Setup',
|
title: '0x Ecosystem Setup',
|
||||||
content: <InstallWalletOnboardingStep />,
|
content: <InstallWalletOnboardingStep />,
|
||||||
placement: 'right',
|
|
||||||
shouldHideBackButton: true,
|
shouldHideBackButton: true,
|
||||||
shouldHideNextButton: true,
|
shouldHideNextButton: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: underMetamaskExtension,
|
||||||
title: '0x Ecosystem Setup',
|
title: '0x Ecosystem Setup',
|
||||||
content: <UnlockWalletOnboardingStep />,
|
content: <UnlockWalletOnboardingStep />,
|
||||||
placement: 'right',
|
|
||||||
shouldHideBackButton: true,
|
shouldHideBackButton: true,
|
||||||
shouldHideNextButton: true,
|
shouldHideNextButton: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: '0x Ecosystem Account Setup',
|
title: '0x Ecosystem Account Setup',
|
||||||
content: <IntroOnboardingStep />,
|
content: <IntroOnboardingStep />,
|
||||||
placement: 'right',
|
|
||||||
shouldHideBackButton: true,
|
shouldHideBackButton: true,
|
||||||
continueButtonDisplay: 'enabled',
|
continueButtonDisplay: 'enabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: 'Step 1: Add ETH',
|
title: 'Step 1: Add ETH',
|
||||||
content: (
|
content: (
|
||||||
<AddEthOnboardingStep userEthBalanceInWei={this.props.userEtherBalanceInWei || new BigNumber(0)} />
|
<AddEthOnboardingStep userEthBalanceInWei={this.props.userEtherBalanceInWei || new BigNumber(0)} />
|
||||||
),
|
),
|
||||||
placement: 'right',
|
|
||||||
continueButtonDisplay: this._userHasVisibleEth() ? 'enabled' : 'disabled',
|
continueButtonDisplay: this._userHasVisibleEth() ? 'enabled' : 'disabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: 'Step 2: Wrap ETH',
|
title: 'Step 2: Wrap ETH',
|
||||||
content: <WrapEthOnboardingStep1 />,
|
content: <WrapEthOnboardingStep1 />,
|
||||||
placement: 'right',
|
|
||||||
continueButtonDisplay: 'enabled',
|
continueButtonDisplay: 'enabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: 'Step 2: Wrap ETH',
|
title: 'Step 2: Wrap ETH',
|
||||||
content: <WrapEthOnboardingStep2 />,
|
content: <WrapEthOnboardingStep2 />,
|
||||||
placement: 'right',
|
|
||||||
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
|
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: 'Step 2: Wrap ETH',
|
title: 'Step 2: Wrap ETH',
|
||||||
content: (
|
content: (
|
||||||
<WrapEthOnboardingStep3
|
<WrapEthOnboardingStep3
|
||||||
@@ -134,11 +145,10 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
placement: 'right',
|
|
||||||
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
|
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: 'Step 3: Unlock Tokens',
|
title: 'Step 3: Unlock Tokens',
|
||||||
content: (
|
content: (
|
||||||
<SetAllowancesOnboardingStep
|
<SetAllowancesOnboardingStep
|
||||||
@@ -147,14 +157,12 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
doesUserHaveAllowancesForWethAndZrx={this._doesUserHaveAllowancesForWethAndZrx()}
|
doesUserHaveAllowancesForWethAndZrx={this._doesUserHaveAllowancesForWethAndZrx()}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
placement: 'right',
|
|
||||||
continueButtonDisplay: this._doesUserHaveAllowancesForWethAndZrx() ? 'enabled' : 'disabled',
|
continueButtonDisplay: this._doesUserHaveAllowancesForWethAndZrx() ? 'enabled' : 'disabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
target: '.wallet',
|
position: nextToWalletPosition,
|
||||||
title: '🎉 The Ecosystem Awaits',
|
title: '🎉 The Ecosystem Awaits',
|
||||||
content: <CongratsOnboardingStep />,
|
content: <CongratsOnboardingStep />,
|
||||||
placement: 'right',
|
|
||||||
continueButtonDisplay: 'enabled',
|
continueButtonDisplay: 'enabled',
|
||||||
shouldHideNextButton: true,
|
shouldHideNextButton: true,
|
||||||
continueButtonText: 'Enter the 0x Ecosystem',
|
continueButtonText: 'Enter the 0x Ecosystem',
|
||||||
@@ -221,7 +229,7 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
}
|
}
|
||||||
private _autoStartOnboardingIfShould(): void {
|
private _autoStartOnboardingIfShould(): void {
|
||||||
if (
|
if (
|
||||||
(this.props.stepIndex === 0 && !this.props.isRunning) ||
|
(this.props.stepIndex === 0 && !this.props.isRunning && this.props.blockchainIsLoaded) ||
|
||||||
(!this.props.isRunning && !this.props.hasBeenClosed && this.props.blockchainIsLoaded)
|
(!this.props.isRunning && !this.props.hasBeenClosed && this.props.blockchainIsLoaded)
|
||||||
) {
|
) {
|
||||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||||
|
@@ -10,7 +10,7 @@ export const UnlockWalletOnboardingStep: React.StatelessComponent<UnlockWalletOn
|
|||||||
<Container marginTop="15px" marginBottom="15px">
|
<Container marginTop="15px" marginBottom="15px">
|
||||||
<img src="/images/metamask_icon.png" height="50px" width="50px" />
|
<img src="/images/metamask_icon.png" height="50px" width="50px" />
|
||||||
</Container>
|
</Container>
|
||||||
<Text center={true}>Unlock your metamask extension to get started.</Text>
|
<Text center={true}>Unlock your MetaMask extension to get started.</Text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -9,6 +9,7 @@ import { Container } from 'ts/components/ui/container';
|
|||||||
import { Image } from 'ts/components/ui/image';
|
import { Image } from 'ts/components/ui/image';
|
||||||
import { Island } from 'ts/components/ui/island';
|
import { Island } from 'ts/components/ui/island';
|
||||||
import { colors } from 'ts/style/colors';
|
import { colors } from 'ts/style/colors';
|
||||||
|
import { media } from 'ts/style/media';
|
||||||
import { styled } from 'ts/style/theme';
|
import { styled } from 'ts/style/theme';
|
||||||
import { WebsiteBackendRelayerInfo } from 'ts/types';
|
import { WebsiteBackendRelayerInfo } from 'ts/types';
|
||||||
import { utils } from 'ts/utils/utils';
|
import { utils } from 'ts/utils/utils';
|
||||||
@@ -111,6 +112,9 @@ const GridTile = styled(PlainGridTile)`
|
|||||||
&:hover {
|
&:hover {
|
||||||
transform: translate(0px, -3px);
|
transform: translate(0px, -3px);
|
||||||
}
|
}
|
||||||
|
${media.small`
|
||||||
|
transform: none;
|
||||||
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface SectionProps {
|
interface SectionProps {
|
||||||
|
@@ -13,9 +13,11 @@ export const store: ReduxStore<State> = createStore(
|
|||||||
);
|
);
|
||||||
store.subscribe(
|
store.subscribe(
|
||||||
_.throttle(() => {
|
_.throttle(() => {
|
||||||
|
const state = store.getState();
|
||||||
// Persisted state
|
// Persisted state
|
||||||
stateStorage.saveState({
|
stateStorage.saveState({
|
||||||
hasPortalOnboardingBeenClosed: store.getState().hasPortalOnboardingBeenClosed,
|
hasPortalOnboardingBeenClosed: state.hasPortalOnboardingBeenClosed,
|
||||||
|
isPortalOnboardingShowing: state.isPortalOnboardingShowing,
|
||||||
});
|
});
|
||||||
}, ONE_SECOND),
|
}, ONE_SECOND),
|
||||||
);
|
);
|
||||||
|
14
packages/website/ts/style/media.ts
Normal file
14
packages/website/ts/style/media.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { css } from 'ts/style/theme';
|
||||||
|
import { ScreenWidths } from 'ts/types';
|
||||||
|
|
||||||
|
const generateMediaWrapper = (screenWidth: ScreenWidths) => (...args: any[]) => css`
|
||||||
|
@media (max-width: ${screenWidth}) {
|
||||||
|
${css.apply(css, args)};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const media = {
|
||||||
|
small: generateMediaWrapper(ScreenWidths.Sm),
|
||||||
|
medium: generateMediaWrapper(ScreenWidths.Md),
|
||||||
|
large: generateMediaWrapper(ScreenWidths.Lg),
|
||||||
|
};
|
@@ -216,10 +216,11 @@ export interface ContractEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void;
|
export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void;
|
||||||
|
// Associated values are in `em` units
|
||||||
export enum ScreenWidths {
|
export enum ScreenWidths {
|
||||||
Sm = 'SM',
|
Sm = 40,
|
||||||
Md = 'MD',
|
Md = 52,
|
||||||
Lg = 'LG',
|
Lg = 64,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AlertTypes {
|
export enum AlertTypes {
|
||||||
|
@@ -29,9 +29,6 @@ import { configs } from 'ts/utils/configs';
|
|||||||
import { constants } from 'ts/utils/constants';
|
import { constants } from 'ts/utils/constants';
|
||||||
import * as u2f from 'ts/vendor/u2f_api';
|
import * as u2f from 'ts/vendor/u2f_api';
|
||||||
|
|
||||||
const LG_MIN_EM = 64;
|
|
||||||
const MD_MIN_EM = 52;
|
|
||||||
|
|
||||||
const isDogfood = (): boolean => _.includes(window.location.href, configs.DOMAIN_DOGFOOD);
|
const isDogfood = (): boolean => _.includes(window.location.href, configs.DOMAIN_DOGFOOD);
|
||||||
|
|
||||||
export const utils = {
|
export const utils = {
|
||||||
@@ -136,9 +133,9 @@ export const utils = {
|
|||||||
|
|
||||||
// This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
|
// This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
|
||||||
// class prefixes. Do not edit these.
|
// class prefixes. Do not edit these.
|
||||||
if (widthInEm > LG_MIN_EM) {
|
if (widthInEm > ScreenWidths.Lg) {
|
||||||
return ScreenWidths.Lg;
|
return ScreenWidths.Lg;
|
||||||
} else if (widthInEm > MD_MIN_EM) {
|
} else if (widthInEm > ScreenWidths.Md) {
|
||||||
return ScreenWidths.Md;
|
return ScreenWidths.Md;
|
||||||
} else {
|
} else {
|
||||||
return ScreenWidths.Sm;
|
return ScreenWidths.Sm;
|
||||||
|
101
yarn.lock
101
yarn.lock
@@ -330,7 +330,7 @@
|
|||||||
|
|
||||||
"@types/mocha@^5.2.2":
|
"@types/mocha@^5.2.2":
|
||||||
version "5.2.3"
|
version "5.2.3"
|
||||||
resolved "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.3.tgz#11f3a5629d67cd444fa6c94536576244e6a52ea9"
|
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.3.tgz#11f3a5629d67cd444fa6c94536576244e6a52ea9"
|
||||||
|
|
||||||
"@types/nock@^9.1.2":
|
"@types/nock@^9.1.2":
|
||||||
version "9.1.3"
|
version "9.1.3"
|
||||||
@@ -1608,6 +1608,12 @@ base-x@^1.1.0:
|
|||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-1.1.0.tgz#42d3d717474f9ea02207f6d1aa1f426913eeb7ac"
|
resolved "https://registry.yarnpkg.com/base-x/-/base-x-1.1.0.tgz#42d3d717474f9ea02207f6d1aa1f426913eeb7ac"
|
||||||
|
|
||||||
|
base-x@^3.0.2:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77"
|
||||||
|
dependencies:
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
base64-js@0.0.8:
|
base64-js@0.0.8:
|
||||||
version "0.0.8"
|
version "0.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
|
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
|
||||||
@@ -1760,6 +1766,24 @@ bip66@^1.1.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
bitcore-lib@^0.15.0:
|
||||||
|
version "0.15.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-0.15.0.tgz#f924be13869f2aab7e04aeec5642ad3359b6cec2"
|
||||||
|
dependencies:
|
||||||
|
bn.js "=4.11.8"
|
||||||
|
bs58 "=4.0.1"
|
||||||
|
buffer-compare "=1.1.1"
|
||||||
|
elliptic "=6.4.0"
|
||||||
|
inherits "=2.0.1"
|
||||||
|
lodash "=4.17.4"
|
||||||
|
|
||||||
|
bitcore-mnemonic@^1.5.0:
|
||||||
|
version "1.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bitcore-mnemonic/-/bitcore-mnemonic-1.5.0.tgz#c7e785beb6bf0616ed4992785dc3658670425a39"
|
||||||
|
dependencies:
|
||||||
|
bitcore-lib "^0.15.0"
|
||||||
|
unorm "^1.3.3"
|
||||||
|
|
||||||
bl@^1.0.0:
|
bl@^1.0.0:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
|
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
|
||||||
@@ -1805,10 +1829,14 @@ bn.js@4.11.7:
|
|||||||
version "4.11.7"
|
version "4.11.7"
|
||||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46"
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46"
|
||||||
|
|
||||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0:
|
bn.js@=4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0:
|
||||||
version "4.11.8"
|
version "4.11.8"
|
||||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
||||||
|
|
||||||
|
bn.js@^2.0.3:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.2.0.tgz#12162bc2ae71fc40a5626c33438f3a875cd37625"
|
||||||
|
|
||||||
body-parser@1.18.2, body-parser@^1.16.0, body-parser@^1.17.1:
|
body-parser@1.18.2, body-parser@^1.16.0, body-parser@^1.17.1:
|
||||||
version "1.18.2"
|
version "1.18.2"
|
||||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
|
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
|
||||||
@@ -1979,6 +2007,12 @@ browserslist@^2.1.2:
|
|||||||
caniuse-lite "^1.0.30000792"
|
caniuse-lite "^1.0.30000792"
|
||||||
electron-to-chromium "^1.3.30"
|
electron-to-chromium "^1.3.30"
|
||||||
|
|
||||||
|
bs58@=4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
|
||||||
|
dependencies:
|
||||||
|
base-x "^3.0.2"
|
||||||
|
|
||||||
bs58@^2.0.1:
|
bs58@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d"
|
resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d"
|
||||||
@@ -2000,6 +2034,10 @@ btoa@1.1.2:
|
|||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.1.2.tgz#3e40b81663f81d2dd6596a4cb714a8dc16cfabe0"
|
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.1.2.tgz#3e40b81663f81d2dd6596a4cb714a8dc16cfabe0"
|
||||||
|
|
||||||
|
buffer-compare@=1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-compare/-/buffer-compare-1.1.1.tgz#5be7be853af89198d1f4ddc090d1d66a48aef596"
|
||||||
|
|
||||||
buffer-crc32@~0.2.3:
|
buffer-crc32@~0.2.3:
|
||||||
version "0.2.13"
|
version "0.2.13"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||||
@@ -2036,7 +2074,7 @@ buffer@^3.0.1:
|
|||||||
ieee754 "^1.1.4"
|
ieee754 "^1.1.4"
|
||||||
isarray "^1.0.0"
|
isarray "^1.0.0"
|
||||||
|
|
||||||
buffer@^4.3.0:
|
buffer@^4.3.0, buffer@^4.9.0:
|
||||||
version "4.9.1"
|
version "4.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2903,7 +2941,7 @@ copyfiles@^1.2.0:
|
|||||||
|
|
||||||
copyfiles@^2.0.0:
|
copyfiles@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/copyfiles/-/copyfiles-2.0.0.tgz#bbd78bb78e8fd6db5c67adf54249317b24560f2a"
|
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.0.0.tgz#bbd78bb78e8fd6db5c67adf54249317b24560f2a"
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.0.5"
|
glob "^7.0.5"
|
||||||
minimatch "^3.0.3"
|
minimatch "^3.0.3"
|
||||||
@@ -3058,7 +3096,7 @@ crypto-js@3.1.9-1, crypto-js@^3.1.9-1:
|
|||||||
version "3.1.9-1"
|
version "3.1.9-1"
|
||||||
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8"
|
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8"
|
||||||
|
|
||||||
crypto-js@^3.1.4:
|
crypto-js@^3.1.4, crypto-js@^3.1.5:
|
||||||
version "3.1.8"
|
version "3.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.8.tgz#715f070bf6014f2ae992a98b3929258b713f08d5"
|
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.8.tgz#715f070bf6014f2ae992a98b3929258b713f08d5"
|
||||||
|
|
||||||
@@ -3720,7 +3758,7 @@ elliptic@6.3.3:
|
|||||||
hash.js "^1.0.0"
|
hash.js "^1.0.0"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
|
|
||||||
elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0:
|
elliptic@=6.4.0, elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0:
|
||||||
version "6.4.0"
|
version "6.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
|
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3732,6 +3770,15 @@ elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0:
|
|||||||
minimalistic-assert "^1.0.0"
|
minimalistic-assert "^1.0.0"
|
||||||
minimalistic-crypto-utils "^1.0.0"
|
minimalistic-crypto-utils "^1.0.0"
|
||||||
|
|
||||||
|
elliptic@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "http://registry.npmjs.org/elliptic/-/elliptic-3.1.0.tgz#c21682ef762769b56a74201609105da11d5f60cc"
|
||||||
|
dependencies:
|
||||||
|
bn.js "^2.0.3"
|
||||||
|
brorand "^1.0.1"
|
||||||
|
hash.js "^1.0.0"
|
||||||
|
inherits "^2.0.1"
|
||||||
|
|
||||||
emojis-list@^2.0.0:
|
emojis-list@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||||
@@ -4031,6 +4078,22 @@ eth-lib@0.2.7:
|
|||||||
elliptic "^6.4.0"
|
elliptic "^6.4.0"
|
||||||
xhr-request-promise "^0.1.2"
|
xhr-request-promise "^0.1.2"
|
||||||
|
|
||||||
|
eth-lightwallet@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/eth-lightwallet/-/eth-lightwallet-3.0.1.tgz#297022932aa568f4e4eb0873bff257f5e5b78709"
|
||||||
|
dependencies:
|
||||||
|
bitcore-lib "^0.15.0"
|
||||||
|
bitcore-mnemonic "^1.5.0"
|
||||||
|
buffer "^4.9.0"
|
||||||
|
crypto-js "^3.1.5"
|
||||||
|
elliptic "^3.1.0"
|
||||||
|
ethereumjs-tx "^1.3.3"
|
||||||
|
ethereumjs-util "^5.1.1"
|
||||||
|
rlp "^2.0.0"
|
||||||
|
scrypt-async "^1.2.0"
|
||||||
|
tweetnacl "0.13.2"
|
||||||
|
web3 "0.20.2"
|
||||||
|
|
||||||
eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
|
eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e"
|
resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e"
|
||||||
@@ -5859,7 +5922,7 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, i
|
|||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||||
|
|
||||||
inherits@2.0.1:
|
inherits@2.0.1, inherits@=2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||||
|
|
||||||
@@ -7204,7 +7267,7 @@ lodash@4.17.2:
|
|||||||
version "4.17.2"
|
version "4.17.2"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42"
|
||||||
|
|
||||||
lodash@4.17.4:
|
lodash@4.17.4, lodash@=4.17.4:
|
||||||
version "4.17.4"
|
version "4.17.4"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||||
|
|
||||||
@@ -10216,7 +10279,7 @@ run-queue@^1.0.0, run-queue@^1.0.3:
|
|||||||
|
|
||||||
run-s@^0.0.0:
|
run-s@^0.0.0:
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
resolved "https://registry.npmjs.org/run-s/-/run-s-0.0.0.tgz#599912be20c00ba7698655c9936d075d31b71754"
|
resolved "https://registry.yarnpkg.com/run-s/-/run-s-0.0.0.tgz#599912be20c00ba7698655c9936d075d31b71754"
|
||||||
|
|
||||||
rustbn.js@~0.1.1:
|
rustbn.js@~0.1.1:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
@@ -10284,6 +10347,10 @@ scoped-regex@^1.0.0:
|
|||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8"
|
resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8"
|
||||||
|
|
||||||
|
scrypt-async@^1.2.0:
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/scrypt-async/-/scrypt-async-1.3.1.tgz#a11fd6fac981b4b823ee01dee0221169500ddae9"
|
||||||
|
|
||||||
scrypt-js@2.0.3:
|
scrypt-js@2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4"
|
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4"
|
||||||
@@ -11730,6 +11797,10 @@ tunnel-agent@^0.6.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
tweetnacl@0.13.2:
|
||||||
|
version "0.13.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.13.2.tgz#453161770469d45cd266c36404e2bc99a8fa9944"
|
||||||
|
|
||||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||||
version "0.14.5"
|
version "0.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||||
@@ -12630,6 +12701,16 @@ web3-utils@1.0.0-beta.34:
|
|||||||
underscore "1.8.3"
|
underscore "1.8.3"
|
||||||
utf8 "2.1.1"
|
utf8 "2.1.1"
|
||||||
|
|
||||||
|
web3@0.20.2:
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.2.tgz#c54dac5fc0e377399c04c1a6ecbb12e4513278d6"
|
||||||
|
dependencies:
|
||||||
|
bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git"
|
||||||
|
crypto-js "^3.1.4"
|
||||||
|
utf8 "^2.1.1"
|
||||||
|
xhr2 "*"
|
||||||
|
xmlhttprequest "*"
|
||||||
|
|
||||||
web3@^0.18.0:
|
web3@^0.18.0:
|
||||||
version "0.18.4"
|
version "0.18.4"
|
||||||
resolved "https://registry.yarnpkg.com/web3/-/web3-0.18.4.tgz#81ec1784145491f2eaa8955b31c06049e07c5e7d"
|
resolved "https://registry.yarnpkg.com/web3/-/web3-0.18.4.tgz#81ec1784145491f2eaa8955b31c06049e07c5e7d"
|
||||||
@@ -13137,7 +13218,7 @@ yargs@^10.0.3:
|
|||||||
|
|
||||||
yargs@^11.0.0:
|
yargs@^11.0.0:
|
||||||
version "11.0.0"
|
version "11.0.0"
|
||||||
resolved "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b"
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b"
|
||||||
dependencies:
|
dependencies:
|
||||||
cliui "^4.0.0"
|
cliui "^4.0.0"
|
||||||
decamelize "^1.1.1"
|
decamelize "^1.1.1"
|
||||||
|
Reference in New Issue
Block a user