UNPKG

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