diff --git a/CHANGELOG.md b/CHANGELOG.md index a58caffa3e9..b788f452d0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -493,4 +493,13 @@ Released with 1.0.0-beta.37 code base. ## [Unreleased] -## [1.8.0] +## [1.7.1] + +### Added +- `transactionPollingInterval` added to web3, contract and method constructor options. defaults to 1 second. (#4584) + +### Fixed +- Fix a typo in the documentation for `methods.myMethod.send` (#4599) +- Added effectiveGasPrice to TransactionReceipt (#4692) +- Correction in documentation for `web3.eth.accounts.signTransaction` (#4576) +- Updated README to include Webpack 5 create-react-app support instructions (#4173) diff --git a/README.md b/README.md index 74d518f98fa..525abb92dd9 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,83 @@ If you are using the types in a `commonjs` module, like in a Node app, you just ## Trouble shooting and known issues. +### Web3 and Create-react-app + +If you are using create-react-app version >=5 you may run into issues building. This is because NodeJS polyfills are not included in the latest version of create-react-app. + +### Solution + + +- Install react-app-rewired and the missing modules + +If you are using yarn: +```bash +yarn add --dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer +``` + +If you are using npm: +```bash +npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process +``` + +- Create `config-overrides.js` in the root of your project folder with the content: + +```javascript +const webpack = require('webpack'); + +module.exports = function override(config) { + const fallback = config.resolve.fallback || {}; + Object.assign(fallback, { + "crypto": require.resolve("crypto-browserify"), + "stream": require.resolve("stream-browserify"), + "assert": require.resolve("assert"), + "http": require.resolve("stream-http"), + "https": require.resolve("https-browserify"), + "os": require.resolve("os-browserify"), + "url": require.resolve("url") + }) + config.resolve.fallback = fallback; + config.plugins = (config.plugins || []).concat([ + new webpack.ProvidePlugin({ + process: 'process/browser', + Buffer: ['buffer', 'Buffer'] + }) + ]) + return config; +} +``` + +- Within `package.json` change the scripts field for start, build and test. Instead of `react-scripts` replace it with `react-app-rewired` + +before: +```typescript +"scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" +}, +``` + +after: +```typescript +"scripts": { + "start": "react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test", + "eject": "react-scripts eject" +}, +``` + +The missing Nodejs polyfills should be included now and your app should be functional with web3. +- If you want to hide the warnings created by the console: + +In `config-overrides.js` within the `override` function, add: + +```javascript +config.ignoreWarnings = [/Failed to parse source map/]; +``` + ### Web3 and Angular ### New solution diff --git a/docs/web3-eth-accounts.rst b/docs/web3-eth-accounts.rst index 2cb66760495..054078f913a 100644 --- a/docs/web3-eth-accounts.rst +++ b/docs/web3-eth-accounts.rst @@ -151,7 +151,7 @@ Parameters 1. ``tx`` - ``Object``: The transaction object as follows: - ``nonce`` - ``String``: (optional) The nonce to use when signing this transaction. Default will use :ref:`web3.eth.getTransactionCount() `. - - ``chainId`` - ``String``: (optional) The chain id to use when signing this transaction. Default will use :ref:`web3.eth.net.getId() `. Web3 will ignore this field if `common.customChain.chainId` is provided. + - ``chainId`` - ``String``: (optional) The chain id to use when signing this transaction. Default will use :ref:`web3.eth.getChainId() `. Web3 will ignore this field if `common.customChain.chainId` is provided. - ``to`` - ``String``: (optional) The recevier of the transaction, can be empty when deploying a contract. - ``data`` - ``String``: (optional) The call data of the transaction, can be empty for simple value transfers. - ``value`` - ``String``: (optional) The value of the transaction in wei. diff --git a/docs/web3-eth-contract.rst b/docs/web3-eth-contract.rst index 47a4c225f62..97b6acfdc2d 100644 --- a/docs/web3-eth-contract.rst +++ b/docs/web3-eth-contract.rst @@ -380,6 +380,27 @@ Returns ------------------------------------------------------------------------------ +.. _eth-contract-module-transactionpollinginterval: + +transactionPollingInterval +===================== + +.. code-block:: javascript + + web3.eth.Contract.transactionPollingInterval + contract.transactionPollingInterval // on contract instance + +The ``transactionPollingInterval`` is used over HTTP connections. This option defines the number of seconds between Web3 calls for a receipt which confirms that a transaction was mined by the network. + + +------- +Returns +------- + +``number``: The current value of transactionPollingInterval (default: 1000ms) + +------------------------------------------------------------------------------ + .. _eth-contract-module-handlerevert: handleRevert @@ -859,7 +880,7 @@ Parameters * ``from`` - ``String``: The address the transaction should be sent from. * ``gasPrice`` - ``String`` (optional): The gas price in wei to use for this transaction. * ``gas`` - ``Number`` (optional): The maximum gas provided for this transaction (gas limit). - * ``value`` - ``Number|String|BN|BigNumber``(optional): The value transferred for the transaction in wei. + * ``value`` - ``Number|String|BN|BigNumber`` (optional): The value transferred for the transaction in wei. * ``nonce`` - ``Number`` (optional): the nonce number of transaction 2. ``callback`` - ``Function`` (optional): This callback will be fired first with the "transactionHash", or with an error object as the first argument. diff --git a/docs/web3-eth.rst b/docs/web3-eth.rst index 3194ef7287d..42628007aab 100644 --- a/docs/web3-eth.rst +++ b/docs/web3-eth.rst @@ -475,6 +475,26 @@ Example web3.eth.transactionPollingTimeout = 1000; +------------------------------------------------------------------------------ + +.. _eth-module-transactionpollinginterval: + +transactionPollingInterval +===================== + +.. code-block:: javascript + + web3.eth.transactionPollingInterval + +The ``transactionPollingInterval`` is used over HTTP connections. This option defines the number of seconds between Web3 calls for a receipt which confirms that a transaction was mined by the network. + + +------- +Returns +------- + +``number``: The current value of transactionPollingInterval (default: 1000ms) + ------------------------------------------------------------------------------ .. _web3-module-handlerevert: @@ -1402,8 +1422,9 @@ Returns - ``to`` - ``String``: Address of the receiver. ``null`` when it's a contract creation transaction. - ``contractAddress`` - ``String``: The contract address created, if the transaction was a contract creation, otherwise ``null``. - ``cumulativeGasUsed`` - ``Number``: The total amount of gas used when this transaction was executed in the block. - - ``gasUsed``- ``Number``: The amount of gas used by this specific transaction alone. + - ``gasUsed`` - ``Number``: The amount of gas used by this specific transaction alone. - ``logs`` - ``Array``: Array of log objects, which this transaction generated. + - ``effectiveGasPrice`` - ``Number``: The actual value per gas deducted from the senders account. Before EIP-1559, this is equal to the transaction's gas price. After, it is equal to baseFeePerGas + min(maxFeePerGas - baseFeePerGas, maxPriorityFeePerGas). ------- Example diff --git a/packages/web3-core-helpers/src/formatters.js b/packages/web3-core-helpers/src/formatters.js index 94b29cfa432..cef20a7090b 100644 --- a/packages/web3-core-helpers/src/formatters.js +++ b/packages/web3-core-helpers/src/formatters.js @@ -288,6 +288,9 @@ var outputTransactionReceiptFormatter = function (receipt) { receipt.logs = receipt.logs.map(outputLogFormatter); } + if (receipt.effectiveGasPrice) { + receipt.effectiveGasPrice = utils.hexToNumber(receipt.effectiveGasPrice) + } if (receipt.contractAddress) { receipt.contractAddress = utils.toChecksumAddress(receipt.contractAddress); } diff --git a/packages/web3-core-method/src/index.js b/packages/web3-core-method/src/index.js index afffc8560a1..e50a286b06e 100644 --- a/packages/web3-core-method/src/index.js +++ b/packages/web3-core-method/src/index.js @@ -56,6 +56,7 @@ var Method = function Method(options) { this.transactionBlockTimeout = options.transactionBlockTimeout || 50; this.transactionConfirmationBlocks = options.transactionConfirmationBlocks || 24; this.transactionPollingTimeout = options.transactionPollingTimeout || 750; + this.transactionPollingInterval = options.transactionPollingInterval || 1000; this.blockHeaderTimeout = options.blockHeaderTimeout || 10; // 10 seconds this.defaultCommon = options.defaultCommon; this.defaultChain = options.defaultChain; @@ -553,7 +554,7 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { let blockHeaderArrived = false; const startInterval = () => { - intervalId = setInterval(checkConfirmation.bind(null, existingReceipt, true), 1000); + intervalId = setInterval(checkConfirmation.bind(null, existingReceipt, true), method.transactionPollingInterval); }; // If provider do not support event subscription use polling diff --git a/packages/web3-core/types/index.d.ts b/packages/web3-core/types/index.d.ts index 4065992bc7b..3015bf288a3 100644 --- a/packages/web3-core/types/index.d.ts +++ b/packages/web3-core/types/index.d.ts @@ -213,6 +213,7 @@ export interface TransactionReceipt { contractAddress?: string; cumulativeGasUsed: number; gasUsed: number; + effectiveGasPrice: number; logs: Log[]; logsBloom: string; events?: { diff --git a/packages/web3-eth-contract/src/index.js b/packages/web3-eth-contract/src/index.js index 65c028379e5..c04758d22ea 100644 --- a/packages/web3-eth-contract/src/index.js +++ b/packages/web3-eth-contract/src/index.js @@ -234,6 +234,19 @@ var Contract = function Contract(jsonInterface, address, options) { }, enumerable: true }); + Object.defineProperty(this, 'transactionPollingInterval', { + get: function () { + if (_this.options.transactionPollingInterval === 0) { + return _this.options.transactionPollingInterval; + } + + return _this.options.transactionPollingInterval || this.constructor.transactionPollingInterval; + }, + set: function (val) { + _this.options.transactionPollingInterval = val; + }, + enumerable: true + }); Object.defineProperty(this, 'transactionConfirmationBlocks', { get: function () { if (_this.options.transactionConfirmationBlocks === 0) { @@ -1045,6 +1058,7 @@ Contract.prototype._executeMethod = function _executeMethod(){ transactionBlockTimeout: _this._parent.transactionBlockTimeout, transactionConfirmationBlocks: _this._parent.transactionConfirmationBlocks, transactionPollingTimeout: _this._parent.transactionPollingTimeout, + transactionPollingInterval: _this._parent.transactionPollingInterval, defaultCommon: _this._parent.defaultCommon, defaultChain: _this._parent.defaultChain, defaultHardfork: _this._parent.defaultHardfork, diff --git a/packages/web3-eth/src/index.js b/packages/web3-eth/src/index.js index a7efae31034..daffdee042b 100644 --- a/packages/web3-eth/src/index.js +++ b/packages/web3-eth/src/index.js @@ -100,6 +100,7 @@ var Eth = function Eth() { var transactionBlockTimeout = 50; var transactionConfirmationBlocks = 24; var transactionPollingTimeout = 750; + var transactionPollingInterval = 1000; var blockHeaderTimeout = 10; // 10 seconds var maxListenersWarningThreshold = 100; var defaultChain, defaultHardfork, defaultCommon; @@ -189,6 +190,23 @@ var Eth = function Eth() { }, enumerable: true }); + Object.defineProperty(this, 'transactionPollingInterval', { + get: function () { + return transactionPollingInterval; + }, + set: function (val) { + transactionPollingInterval = val; + + // also set on the Contract object + _this.Contract.transactionPollingInterval = transactionPollingInterval; + + // update defaultBlock + methods.forEach(function(method) { + method.transactionPollingInterval = transactionPollingInterval; + }); + }, + enumerable: true + }); Object.defineProperty(this, 'transactionConfirmationBlocks', { get: function () { return transactionConfirmationBlocks; @@ -351,6 +369,7 @@ var Eth = function Eth() { this.Contract.transactionBlockTimeout = this.transactionBlockTimeout; this.Contract.transactionConfirmationBlocks = this.transactionConfirmationBlocks; this.Contract.transactionPollingTimeout = this.transactionPollingTimeout; + this.Contract.transactionPollingInterval = this.transactionPollingInterval; this.Contract.blockHeaderTimeout = this.blockHeaderTimeout; this.Contract.handleRevert = this.handleRevert; this.Contract._requestManager = this._requestManager; @@ -680,6 +699,7 @@ var Eth = function Eth() { method.transactionBlockTimeout = _this.transactionBlockTimeout; method.transactionConfirmationBlocks = _this.transactionConfirmationBlocks; method.transactionPollingTimeout = _this.transactionPollingTimeout; + method.transactionPollingInterval = _this.transactionPollingInterval; method.handleRevert = _this.handleRevert; }); diff --git a/test/contract.js b/test/contract.js index 3c7352d4383..9a7fa16894d 100644 --- a/test/contract.js +++ b/test/contract.js @@ -356,6 +356,21 @@ var runTests = function(contractFactory) { assert.equal(contract.options.transactionPollingTimeout, 0); }); + it('should define the transactionPollingInterval object property if passed over the options', function() { + var provider = new FakeIpcProvider(); + var contract = contractFactory(abi, address, {transactionPollingInterval: 0}, provider); + + assert.equal(contract.transactionPollingInterval, 0); + assert.equal(contract.options.transactionPollingInterval, 0); + }); + it('should update the transactionPollingInterval property in the options object', function() { + var provider = new FakeIpcProvider(); + var contract = contractFactory(abi, address, {transactionPollingInterval: 1}, provider); + + contract.transactionPollingInterval = 0; + + assert.equal(contract.options.transactionPollingInterval, 0); + }); it('should define the transactionConfirmationBlocks object property if passed over the options', function() { var provider = new FakeIpcProvider(); var contract = contractFactory(abi, address, {transactionConfirmationBlocks: 0}, provider); diff --git a/test/eth.getTransactionReceipt.js b/test/eth.getTransactionReceipt.js index dabb7f6bb64..ee86e5bf85d 100644 --- a/test/eth.getTransactionReceipt.js +++ b/test/eth.getTransactionReceipt.js @@ -10,6 +10,7 @@ var txResult = { "contractAddress":"0x407d73d8a49eeb85d32cf465507dd71d507100c1", "cumulativeGasUsed":"0x7f110", "gasUsed": "0x7f110", + "effectiveGasPrice": "0x09184e72a000", "logs": [{ transactionIndex: '0x3e8', logIndex: '0x3e8', @@ -36,6 +37,7 @@ var formattedTxResult = { "contractAddress":"0x407D73d8a49eeb85D32Cf465507dd71d507100c1", // checksum address "cumulativeGasUsed": 520464, "gasUsed": 520464, + "effectiveGasPrice": 10000000000000, "logs": [{ id: "log_2b801386", transactionIndex: 1000, diff --git a/test/eth.transactionPollingInterval.js b/test/eth.transactionPollingInterval.js new file mode 100644 index 00000000000..06505e598f8 --- /dev/null +++ b/test/eth.transactionPollingInterval.js @@ -0,0 +1,25 @@ +var chai = require('chai'); +var assert = chai.assert; +var Eth = require('../packages/web3-eth'); + +var eth = new Eth(); + +var setValue = 123; + +describe('web3.eth', function () { + describe('transactionPollingInterval', function () { + it('should check if transactionPollingInterval is set to proper value', function () { + assert.equal(eth.transactionPollingInterval, 1000); + assert.equal(eth.Contract.transactionPollingInterval, 1000); + assert.equal(eth.getCode.method.transactionPollingInterval, 1000); + }); + it('should set transactionPollingInterval for all sub packages is set to proper value, if Eth package is changed', function () { + eth.transactionPollingInterval = setValue; + + assert.equal(eth.transactionPollingInterval, setValue); + assert.equal(eth.Contract.transactionPollingInterval, setValue); + assert.equal(eth.getCode.method.transactionPollingInterval, setValue); + }); + }); +}); +