UNPKG

39.1 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|InsufficientFunds/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|revert/)) {
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 if (typeof (error.message) === "string" && error.message.match(/user denied/i)) {
306 logger.throwError("user rejected transaction", logger_1.Logger.errors.ACTION_REJECTED, {
307 action: "sendTransaction",
308 transaction: tx
309 });
310 }
311 return checkError("sendTransaction", error, hexTx);
312 });
313 });
314 };
315 JsonRpcSigner.prototype.signTransaction = function (transaction) {
316 return logger.throwError("signing transactions is unsupported", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
317 operation: "signTransaction"
318 });
319 };
320 JsonRpcSigner.prototype.sendTransaction = function (transaction) {
321 return __awaiter(this, void 0, void 0, function () {
322 var blockNumber, hash, error_1;
323 var _this = this;
324 return __generator(this, function (_a) {
325 switch (_a.label) {
326 case 0: return [4 /*yield*/, this.provider._getInternalBlockNumber(100 + 2 * this.provider.pollingInterval)];
327 case 1:
328 blockNumber = _a.sent();
329 return [4 /*yield*/, this.sendUncheckedTransaction(transaction)];
330 case 2:
331 hash = _a.sent();
332 _a.label = 3;
333 case 3:
334 _a.trys.push([3, 5, , 6]);
335 return [4 /*yield*/, (0, web_1.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
336 var tx;
337 return __generator(this, function (_a) {
338 switch (_a.label) {
339 case 0: return [4 /*yield*/, this.provider.getTransaction(hash)];
340 case 1:
341 tx = _a.sent();
342 if (tx === null) {
343 return [2 /*return*/, undefined];
344 }
345 return [2 /*return*/, this.provider._wrapTransaction(tx, hash, blockNumber)];
346 }
347 });
348 }); }, { oncePoll: this.provider })];
349 case 4:
350 // Unfortunately, JSON-RPC only provides and opaque transaction hash
351 // for a response, and we need the actual transaction, so we poll
352 // for it; it should show up very quickly
353 return [2 /*return*/, _a.sent()];
354 case 5:
355 error_1 = _a.sent();
356 error_1.transactionHash = hash;
357 throw error_1;
358 case 6: return [2 /*return*/];
359 }
360 });
361 });
362 };
363 JsonRpcSigner.prototype.signMessage = function (message) {
364 return __awaiter(this, void 0, void 0, function () {
365 var data, address, error_2;
366 return __generator(this, function (_a) {
367 switch (_a.label) {
368 case 0:
369 data = ((typeof (message) === "string") ? (0, strings_1.toUtf8Bytes)(message) : message);
370 return [4 /*yield*/, this.getAddress()];
371 case 1:
372 address = _a.sent();
373 _a.label = 2;
374 case 2:
375 _a.trys.push([2, 4, , 5]);
376 return [4 /*yield*/, this.provider.send("personal_sign", [(0, bytes_1.hexlify)(data), address.toLowerCase()])];
377 case 3: return [2 /*return*/, _a.sent()];
378 case 4:
379 error_2 = _a.sent();
380 if (typeof (error_2.message) === "string" && error_2.message.match(/user denied/i)) {
381 logger.throwError("user rejected signing", logger_1.Logger.errors.ACTION_REJECTED, {
382 action: "signMessage",
383 from: address,
384 messageData: message
385 });
386 }
387 throw error_2;
388 case 5: return [2 /*return*/];
389 }
390 });
391 });
392 };
393 JsonRpcSigner.prototype._legacySignMessage = function (message) {
394 return __awaiter(this, void 0, void 0, function () {
395 var data, address, error_3;
396 return __generator(this, function (_a) {
397 switch (_a.label) {
398 case 0:
399 data = ((typeof (message) === "string") ? (0, strings_1.toUtf8Bytes)(message) : message);
400 return [4 /*yield*/, this.getAddress()];
401 case 1:
402 address = _a.sent();
403 _a.label = 2;
404 case 2:
405 _a.trys.push([2, 4, , 5]);
406 return [4 /*yield*/, this.provider.send("eth_sign", [address.toLowerCase(), (0, bytes_1.hexlify)(data)])];
407 case 3:
408 // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
409 return [2 /*return*/, _a.sent()];
410 case 4:
411 error_3 = _a.sent();
412 if (typeof (error_3.message) === "string" && error_3.message.match(/user denied/i)) {
413 logger.throwError("user rejected signing", logger_1.Logger.errors.ACTION_REJECTED, {
414 action: "_legacySignMessage",
415 from: address,
416 messageData: message
417 });
418 }
419 throw error_3;
420 case 5: return [2 /*return*/];
421 }
422 });
423 });
424 };
425 JsonRpcSigner.prototype._signTypedData = function (domain, types, value) {
426 return __awaiter(this, void 0, void 0, function () {
427 var populated, address, error_4;
428 var _this = this;
429 return __generator(this, function (_a) {
430 switch (_a.label) {
431 case 0: return [4 /*yield*/, hash_1._TypedDataEncoder.resolveNames(domain, types, value, function (name) {
432 return _this.provider.resolveName(name);
433 })];
434 case 1:
435 populated = _a.sent();
436 return [4 /*yield*/, this.getAddress()];
437 case 2:
438 address = _a.sent();
439 _a.label = 3;
440 case 3:
441 _a.trys.push([3, 5, , 6]);
442 return [4 /*yield*/, this.provider.send("eth_signTypedData_v4", [
443 address.toLowerCase(),
444 JSON.stringify(hash_1._TypedDataEncoder.getPayload(populated.domain, types, populated.value))
445 ])];
446 case 4: return [2 /*return*/, _a.sent()];
447 case 5:
448 error_4 = _a.sent();
449 if (typeof (error_4.message) === "string" && error_4.message.match(/user denied/i)) {
450 logger.throwError("user rejected signing", logger_1.Logger.errors.ACTION_REJECTED, {
451 action: "_signTypedData",
452 from: address,
453 messageData: { domain: populated.domain, types: types, value: populated.value }
454 });
455 }
456 throw error_4;
457 case 6: return [2 /*return*/];
458 }
459 });
460 });
461 };
462 JsonRpcSigner.prototype.unlock = function (password) {
463 return __awaiter(this, void 0, void 0, function () {
464 var provider, address;
465 return __generator(this, function (_a) {
466 switch (_a.label) {
467 case 0:
468 provider = this.provider;
469 return [4 /*yield*/, this.getAddress()];
470 case 1:
471 address = _a.sent();
472 return [2 /*return*/, provider.send("personal_unlockAccount", [address.toLowerCase(), password, null])];
473 }
474 });
475 });
476 };
477 return JsonRpcSigner;
478}(abstract_signer_1.Signer));
479exports.JsonRpcSigner = JsonRpcSigner;
480var UncheckedJsonRpcSigner = /** @class */ (function (_super) {
481 __extends(UncheckedJsonRpcSigner, _super);
482 function UncheckedJsonRpcSigner() {
483 return _super !== null && _super.apply(this, arguments) || this;
484 }
485 UncheckedJsonRpcSigner.prototype.sendTransaction = function (transaction) {
486 var _this = this;
487 return this.sendUncheckedTransaction(transaction).then(function (hash) {
488 return {
489 hash: hash,
490 nonce: null,
491 gasLimit: null,
492 gasPrice: null,
493 data: null,
494 value: null,
495 chainId: null,
496 confirmations: 0,
497 from: null,
498 wait: function (confirmations) { return _this.provider.waitForTransaction(hash, confirmations); }
499 };
500 });
501 };
502 return UncheckedJsonRpcSigner;
503}(JsonRpcSigner));
504var allowedTransactionKeys = {
505 chainId: true, data: true, gasLimit: true, gasPrice: true, nonce: true, to: true, value: true,
506 type: true, accessList: true,
507 maxFeePerGas: true, maxPriorityFeePerGas: true
508};
509var JsonRpcProvider = /** @class */ (function (_super) {
510 __extends(JsonRpcProvider, _super);
511 function JsonRpcProvider(url, network) {
512 var _this = this;
513 var networkOrReady = network;
514 // The network is unknown, query the JSON-RPC for it
515 if (networkOrReady == null) {
516 networkOrReady = new Promise(function (resolve, reject) {
517 setTimeout(function () {
518 _this.detectNetwork().then(function (network) {
519 resolve(network);
520 }, function (error) {
521 reject(error);
522 });
523 }, 0);
524 });
525 }
526 _this = _super.call(this, networkOrReady) || this;
527 // Default URL
528 if (!url) {
529 url = (0, properties_1.getStatic)(_this.constructor, "defaultUrl")();
530 }
531 if (typeof (url) === "string") {
532 (0, properties_1.defineReadOnly)(_this, "connection", Object.freeze({
533 url: url
534 }));
535 }
536 else {
537 (0, properties_1.defineReadOnly)(_this, "connection", Object.freeze((0, properties_1.shallowCopy)(url)));
538 }
539 _this._nextId = 42;
540 return _this;
541 }
542 Object.defineProperty(JsonRpcProvider.prototype, "_cache", {
543 get: function () {
544 if (this._eventLoopCache == null) {
545 this._eventLoopCache = {};
546 }
547 return this._eventLoopCache;
548 },
549 enumerable: false,
550 configurable: true
551 });
552 JsonRpcProvider.defaultUrl = function () {
553 return "http:/\/localhost:8545";
554 };
555 JsonRpcProvider.prototype.detectNetwork = function () {
556 var _this = this;
557 if (!this._cache["detectNetwork"]) {
558 this._cache["detectNetwork"] = this._uncachedDetectNetwork();
559 // Clear this cache at the beginning of the next event loop
560 setTimeout(function () {
561 _this._cache["detectNetwork"] = null;
562 }, 0);
563 }
564 return this._cache["detectNetwork"];
565 };
566 JsonRpcProvider.prototype._uncachedDetectNetwork = function () {
567 return __awaiter(this, void 0, void 0, function () {
568 var chainId, error_5, error_6, getNetwork;
569 return __generator(this, function (_a) {
570 switch (_a.label) {
571 case 0: return [4 /*yield*/, timer(0)];
572 case 1:
573 _a.sent();
574 chainId = null;
575 _a.label = 2;
576 case 2:
577 _a.trys.push([2, 4, , 9]);
578 return [4 /*yield*/, this.send("eth_chainId", [])];
579 case 3:
580 chainId = _a.sent();
581 return [3 /*break*/, 9];
582 case 4:
583 error_5 = _a.sent();
584 _a.label = 5;
585 case 5:
586 _a.trys.push([5, 7, , 8]);
587 return [4 /*yield*/, this.send("net_version", [])];
588 case 6:
589 chainId = _a.sent();
590 return [3 /*break*/, 8];
591 case 7:
592 error_6 = _a.sent();
593 return [3 /*break*/, 8];
594 case 8: return [3 /*break*/, 9];
595 case 9:
596 if (chainId != null) {
597 getNetwork = (0, properties_1.getStatic)(this.constructor, "getNetwork");
598 try {
599 return [2 /*return*/, getNetwork(bignumber_1.BigNumber.from(chainId).toNumber())];
600 }
601 catch (error) {
602 return [2 /*return*/, logger.throwError("could not detect network", logger_1.Logger.errors.NETWORK_ERROR, {
603 chainId: chainId,
604 event: "invalidNetwork",
605 serverError: error
606 })];
607 }
608 }
609 return [2 /*return*/, logger.throwError("could not detect network", logger_1.Logger.errors.NETWORK_ERROR, {
610 event: "noNetwork"
611 })];
612 }
613 });
614 });
615 };
616 JsonRpcProvider.prototype.getSigner = function (addressOrIndex) {
617 return new JsonRpcSigner(_constructorGuard, this, addressOrIndex);
618 };
619 JsonRpcProvider.prototype.getUncheckedSigner = function (addressOrIndex) {
620 return this.getSigner(addressOrIndex).connectUnchecked();
621 };
622 JsonRpcProvider.prototype.listAccounts = function () {
623 var _this = this;
624 return this.send("eth_accounts", []).then(function (accounts) {
625 return accounts.map(function (a) { return _this.formatter.address(a); });
626 });
627 };
628 JsonRpcProvider.prototype.send = function (method, params) {
629 var _this = this;
630 var request = {
631 method: method,
632 params: params,
633 id: (this._nextId++),
634 jsonrpc: "2.0"
635 };
636 this.emit("debug", {
637 action: "request",
638 request: (0, properties_1.deepCopy)(request),
639 provider: this
640 });
641 // We can expand this in the future to any call, but for now these
642 // are the biggest wins and do not require any serializing parameters.
643 var cache = (["eth_chainId", "eth_blockNumber"].indexOf(method) >= 0);
644 if (cache && this._cache[method]) {
645 return this._cache[method];
646 }
647 var result = (0, web_1.fetchJson)(this.connection, JSON.stringify(request), getResult).then(function (result) {
648 _this.emit("debug", {
649 action: "response",
650 request: request,
651 response: result,
652 provider: _this
653 });
654 return result;
655 }, function (error) {
656 _this.emit("debug", {
657 action: "response",
658 error: error,
659 request: request,
660 provider: _this
661 });
662 throw error;
663 });
664 // Cache the fetch, but clear it on the next event loop
665 if (cache) {
666 this._cache[method] = result;
667 setTimeout(function () {
668 _this._cache[method] = null;
669 }, 0);
670 }
671 return result;
672 };
673 JsonRpcProvider.prototype.prepareRequest = function (method, params) {
674 switch (method) {
675 case "getBlockNumber":
676 return ["eth_blockNumber", []];
677 case "getGasPrice":
678 return ["eth_gasPrice", []];
679 case "getBalance":
680 return ["eth_getBalance", [getLowerCase(params.address), params.blockTag]];
681 case "getTransactionCount":
682 return ["eth_getTransactionCount", [getLowerCase(params.address), params.blockTag]];
683 case "getCode":
684 return ["eth_getCode", [getLowerCase(params.address), params.blockTag]];
685 case "getStorageAt":
686 return ["eth_getStorageAt", [getLowerCase(params.address), (0, bytes_1.hexZeroPad)(params.position, 32), params.blockTag]];
687 case "sendTransaction":
688 return ["eth_sendRawTransaction", [params.signedTransaction]];
689 case "getBlock":
690 if (params.blockTag) {
691 return ["eth_getBlockByNumber", [params.blockTag, !!params.includeTransactions]];
692 }
693 else if (params.blockHash) {
694 return ["eth_getBlockByHash", [params.blockHash, !!params.includeTransactions]];
695 }
696 return null;
697 case "getTransaction":
698 return ["eth_getTransactionByHash", [params.transactionHash]];
699 case "getTransactionReceipt":
700 return ["eth_getTransactionReceipt", [params.transactionHash]];
701 case "call": {
702 var hexlifyTransaction = (0, properties_1.getStatic)(this.constructor, "hexlifyTransaction");
703 return ["eth_call", [hexlifyTransaction(params.transaction, { from: true }), params.blockTag]];
704 }
705 case "estimateGas": {
706 var hexlifyTransaction = (0, properties_1.getStatic)(this.constructor, "hexlifyTransaction");
707 return ["eth_estimateGas", [hexlifyTransaction(params.transaction, { from: true })]];
708 }
709 case "getLogs":
710 if (params.filter && params.filter.address != null) {
711 params.filter.address = getLowerCase(params.filter.address);
712 }
713 return ["eth_getLogs", [params.filter]];
714 default:
715 break;
716 }
717 return null;
718 };
719 JsonRpcProvider.prototype.perform = function (method, params) {
720 return __awaiter(this, void 0, void 0, function () {
721 var tx, feeData, args, error_7;
722 return __generator(this, function (_a) {
723 switch (_a.label) {
724 case 0:
725 if (!(method === "call" || method === "estimateGas")) return [3 /*break*/, 2];
726 tx = params.transaction;
727 if (!(tx && tx.type != null && bignumber_1.BigNumber.from(tx.type).isZero())) return [3 /*break*/, 2];
728 if (!(tx.maxFeePerGas == null && tx.maxPriorityFeePerGas == null)) return [3 /*break*/, 2];
729 return [4 /*yield*/, this.getFeeData()];
730 case 1:
731 feeData = _a.sent();
732 if (feeData.maxFeePerGas == null && feeData.maxPriorityFeePerGas == null) {
733 // Network doesn't know about EIP-1559 (and hence type)
734 params = (0, properties_1.shallowCopy)(params);
735 params.transaction = (0, properties_1.shallowCopy)(tx);
736 delete params.transaction.type;
737 }
738 _a.label = 2;
739 case 2:
740 args = this.prepareRequest(method, params);
741 if (args == null) {
742 logger.throwError(method + " not implemented", logger_1.Logger.errors.NOT_IMPLEMENTED, { operation: method });
743 }
744 _a.label = 3;
745 case 3:
746 _a.trys.push([3, 5, , 6]);
747 return [4 /*yield*/, this.send(args[0], args[1])];
748 case 4: return [2 /*return*/, _a.sent()];
749 case 5:
750 error_7 = _a.sent();
751 return [2 /*return*/, checkError(method, error_7, params)];
752 case 6: return [2 /*return*/];
753 }
754 });
755 });
756 };
757 JsonRpcProvider.prototype._startEvent = function (event) {
758 if (event.tag === "pending") {
759 this._startPending();
760 }
761 _super.prototype._startEvent.call(this, event);
762 };
763 JsonRpcProvider.prototype._startPending = function () {
764 if (this._pendingFilter != null) {
765 return;
766 }
767 var self = this;
768 var pendingFilter = this.send("eth_newPendingTransactionFilter", []);
769 this._pendingFilter = pendingFilter;
770 pendingFilter.then(function (filterId) {
771 function poll() {
772 self.send("eth_getFilterChanges", [filterId]).then(function (hashes) {
773 if (self._pendingFilter != pendingFilter) {
774 return null;
775 }
776 var seq = Promise.resolve();
777 hashes.forEach(function (hash) {
778 // @TODO: This should be garbage collected at some point... How? When?
779 self._emitted["t:" + hash.toLowerCase()] = "pending";
780 seq = seq.then(function () {
781 return self.getTransaction(hash).then(function (tx) {
782 self.emit("pending", tx);
783 return null;
784 });
785 });
786 });
787 return seq.then(function () {
788 return timer(1000);
789 });
790 }).then(function () {
791 if (self._pendingFilter != pendingFilter) {
792 self.send("eth_uninstallFilter", [filterId]);
793 return;
794 }
795 setTimeout(function () { poll(); }, 0);
796 return null;
797 }).catch(function (error) { });
798 }
799 poll();
800 return filterId;
801 }).catch(function (error) { });
802 };
803 JsonRpcProvider.prototype._stopEvent = function (event) {
804 if (event.tag === "pending" && this.listenerCount("pending") === 0) {
805 this._pendingFilter = null;
806 }
807 _super.prototype._stopEvent.call(this, event);
808 };
809 // Convert an ethers.js transaction into a JSON-RPC transaction
810 // - gasLimit => gas
811 // - All values hexlified
812 // - All numeric values zero-striped
813 // - All addresses are lowercased
814 // NOTE: This allows a TransactionRequest, but all values should be resolved
815 // before this is called
816 // @TODO: This will likely be removed in future versions and prepareRequest
817 // will be the preferred method for this.
818 JsonRpcProvider.hexlifyTransaction = function (transaction, allowExtra) {
819 // Check only allowed properties are given
820 var allowed = (0, properties_1.shallowCopy)(allowedTransactionKeys);
821 if (allowExtra) {
822 for (var key in allowExtra) {
823 if (allowExtra[key]) {
824 allowed[key] = true;
825 }
826 }
827 }
828 (0, properties_1.checkProperties)(transaction, allowed);
829 var result = {};
830 // JSON-RPC now requires numeric values to be "quantity" values
831 ["chainId", "gasLimit", "gasPrice", "type", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "value"].forEach(function (key) {
832 if (transaction[key] == null) {
833 return;
834 }
835 var value = (0, bytes_1.hexValue)(bignumber_1.BigNumber.from(transaction[key]));
836 if (key === "gasLimit") {
837 key = "gas";
838 }
839 result[key] = value;
840 });
841 ["from", "to", "data"].forEach(function (key) {
842 if (transaction[key] == null) {
843 return;
844 }
845 result[key] = (0, bytes_1.hexlify)(transaction[key]);
846 });
847 if (transaction.accessList) {
848 result["accessList"] = (0, transactions_1.accessListify)(transaction.accessList);
849 }
850 return result;
851 };
852 return JsonRpcProvider;
853}(base_provider_1.BaseProvider));
854exports.JsonRpcProvider = JsonRpcProvider;
855//# sourceMappingURL=json-rpc-provider.js.map
\No newline at end of file