json-rpc-provider.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. if (typeof b !== "function" && b !== null)
  11. throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
  12. extendStatics(d, b);
  13. function __() { this.constructor = d; }
  14. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  15. };
  16. })();
  17. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  18. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  19. return new (P || (P = Promise))(function (resolve, reject) {
  20. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  21. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  22. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  23. step((generator = generator.apply(thisArg, _arguments || [])).next());
  24. });
  25. };
  26. var __generator = (this && this.__generator) || function (thisArg, body) {
  27. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  28. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  29. function verb(n) { return function (v) { return step([n, v]); }; }
  30. function step(op) {
  31. if (f) throw new TypeError("Generator is already executing.");
  32. while (_) try {
  33. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  34. if (y = 0, t) op = [op[0] & 2, t.value];
  35. switch (op[0]) {
  36. case 0: case 1: t = op; break;
  37. case 4: _.label++; return { value: op[1], done: false };
  38. case 5: _.label++; y = op[1]; op = [0]; continue;
  39. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  40. default:
  41. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  42. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  43. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  44. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  45. if (t[2]) _.ops.pop();
  46. _.trys.pop(); continue;
  47. }
  48. op = body.call(thisArg, _);
  49. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  50. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  51. }
  52. };
  53. Object.defineProperty(exports, "__esModule", { value: true });
  54. exports.JsonRpcProvider = exports.JsonRpcSigner = void 0;
  55. var abstract_signer_1 = require("@ethersproject/abstract-signer");
  56. var bignumber_1 = require("@ethersproject/bignumber");
  57. var bytes_1 = require("@ethersproject/bytes");
  58. var hash_1 = require("@ethersproject/hash");
  59. var properties_1 = require("@ethersproject/properties");
  60. var strings_1 = require("@ethersproject/strings");
  61. var transactions_1 = require("@ethersproject/transactions");
  62. var web_1 = require("@ethersproject/web");
  63. var logger_1 = require("@ethersproject/logger");
  64. var _version_1 = require("./_version");
  65. var logger = new logger_1.Logger(_version_1.version);
  66. var base_provider_1 = require("./base-provider");
  67. var errorGas = ["call", "estimateGas"];
  68. function checkError(method, error, params) {
  69. // Undo the "convenience" some nodes are attempting to prevent backwards
  70. // incompatibility; maybe for v6 consider forwarding reverts as errors
  71. if (method === "call" && error.code === logger_1.Logger.errors.SERVER_ERROR) {
  72. var e = error.error;
  73. if (e && e.message.match("reverted") && (0, bytes_1.isHexString)(e.data)) {
  74. return e.data;
  75. }
  76. logger.throwError("missing revert data in call exception", logger_1.Logger.errors.CALL_EXCEPTION, {
  77. error: error,
  78. data: "0x"
  79. });
  80. }
  81. var message = error.message;
  82. if (error.code === logger_1.Logger.errors.SERVER_ERROR && error.error && typeof (error.error.message) === "string") {
  83. message = error.error.message;
  84. }
  85. else if (typeof (error.body) === "string") {
  86. message = error.body;
  87. }
  88. else if (typeof (error.responseText) === "string") {
  89. message = error.responseText;
  90. }
  91. message = (message || "").toLowerCase();
  92. var transaction = params.transaction || params.signedTransaction;
  93. // "insufficient funds for gas * price + value + cost(data)"
  94. if (message.match(/insufficient funds|base fee exceeds gas limit/)) {
  95. logger.throwError("insufficient funds for intrinsic transaction cost", logger_1.Logger.errors.INSUFFICIENT_FUNDS, {
  96. error: error,
  97. method: method,
  98. transaction: transaction
  99. });
  100. }
  101. // "nonce too low"
  102. if (message.match(/nonce too low/)) {
  103. logger.throwError("nonce has already been used", logger_1.Logger.errors.NONCE_EXPIRED, {
  104. error: error,
  105. method: method,
  106. transaction: transaction
  107. });
  108. }
  109. // "replacement transaction underpriced"
  110. if (message.match(/replacement transaction underpriced/)) {
  111. logger.throwError("replacement fee too low", logger_1.Logger.errors.REPLACEMENT_UNDERPRICED, {
  112. error: error,
  113. method: method,
  114. transaction: transaction
  115. });
  116. }
  117. // "replacement transaction underpriced"
  118. if (message.match(/only replay-protected/)) {
  119. logger.throwError("legacy pre-eip-155 transactions not supported", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
  120. error: error,
  121. method: method,
  122. transaction: transaction
  123. });
  124. }
  125. if (errorGas.indexOf(method) >= 0 && message.match(/gas required exceeds allowance|always failing transaction|execution reverted/)) {
  126. logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", logger_1.Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
  127. error: error,
  128. method: method,
  129. transaction: transaction
  130. });
  131. }
  132. throw error;
  133. }
  134. function timer(timeout) {
  135. return new Promise(function (resolve) {
  136. setTimeout(resolve, timeout);
  137. });
  138. }
  139. function getResult(payload) {
  140. if (payload.error) {
  141. // @TODO: not any
  142. var error = new Error(payload.error.message);
  143. error.code = payload.error.code;
  144. error.data = payload.error.data;
  145. throw error;
  146. }
  147. return payload.result;
  148. }
  149. function getLowerCase(value) {
  150. if (value) {
  151. return value.toLowerCase();
  152. }
  153. return value;
  154. }
  155. var _constructorGuard = {};
  156. var JsonRpcSigner = /** @class */ (function (_super) {
  157. __extends(JsonRpcSigner, _super);
  158. function JsonRpcSigner(constructorGuard, provider, addressOrIndex) {
  159. var _newTarget = this.constructor;
  160. var _this = this;
  161. logger.checkNew(_newTarget, JsonRpcSigner);
  162. _this = _super.call(this) || this;
  163. if (constructorGuard !== _constructorGuard) {
  164. throw new Error("do not call the JsonRpcSigner constructor directly; use provider.getSigner");
  165. }
  166. (0, properties_1.defineReadOnly)(_this, "provider", provider);
  167. if (addressOrIndex == null) {
  168. addressOrIndex = 0;
  169. }
  170. if (typeof (addressOrIndex) === "string") {
  171. (0, properties_1.defineReadOnly)(_this, "_address", _this.provider.formatter.address(addressOrIndex));
  172. (0, properties_1.defineReadOnly)(_this, "_index", null);
  173. }
  174. else if (typeof (addressOrIndex) === "number") {
  175. (0, properties_1.defineReadOnly)(_this, "_index", addressOrIndex);
  176. (0, properties_1.defineReadOnly)(_this, "_address", null);
  177. }
  178. else {
  179. logger.throwArgumentError("invalid address or index", "addressOrIndex", addressOrIndex);
  180. }
  181. return _this;
  182. }
  183. JsonRpcSigner.prototype.connect = function (provider) {
  184. return logger.throwError("cannot alter JSON-RPC Signer connection", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
  185. operation: "connect"
  186. });
  187. };
  188. JsonRpcSigner.prototype.connectUnchecked = function () {
  189. return new UncheckedJsonRpcSigner(_constructorGuard, this.provider, this._address || this._index);
  190. };
  191. JsonRpcSigner.prototype.getAddress = function () {
  192. var _this = this;
  193. if (this._address) {
  194. return Promise.resolve(this._address);
  195. }
  196. return this.provider.send("eth_accounts", []).then(function (accounts) {
  197. if (accounts.length <= _this._index) {
  198. logger.throwError("unknown account #" + _this._index, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
  199. operation: "getAddress"
  200. });
  201. }
  202. return _this.provider.formatter.address(accounts[_this._index]);
  203. });
  204. };
  205. JsonRpcSigner.prototype.sendUncheckedTransaction = function (transaction) {
  206. var _this = this;
  207. transaction = (0, properties_1.shallowCopy)(transaction);
  208. var fromAddress = this.getAddress().then(function (address) {
  209. if (address) {
  210. address = address.toLowerCase();
  211. }
  212. return address;
  213. });
  214. // The JSON-RPC for eth_sendTransaction uses 90000 gas; if the user
  215. // wishes to use this, it is easy to specify explicitly, otherwise
  216. // we look it up for them.
  217. if (transaction.gasLimit == null) {
  218. var estimate = (0, properties_1.shallowCopy)(transaction);
  219. estimate.from = fromAddress;
  220. transaction.gasLimit = this.provider.estimateGas(estimate);
  221. }
  222. if (transaction.to != null) {
  223. transaction.to = Promise.resolve(transaction.to).then(function (to) { return __awaiter(_this, void 0, void 0, function () {
  224. var address;
  225. return __generator(this, function (_a) {
  226. switch (_a.label) {
  227. case 0:
  228. if (to == null) {
  229. return [2 /*return*/, null];
  230. }
  231. return [4 /*yield*/, this.provider.resolveName(to)];
  232. case 1:
  233. address = _a.sent();
  234. if (address == null) {
  235. logger.throwArgumentError("provided ENS name resolves to null", "tx.to", to);
  236. }
  237. return [2 /*return*/, address];
  238. }
  239. });
  240. }); });
  241. }
  242. return (0, properties_1.resolveProperties)({
  243. tx: (0, properties_1.resolveProperties)(transaction),
  244. sender: fromAddress
  245. }).then(function (_a) {
  246. var tx = _a.tx, sender = _a.sender;
  247. if (tx.from != null) {
  248. if (tx.from.toLowerCase() !== sender) {
  249. logger.throwArgumentError("from address mismatch", "transaction", transaction);
  250. }
  251. }
  252. else {
  253. tx.from = sender;
  254. }
  255. var hexTx = _this.provider.constructor.hexlifyTransaction(tx, { from: true });
  256. return _this.provider.send("eth_sendTransaction", [hexTx]).then(function (hash) {
  257. return hash;
  258. }, function (error) {
  259. return checkError("sendTransaction", error, hexTx);
  260. });
  261. });
  262. };
  263. JsonRpcSigner.prototype.signTransaction = function (transaction) {
  264. return logger.throwError("signing transactions is unsupported", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
  265. operation: "signTransaction"
  266. });
  267. };
  268. JsonRpcSigner.prototype.sendTransaction = function (transaction) {
  269. return __awaiter(this, void 0, void 0, function () {
  270. var blockNumber, hash, error_1;
  271. var _this = this;
  272. return __generator(this, function (_a) {
  273. switch (_a.label) {
  274. case 0: return [4 /*yield*/, this.provider._getInternalBlockNumber(100 + 2 * this.provider.pollingInterval)];
  275. case 1:
  276. blockNumber = _a.sent();
  277. return [4 /*yield*/, this.sendUncheckedTransaction(transaction)];
  278. case 2:
  279. hash = _a.sent();
  280. _a.label = 3;
  281. case 3:
  282. _a.trys.push([3, 5, , 6]);
  283. return [4 /*yield*/, (0, web_1.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
  284. var tx;
  285. return __generator(this, function (_a) {
  286. switch (_a.label) {
  287. case 0: return [4 /*yield*/, this.provider.getTransaction(hash)];
  288. case 1:
  289. tx = _a.sent();
  290. if (tx === null) {
  291. return [2 /*return*/, undefined];
  292. }
  293. return [2 /*return*/, this.provider._wrapTransaction(tx, hash, blockNumber)];
  294. }
  295. });
  296. }); }, { oncePoll: this.provider })];
  297. case 4:
  298. // Unfortunately, JSON-RPC only provides and opaque transaction hash
  299. // for a response, and we need the actual transaction, so we poll
  300. // for it; it should show up very quickly
  301. return [2 /*return*/, _a.sent()];
  302. case 5:
  303. error_1 = _a.sent();
  304. error_1.transactionHash = hash;
  305. throw error_1;
  306. case 6: return [2 /*return*/];
  307. }
  308. });
  309. });
  310. };
  311. JsonRpcSigner.prototype.signMessage = function (message) {
  312. return __awaiter(this, void 0, void 0, function () {
  313. var data, address;
  314. return __generator(this, function (_a) {
  315. switch (_a.label) {
  316. case 0:
  317. data = ((typeof (message) === "string") ? (0, strings_1.toUtf8Bytes)(message) : message);
  318. return [4 /*yield*/, this.getAddress()];
  319. case 1:
  320. address = _a.sent();
  321. return [4 /*yield*/, this.provider.send("personal_sign", [(0, bytes_1.hexlify)(data), address.toLowerCase()])];
  322. case 2: return [2 /*return*/, _a.sent()];
  323. }
  324. });
  325. });
  326. };
  327. JsonRpcSigner.prototype._legacySignMessage = function (message) {
  328. return __awaiter(this, void 0, void 0, function () {
  329. var data, address;
  330. return __generator(this, function (_a) {
  331. switch (_a.label) {
  332. case 0:
  333. data = ((typeof (message) === "string") ? (0, strings_1.toUtf8Bytes)(message) : message);
  334. return [4 /*yield*/, this.getAddress()];
  335. case 1:
  336. address = _a.sent();
  337. return [4 /*yield*/, this.provider.send("eth_sign", [address.toLowerCase(), (0, bytes_1.hexlify)(data)])];
  338. case 2:
  339. // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
  340. return [2 /*return*/, _a.sent()];
  341. }
  342. });
  343. });
  344. };
  345. JsonRpcSigner.prototype._signTypedData = function (domain, types, value) {
  346. return __awaiter(this, void 0, void 0, function () {
  347. var populated, address;
  348. var _this = this;
  349. return __generator(this, function (_a) {
  350. switch (_a.label) {
  351. case 0: return [4 /*yield*/, hash_1._TypedDataEncoder.resolveNames(domain, types, value, function (name) {
  352. return _this.provider.resolveName(name);
  353. })];
  354. case 1:
  355. populated = _a.sent();
  356. return [4 /*yield*/, this.getAddress()];
  357. case 2:
  358. address = _a.sent();
  359. return [4 /*yield*/, this.provider.send("eth_signTypedData_v4", [
  360. address.toLowerCase(),
  361. JSON.stringify(hash_1._TypedDataEncoder.getPayload(populated.domain, types, populated.value))
  362. ])];
  363. case 3: return [2 /*return*/, _a.sent()];
  364. }
  365. });
  366. });
  367. };
  368. JsonRpcSigner.prototype.unlock = function (password) {
  369. return __awaiter(this, void 0, void 0, function () {
  370. var provider, address;
  371. return __generator(this, function (_a) {
  372. switch (_a.label) {
  373. case 0:
  374. provider = this.provider;
  375. return [4 /*yield*/, this.getAddress()];
  376. case 1:
  377. address = _a.sent();
  378. return [2 /*return*/, provider.send("personal_unlockAccount", [address.toLowerCase(), password, null])];
  379. }
  380. });
  381. });
  382. };
  383. return JsonRpcSigner;
  384. }(abstract_signer_1.Signer));
  385. exports.JsonRpcSigner = JsonRpcSigner;
  386. var UncheckedJsonRpcSigner = /** @class */ (function (_super) {
  387. __extends(UncheckedJsonRpcSigner, _super);
  388. function UncheckedJsonRpcSigner() {
  389. return _super !== null && _super.apply(this, arguments) || this;
  390. }
  391. UncheckedJsonRpcSigner.prototype.sendTransaction = function (transaction) {
  392. var _this = this;
  393. return this.sendUncheckedTransaction(transaction).then(function (hash) {
  394. return {
  395. hash: hash,
  396. nonce: null,
  397. gasLimit: null,
  398. gasPrice: null,
  399. data: null,
  400. value: null,
  401. chainId: null,
  402. confirmations: 0,
  403. from: null,
  404. wait: function (confirmations) { return _this.provider.waitForTransaction(hash, confirmations); }
  405. };
  406. });
  407. };
  408. return UncheckedJsonRpcSigner;
  409. }(JsonRpcSigner));
  410. var allowedTransactionKeys = {
  411. chainId: true, data: true, gasLimit: true, gasPrice: true, nonce: true, to: true, value: true,
  412. type: true, accessList: true,
  413. maxFeePerGas: true, maxPriorityFeePerGas: true
  414. };
  415. var JsonRpcProvider = /** @class */ (function (_super) {
  416. __extends(JsonRpcProvider, _super);
  417. function JsonRpcProvider(url, network) {
  418. var _newTarget = this.constructor;
  419. var _this = this;
  420. logger.checkNew(_newTarget, JsonRpcProvider);
  421. var networkOrReady = network;
  422. // The network is unknown, query the JSON-RPC for it
  423. if (networkOrReady == null) {
  424. networkOrReady = new Promise(function (resolve, reject) {
  425. setTimeout(function () {
  426. _this.detectNetwork().then(function (network) {
  427. resolve(network);
  428. }, function (error) {
  429. reject(error);
  430. });
  431. }, 0);
  432. });
  433. }
  434. _this = _super.call(this, networkOrReady) || this;
  435. // Default URL
  436. if (!url) {
  437. url = (0, properties_1.getStatic)(_this.constructor, "defaultUrl")();
  438. }
  439. if (typeof (url) === "string") {
  440. (0, properties_1.defineReadOnly)(_this, "connection", Object.freeze({
  441. url: url
  442. }));
  443. }
  444. else {
  445. (0, properties_1.defineReadOnly)(_this, "connection", Object.freeze((0, properties_1.shallowCopy)(url)));
  446. }
  447. _this._nextId = 42;
  448. return _this;
  449. }
  450. Object.defineProperty(JsonRpcProvider.prototype, "_cache", {
  451. get: function () {
  452. if (this._eventLoopCache == null) {
  453. this._eventLoopCache = {};
  454. }
  455. return this._eventLoopCache;
  456. },
  457. enumerable: false,
  458. configurable: true
  459. });
  460. JsonRpcProvider.defaultUrl = function () {
  461. return "http:/\/localhost:8545";
  462. };
  463. JsonRpcProvider.prototype.detectNetwork = function () {
  464. var _this = this;
  465. if (!this._cache["detectNetwork"]) {
  466. this._cache["detectNetwork"] = this._uncachedDetectNetwork();
  467. // Clear this cache at the beginning of the next event loop
  468. setTimeout(function () {
  469. _this._cache["detectNetwork"] = null;
  470. }, 0);
  471. }
  472. return this._cache["detectNetwork"];
  473. };
  474. JsonRpcProvider.prototype._uncachedDetectNetwork = function () {
  475. return __awaiter(this, void 0, void 0, function () {
  476. var chainId, error_2, error_3, getNetwork;
  477. return __generator(this, function (_a) {
  478. switch (_a.label) {
  479. case 0: return [4 /*yield*/, timer(0)];
  480. case 1:
  481. _a.sent();
  482. chainId = null;
  483. _a.label = 2;
  484. case 2:
  485. _a.trys.push([2, 4, , 9]);
  486. return [4 /*yield*/, this.send("eth_chainId", [])];
  487. case 3:
  488. chainId = _a.sent();
  489. return [3 /*break*/, 9];
  490. case 4:
  491. error_2 = _a.sent();
  492. _a.label = 5;
  493. case 5:
  494. _a.trys.push([5, 7, , 8]);
  495. return [4 /*yield*/, this.send("net_version", [])];
  496. case 6:
  497. chainId = _a.sent();
  498. return [3 /*break*/, 8];
  499. case 7:
  500. error_3 = _a.sent();
  501. return [3 /*break*/, 8];
  502. case 8: return [3 /*break*/, 9];
  503. case 9:
  504. if (chainId != null) {
  505. getNetwork = (0, properties_1.getStatic)(this.constructor, "getNetwork");
  506. try {
  507. return [2 /*return*/, getNetwork(bignumber_1.BigNumber.from(chainId).toNumber())];
  508. }
  509. catch (error) {
  510. return [2 /*return*/, logger.throwError("could not detect network", logger_1.Logger.errors.NETWORK_ERROR, {
  511. chainId: chainId,
  512. event: "invalidNetwork",
  513. serverError: error
  514. })];
  515. }
  516. }
  517. return [2 /*return*/, logger.throwError("could not detect network", logger_1.Logger.errors.NETWORK_ERROR, {
  518. event: "noNetwork"
  519. })];
  520. }
  521. });
  522. });
  523. };
  524. JsonRpcProvider.prototype.getSigner = function (addressOrIndex) {
  525. return new JsonRpcSigner(_constructorGuard, this, addressOrIndex);
  526. };
  527. JsonRpcProvider.prototype.getUncheckedSigner = function (addressOrIndex) {
  528. return this.getSigner(addressOrIndex).connectUnchecked();
  529. };
  530. JsonRpcProvider.prototype.listAccounts = function () {
  531. var _this = this;
  532. return this.send("eth_accounts", []).then(function (accounts) {
  533. return accounts.map(function (a) { return _this.formatter.address(a); });
  534. });
  535. };
  536. JsonRpcProvider.prototype.send = function (method, params) {
  537. var _this = this;
  538. var request = {
  539. method: method,
  540. params: params,
  541. id: (this._nextId++),
  542. jsonrpc: "2.0"
  543. };
  544. this.emit("debug", {
  545. action: "request",
  546. request: (0, properties_1.deepCopy)(request),
  547. provider: this
  548. });
  549. // We can expand this in the future to any call, but for now these
  550. // are the biggest wins and do not require any serializing parameters.
  551. var cache = (["eth_chainId", "eth_blockNumber"].indexOf(method) >= 0);
  552. if (cache && this._cache[method]) {
  553. return this._cache[method];
  554. }
  555. var result = (0, web_1.fetchJson)(this.connection, JSON.stringify(request), getResult).then(function (result) {
  556. _this.emit("debug", {
  557. action: "response",
  558. request: request,
  559. response: result,
  560. provider: _this
  561. });
  562. return result;
  563. }, function (error) {
  564. _this.emit("debug", {
  565. action: "response",
  566. error: error,
  567. request: request,
  568. provider: _this
  569. });
  570. throw error;
  571. });
  572. // Cache the fetch, but clear it on the next event loop
  573. if (cache) {
  574. this._cache[method] = result;
  575. setTimeout(function () {
  576. _this._cache[method] = null;
  577. }, 0);
  578. }
  579. return result;
  580. };
  581. JsonRpcProvider.prototype.prepareRequest = function (method, params) {
  582. switch (method) {
  583. case "getBlockNumber":
  584. return ["eth_blockNumber", []];
  585. case "getGasPrice":
  586. return ["eth_gasPrice", []];
  587. case "getBalance":
  588. return ["eth_getBalance", [getLowerCase(params.address), params.blockTag]];
  589. case "getTransactionCount":
  590. return ["eth_getTransactionCount", [getLowerCase(params.address), params.blockTag]];
  591. case "getCode":
  592. return ["eth_getCode", [getLowerCase(params.address), params.blockTag]];
  593. case "getStorageAt":
  594. return ["eth_getStorageAt", [getLowerCase(params.address), params.position, params.blockTag]];
  595. case "sendTransaction":
  596. return ["eth_sendRawTransaction", [params.signedTransaction]];
  597. case "getBlock":
  598. if (params.blockTag) {
  599. return ["eth_getBlockByNumber", [params.blockTag, !!params.includeTransactions]];
  600. }
  601. else if (params.blockHash) {
  602. return ["eth_getBlockByHash", [params.blockHash, !!params.includeTransactions]];
  603. }
  604. return null;
  605. case "getTransaction":
  606. return ["eth_getTransactionByHash", [params.transactionHash]];
  607. case "getTransactionReceipt":
  608. return ["eth_getTransactionReceipt", [params.transactionHash]];
  609. case "call": {
  610. var hexlifyTransaction = (0, properties_1.getStatic)(this.constructor, "hexlifyTransaction");
  611. return ["eth_call", [hexlifyTransaction(params.transaction, { from: true }), params.blockTag]];
  612. }
  613. case "estimateGas": {
  614. var hexlifyTransaction = (0, properties_1.getStatic)(this.constructor, "hexlifyTransaction");
  615. return ["eth_estimateGas", [hexlifyTransaction(params.transaction, { from: true })]];
  616. }
  617. case "getLogs":
  618. if (params.filter && params.filter.address != null) {
  619. params.filter.address = getLowerCase(params.filter.address);
  620. }
  621. return ["eth_getLogs", [params.filter]];
  622. default:
  623. break;
  624. }
  625. return null;
  626. };
  627. JsonRpcProvider.prototype.perform = function (method, params) {
  628. return __awaiter(this, void 0, void 0, function () {
  629. var tx, feeData, args, error_4;
  630. return __generator(this, function (_a) {
  631. switch (_a.label) {
  632. case 0:
  633. if (!(method === "call" || method === "estimateGas")) return [3 /*break*/, 2];
  634. tx = params.transaction;
  635. if (!(tx && tx.type != null && bignumber_1.BigNumber.from(tx.type).isZero())) return [3 /*break*/, 2];
  636. if (!(tx.maxFeePerGas == null && tx.maxPriorityFeePerGas == null)) return [3 /*break*/, 2];
  637. return [4 /*yield*/, this.getFeeData()];
  638. case 1:
  639. feeData = _a.sent();
  640. if (feeData.maxFeePerGas == null && feeData.maxPriorityFeePerGas == null) {
  641. // Network doesn't know about EIP-1559 (and hence type)
  642. params = (0, properties_1.shallowCopy)(params);
  643. params.transaction = (0, properties_1.shallowCopy)(tx);
  644. delete params.transaction.type;
  645. }
  646. _a.label = 2;
  647. case 2:
  648. args = this.prepareRequest(method, params);
  649. if (args == null) {
  650. logger.throwError(method + " not implemented", logger_1.Logger.errors.NOT_IMPLEMENTED, { operation: method });
  651. }
  652. _a.label = 3;
  653. case 3:
  654. _a.trys.push([3, 5, , 6]);
  655. return [4 /*yield*/, this.send(args[0], args[1])];
  656. case 4: return [2 /*return*/, _a.sent()];
  657. case 5:
  658. error_4 = _a.sent();
  659. return [2 /*return*/, checkError(method, error_4, params)];
  660. case 6: return [2 /*return*/];
  661. }
  662. });
  663. });
  664. };
  665. JsonRpcProvider.prototype._startEvent = function (event) {
  666. if (event.tag === "pending") {
  667. this._startPending();
  668. }
  669. _super.prototype._startEvent.call(this, event);
  670. };
  671. JsonRpcProvider.prototype._startPending = function () {
  672. if (this._pendingFilter != null) {
  673. return;
  674. }
  675. var self = this;
  676. var pendingFilter = this.send("eth_newPendingTransactionFilter", []);
  677. this._pendingFilter = pendingFilter;
  678. pendingFilter.then(function (filterId) {
  679. function poll() {
  680. self.send("eth_getFilterChanges", [filterId]).then(function (hashes) {
  681. if (self._pendingFilter != pendingFilter) {
  682. return null;
  683. }
  684. var seq = Promise.resolve();
  685. hashes.forEach(function (hash) {
  686. // @TODO: This should be garbage collected at some point... How? When?
  687. self._emitted["t:" + hash.toLowerCase()] = "pending";
  688. seq = seq.then(function () {
  689. return self.getTransaction(hash).then(function (tx) {
  690. self.emit("pending", tx);
  691. return null;
  692. });
  693. });
  694. });
  695. return seq.then(function () {
  696. return timer(1000);
  697. });
  698. }).then(function () {
  699. if (self._pendingFilter != pendingFilter) {
  700. self.send("eth_uninstallFilter", [filterId]);
  701. return;
  702. }
  703. setTimeout(function () { poll(); }, 0);
  704. return null;
  705. }).catch(function (error) { });
  706. }
  707. poll();
  708. return filterId;
  709. }).catch(function (error) { });
  710. };
  711. JsonRpcProvider.prototype._stopEvent = function (event) {
  712. if (event.tag === "pending" && this.listenerCount("pending") === 0) {
  713. this._pendingFilter = null;
  714. }
  715. _super.prototype._stopEvent.call(this, event);
  716. };
  717. // Convert an ethers.js transaction into a JSON-RPC transaction
  718. // - gasLimit => gas
  719. // - All values hexlified
  720. // - All numeric values zero-striped
  721. // - All addresses are lowercased
  722. // NOTE: This allows a TransactionRequest, but all values should be resolved
  723. // before this is called
  724. // @TODO: This will likely be removed in future versions and prepareRequest
  725. // will be the preferred method for this.
  726. JsonRpcProvider.hexlifyTransaction = function (transaction, allowExtra) {
  727. // Check only allowed properties are given
  728. var allowed = (0, properties_1.shallowCopy)(allowedTransactionKeys);
  729. if (allowExtra) {
  730. for (var key in allowExtra) {
  731. if (allowExtra[key]) {
  732. allowed[key] = true;
  733. }
  734. }
  735. }
  736. (0, properties_1.checkProperties)(transaction, allowed);
  737. var result = {};
  738. // JSON-RPC now requires numeric values to be "quantity" values
  739. ["chainId", "gasLimit", "gasPrice", "type", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "value"].forEach(function (key) {
  740. if (transaction[key] == null) {
  741. return;
  742. }
  743. var value = (0, bytes_1.hexValue)(transaction[key]);
  744. if (key === "gasLimit") {
  745. key = "gas";
  746. }
  747. result[key] = value;
  748. });
  749. ["from", "to", "data"].forEach(function (key) {
  750. if (transaction[key] == null) {
  751. return;
  752. }
  753. result[key] = (0, bytes_1.hexlify)(transaction[key]);
  754. });
  755. if (transaction.accessList) {
  756. result["accessList"] = (0, transactions_1.accessListify)(transaction.accessList);
  757. }
  758. return result;
  759. };
  760. return JsonRpcProvider;
  761. }(base_provider_1.BaseProvider));
  762. exports.JsonRpcProvider = JsonRpcProvider;
  763. //# sourceMappingURL=json-rpc-provider.js.map