web3-core-method
Advanced tools
Comparing version 1.2.4 to 1.2.5-rc.0
{ | ||
"name": "web3-core-method", | ||
"version": "1.2.4", | ||
"version": "1.2.5-rc.0", | ||
"description": "Creates the methods on the web3 modules. This is an internal package.", | ||
@@ -17,6 +17,6 @@ "repository": "https://github.com/ethereum/web3.js/tree/1.x/packages/web3-core-method", | ||
"underscore": "1.9.1", | ||
"web3-core-helpers": "1.2.4", | ||
"web3-core-promievent": "1.2.4", | ||
"web3-core-subscriptions": "1.2.4", | ||
"web3-utils": "1.2.4" | ||
"web3-core-helpers": "1.2.5-rc.0", | ||
"web3-core-promievent": "1.2.5-rc.0", | ||
"web3-core-subscriptions": "1.2.5-rc.0", | ||
"web3-utils": "1.2.5-rc.0" | ||
}, | ||
@@ -27,3 +27,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "341015ab24efc3ea1e5d8afd07e8c92a7c738536" | ||
"gitHead": "e919f81ccf7fee23a2d9075fa141bec0ff4a087a" | ||
} |
261
src/index.js
@@ -46,2 +46,3 @@ /* | ||
this.extraFormatters = options.extraFormatters; | ||
this.abiCoder = options.abiCoder; // Will be used to encode the revert reason string | ||
@@ -61,5 +62,6 @@ this.requestManager = options.requestManager; | ||
this.defaultHardfork = options.defaultHardfork; | ||
this.handleRevert = options.handleRevert; | ||
}; | ||
Method.prototype.setRequestManager = function(requestManager, accounts) { | ||
Method.prototype.setRequestManager = function (requestManager, accounts) { | ||
this.requestManager = requestManager; | ||
@@ -74,3 +76,3 @@ | ||
Method.prototype.createFunction = function(requestManager, accounts) { | ||
Method.prototype.createFunction = function (requestManager, accounts) { | ||
var func = this.buildCall(); | ||
@@ -84,3 +86,3 @@ func.call = this.call; | ||
Method.prototype.attachToObject = function(obj) { | ||
Method.prototype.attachToObject = function (obj) { | ||
var func = this.buildCall(); | ||
@@ -104,3 +106,3 @@ func.call = this.call; | ||
*/ | ||
Method.prototype.getCall = function(args) { | ||
Method.prototype.getCall = function (args) { | ||
return _.isFunction(this.call) ? this.call(args) : this.call; | ||
@@ -116,3 +118,3 @@ }; | ||
*/ | ||
Method.prototype.extractCallback = function(args) { | ||
Method.prototype.extractCallback = function (args) { | ||
if (_.isFunction(args[args.length - 1])) { | ||
@@ -130,3 +132,3 @@ return args.pop(); // modify the args array! | ||
*/ | ||
Method.prototype.validateArgs = function(args) { | ||
Method.prototype.validateArgs = function (args) { | ||
if (args.length !== this.params) { | ||
@@ -144,3 +146,3 @@ throw errors.InvalidNumberOfParams(args.length, this.params, this.name); | ||
*/ | ||
Method.prototype.formatInput = function(args) { | ||
Method.prototype.formatInput = function (args) { | ||
var _this = this; | ||
@@ -152,3 +154,3 @@ | ||
return this.inputFormatter.map(function(formatter, index) { | ||
return this.inputFormatter.map(function (formatter, index) { | ||
// bind this for defaultBlock, and defaultAccount | ||
@@ -166,7 +168,7 @@ return formatter ? formatter.call(_this, args[index]) : args[index]; | ||
*/ | ||
Method.prototype.formatOutput = function(result) { | ||
Method.prototype.formatOutput = function (result) { | ||
var _this = this; | ||
if (_.isArray(result)) { | ||
return result.map(function(res) { | ||
return result.map(function (res) { | ||
return _this.outputFormatter && res ? _this.outputFormatter(res) : res; | ||
@@ -186,3 +188,3 @@ }); | ||
*/ | ||
Method.prototype.toPayload = function(args) { | ||
Method.prototype.toPayload = function (args) { | ||
var call = this.getCall(args); | ||
@@ -207,3 +209,3 @@ var callback = this.extractCallback(args); | ||
Method.prototype._confirmTransaction = function(defer, result, payload) { | ||
Method.prototype._confirmTransaction = function (defer, result, payload) { | ||
var method = this, | ||
@@ -221,3 +223,4 @@ promiseResolved = false, | ||
payload.params[0].from && | ||
!payload.params[0].to; | ||
!payload.params[0].to, | ||
hasBytecode = isContractDeployment && payload.params[0].data.length > 2; | ||
@@ -230,3 +233,3 @@ // add custom send Methods | ||
params: 2, | ||
inputFormatter: [formatters.inputBlockNumberFormatter, function(val) { | ||
inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { | ||
return !!val; | ||
@@ -263,3 +266,3 @@ }], | ||
var _ethereumCall = {}; | ||
_.each(_ethereumCalls, function(mthd) { | ||
_.each(_ethereumCalls, function (mthd) { | ||
mthd.attachToObject(_ethereumCall); | ||
@@ -271,3 +274,3 @@ mthd.requestManager = method.requestManager; // assign rather than call setRequestManager() | ||
// fire "receipt" and confirmation events and resolve after | ||
var checkConfirmation = function(existingReceipt, isPolling, err, blockHeader, sub) { | ||
var checkConfirmation = function (existingReceipt, isPolling, err, blockHeader, sub) { | ||
if (!err) { | ||
@@ -277,3 +280,3 @@ // create fake unsubscribe | ||
sub = { | ||
unsubscribe: function() { | ||
unsubscribe: function () { | ||
clearInterval(intervalId); | ||
@@ -286,3 +289,3 @@ } | ||
// catch error from requesting receipt | ||
.catch(function(err) { | ||
.catch(function (err) { | ||
sub.unsubscribe(); | ||
@@ -300,3 +303,3 @@ promiseResolved = true; | ||
// if CONFIRMATION listener exists check for confirmations, by setting canUnsubscribe = false | ||
.then(async function(receipt) { | ||
.then(async function (receipt) { | ||
if (!receipt || !receipt.blockHash) { | ||
@@ -350,3 +353,3 @@ throw new Error('Receipt missing or blockHash null'); | ||
// CHECK for CONTRACT DEPLOYMENT | ||
.then(function(receipt) { | ||
.then(async function (receipt) { | ||
@@ -363,3 +366,3 @@ if (isContractDeployment && !promiseResolved) { | ||
utils._fireError( | ||
new Error('The transaction receipt didn\'t contain a contract address.'), | ||
errors.NoContractAddressFoundError(receipt), | ||
defer.eventEmitter, | ||
@@ -373,39 +376,46 @@ defer.reject, | ||
_ethereumCall.getCode(receipt.contractAddress, function(e, code) { | ||
var code; | ||
try { | ||
code = await _ethereumCall.getCode(receipt.contractAddress); | ||
} catch(err){ | ||
// ignore; | ||
} | ||
if (!code) { | ||
return; | ||
} | ||
if (!code) { | ||
return; | ||
} | ||
// If deployment is status.true and there was a real | ||
// bytecode string, assume it was successful. | ||
var deploymentSuccess = receipt.status === true && hasBytecode; | ||
if (code.length > 2) { | ||
defer.eventEmitter.emit('receipt', receipt); | ||
if (deploymentSuccess || code.length > 2) { | ||
defer.eventEmitter.emit('receipt', receipt); | ||
// if contract, return instance instead of receipt | ||
if (method.extraFormatters && method.extraFormatters.contractDeployFormatter) { | ||
defer.resolve(method.extraFormatters.contractDeployFormatter(receipt)); | ||
} else { | ||
defer.resolve(receipt); | ||
} | ||
// need to remove listeners, as they aren't removed automatically when succesfull | ||
if (canUnsubscribe) { | ||
defer.eventEmitter.removeAllListeners(); | ||
} | ||
// if contract, return instance instead of receipt | ||
if (method.extraFormatters && method.extraFormatters.contractDeployFormatter) { | ||
defer.resolve(method.extraFormatters.contractDeployFormatter(receipt)); | ||
} else { | ||
utils._fireError( | ||
new Error('The contract code couldn\'t be stored, please check your gas limit.'), | ||
defer.eventEmitter, | ||
defer.reject, | ||
null, | ||
receipt | ||
); | ||
defer.resolve(receipt); | ||
} | ||
// need to remove listeners, as they aren't removed automatically when succesfull | ||
if (canUnsubscribe) { | ||
sub.unsubscribe(); | ||
defer.eventEmitter.removeAllListeners(); | ||
} | ||
promiseResolved = true; | ||
}); | ||
} else { | ||
utils._fireError( | ||
errors.ContractCodeNotStoredError(receipt), | ||
defer.eventEmitter, | ||
defer.reject, | ||
null, | ||
receipt | ||
); | ||
} | ||
if (canUnsubscribe) { | ||
sub.unsubscribe(); | ||
} | ||
promiseResolved = true; | ||
} | ||
@@ -416,3 +426,3 @@ | ||
// CHECK for normal tx check for receipt only | ||
.then(function(receipt) { | ||
.then(async function (receipt) { | ||
if (!isContractDeployment && !promiseResolved) { | ||
@@ -434,12 +444,40 @@ if (!receipt.outOfGas && | ||
if (receipt.status === false || receipt.status === '0x0') { | ||
utils._fireError( | ||
new Error('Transaction has been reverted by the EVM:\n' + receiptJSON), | ||
defer.eventEmitter, | ||
defer.reject, | ||
null, | ||
receipt | ||
); | ||
try { | ||
var revertMessage = null; | ||
if (method.handleRevert && method.call === 'eth_sendTransaction') { | ||
// Get revert reason string with eth_call | ||
revertMessage = await method.getRevertReason( | ||
payload.params[0], | ||
receipt.blockNumber | ||
); | ||
if (revertMessage) { // Only throw a revert error if a revert reason is existing | ||
utils._fireError( | ||
errors.TransactionRevertInstructionError(revertMessage.reason, revertMessage.signature, receipt), | ||
defer.eventEmitter, | ||
defer.reject, | ||
null, | ||
receipt | ||
); | ||
} else { | ||
throw false; // Throw false and let the try/catch statement handle the error correctly after | ||
} | ||
} else { | ||
throw false; // Throw false and let the try/catch statement handle the error correctly after | ||
} | ||
} catch (error) { | ||
// Throw an normal revert error if no revert reason is given or the detection of it is disabled | ||
utils._fireError( | ||
errors.TransactionRevertedWithoutReasonError(receipt), | ||
defer.eventEmitter, | ||
defer.reject, | ||
null, | ||
receipt | ||
); | ||
} | ||
} else { | ||
// Throw OOG if status is not existing and provided gas and used gas are equal | ||
utils._fireError( | ||
new Error('Transaction ran out of gas. Please provide more gas:\n' + receiptJSON), | ||
errors.TransactionOutOfGasError(receipt), | ||
defer.eventEmitter, | ||
@@ -461,3 +499,3 @@ defer.reject, | ||
// time out the transaction if not mined after 50 blocks | ||
.catch(function() { | ||
.catch(function () { | ||
timeoutCount++; | ||
@@ -472,3 +510,3 @@ | ||
utils._fireError( | ||
new Error('Transaction was not mined within ' + method.transactionPollingTimeout + ' seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!'), | ||
errors.TransactionError('Transaction was not mined within ' + method.transactionPollingTimeout + ' seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!'), | ||
defer.eventEmitter, | ||
@@ -483,3 +521,3 @@ defer.reject | ||
utils._fireError( | ||
new Error('Transaction was not mined within ' + method.transactionBlockTimeout + ' blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!'), | ||
errors.TransactionError('Transaction was not mined within ' + method.transactionBlockTimeout + ' blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!'), | ||
defer.eventEmitter, | ||
@@ -504,3 +542,3 @@ defer.reject | ||
// start watching for confirmation depending on the support features of the provider | ||
var startWatching = function(existingReceipt) { | ||
var startWatching = function (existingReceipt) { | ||
// if provider allows PUB/SUB | ||
@@ -517,3 +555,3 @@ if (_.isFunction(this.requestManager.provider.on)) { | ||
_ethereumCall.getTransactionReceipt(result) | ||
.then(function(receipt) { | ||
.then(function (receipt) { | ||
if (receipt && receipt.blockHash) { | ||
@@ -530,3 +568,3 @@ if (defer.eventEmitter.listeners('confirmation').length > 0) { | ||
}) | ||
.catch(function() { | ||
.catch(function () { | ||
if (!promiseResolved) startWatching(); | ||
@@ -538,3 +576,3 @@ }); | ||
var getWallet = function(from, accounts) { | ||
var getWallet = function (from, accounts) { | ||
var wallet = null; | ||
@@ -558,14 +596,32 @@ | ||
Method.prototype.buildCall = function() { | ||
Method.prototype.buildCall = function () { | ||
var method = this, | ||
isSendTx = (method.call === 'eth_sendTransaction' || method.call === 'eth_sendRawTransaction'); // || method.call === 'personal_sendTransaction' | ||
isSendTx = (method.call === 'eth_sendTransaction' || method.call === 'eth_sendRawTransaction'), // || method.call === 'personal_sendTransaction' | ||
isCall = (method.call === 'eth_call'); | ||
// actual send function | ||
var send = function() { | ||
var send = function () { | ||
var defer = promiEvent(!isSendTx), | ||
payload = method.toPayload(Array.prototype.slice.call(arguments)); | ||
// CALLBACK function | ||
var sendTxCallback = function (err, result) { | ||
if (method.handleRevert && !err && isCall && (method.isRevertReasonString(result) && method.abiCoder)) { | ||
var reason = method.abiCoder.decodeParameter('string', '0x' + result.substring(10)); | ||
var signature = 'Error(String)'; | ||
// CALLBACK function | ||
var sendTxCallback = function(err, result) { | ||
utils._fireError( | ||
errors.RevertInstructionError(reason, signature), | ||
defer.eventEmitter, | ||
defer.reject, | ||
payload.callback, | ||
{ | ||
reason: reason, | ||
signature: signature | ||
} | ||
); | ||
return; | ||
} | ||
try { | ||
@@ -595,6 +651,4 @@ result = method.formatOutput(result); | ||
if (!isSendTx) { | ||
if (!err) { | ||
defer.resolve(result); | ||
} | ||
@@ -612,3 +666,3 @@ | ||
// SENDS the SIGNED SIGNATURE | ||
var sendSignedTx = function(sign) { | ||
var sendSignedTx = function (sign) { | ||
@@ -624,3 +678,3 @@ var signedPayload = _.extend({}, payload, { | ||
var sendRequest = function(payload, method) { | ||
var sendRequest = function (payload, method) { | ||
@@ -654,7 +708,7 @@ if (method && method.accounts && method.accounts.wallet && method.accounts.wallet.length) { | ||
.then(sendSignedTx) | ||
.catch(function(err) { | ||
.catch(function (err) { | ||
if (_.isFunction(defer.eventEmitter.listeners) && defer.eventEmitter.listeners('error').length) { | ||
defer.eventEmitter.emit('error', err); | ||
defer.eventEmitter.removeAllListeners(); | ||
defer.eventEmitter.catch(function() { | ||
defer.eventEmitter.catch(function () { | ||
}); | ||
@@ -699,3 +753,3 @@ } | ||
getGasPrice(function(err, gasPrice) { | ||
getGasPrice(function (err, gasPrice) { | ||
@@ -724,2 +778,53 @@ if (gasPrice) { | ||
/** | ||
* Returns the revert reason string if existing or otherwise false. | ||
* | ||
* @method getRevertReason | ||
* | ||
* @param {Object} txOptions | ||
* @param {Number} blockNumber | ||
* | ||
* @returns {Promise<Boolean|String>} | ||
*/ | ||
Method.prototype.getRevertReason = function (txOptions, blockNumber) { | ||
var self = this; | ||
return new Promise(function (resolve, reject) { | ||
(new Method({ | ||
name: 'call', | ||
call: 'eth_call', | ||
params: 2, | ||
abiCoder: self.abiCoder, | ||
handleRevert: true | ||
})) | ||
.createFunction(self.requestManager)(txOptions, utils.numberToHex(blockNumber)) | ||
.then(function () { | ||
resolve(false); | ||
}) | ||
.catch(function (error) { | ||
if (error.reason) { | ||
resolve({ | ||
reason: error.reason, | ||
signature: error.signature | ||
}); | ||
} else { | ||
reject(error); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
* Checks if the given hex string is a revert message from the EVM | ||
* | ||
* @method isRevertReasonString | ||
* | ||
* @param {String} data - Hex string prefixed with 0x | ||
* | ||
* @returns {Boolean} | ||
*/ | ||
Method.prototype.isRevertReasonString = function (data) { | ||
return _.isString(data) && ((data.length - 2) / 2) % 32 === 4 && data.substring(0, 10) === '0x08c379a0'; | ||
}; | ||
/** | ||
* Should be called to create the pure JSONRPC request which can be used in a batch request | ||
@@ -730,3 +835,3 @@ * | ||
*/ | ||
Method.prototype.request = function() { | ||
Method.prototype.request = function () { | ||
var payload = this.toPayload(Array.prototype.slice.call(arguments)); | ||
@@ -733,0 +838,0 @@ payload.format = this.formatOutput.bind(this); |
@@ -32,2 +32,3 @@ /* | ||
defaultAccount?: string | null; | ||
abiCoder?: any | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
34218
740
2
+ Addedweb3-core-helpers@1.2.5-rc.0(transitive)
+ Addedweb3-core-promievent@1.2.5-rc.0(transitive)
+ Addedweb3-core-subscriptions@1.2.5-rc.0(transitive)
+ Addedweb3-eth-iban@1.2.5-rc.0(transitive)
+ Addedweb3-utils@1.2.5-rc.0(transitive)
- Removedweb3-core-helpers@1.2.4(transitive)
- Removedweb3-core-promievent@1.2.4(transitive)
- Removedweb3-core-subscriptions@1.2.4(transitive)
- Removedweb3-eth-iban@1.2.4(transitive)
- Removedweb3-utils@1.2.4(transitive)
Updatedweb3-core-helpers@1.2.5-rc.0
Updatedweb3-utils@1.2.5-rc.0