UNPKG

web3-provider-engine

Version:

A JavaScript library for composing Ethereum provider objects using middleware modules

1,278 lines (1,253 loc) 2.56 MB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ZeroClientProvider = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; var EventEmitter = require('events').EventEmitter; var inherits = require('util').inherits; var ethUtil = require('@ethereumjs/util'); var _require = require('eth-block-tracker'), PollingBlockTracker = _require.PollingBlockTracker; var map = require('async/map'); var eachSeries = require('async/eachSeries'); var Stoplight = require('./util/stoplight.js'); var cacheUtils = require('./util/rpc-cache-utils.js'); var createPayload = require('./util/create-payload.js'); var noop = function noop() {}; module.exports = Web3ProviderEngine; inherits(Web3ProviderEngine, EventEmitter); function Web3ProviderEngine(opts) { var self = this; EventEmitter.call(self); self.setMaxListeners(30); // parse options opts = opts || {}; // block polling var directProvider = { sendAsync: self._handleAsync.bind(self) }; var blockTrackerProvider = opts.blockTrackerProvider || directProvider; self._blockTracker = opts.blockTracker || new PollingBlockTracker({ provider: blockTrackerProvider, pollingInterval: opts.pollingInterval || 4000, setSkipCacheFlag: true }); // set initialization blocker self._ready = new Stoplight(); // local state self.currentBlock = null; self._providers = []; } // public Web3ProviderEngine.prototype.start = function () { var _this = this; var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop; var self = this; // trigger start self._ready.go(); // on new block, request block body and emit as events self._blockTracker.on('latest', function (blockNumber) { // get block body self._getBlockByNumberWithRetry(blockNumber, function (err, block) { if (err) { _this.emit('error', err); return; } if (!block) { console.log(block); _this.emit('error', new Error("Could not find block")); return; } var bufferBlock = toBufferBlock(block); // set current + emit "block" event self._setCurrentBlock(bufferBlock); // emit other events self.emit('rawBlock', block); self.emit('latest', block); }); }); // forward other events self._blockTracker.on('sync', self.emit.bind(self, 'sync')); self._blockTracker.on('error', self.emit.bind(self, 'error')); // update state self._running = true; // signal that we started self.emit('start'); }; Web3ProviderEngine.prototype.stop = function () { var self = this; // stop block polling by removing event listeners self._blockTracker.removeAllListeners(); // update state self._running = false; // signal that we stopped self.emit('stop'); }; Web3ProviderEngine.prototype.isRunning = function () { var self = this; return self._running; }; Web3ProviderEngine.prototype.addProvider = function (source, index) { var self = this; if (typeof index === 'number') { self._providers.splice(index, 0, source); } else { self._providers.push(source); } source.setEngine(this); }; Web3ProviderEngine.prototype.removeProvider = function (source) { var self = this; var index = self._providers.indexOf(source); if (index < 0) throw new Error('Provider not found.'); self._providers.splice(index, 1); }; Web3ProviderEngine.prototype.send = function (payload) { throw new Error('Web3ProviderEngine does not support synchronous requests.'); }; Web3ProviderEngine.prototype.sendAsync = function (payload, cb) { var self = this; self._ready["await"](function () { if (Array.isArray(payload)) { // handle batch map(payload, self._handleAsync.bind(self), cb); } else { // handle single self._handleAsync(payload, cb); } }); }; // private Web3ProviderEngine.prototype._getBlockByNumberWithRetry = function (blockNumber, cb) { var self = this; var retriesRemaining = 5; attemptRequest(); return; function attemptRequest() { self._getBlockByNumber(blockNumber, afterRequest); } function afterRequest(err, block) { // anomalous error occurred if (err) return cb(err); // block not ready yet if (!block) { if (retriesRemaining > 0) { // wait 1s then try again retriesRemaining--; setTimeout(function () { attemptRequest(); }, 1000); return; } else { // give up, return a null block cb(null, null); return; } } // otherwise return result cb(null, block); return; } }; Web3ProviderEngine.prototype._getBlockByNumber = function (blockNumber, cb) { var req = createPayload({ method: 'eth_getBlockByNumber', params: [blockNumber, false], skipCache: true }); this._handleAsync(req, function (err, res) { if (err) return cb(err); return cb(null, res.result); }); }; Web3ProviderEngine.prototype._handleAsync = function (payload, finished) { var self = this; var currentProvider = -1; var result = null; var error = null; var stack = []; next(); function next(after) { currentProvider += 1; stack.unshift(after); // Bubbled down as far as we could go, and the request wasn't // handled. Return an error. if (currentProvider >= self._providers.length) { end(new Error('Request for method "' + payload.method + '" not handled by any subprovider. Please check your subprovider configuration to ensure this method is handled.')); } else { try { var provider = self._providers[currentProvider]; provider.handleRequest(payload, next, end); } catch (e) { end(e); } } } function end(_error, _result) { error = _error; result = _result; eachSeries(stack, function (fn, callback) { if (fn) { fn(error, result, callback); } else { callback(); } }, function () { var resultObj = { id: payload.id, jsonrpc: payload.jsonrpc, result: result }; if (error != null) { resultObj.error = { message: error.stack || error.message || error, code: -32000 }; // respond with both error formats finished(error, resultObj); } else { finished(null, resultObj); } }); } }; // // from remote-data // Web3ProviderEngine.prototype._setCurrentBlock = function (block) { var self = this; self.currentBlock = block; self.emit('block', block); }; // util function toBufferBlock(jsonBlock) { return { number: ethUtil.toBuffer(jsonBlock.number), hash: ethUtil.toBuffer(jsonBlock.hash), parentHash: ethUtil.toBuffer(jsonBlock.parentHash), nonce: ethUtil.toBuffer(jsonBlock.nonce), mixHash: ethUtil.toBuffer(jsonBlock.mixHash), sha3Uncles: ethUtil.toBuffer(jsonBlock.sha3Uncles), logsBloom: ethUtil.toBuffer(jsonBlock.logsBloom), transactionsRoot: ethUtil.toBuffer(jsonBlock.transactionsRoot), stateRoot: ethUtil.toBuffer(jsonBlock.stateRoot), receiptsRoot: ethUtil.toBuffer(jsonBlock.receiptRoot || jsonBlock.receiptsRoot), miner: ethUtil.toBuffer(jsonBlock.miner), difficulty: ethUtil.toBuffer(jsonBlock.difficulty), totalDifficulty: ethUtil.toBuffer(jsonBlock.totalDifficulty), size: ethUtil.toBuffer(jsonBlock.size), extraData: ethUtil.toBuffer(jsonBlock.extraData), gasLimit: ethUtil.toBuffer(jsonBlock.gasLimit), gasUsed: ethUtil.toBuffer(jsonBlock.gasUsed), timestamp: ethUtil.toBuffer(jsonBlock.timestamp), transactions: jsonBlock.transactions }; } },{"./util/create-payload.js":450,"./util/rpc-cache-utils.js":453,"./util/stoplight.js":454,"@ethereumjs/util":74,"async/eachSeries":256,"async/map":272,"eth-block-tracker":306,"events":311,"util":431}],2:[function(require,module,exports){ module.exports={ "name": "goerli", "chainId": 5, "networkId": 5, "defaultHardfork": "merge", "consensus": { "type": "poa", "algorithm": "clique", "clique": { "period": 15, "epoch": 30000 } }, "comment": "Cross-client PoA test network", "url": "https://github.com/goerli/testnet", "genesis": { "timestamp": "0x5c51a607", "gasLimit": 10485760, "difficulty": 1, "nonce": "0x0000000000000000", "extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, "hardforks": [ { "name": "chainstart", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "homestead", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "tangerineWhistle", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "spuriousDragon", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "byzantium", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "constantinople", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "petersburg", "block": 0, "forkHash": "0xa3f5ab08" }, { "name": "istanbul", "block": 1561651, "forkHash": "0xc25efa5c" }, { "name": "berlin", "block": 4460644, "forkHash": "0x757a1c47" }, { "name": "london", "block": 5062605, "forkHash": "0xb8c6299d" }, { "//_comment": "The forkHash will remain same as mergeForkIdTransition is post merge, terminal block: https://goerli.etherscan.io/block/7382818", "name": "merge", "ttd": "10790000", "block": 7382819, "forkHash": "0xb8c6299d" }, { "name": "mergeForkIdTransition", "block": null, "forkHash": null }, { "name": "shanghai", "block": null, "timestamp": "1678832736", "forkHash": "0xf9843abf" } ], "bootstrapNodes": [ { "ip": "51.141.78.53", "port": 30303, "id": "011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a", "location": "", "comment": "Upstream bootnode 1" }, { "ip": "13.93.54.137", "port": 30303, "id": "176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b", "location": "", "comment": "Upstream bootnode 2" }, { "ip": "94.237.54.114", "port": 30313, "id": "46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291", "location": "", "comment": "Upstream bootnode 3" }, { "ip": "18.218.250.66", "port": 30313, "id": "b5948a2d3e9d486c4d75bf32713221c2bd6cf86463302339299bd227dc2e276cd5a1c7ca4f43a0e9122fe9af884efed563bd2a1fd28661f3b5f5ad7bf1de5949", "location": "", "comment": "Upstream bootnode 4" }, { "ip": "3.11.147.67", "port": 30303, "id": "a61215641fb8714a373c80edbfa0ea8878243193f57c96eeb44d0bc019ef295abd4e044fd619bfc4c59731a73fb79afe84e9ab6da0c743ceb479cbb6d263fa91", "location": "", "comment": "Ethereum Foundation bootnode" }, { "ip": "51.15.116.226", "port": 30303, "id": "a869b02cec167211fb4815a82941db2e7ed2936fd90e78619c53eb17753fcf0207463e3419c264e2a1dd8786de0df7e68cf99571ab8aeb7c4e51367ef186b1dd", "location": "", "comment": "Goerli Initiative bootnode" }, { "ip": "51.15.119.157", "port": 30303, "id": "807b37ee4816ecf407e9112224494b74dd5933625f655962d892f2f0f02d7fbbb3e2a94cf87a96609526f30c998fd71e93e2f53015c558ffc8b03eceaf30ee33", "location": "", "comment": "Goerli Initiative bootnode" }, { "ip": "51.15.119.157", "port": 40303, "id": "a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd", "location": "", "comment": "Goerli Initiative bootnode" } ], "dnsNetworks": [ "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.goerli.ethdisco.net" ] } },{}],3:[function(require,module,exports){ module.exports={ "name": "mainnet", "chainId": 1, "networkId": 1, "defaultHardfork": "merge", "consensus": { "type": "pow", "algorithm": "ethash", "ethash": {} }, "comment": "The Ethereum main chain", "url": "https://ethstats.net/", "genesis": { "gasLimit": 5000, "difficulty": 17179869184, "nonce": "0x0000000000000042", "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa" }, "hardforks": [ { "name": "chainstart", "block": 0, "forkHash": "0xfc64ec04" }, { "name": "homestead", "block": 1150000, "forkHash": "0x97c2c34c" }, { "name": "dao", "block": 1920000, "forkHash": "0x91d1f948" }, { "name": "tangerineWhistle", "block": 2463000, "forkHash": "0x7a64da13" }, { "name": "spuriousDragon", "block": 2675000, "forkHash": "0x3edd5b10" }, { "name": "byzantium", "block": 4370000, "forkHash": "0xa00bc324" }, { "name": "constantinople", "block": 7280000, "forkHash": "0x668db0af" }, { "name": "petersburg", "block": 7280000, "forkHash": "0x668db0af" }, { "name": "istanbul", "block": 9069000, "forkHash": "0x879d6e30" }, { "name": "muirGlacier", "block": 9200000, "forkHash": "0xe029e991" }, { "name": "berlin", "block": 12244000, "forkHash": "0x0eb440f6" }, { "name": "london", "block": 12965000, "forkHash": "0xb715077d" }, { "name": "arrowGlacier", "block": 13773000, "forkHash": "0x20c327fc" }, { "name": "grayGlacier", "block": 15050000, "forkHash": "0xf0afd0e3" }, { "//_comment": "The forkHash will remain same as mergeForkIdTransition is post merge, terminal block: https://etherscan.io/block/15537393", "name": "merge", "ttd": "58750000000000000000000", "block": 15537394, "forkHash": "0xf0afd0e3" }, { "name": "mergeForkIdTransition", "block": null, "forkHash": null }, { "name": "shanghai", "block": null, "timestamp": "1681338455", "forkHash": "0xdce96c2d" } ], "bootstrapNodes": [ { "ip": "18.138.108.67", "port": 30303, "id": "d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666", "location": "ap-southeast-1-001", "comment": "bootnode-aws-ap-southeast-1-001" }, { "ip": "3.209.45.79", "port": 30303, "id": "22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de", "location": "us-east-1-001", "comment": "bootnode-aws-us-east-1-001" }, { "ip": "65.108.70.101", "port": 30303, "id": "2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc", "location": "eu-west-1-001", "comment": "bootnode-hetzner-hel" }, { "ip": "157.90.35.166", "port": 30303, "id": "4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052", "location": "eu-central-1-001", "comment": "bootnode-hetzner-fsn" } ], "dnsNetworks": [ "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net" ] } },{}],4:[function(require,module,exports){ module.exports={ "name": "rinkeby", "chainId": 4, "networkId": 4, "defaultHardfork": "london", "consensus": { "type": "poa", "algorithm": "clique", "clique": { "period": 15, "epoch": 30000 } }, "comment": "PoA test network", "url": "https://www.rinkeby.io", "genesis": { "timestamp": "0x58ee40ba", "gasLimit": 4700000, "difficulty": 1, "nonce": "0x0000000000000000", "extraData": "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, "hardforks": [ { "name": "chainstart", "block": 0, "forkHash": "0x3b8e0691" }, { "name": "homestead", "block": 1, "forkHash": "0x60949295" }, { "name": "tangerineWhistle", "block": 2, "forkHash": "0x8bde40dd" }, { "name": "spuriousDragon", "block": 3, "forkHash": "0xcb3a64bb" }, { "name": "byzantium", "block": 1035301, "forkHash": "0x8d748b57" }, { "name": "constantinople", "block": 3660663, "forkHash": "0xe49cab14" }, { "name": "petersburg", "block": 4321234, "forkHash": "0xafec6b27" }, { "name": "istanbul", "block": 5435345, "forkHash": "0xcbdb8838" }, { "name": "berlin", "block": 8290928, "forkHash": "0x6910c8bd" }, { "name": "london", "block": 8897988, "forkHash": "0x8e29f2f3" }, { "name": "merge", "block": null, "forkHash": null }, { "name": "shanghai", "block": null, "forkHash": null } ], "bootstrapNodes": [ { "ip": "52.169.42.101", "port": 30303, "id": "a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf", "location": "", "comment": "IE" }, { "ip": "52.3.158.184", "port": 30303, "id": "343149e4feefa15d882d9fe4ac7d88f885bd05ebb735e547f12e12080a9fa07c8014ca6fd7f373123488102fe5e34111f8509cf0b7de3f5b44339c9f25e87cb8", "location": "", "comment": "INFURA" }, { "ip": "159.89.28.211", "port": 30303, "id": "b6b28890b006743680c52e64e0d16db57f28124885595fa03a562be1d2bf0f3a1da297d56b13da25fb992888fd556d4c1a27b1f39d531bde7de1921c90061cc6", "location": "", "comment": "AKASHA" } ], "dnsNetworks": [ "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.rinkeby.ethdisco.net" ] } },{}],5:[function(require,module,exports){ module.exports={ "name": "ropsten", "chainId": 3, "networkId": 3, "defaultHardfork": "merge", "consensus": { "type": "pow", "algorithm": "ethash", "ethash": {} }, "comment": "PoW test network", "url": "https://github.com/ethereum/ropsten", "genesis": { "gasLimit": 16777216, "difficulty": 1048576, "nonce": "0x0000000000000042", "extraData": "0x3535353535353535353535353535353535353535353535353535353535353535" }, "hardforks": [ { "name": "chainstart", "block": 0, "forkHash": "0x30c7ddbc" }, { "name": "homestead", "block": 0, "forkHash": "0x30c7ddbc" }, { "name": "tangerineWhistle", "block": 0, "forkHash": "0x30c7ddbc" }, { "name": "spuriousDragon", "block": 10, "forkHash": "0x63760190" }, { "name": "byzantium", "block": 1700000, "forkHash": "0x3ea159c7" }, { "name": "constantinople", "block": 4230000, "forkHash": "0x97b544f3" }, { "name": "petersburg", "block": 4939394, "forkHash": "0xd6e2149b" }, { "name": "istanbul", "block": 6485846, "forkHash": "0x4bc66396" }, { "name": "muirGlacier", "block": 7117117, "forkHash": "0x6727ef90" }, { "name": "berlin", "block": 9812189, "forkHash": "0xa157d377" }, { "name": "london", "block": 10499401, "forkHash": "0x7119b6b3" }, { "//_comment": "The forkHash will remain same as mergeForkIdTransition is post merge", "name": "merge", "ttd": "50000000000000000", "block": null, "forkHash": "0x7119b6b3" }, { "name": "mergeForkIdTransition", "block": null, "forkHash": null }, { "name": "shanghai", "block": null, "forkHash": null } ], "bootstrapNodes": [ { "ip": "52.176.7.10", "port": 30303, "id": "30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606", "location": "", "comment": "US-Azure geth" }, { "ip": "52.176.100.77", "port": 30303, "id": "865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c", "location": "", "comment": "US-Azure parity" }, { "ip": "52.232.243.152", "port": 30303, "id": "6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f", "location": "", "comment": "Parity" }, { "ip": "192.81.208.223", "port": 30303, "id": "94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09", "location": "", "comment": "@gpip" } ], "dnsNetworks": [ "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.ropsten.ethdisco.net" ] } },{}],6:[function(require,module,exports){ module.exports={ "name": "sepolia", "chainId": 11155111, "networkId": 11155111, "defaultHardfork": "merge", "consensus": { "type": "pow", "algorithm": "ethash", "ethash": {} }, "comment": "PoW test network to replace Ropsten", "url": "https://github.com/ethereum/go-ethereum/pull/23730", "genesis": { "timestamp": "0x6159af19", "gasLimit": 30000000, "difficulty": 131072, "nonce": "0x0000000000000000", "extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521" }, "hardforks": [ { "name": "chainstart", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "homestead", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "tangerineWhistle", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "spuriousDragon", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "byzantium", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "constantinople", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "petersburg", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "istanbul", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "muirGlacier", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "berlin", "block": 0, "forkHash": "0xfe3366e7" }, { "name": "london", "block": 0, "forkHash": "0xfe3366e7" }, { "//_comment": "The forkHash will remain same as mergeForkIdTransition is post merge, terminal block: https://sepolia.etherscan.io/block/1450408", "name": "merge", "ttd": "17000000000000000", "block": 1450409, "forkHash": "0xfe3366e7" }, { "name": "mergeForkIdTransition", "block": 1735371, "forkHash": "0xb96cbd13" }, { "name": "shanghai", "block": null, "timestamp": "1677557088", "forkHash": "0xf7f9bc08" } ], "bootstrapNodes": [ { "ip": "18.168.182.86", "port": 30303, "id": "9246d00bc8fd1742e5ad2428b80fc4dc45d786283e05ef6edbd9002cbc335d40998444732fbe921cb88e1d2c73d1b1de53bae6a2237996e9bfe14f871baf7066", "location": "", "comment": "geth" }, { "ip": "52.14.151.177", "port": 30303, "id": "ec66ddcf1a974950bd4c782789a7e04f8aa7110a72569b6e65fcd51e937e74eed303b1ea734e4d19cfaec9fbff9b6ee65bf31dcb50ba79acce9dd63a6aca61c7", "location": "", "comment": "besu" }, { "ip": "165.22.196.173", "port": 30303, "id": "ce970ad2e9daa9e14593de84a8b49da3d54ccfdf83cbc4fe519cb8b36b5918ed4eab087dedd4a62479b8d50756b492d5f762367c8d20329a7854ec01547568a6", "location": "", "comment": "EF" }, { "ip": "65.108.95.67", "port": 30303, "id": "075503b13ed736244896efcde2a992ec0b451357d46cb7a8132c0384721742597fc8f0d91bbb40bb52e7d6e66728d36a1fda09176294e4a30cfac55dcce26bc6", "location": "", "comment": "lodestar" } ], "dnsNetworks": [ "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.sepolia.ethdisco.net" ] } },{}],7:[function(require,module,exports){ (function (Buffer){(function (){ "use strict"; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports.Common = void 0; var util_1 = require("@ethereumjs/util"); var crc_32_1 = require("crc-32"); var events_1 = require("events"); var goerli = require("./chains/goerli.json"); var mainnet = require("./chains/mainnet.json"); var rinkeby = require("./chains/rinkeby.json"); var ropsten = require("./chains/ropsten.json"); var sepolia = require("./chains/sepolia.json"); var eips_1 = require("./eips"); var enums_1 = require("./enums"); var hardforks_1 = require("./hardforks"); var utils_1 = require("./utils"); /** * Common class to access chain and hardfork parameters and to provide * a unified and shared view on the network and hardfork state. * * Use the {@link Common.custom} static constructor for creating simple * custom chain {@link Common} objects (more complete custom chain setups * can be created via the main constructor and the {@link CommonOpts.customChains} parameter). */ var Common = /*#__PURE__*/function (_events_1$EventEmitte) { _inherits(Common, _events_1$EventEmitte); var _super = _createSuper(Common); function Common(opts) { var _opts$customChains, _this$_chainParams$de; var _this; _classCallCheck(this, Common); _this = _super.call(this); _this._eips = []; _this._customChains = (_opts$customChains = opts.customChains) !== null && _opts$customChains !== void 0 ? _opts$customChains : []; _this._chainParams = _this.setChain(opts.chain); _this.DEFAULT_HARDFORK = (_this$_chainParams$de = _this._chainParams.defaultHardfork) !== null && _this$_chainParams$de !== void 0 ? _this$_chainParams$de : enums_1.Hardfork.Merge; // Assign hardfork changes in the sequence of the applied hardforks _this.HARDFORK_CHANGES = _this.hardforks().map(function (hf) { return [hf.name, hardforks_1.hardforks[hf.name]]; }); _this._hardfork = _this.DEFAULT_HARDFORK; if (opts.hardfork !== undefined) { _this.setHardfork(opts.hardfork); } if (opts.eips) { _this.setEIPs(opts.eips); } return _this; } /** * Creates a {@link Common} object for a custom chain, based on a standard one. * * It uses all the {@link Chain} parameters from the {@link baseChain} option except the ones overridden * in a provided {@link chainParamsOrName} dictionary. Some usage example: * * ```javascript * Common.custom({chainId: 123}) * ``` * * There are also selected supported custom chains which can be initialized by using one of the * {@link CustomChains} for {@link chainParamsOrName}, e.g.: * * ```javascript * Common.custom(CustomChains.MaticMumbai) * ``` * * Note that these supported custom chains only provide some base parameters (usually the chain and * network ID and a name) and can only be used for selected use cases (e.g. sending a tx with * the `@ethereumjs/tx` library to a Layer-2 chain). * * @param chainParamsOrName Custom parameter dict (`name` will default to `custom-chain`) or string with name of a supported custom chain * @param opts Custom chain options to set the {@link CustomCommonOpts.baseChain}, selected {@link CustomCommonOpts.hardfork} and others */ _createClass(Common, [{ key: "setChain", value: /** * Sets the chain * @param chain String ('mainnet') or Number (1) chain representation. * Or, a Dictionary of chain parameters for a private network. * @returns The dictionary with parameters set as chain */ function setChain(chain) { if (typeof chain === 'number' || typeof chain === 'bigint' || typeof chain === 'string') { this._chainParams = Common._getChainParams(chain, this._customChains); } else if (_typeof(chain) === 'object') { if (this._customChains.length > 0) { throw new Error('Chain must be a string, number, or bigint when initialized with customChains passed in'); } var required = ['networkId', 'genesis', 'hardforks', 'bootstrapNodes']; for (var _i = 0, _required = required; _i < _required.length; _i++) { var param = _required[_i]; if (!(param in chain)) { throw new Error("Missing required chain parameter: ".concat(param)); } } this._chainParams = chain; } else { throw new Error('Wrong input format'); } var _iterator = _createForOfIteratorHelper(this.hardforks()), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var hf = _step.value; if (hf.block === undefined) { throw new Error("Hardfork cannot have undefined block number"); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return this._chainParams; } /** * Sets the hardfork to get params for * @param hardfork String identifier (e.g. 'byzantium') or {@link Hardfork} enum */ }, { key: "setHardfork", value: function setHardfork(hardfork) { var existing = false; var _iterator2 = _createForOfIteratorHelper(this.HARDFORK_CHANGES), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var hfChanges = _step2.value; if (hfChanges[0] === hardfork) { if (this._hardfork !== hardfork) { this._hardfork = hardfork; this.emit('hardforkChanged', hardfork); } existing = true; } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } if (!existing) { throw new Error("Hardfork with name ".concat(hardfork, " not supported")); } } /** * Returns the hardfork based on the block number or an optional * total difficulty (Merge HF) provided. * * An optional TD takes precedence in case the corresponding HF block * is set to `null` or otherwise needs to match (if not an error * will be thrown). * * @param blockNumber * @param td : total difficulty of the parent block (for block hf) OR of the chain latest (for chain hf) * @param timestamp: timestamp in seconds at which block was/is to be minted * @returns The name of the HF */ }, { key: "getHardforkByBlockNumber", value: function getHardforkByBlockNumber(blockNumber, td, timestamp) { blockNumber = (0, util_1.toType)(blockNumber, util_1.TypeOutput.BigInt); td = (0, util_1.toType)(td, util_1.TypeOutput.BigInt); timestamp = (0, util_1.toType)(timestamp, util_1.TypeOutput.Number); // Filter out hardforks with no block number, no ttd or no timestamp (i.e. unapplied hardforks) var hfs = this.hardforks().filter(function (hf) { return hf.block !== null || hf.ttd !== null && hf.ttd !== undefined || hf.timestamp !== undefined; }); var mergeIndex = hfs.findIndex(function (hf) { return hf.ttd !== null && hf.ttd !== undefined; }); var doubleTTDHF = hfs.slice(mergeIndex + 1).findIndex(function (hf) { return hf.ttd !== null && hf.ttd !== undefined; }); if (doubleTTDHF >= 0) { throw Error("More than one merge hardforks found with ttd specified"); } // Find the first hardfork that has a block number greater than `blockNumber` // (skips the merge hardfork since it cannot have a block number specified). // If timestamp is not provided, it also skips timestamps hardforks to continue // discovering/checking number hardforks. var hfIndex = hfs.findIndex(function (hf) { return hf.block !== null && hf.block > blockNumber || timestamp !== undefined && Number(hf.timestamp) > timestamp; }); if (hfIndex === -1) { // all hardforks apply, set hfIndex to the last one as that's the candidate hfIndex = hfs.length; } else if (hfIndex === 0) { // cannot have a case where a block number is before all applied hardforks // since the chain has to start with a hardfork throw Error('Must have at least one hardfork at block 0'); } // If timestamp is not provided, we need to rollback to the last hf with block or ttd if (timestamp === undefined) { var stepBack = hfs.slice(0, hfIndex).reverse().findIndex(function (hf) { return hf.block !== null || hf.ttd !== undefined; }); hfIndex = hfIndex - stepBack; } // Move hfIndex one back to arrive at candidate hardfork hfIndex = hfIndex - 1; // If the timestamp was not provided, we could have skipped timestamp hardforks to look for number // hardforks. so it will now be needed to rollback if (hfs[hfIndex].block === null && hfs[hfIndex].timestamp === undefined) { // We're on the merge hardfork. Let's check the TTD if (td === undefined || td === null || BigInt(hfs[hfIndex].ttd) > td) { // Merge ttd greater than current td so we're on hardfork before merge hfIndex -= 1; } } else { if (mergeIndex >= 0 && td !== undefined && td !== null) { if (hfIndex >= mergeIndex && BigInt(hfs[mergeIndex].ttd) > td) { throw Error('Maximum HF determined by total difficulty is lower than the block number HF'); } else if (hfIndex < mergeIndex && BigInt(hfs[mergeIndex].ttd) <= td) { throw Error('HF determined by block number is lower than the minimum total difficulty HF'); } } } var hfStartIndex = hfIndex; // Move the hfIndex to the end of the hardforks that might be scheduled on the same block/timestamp // This won't anyway be the case with Merge hfs for (; hfIndex < hfs.length - 1; hfIndex++) { // break out if hfIndex + 1 is not scheduled at hfIndex if (hfs[hfIndex].block !== hfs[hfIndex + 1].block || hfs[hfIndex].timestamp !== hfs[hfIndex + 1].timestamp) { break; } } if (timestamp) { var minTimeStamp = hfs.slice(0, hfStartIndex).reduce(function (acc, hf) { var _hf$timestamp; return Math.max(Number((_hf$timestamp = hf.timestamp) !== null && _hf$timestamp !== void 0 ? _hf$timestamp : '0'), acc); }, 0); if (minTimeStamp > timestamp) { throw Error("Maximum HF determined by timestamp is lower than the block number/ttd HF"); } var maxTimeStamp = hfs.slice(hfIndex + 1).reduce(function (acc, hf) { var _hf$timestamp2; return Math.min(Number((_hf$timestamp2 = hf.timestamp) !== null && _hf$timestamp2 !== void 0 ? _hf$timestamp2 : timestamp), acc); }, timestamp); if (maxTimeStamp < timestamp) { throw Error("Maximum HF determined by block number/ttd is lower than timestamp HF"); } } var hardfork = hfs[hfIndex]; return hardfork.name; } /** * Sets a new hardfork based on the block number or an optional * total difficulty (Merge HF) provided. * * An optional TD takes precedence in case the corresponding HF block * is set to `null` or otherwise needs to match (if not an error * will be thrown). * * @param blockNumber * @param td * @param timestamp * @returns The name of the HF set */ }, { key: "setHardforkByBlockNumber", value: function setHardforkByBlockNumber(blockNumber, td, timestamp) { var hardfork = this.getHardforkByBlockNumber(blockNumber, td, timestamp); this.setHardfork(hardfork); return hardfork; } /** * Internal helper function, returns the params for the given hardfork for the chain set * @param hardfork Hardfork name * @returns Dictionary with hardfork params or null if hardfork not on chain */ }, { key: "_getHardfork", value: function _getHardfork(hardfork) { var hfs = this.hardforks(); var _iterator3 = _createForOfIteratorHelper(hfs), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var hf = _step3.value; if (hf['name'] === hardfork) return hf; } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } return null; } /** * Sets the active EIPs * @param eips */ }, { key: "setEIPs", value: function setEIPs() { var eips = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var _iterator4 = _createForOfIteratorHelper(eips), _step4; try { for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { var eip = _step4.value; if (!(eip in eips_1.EIPs)) { throw new Error("".concat(eip, " not supported")); } var minHF = this.gteHardfork(eips_1.EIPs[eip]['minimumHardfork']); if (!minHF) { throw new Error("".concat(eip, " cannot be activated on hardfork ").concat(this.hardfork(), ", minimumHardfork: ").concat(minHF)); } if (eips_1.EIPs[eip].requiredEIPs !== undefined) { var _iterator5 = _createForOfIteratorHelper(eips_1.EIPs[eip].requiredEIPs), _step5; try { for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { var elem = _step5.value; if (!(eips.includes(elem) || this.isActivatedEIP(elem))) { throw new Error("".concat(eip, " requires EIP ").concat(elem, ", but is not included in the EIP list")); }