diff options
25 files changed, 305 insertions, 223 deletions
diff --git a/packages/contract-wrappers/test/ether_token_wrapper_test.ts b/packages/contract-wrappers/test/ether_token_wrapper_test.ts index e06fe96e5..a2154c2bd 100644 --- a/packages/contract-wrappers/test/ether_token_wrapper_test.ts +++ b/packages/contract-wrappers/test/ether_token_wrapper_test.ts @@ -95,7 +95,7 @@ describe('EtherTokenWrapper', () => { depositWeiAmount, addressWithETH, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync( @@ -137,7 +137,7 @@ describe('EtherTokenWrapper', () => { depositWeiAmount, addressWithETH, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync( @@ -347,7 +347,7 @@ describe('EtherTokenWrapper', () => { }); it('should get logs with decoded args emitted by Approval', async () => { txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const eventName = EtherTokenEvents.Approval; const indexFilterValues = {}; const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>( @@ -381,7 +381,7 @@ describe('EtherTokenWrapper', () => { }); it('should only get the logs with the correct event name', async () => { txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const differentEventName = EtherTokenEvents.Transfer; const indexFilterValues = {}; const logs = await contractWrappers.etherToken.getLogsAsync( @@ -394,12 +394,12 @@ describe('EtherTokenWrapper', () => { }); it('should only get the logs with the correct indexed fields', async () => { txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync( etherTokenAddress, addressWithoutFunds, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const eventName = EtherTokenEvents.Approval; const indexFilterValues = { _owner: addressWithETH, diff --git a/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts b/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts index 77c73ba8f..cf7520ea0 100644 --- a/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts +++ b/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts @@ -60,7 +60,7 @@ describe('ExchangeTransferSimulator', () => { }); it("throws if the user doesn't have enough balance", async () => { txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); return expect( exchangeTransferSimulator.transferFromAsync( exampleTokenAddress, @@ -74,9 +74,9 @@ describe('ExchangeTransferSimulator', () => { }); it('updates balances and proxyAllowance after transfer', async () => { txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); await exchangeTransferSimulator.transferFromAsync( exampleTokenAddress, sender, @@ -95,9 +95,9 @@ describe('ExchangeTransferSimulator', () => { }); it("doesn't update proxyAllowance after transfer if unlimited", async () => { txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); await exchangeTransferSimulator.transferFromAsync( exampleTokenAddress, sender, diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts index 99384e0fa..d35d2b819 100644 --- a/packages/contract-wrappers/test/exchange_wrapper_test.ts +++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts @@ -276,7 +276,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); expect( await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); @@ -305,7 +305,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); expect( await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); @@ -338,7 +338,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); expect( await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient), ).to.be.bignumber.equal(makerFee.plus(takerFee)); @@ -469,7 +469,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( anotherOrderHashHex, @@ -595,7 +595,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( anotherOrderHashHex, @@ -611,7 +611,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); const zeroAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(anotherOrderHashHex); expect(filledAmount).to.be.bignumber.equal(fillableAmount); @@ -632,7 +632,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( anotherOrderHashHex, @@ -730,7 +730,7 @@ describe('ExchangeWrapper', () => { describe('successful cancels', () => { it('should cancel an order', async () => { const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex); expect(cancelledAmount).to.be.bignumber.equal(cancelAmount); }); @@ -1112,7 +1112,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const eventName = ExchangeEvents.LogFill; const indexFilterValues = {}; const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues); @@ -1133,7 +1133,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const differentEventName = ExchangeEvents.LogCancel; const indexFilterValues = {}; const logs = await contractWrappers.exchange.getLogsAsync( @@ -1157,7 +1157,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const differentMakerAddress = userAddresses[2]; const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( @@ -1173,7 +1173,7 @@ describe('ExchangeWrapper', () => { shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const eventName = ExchangeEvents.LogFill; const indexFilterValues = { diff --git a/packages/contract-wrappers/test/token_wrapper_test.ts b/packages/contract-wrappers/test/token_wrapper_test.ts index 9280f65cb..12bf72d85 100644 --- a/packages/contract-wrappers/test/token_wrapper_test.ts +++ b/packages/contract-wrappers/test/token_wrapper_test.ts @@ -542,7 +542,7 @@ describe('TokenWrapper', () => { }); it('should get logs with decoded args emitted by Approval', async () => { txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const eventName = TokenEvents.Approval; const indexFilterValues = {}; const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>( @@ -560,7 +560,7 @@ describe('TokenWrapper', () => { }); it('should only get the logs with the correct event name', async () => { txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const differentEventName = TokenEvents.Transfer; const indexFilterValues = {}; const logs = await contractWrappers.token.getLogsAsync( @@ -573,9 +573,9 @@ describe('TokenWrapper', () => { }); it('should only get the logs with the correct indexed fields', async () => { txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds); - await web3Wrapper.awaitTransactionMinedAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash); const eventName = TokenEvents.Approval; const indexFilterValues = { _owner: coinbase, diff --git a/packages/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars index 41f46695b..b2765b1a5 100644 --- a/packages/contract_templates/contract.handlebars +++ b/packages/contract_templates/contract.handlebars @@ -76,7 +76,7 @@ export class {{contractName}}Contract extends BaseContract { ); const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); logUtils.log(`transactionHash: ${txHash}`); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); logUtils.log(`{{contractName}} successfully deployed at ${txReceipt.contractAddress}`); const contractInstance = new {{contractName}}Contract(abi, txReceipt.contractAddress as string, provider, txDefaults); contractInstance.constructorArgs = [{{> params inputs=ctor.inputs}}]; diff --git a/packages/contracts/src/utils/exchange_wrapper.ts b/packages/contracts/src/utils/exchange_wrapper.ts index 0d0977ab8..c353442f3 100644 --- a/packages/contracts/src/utils/exchange_wrapper.ts +++ b/packages/contracts/src/utils/exchange_wrapper.ts @@ -247,7 +247,7 @@ export class ExchangeWrapper { return tx; } private async _getTxWithDecodedExchangeLogsAsync(txHash: string): Promise<TransactionReceiptWithDecodedLogs> { - const tx = await this._web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const tx = await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); tx.logs = _.map(tx.logs, log => this._logDecoder.decodeLogOrThrow(log)); return tx; diff --git a/packages/contracts/test/asset_proxy/authorizable.ts b/packages/contracts/test/asset_proxy/authorizable.ts index 52e9ea87f..87f89c513 100644 --- a/packages/contracts/test/asset_proxy/authorizable.ts +++ b/packages/contracts/test/asset_proxy/authorizable.ts @@ -48,7 +48,7 @@ describe('Authorizable', () => { ).to.be.rejectedWith(constants.REVERT); }); it('should allow owner to add an authorized address', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -56,7 +56,7 @@ describe('Authorizable', () => { expect(isAuthorized).to.be.true(); }); it('should throw if owner attempts to authorize a duplicate address', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -68,7 +68,7 @@ describe('Authorizable', () => { describe('removeAuthorizedAddress', () => { it('should throw if not called by owner', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -80,11 +80,11 @@ describe('Authorizable', () => { }); it('should allow owner to remove an authorized address', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: owner, }), @@ -107,7 +107,7 @@ describe('Authorizable', () => { it('should return all authorized addresses', async () => { const initial = await authorizable.getAuthorizedAddresses.callAsync(); expect(initial).to.have.length(0); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner, }), @@ -117,7 +117,7 @@ describe('Authorizable', () => { expect(afterAdd).to.have.length(1); expect(afterAdd).to.include(address); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, { from: owner, }), diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts index 4ee38db80..9bcdfa2b8 100644 --- a/packages/contracts/test/asset_proxy/proxies.ts +++ b/packages/contracts/test/asset_proxy/proxies.ts @@ -52,7 +52,7 @@ describe('Asset Transfer Proxies', () => { [zrxToken] = await erc20Wrapper.deployDummyTokensAsync(); erc20Proxy = await erc20Wrapper.deployProxyAsync(); await erc20Wrapper.setBalancesAndAllowancesAsync(); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeAddress, { from: owner, }), @@ -64,7 +64,7 @@ describe('Asset Transfer Proxies', () => { await erc721Wrapper.setBalancesAndAllowancesAsync(); const erc721Balances = await erc721Wrapper.getBalancesAsync(); erc721MakerTokenId = erc721Balances[makerAddress][erc721Token.address][0]; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeAddress, { from: owner, }), @@ -85,7 +85,7 @@ describe('Asset Transfer Proxies', () => { // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(10); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.transferFrom.sendTransactionAsync( encodedProxyMetadata, makerAddress, @@ -111,7 +111,7 @@ describe('Asset Transfer Proxies', () => { // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(0); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.transferFrom.sendTransactionAsync( encodedProxyMetadata, makerAddress, @@ -137,7 +137,7 @@ describe('Asset Transfer Proxies', () => { // Create allowance less than transfer amount. Set allowance on proxy. const allowance = new BigNumber(0); const transferAmount = new BigNumber(10); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await zrxToken.approve.sendTransactionAsync(erc20Proxy.address, allowance, { from: makerAddress, }), @@ -193,7 +193,10 @@ describe('Asset Transfer Proxies', () => { amounts, { from: exchangeAddress }, ); - const res = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const res = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); const newBalances = await erc20Wrapper.getBalancesAsync(); expect(res.logs.length).to.equal(numTransfers); @@ -246,7 +249,7 @@ describe('Asset Transfer Proxies', () => { // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(1); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.transferFrom.sendTransactionAsync( encodedProxyMetadata, makerAddress, @@ -314,7 +317,7 @@ describe('Asset Transfer Proxies', () => { erc721MakerTokenId, ); // Remove transfer approval for makerAddress. - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, false, { from: makerAddress, }), @@ -376,7 +379,10 @@ describe('Asset Transfer Proxies', () => { amounts, { from: exchangeAddress }, ); - const res = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const res = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); expect(res.logs.length).to.equal(numTransfers); const newOwnerMakerAssetA = await erc721Token.ownerOf.callAsync(makerTokenIdA); diff --git a/packages/contracts/test/ether_token.ts b/packages/contracts/test/ether_token.ts index 9b04dd187..5c8a5e199 100644 --- a/packages/contracts/test/ether_token.ts +++ b/packages/contracts/test/ether_token.ts @@ -61,7 +61,10 @@ describe('EtherToken', () => { const ethToDeposit = new BigNumber(Web3Wrapper.toWei(new BigNumber(1))); const txHash = await contractWrappers.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account); - const receipt = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const receipt = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); const ethSpentOnGas = gasPrice.times(receipt.gasUsed); const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); @@ -97,7 +100,10 @@ describe('EtherToken', () => { gasLimit: constants.MAX_ETHERTOKEN_WITHDRAW_GAS, }, ); - const receipt = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const receipt = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); const ethSpentOnGas = gasPrice.times(receipt.gasUsed); const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); @@ -124,7 +130,10 @@ describe('EtherToken', () => { gasPrice, }); - const receipt = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const receipt = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); const ethSpentOnGas = gasPrice.times(receipt.gasUsed); const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account); diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index f1d9a4156..4776216ca 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -94,13 +94,13 @@ describe('Exchange core', () => { await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC721, erc721Proxy.address, owner); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner, }), constants.AWAIT_TRANSACTION_MINED_MS, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner, }), @@ -527,7 +527,7 @@ describe('Exchange core', () => { }); it('should throw if maker allowances are too low to fill order', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), { from: makerAddress, }), @@ -539,7 +539,7 @@ describe('Exchange core', () => { await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith( constants.REVERT, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, { from: makerAddress, }), @@ -548,7 +548,7 @@ describe('Exchange core', () => { }); it('should throw if taker allowances are too low to fill order', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), { from: takerAddress, }), @@ -560,7 +560,7 @@ describe('Exchange core', () => { await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith( constants.REVERT, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, { from: takerAddress, }), diff --git a/packages/contracts/test/exchange/dispatcher.ts b/packages/contracts/test/exchange/dispatcher.ts index a2238bd10..b9c7039bd 100644 --- a/packages/contracts/test/exchange/dispatcher.ts +++ b/packages/contracts/test/exchange/dispatcher.ts @@ -61,13 +61,13 @@ describe('AssetProxyDispatcher', () => { provider, txDefaults, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(assetProxyDispatcher.address, { from: owner, }), constants.AWAIT_TRANSACTION_MINED_MS, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(assetProxyDispatcher.address, { from: owner, }), @@ -83,7 +83,7 @@ describe('AssetProxyDispatcher', () => { describe('registerAssetProxy', () => { it('should record proxy upon registration', async () => { const prevProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -99,7 +99,7 @@ describe('AssetProxyDispatcher', () => { it('should be able to record multiple proxies', async () => { // Record first proxy const prevERC20ProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -112,7 +112,7 @@ describe('AssetProxyDispatcher', () => { expect(proxyAddress).to.be.equal(erc20Proxy.address); // Record another proxy const prevERC721ProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC721, erc721Proxy.address, @@ -128,7 +128,7 @@ describe('AssetProxyDispatcher', () => { it('should replace proxy address upon re-registration', async () => { // Initial registration const prevProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -148,7 +148,7 @@ describe('AssetProxyDispatcher', () => { // Register new ERC20 Transfer Proxy contract const newAddress = newErc20TransferProxy.address; const currentAddress = erc20Proxy.address; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, newAddress, @@ -165,7 +165,7 @@ describe('AssetProxyDispatcher', () => { it('should throw if registering with incorrect "currentAssetProxyAddress" field', async () => { // Initial registration const prevProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -190,7 +190,7 @@ describe('AssetProxyDispatcher', () => { it('should be able to reset proxy address to NULL', async () => { // Initial registration const prevProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -203,7 +203,7 @@ describe('AssetProxyDispatcher', () => { expect(proxyAddress).to.be.equal(erc20Proxy.address); // The following transaction will reset the proxy address const newProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, newProxyAddress, @@ -244,7 +244,7 @@ describe('AssetProxyDispatcher', () => { describe('getAssetProxy', () => { it('should return correct address of registered proxy', async () => { const prevProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -267,7 +267,7 @@ describe('AssetProxyDispatcher', () => { it('should dispatch transfer to registered proxy', async () => { // Register ERC20 proxy const prevProxyAddress = constants.NULL_ADDRESS; - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync( AssetProxyId.ERC20, erc20Proxy.address, @@ -281,7 +281,7 @@ describe('AssetProxyDispatcher', () => { // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(10); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync( encodedProxyMetadata, makerAddress, diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts index 8a3c91520..1834e929c 100644 --- a/packages/contracts/test/exchange/match_orders.ts +++ b/packages/contracts/test/exchange/match_orders.ts @@ -120,13 +120,13 @@ describe('matchOrders', () => { await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC721, erc721Proxy.address, owner); // Authorize ERC20 and ERC721 trades by exchange - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner, }), constants.AWAIT_TRANSACTION_MINED_MS, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner, }), diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts index 203c05e53..24f7230fa 100644 --- a/packages/contracts/test/exchange/transactions.ts +++ b/packages/contracts/test/exchange/transactions.ts @@ -82,7 +82,7 @@ describe('Exchange transactions', () => { exchangeWrapper = new ExchangeWrapper(exchange, provider); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index 39f861968..e7217c2a7 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -87,13 +87,13 @@ describe('Exchange wrappers', () => { await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC721, erc721Proxy.address, owner); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner, }), constants.AWAIT_TRANSACTION_MINED_MS, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner, }), @@ -256,14 +256,14 @@ describe('Exchange wrappers', () => { it('should not change erc20Balances if maker allowances are too low to fill order', async () => { const signedOrder = orderFactory.newSignedOrder(); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), { from: makerAddress, }), constants.AWAIT_TRANSACTION_MINED_MS, ); await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, { from: makerAddress, }), @@ -276,14 +276,14 @@ describe('Exchange wrappers', () => { it('should not change erc20Balances if taker allowances are too low to fill order', async () => { const signedOrder = orderFactory.newSignedOrder(); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), { from: takerAddress, }), constants.AWAIT_TRANSACTION_MINED_MS, ); await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, { from: takerAddress, }), diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts index 6f18de3e7..732077df2 100644 --- a/packages/contracts/test/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -79,7 +79,7 @@ describe('MultiSigWalletWithTimeLock', () => { args: [SECONDS_TIME_LOCKED.toNumber()], }; const txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync( + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( txHash, constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -102,7 +102,7 @@ describe('MultiSigWalletWithTimeLock', () => { args: [SECONDS_TIME_LOCKED.toNumber()], }; let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync( + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( txHash, constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -112,7 +112,10 @@ describe('MultiSigWalletWithTimeLock', () => { txId = log.args.transactionId; txHash = await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const res = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const res = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); expect(res.logs).to.have.length(2); const blockNum = await web3Wrapper.getBlockNumberAsync(); @@ -132,7 +135,7 @@ describe('MultiSigWalletWithTimeLock', () => { args: [SECONDS_TIME_LOCKED.toNumber()], }; let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync( + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( txHash, constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -142,12 +145,15 @@ describe('MultiSigWalletWithTimeLock', () => { txId = log.args.transactionId; txHash = await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); expect(initialSecondsTimeLocked).to.be.equal(0); txHash = await multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }); - const res = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const res = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); expect(res.logs).to.have.length(2); const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.callAsync()); @@ -182,7 +188,7 @@ describe('MultiSigWalletWithTimeLock', () => { args: [newSecondsTimeLocked], }; let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - let txReceipt = await web3Wrapper.awaitTransactionMinedAsync( + let txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( txHash, constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -193,7 +199,10 @@ describe('MultiSigWalletWithTimeLock', () => { txHash = await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1], }); - txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( + txHash, + constants.AWAIT_TRANSACTION_MINED_MS, + ); expect(txReceipt.logs).to.have.length(2); }); const newSecondsTimeLocked = 0; @@ -205,7 +214,7 @@ describe('MultiSigWalletWithTimeLock', () => { it('should execute if it has enough confirmations and is past the time lock', async () => { await web3Wrapper.increaseTimeAsync(SECONDS_TIME_LOCKED.toNumber()); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), constants.AWAIT_TRANSACTION_MINED_MS, ); diff --git a/packages/contracts/test/token_registry.ts b/packages/contracts/test/token_registry.ts index 49d4f3901..1cc519c53 100644 --- a/packages/contracts/test/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -142,7 +142,7 @@ describe('TokenRegistry', () => { }); it('should change the token name when called by owner', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await tokenReg.setTokenName.sendTransactionAsync(token1.address, token2.name, { from: owner, }), @@ -184,7 +184,7 @@ describe('TokenRegistry', () => { }); it('should change the token symbol when called by owner', async () => { - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await tokenReg.setTokenSymbol.sendTransactionAsync(token1.address, token2.symbol, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); @@ -228,7 +228,7 @@ describe('TokenRegistry', () => { it('should remove token metadata when called by owner', async () => { const index = new BigNumber(0); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await tokenReg.removeToken.sendTransactionAsync(token1.address, index, { from: owner, }), diff --git a/packages/contracts/test/unlimited_allowance_token.ts b/packages/contracts/test/unlimited_allowance_token.ts index e831301e1..e3e3bd485 100644 --- a/packages/contracts/test/unlimited_allowance_token.ts +++ b/packages/contracts/test/unlimited_allowance_token.ts @@ -46,7 +46,7 @@ describe('UnlimitedAllowanceToken', () => { constants.DUMMY_TOKEN_DECIMALS, constants.DUMMY_TOKEN_TOTAL_SUPPLY, ); - await web3Wrapper.awaitTransactionMinedAsync( + await web3Wrapper.awaitTransactionSuccessAsync( await token.mint.sendTransactionAsync(MAX_MINT_VALUE, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); diff --git a/packages/fill-scenarios/src/index.ts b/packages/fill-scenarios/src/index.ts index 7e5c6cc08..e139722a7 100644 --- a/packages/fill-scenarios/src/index.ts +++ b/packages/fill-scenarios/src/index.ts @@ -49,7 +49,7 @@ export class FillScenarios { const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, { from: this._coinbase, }); - await this._web3Wrapper.awaitTransactionMinedAsync(txHash); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); } } } diff --git a/packages/metacoin/test/metacoin_test.ts b/packages/metacoin/test/metacoin_test.ts index d1331a4dc..034c1265e 100644 --- a/packages/metacoin/test/metacoin_test.ts +++ b/packages/metacoin/test/metacoin_test.ts @@ -52,7 +52,7 @@ describe('Metacoin', () => { }, { from: devConstants.TESTRPC_FIRST_ADDRESS }, ); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>; expect(transferLogs.args).to.be.deep.equal({ _to: ZERO_ADDRESS, @@ -77,7 +77,7 @@ describe('Metacoin', () => { callback, { from: devConstants.TESTRPC_FIRST_ADDRESS }, ); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>; expect(transferLogs.args).to.be.deep.equal({ _to: ZERO_ADDRESS, @@ -104,7 +104,7 @@ describe('Metacoin', () => { }, { from: devConstants.TESTRPC_FIRST_ADDRESS }, ); - const txReceipt = await web3Wrapper.awaitTransactionMinedAsync(txHash); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); const transferLogs = txReceipt.logs[0] as LogWithDecodedArgs<TransferContractEventArgs>; expect(transferLogs.args).to.be.deep.equal({ _to: ZERO_ADDRESS, diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 91a1af870..40a554522 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -328,6 +328,10 @@ export class Web3Wrapper { } /** * Waits for a transaction to be mined and returns the transaction receipt. + * Note that just because a transaction was mined does not mean it was + * successful. You need to check the status code of the transaction receipt + * to find out if it was successful, or use the helper method + * awaitTransactionSuccessAsync. * @param txHash Transaction hash * @param pollingIntervalMs How often (in ms) should we check if the transaction is mined. * @param timeoutMs How long (in ms) to poll for transaction mined until aborting. @@ -377,6 +381,28 @@ export class Web3Wrapper { const txReceipt = await txReceiptPromise; return txReceipt; } + /** + * Waits for a transaction to be mined and returns the transaction receipt. + * Unlike awaitTransactionMinedAsync, it will throw if the receipt has a + * status that is not equal to 1. A status of 0 or null indicates that the + * transaction was mined, but failed. See: + * https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethgettransactionreceipt + * @param txHash Transaction hash + * @param pollingIntervalMs How often (in ms) should we check if the transaction is mined. + * @param timeoutMs How long (in ms) to poll for transaction mined until aborting. + * @return Transaction receipt with decoded log args. + */ + public async awaitTransactionSuccessAsync( + txHash: string, + pollingIntervalMs: number = 1000, + timeoutMs?: number, + ): Promise<TransactionReceiptWithDecodedLogs> { + const receipt = await this.awaitTransactionMinedAsync(txHash, pollingIntervalMs, timeoutMs); + if (receipt.status !== 1) { + throw new Error(`Transaction failed: ${txHash}`); + } + return receipt; + } private async _sendRawPayloadAsync<A>(payload: Partial<JSONRPCRequestPayload>): Promise<A> { const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider); const response = await promisify<JSONRPCResponsePayload>(sendAsync)(payload); diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index d18f3b398..212e829dd 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -623,7 +623,7 @@ export class Blockchain { ); const provider = this._contractWrappers.getProvider(); const web3Wrapper = new Web3Wrapper(provider); - const receipt = await web3Wrapper.awaitTransactionMinedAsync(txHash); + const receipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); return receipt; } private _doesUserAddressExist(): boolean { diff --git a/packages/website/ts/components/ui/icon_button.tsx b/packages/website/ts/components/ui/icon_button.tsx new file mode 100644 index 000000000..2f5172f05 --- /dev/null +++ b/packages/website/ts/components/ui/icon_button.tsx @@ -0,0 +1,63 @@ +import { colors, Styles } from '@0xproject/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; + +export interface IconButtonProps { + iconName: string; + labelText?: string; + onClick: () => void; + color?: string; +} +interface IconButtonState { + isHovering: boolean; +} +export class IconButton extends React.Component<IconButtonProps, IconButtonState> { + public static defaultProps: Partial<IconButtonProps> = { + onClick: _.noop, + labelText: '', + color: colors.mediumBlue, + }; + public constructor(props: IconButtonProps) { + super(props); + this.state = { + isHovering: false, + }; + } + public render(): React.ReactNode { + const styles: Styles = { + root: { + cursor: 'pointer', + opacity: this.state.isHovering ? 0.5 : 1, + }, + icon: { + color: this.props.color, + fontSize: 20, + }, + label: { + color: this.props.color, + fontSize: 10, + }, + }; + return ( + <div + className="flex items-center py2" + onClick={this.props.onClick} + onMouseEnter={this._onToggleHover.bind(this, true)} + onMouseLeave={this._onToggleHover.bind(this, false)} + style={styles.root} + > + <i style={styles.icon} className={`zmdi ${this.props.iconName}`} /> + {!_.isEmpty(this.props.labelText) && ( + <div className="pl1" style={styles.label}> + {this.props.labelText} + </div> + )} + </div> + ); + } + private _onToggleHover(isHovering: boolean): void { + this.setState({ + isHovering, + }); + } +} diff --git a/packages/website/ts/components/ui/token_icon.tsx b/packages/website/ts/components/ui/token_icon.tsx index a9ad567ef..0875cc56b 100644 --- a/packages/website/ts/components/ui/token_icon.tsx +++ b/packages/website/ts/components/ui/token_icon.tsx @@ -6,6 +6,7 @@ import { Token } from 'ts/types'; interface TokenIconProps { token: Token; diameter: number; + link?: string; } interface TokenIconState {} @@ -14,14 +15,20 @@ export class TokenIcon extends React.Component<TokenIconProps, TokenIconState> { public render(): React.ReactNode { const token = this.props.token; const diameter = this.props.diameter; - return ( - <div> - {token.isRegistered && !_.isUndefined(token.iconUrl) ? ( - <img style={{ width: diameter, height: diameter }} src={token.iconUrl} /> - ) : ( - <Identicon address={token.address} diameter={diameter} /> - )} - </div> - ); + const icon = + token.isRegistered && !_.isUndefined(token.iconUrl) ? ( + <img style={{ width: diameter, height: diameter }} src={token.iconUrl} /> + ) : ( + <Identicon address={token.address} diameter={diameter} /> + ); + if (_.isEmpty(this.props.link)) { + return icon; + } else { + return ( + <a href={this.props.link} target="_blank" style={{ textDecoration: 'none' }}> + {icon} + </a> + ); + } } } diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index afcf3862f..d0354580d 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -9,7 +9,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import FlatButton from 'material-ui/FlatButton'; import FloatingActionButton from 'material-ui/FloatingActionButton'; -import { List, ListItem } from 'material-ui/List'; +import { ListItem } from 'material-ui/List'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import ContentAdd from 'material-ui/svg-icons/content/add'; import ContentRemove from 'material-ui/svg-icons/content/remove'; @@ -23,6 +23,7 @@ import firstBy = require('thenby'); import { Blockchain } from 'ts/blockchain'; import { AllowanceToggle } from 'ts/components/inputs/allowance_toggle'; +import { IconButton } from 'ts/components/ui/icon_button'; import { Identicon } from 'ts/components/ui/identicon'; import { TokenIcon } from 'ts/components/ui/token_icon'; import { WalletDisconnectedItem } from 'ts/components/wallet/wallet_disconnected_item'; @@ -91,12 +92,6 @@ const styles: Styles = { boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`, overflow: 'hidden', }, - list: { - padding: 0, - }, - tokenItemInnerDiv: { - paddingLeft: 60, - }, headerItemInnerDiv: { paddingLeft: 65, }, @@ -114,23 +109,19 @@ const styles: Styles = { tokenItem: { backgroundColor: colors.walletDefaultItemBackground, }, - wrappedEtherOpenButtonLabel: { - fontSize: 10, - }, amountLabel: { fontWeight: 'bold', color: colors.black, }, + valueLabel: { + color: colors.grey, + fontSize: 14, + }, paddedItem: { paddingTop: 8, paddingBottom: 8, }, - accessoryItemsContainer: { - width: 150, - right: 8, - }, bodyInnerDiv: { - padding: 0, // TODO: make this completely responsive maxHeight: 475, overflow: 'auto', @@ -154,6 +145,7 @@ const FOOTER_ITEM_KEY = 'FOOTER'; const DISCONNECTED_ITEM_KEY = 'DISCONNECTED'; const ETHER_ITEM_KEY = 'ETHER'; const USD_DECIMAL_PLACES = 2; +const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56; export class Wallet extends React.Component<WalletProps, WalletState> { private _isUnmounted: boolean; @@ -204,16 +196,13 @@ export class Wallet extends React.Component<WalletProps, WalletState> { } public render(): React.ReactNode { const isReadyToRender = this.props.blockchainIsLoaded && this.props.blockchainErr === BlockchainErrs.NoError; - return <div style={styles.root}>{isReadyToRender && this._renderRows()}</div>; - } - private _renderRows(): React.ReactNode { const isAddressAvailable = !_.isEmpty(this.props.userAddress); return ( - <List style={styles.list}> - {isAddressAvailable + <div className="flex flex-column" style={styles.root}> + {isReadyToRender && isAddressAvailable ? _.concat(this._renderConnectedHeaderRows(), this._renderBody(), this._renderFooterRows()) : _.concat(this._renderDisconnectedHeaderRows(), this._renderDisconnectedRows())} - </List> + </div> ); } private _renderDisconnectedHeaderRows(): React.ReactElement<{}> { @@ -259,15 +248,15 @@ export class Wallet extends React.Component<WalletProps, WalletState> { overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden', }; return ( - <ListItem + <div + style={bodyStyle} key={BODY_ITEM_KEY} - innerDivStyle={bodyStyle} onMouseEnter={this._onSidebarHover.bind(this)} onMouseLeave={this._onSidebarHoverOff.bind(this)} > {this._renderEthRows()} {this._renderTokenRows()} - </ListItem> + </div> ); } private _onSidebarHover(event: React.FormEvent<HTMLInputElement>): void { @@ -329,6 +318,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { ); } private _renderEthRows(): React.ReactNode { + const icon = <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />; const primaryText = this._renderAmount( this.props.userEtherBalanceInWei, constants.DECIMAL_PLACES_ETH, @@ -350,33 +340,8 @@ export class Wallet extends React.Component<WalletProps, WalletState> { const style = isInWrappedEtherState ? { ...walletItemStyles.focusedItem, ...styles.paddedItem } : { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem }; - return ( - <div key={ETHER_ITEM_KEY}> - <ListItem - primaryText={primaryText} - secondaryText={secondaryText} - leftIcon={<img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />} - rightAvatar={this._renderAccessoryItems(accessoryItemConfig)} - disableTouchRipple={true} - style={style} - innerDivStyle={styles.tokenItemInnerDiv} - /> - {isInWrappedEtherState && ( - <WrapEtherItem - userAddress={this.props.userAddress} - networkId={this.props.networkId} - blockchain={this.props.blockchain} - dispatcher={this.props.dispatcher} - userEtherBalanceInWei={this.props.userEtherBalanceInWei} - direction={accessoryItemConfig.wrappedEtherDirection} - etherToken={etherToken} - lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} - onConversionSuccessful={this._closeWrappedEtherActionRow.bind(this)} - refetchEthTokenStateAsync={this._refetchTokenStateAsync.bind(this, etherToken.address)} - /> - )} - </div> - ); + const key = ETHER_ITEM_KEY; + return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig); } private _renderTokenRows(): React.ReactNode { const trackedTokens = this.props.trackedTokens; @@ -394,6 +359,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { this.props.networkId, EtherscanLinkSuffixes.Address, ); + const icon = <TokenIcon token={token} diameter={ICON_DIMENSION} link={tokenLink} />; const primaryText = this._renderAmount(tokenState.balance, token.decimals, token.symbol); const secondaryText = this._renderValue(tokenState.balance, token.decimals, tokenState.price); const wrappedEtherDirection = token.symbol === ETHER_TOKEN_SYMBOL ? Side.Receive : undefined; @@ -404,26 +370,34 @@ export class Wallet extends React.Component<WalletProps, WalletState> { tokenState, }, }; - // if this is the last item in the list, do not render the border, it is rendered by the footer - const borderedStyle = index !== this.props.trackedTokens.length - 1 ? styles.borderedItem : {}; + const key = token.address; + return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig); + } + private _renderBalanceRow( + key: string, + icon: React.ReactNode, + primaryText: React.ReactNode, + secondaryText: React.ReactNode, + accessoryItemConfig: AccessoryItemConfig, + ): React.ReactNode { const shouldShowWrapEtherItem = !_.isUndefined(this.state.wrappedEtherDirection) && this.state.wrappedEtherDirection === accessoryItemConfig.wrappedEtherDirection; const style = shouldShowWrapEtherItem ? { ...walletItemStyles.focusedItem, ...styles.paddedItem } - : { ...styles.tokenItem, ...borderedStyle, ...styles.paddedItem }; + : { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem }; const etherToken = this._getEthToken(); return ( - <div key={token.address}> - <ListItem - primaryText={primaryText} - secondaryText={secondaryText} - leftIcon={this._renderTokenIcon(token, tokenLink)} - rightAvatar={this._renderAccessoryItems(accessoryItemConfig)} - disableTouchRipple={true} - style={style} - innerDivStyle={styles.tokenItemInnerDiv} - /> + <div key={key} className="flex flex-column"> + <div className="flex items-center" style={style}> + <div className="px2">{icon}</div> + <div className="flex-none pr2 pt2 pb2"> + {primaryText} + {secondaryText} + </div> + <div className="flex-auto" /> + <div>{this._renderAccessoryItems(accessoryItemConfig)}</div> + </div> {shouldShowWrapEtherItem && ( <WrapEtherItem userAddress={this.props.userAddress} @@ -444,16 +418,19 @@ export class Wallet extends React.Component<WalletProps, WalletState> { private _renderAccessoryItems(config: AccessoryItemConfig): React.ReactElement<{}> { const shouldShowWrappedEtherAction = !_.isUndefined(config.wrappedEtherDirection); const shouldShowToggle = !_.isUndefined(config.allowanceToggleConfig); + // if we don't have a toggle, we still want some space to the right of the "wrap" button so that it aligns with + // the "unwrap" button in the row below + const toggle = shouldShowToggle ? ( + this._renderAllowanceToggle(config.allowanceToggleConfig) + ) : ( + <div style={{ width: NO_ALLOWANCE_TOGGLE_SPACE_WIDTH }} /> + ); return ( - <div style={styles.accessoryItemsContainer}> - <div className="flex"> - <div className="flex-auto"> - {shouldShowWrappedEtherAction && this._renderWrappedEtherButton(config.wrappedEtherDirection)} - </div> - <div className="flex-last py1"> - {shouldShowToggle && this._renderAllowanceToggle(config.allowanceToggleConfig)} - </div> + <div className="flex items-center"> + <div className="flex-auto"> + {shouldShowWrappedEtherAction && this._renderWrappedEtherButton(config.wrappedEtherDirection)} </div> + <div className="flex-last pl2">{toggle}</div> </div> ); } @@ -486,37 +463,24 @@ export class Wallet extends React.Component<WalletProps, WalletState> { const value = unitAmount.mul(price); const formattedAmount = value.toFixed(USD_DECIMAL_PLACES); const result = `$${formattedAmount}`; - return result; - } - private _renderTokenIcon(token: Token, tokenLink?: string): React.ReactElement<{}> { - const tooltipId = `tooltip-${token.address}`; - const tokenIcon = <TokenIcon token={token} diameter={ICON_DIMENSION} />; - if (_.isUndefined(tokenLink)) { - return tokenIcon; - } else { - return ( - <a href={tokenLink} target="_blank" style={{ textDecoration: 'none' }}> - {tokenIcon} - </a> - ); - } + return <div style={styles.valueLabel}>{result}</div>; } private _renderWrappedEtherButton(wrappedEtherDirection: Side): React.ReactNode { const isWrappedEtherDirectionOpen = this.state.wrappedEtherDirection === wrappedEtherDirection; let buttonLabel; - let buttonIcon; + let buttonIconName; if (isWrappedEtherDirectionOpen) { buttonLabel = 'cancel'; - buttonIcon = <Close />; + buttonIconName = 'zmdi-close'; } else { switch (wrappedEtherDirection) { case Side.Deposit: buttonLabel = 'wrap'; - buttonIcon = <NavigationArrowDownward />; + buttonIconName = 'zmdi-long-arrow-down'; break; case Side.Receive: buttonLabel = 'unwrap'; - buttonIcon = <NavigationArrowUpward />; + buttonIconName = 'zmdi-long-arrow-up'; break; default: throw utils.spawnSwitchErr('wrappedEtherDirection', wrappedEtherDirection); @@ -526,14 +490,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { ? this._closeWrappedEtherActionRow.bind(this) : this._openWrappedEtherActionRow.bind(this, wrappedEtherDirection); return ( - <FlatButton - label={buttonLabel} - labelPosition="after" - primary={true} - icon={buttonIcon} - labelStyle={styles.wrappedEtherOpenButtonLabel} - onClick={onClick} - /> + <IconButton iconName={buttonIconName} labelText={buttonLabel} onClick={onClick} color={colors.mediumBlue} /> ); } private _getInitialTrackedTokenStateByAddress(tokenAddresses: string[]): TokenStateByAddress { diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx index 0a0a8a1fe..1dfcffadf 100644 --- a/packages/website/ts/components/wallet/wrap_ether_item.tsx +++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx @@ -37,7 +37,10 @@ interface WrapEtherItemState { } const styles: Styles = { - topLabel: { color: colors.black, fontSize: 11 }, + topLabel: { + color: colors.black, + fontSize: 11, + }, inputContainer: { backgroundColor: colors.white, borderBottomRightRadius: 3, @@ -45,9 +48,10 @@ const styles: Styles = { borderTopRightRadius: 3, borderTopLeftRadius: 3, padding: 4, - width: 125, }, - amountInput: { height: 34 }, + amountInput: { + height: 34, + }, amountInputLabel: { paddingTop: 10, paddingRight: 10, @@ -58,8 +62,6 @@ const styles: Styles = { amountInputHint: { bottom: 18, }, - innerDiv: { paddingLeft: 60, paddingTop: 0, paddingBottom: 10 }, - wrapEtherConfirmationButtonContainer: { width: 128, top: 19 }, wrapEtherConfirmationButtonLabel: { fontSize: 12, color: colors.white, @@ -70,6 +72,9 @@ const styles: Styles = { color: colors.red, minHeight: 20, }, + conversionSpinner: { + paddingTop: 26, + }, }; export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEtherItemState> { @@ -88,11 +93,13 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther ); const isWrappingEth = this.props.direction === Side.Deposit; const topLabelText = isWrappingEth ? 'Convert ETH into WETH 1:1' : 'Convert WETH into ETH 1:1'; + return ( - <ListItem - primaryText={ - <div> - <div style={styles.topLabel}>{topLabelText}</div> + <div className="flex" style={walletItemStyles.focusedItem}> + <div>{this._renderIsEthConversionHappeningSpinner()} </div> + <div className="flex flex-column"> + <div style={styles.topLabel}>{topLabelText}</div> + <div className="flex items-center"> <div style={styles.inputContainer}> {isWrappingEth ? ( <EthAmountInput @@ -131,16 +138,12 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther /> )} </div> - {this._renderErrorMsg()} + <div>{this._renderWrapEtherConfirmationButton()}</div> </div> - } - secondaryTextLines={2} - disableTouchRipple={true} - style={walletItemStyles.focusedItem} - innerDivStyle={styles.innerDiv} - leftIcon={this._renderIsEthConversionHappeningSpinner()} - rightAvatar={this._renderWrapEtherConfirmationButton()} - /> + + {this._renderErrorMsg()} + </div> + </div> ); } private _onValueChange(isValid: boolean, amount?: BigNumber): void { @@ -154,17 +157,19 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther }); } private _renderIsEthConversionHappeningSpinner(): React.ReactElement<{}> { - return this.state.isEthConversionHappening ? ( - <div className="pl1" style={{ paddingTop: 10 }}> + const visibility = this.state.isEthConversionHappening ? 'visible' : 'hidden'; + const style: React.CSSProperties = { ...styles.conversionSpinner, visibility }; + return ( + <div className="pl3 pr2" style={style}> <i className="zmdi zmdi-spinner zmdi-hc-spin" /> </div> - ) : null; + ); } private _renderWrapEtherConfirmationButton(): React.ReactElement<{}> { const isWrappingEth = this.props.direction === Side.Deposit; const labelText = isWrappingEth ? 'wrap' : 'unwrap'; return ( - <div style={styles.wrapEtherConfirmationButtonContainer}> + <div className="pl1 pr3"> <FlatButton backgroundColor={colors.wrapEtherConfirmationButton} label={labelText} |