@qevm/providers 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +3 -9
  2. package/lib/_version.d.ts +1 -1
  3. package/lib/_version.js +1 -1
  4. package/lib/base-provider.d.ts +5 -6
  5. package/lib/base-provider.d.ts.map +1 -1
  6. package/lib/base-provider.js +1658 -2158
  7. package/lib/base-provider.js.map +1 -1
  8. package/lib/browser-ipc-provider.d.ts.map +1 -1
  9. package/lib/browser-ipc-provider.js +1 -1
  10. package/lib/browser-ipc-provider.js.map +1 -1
  11. package/lib/browser-net.d.ts.map +1 -1
  12. package/lib/browser-net.js +1 -2
  13. package/lib/browser-net.js.map +1 -1
  14. package/lib/browser-ws.d.ts.map +1 -1
  15. package/lib/browser-ws.js +6 -6
  16. package/lib/browser-ws.js.map +1 -1
  17. package/lib/fallback-provider.d.ts +1 -1
  18. package/lib/fallback-provider.d.ts.map +1 -1
  19. package/lib/fallback-provider.js +354 -452
  20. package/lib/fallback-provider.js.map +1 -1
  21. package/lib/formatter.d.ts +4 -4
  22. package/lib/formatter.d.ts.map +1 -1
  23. package/lib/formatter.js +135 -132
  24. package/lib/formatter.js.map +1 -1
  25. package/lib/index.d.ts +3 -10
  26. package/lib/index.d.ts.map +1 -1
  27. package/lib/index.js +20 -43
  28. package/lib/index.js.map +1 -1
  29. package/lib/ipc-provider.d.ts +1 -1
  30. package/lib/ipc-provider.d.ts.map +1 -1
  31. package/lib/ipc-provider.js +24 -42
  32. package/lib/ipc-provider.js.map +1 -1
  33. package/lib/json-rpc-batch-provider.d.ts +0 -1
  34. package/lib/json-rpc-batch-provider.d.ts.map +1 -1
  35. package/lib/json-rpc-batch-provider.js +29 -50
  36. package/lib/json-rpc-batch-provider.js.map +1 -1
  37. package/lib/json-rpc-provider.d.ts +3 -3
  38. package/lib/json-rpc-provider.d.ts.map +1 -1
  39. package/lib/json-rpc-provider.js +417 -518
  40. package/lib/json-rpc-provider.js.map +1 -1
  41. package/lib/url-json-rpc-provider.d.ts +2 -2
  42. package/lib/url-json-rpc-provider.d.ts.map +1 -1
  43. package/lib/url-json-rpc-provider.js +47 -118
  44. package/lib/url-json-rpc-provider.js.map +1 -1
  45. package/lib/web3-provider.d.ts +3 -4
  46. package/lib/web3-provider.d.ts.map +1 -1
  47. package/lib/web3-provider.js +53 -77
  48. package/lib/web3-provider.js.map +1 -1
  49. package/lib/websocket-provider.d.ts +3 -3
  50. package/lib/websocket-provider.d.ts.map +1 -1
  51. package/lib/websocket-provider.js +136 -229
  52. package/lib/websocket-provider.js.map +1 -1
  53. package/lib/ws.d.ts.map +1 -1
  54. package/lib/ws.js +1 -1
  55. package/lib/ws.js.map +1 -1
  56. package/package.json +61 -55
  57. package/src.ts/_version.ts +1 -1
  58. package/src.ts/base-provider.ts +1427 -654
  59. package/src.ts/browser-ipc-provider.ts +1 -3
  60. package/src.ts/browser-net.ts +1 -1
  61. package/src.ts/browser-ws.ts +14 -8
  62. package/src.ts/fallback-provider.ts +379 -202
  63. package/src.ts/formatter.ts +163 -83
  64. package/src.ts/index.ts +54 -68
  65. package/src.ts/ipc-provider.ts +8 -7
  66. package/src.ts/json-rpc-batch-provider.ts +49 -45
  67. package/src.ts/json-rpc-provider.ts +597 -248
  68. package/src.ts/url-json-rpc-provider.ts +35 -16
  69. package/src.ts/web3-provider.ts +87 -54
  70. package/src.ts/websocket-provider.ts +125 -67
  71. package/src.ts/ws.ts +1 -1
  72. package/lib/alchemy-provider.d.ts +0 -17
  73. package/lib/alchemy-provider.d.ts.map +0 -1
  74. package/lib/alchemy-provider.js +0 -112
  75. package/lib/alchemy-provider.js.map +0 -1
  76. package/lib/ankr-provider.d.ts +0 -10
  77. package/lib/ankr-provider.d.ts.map +0 -1
  78. package/lib/ankr-provider.js +0 -79
  79. package/lib/ankr-provider.js.map +0 -1
  80. package/lib/cloudflare-provider.d.ts +0 -8
  81. package/lib/cloudflare-provider.d.ts.map +0 -1
  82. package/lib/cloudflare-provider.js +0 -100
  83. package/lib/cloudflare-provider.js.map +0 -1
  84. package/lib/etherscan-provider.d.ts +0 -18
  85. package/lib/etherscan-provider.d.ts.map +0 -1
  86. package/lib/etherscan-provider.js +0 -528
  87. package/lib/etherscan-provider.js.map +0 -1
  88. package/lib/infura-provider.d.ts +0 -21
  89. package/lib/infura-provider.d.ts.map +0 -1
  90. package/lib/infura-provider.js +0 -141
  91. package/lib/infura-provider.js.map +0 -1
  92. package/lib/nodesmith-provider.d.ts +0 -7
  93. package/lib/nodesmith-provider.d.ts.map +0 -1
  94. package/lib/nodesmith-provider.js +0 -64
  95. package/lib/nodesmith-provider.js.map +0 -1
  96. package/lib/pocket-provider.d.ts +0 -12
  97. package/lib/pocket-provider.d.ts.map +0 -1
  98. package/lib/pocket-provider.js +0 -98
  99. package/lib/pocket-provider.js.map +0 -1
  100. package/src.ts/alchemy-provider.ts +0 -101
  101. package/src.ts/ankr-provider.ts +0 -68
  102. package/src.ts/cloudflare-provider.ts +0 -42
  103. package/src.ts/etherscan-provider.ts +0 -454
  104. package/src.ts/infura-provider.ts +0 -143
  105. package/src.ts/nodesmith-provider.ts +0 -50
  106. package/src.ts/pocket-provider.ts +0 -93
@@ -1,78 +1,27 @@
1
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
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
54
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
55
4
  };
56
5
  Object.defineProperty(exports, "__esModule", { value: true });
57
6
  exports.BaseProvider = exports.Resolver = exports.Event = void 0;
58
- var abstract_provider_1 = require("@qevm/abstract-provider");
59
- var base64_1 = require("@ethersproject/base64");
60
- var basex_1 = require("@ethersproject/basex");
61
- var bignumber_1 = require("@ethersproject/bignumber");
62
- var bytes_1 = require("@qevm/bytes");
63
- var constants_1 = require("@ethersproject/constants");
64
- var hash_1 = require("@qevm/hash");
65
- var networks_1 = require("@ethersproject/networks");
66
- var properties_1 = require("@ethersproject/properties");
67
- var sha2_1 = require("@ethersproject/sha2");
68
- var strings_1 = require("@ethersproject/strings");
69
- var web_1 = require("@ethersproject/web");
70
- var bech32_1 = __importDefault(require("bech32"));
71
- var logger_1 = require("@ethersproject/logger");
72
- var _version_1 = require("./_version");
73
- var logger = new logger_1.Logger(_version_1.version);
74
- var formatter_1 = require("./formatter");
75
- var MAX_CCIP_REDIRECTS = 10;
7
+ const abstract_provider_1 = require("@qevm/abstract-provider");
8
+ const base64_1 = require("@qevm/base64");
9
+ const basex_1 = require("@qevm/basex");
10
+ const bignumber_1 = require("@qevm/bignumber");
11
+ const bytes_1 = require("@qevm/bytes");
12
+ const constants_1 = require("@qevm/constants");
13
+ const hash_1 = require("@qevm/hash");
14
+ const networks_1 = require("@qevm/networks");
15
+ const properties_1 = require("@qevm/properties");
16
+ const sha2_1 = require("@qevm/sha2");
17
+ const strings_1 = require("@qevm/strings");
18
+ const web_1 = require("@qevm/web");
19
+ const bech32_1 = __importDefault(require("bech32"));
20
+ const logger_1 = require("@qevm/logger");
21
+ const _version_1 = require("./_version");
22
+ const logger = new logger_1.Logger(_version_1.version);
23
+ const formatter_1 = require("./formatter");
24
+ const MAX_CCIP_REDIRECTS = 10;
76
25
  //////////////////////////////
77
26
  // Event Serializeing
78
27
  function checkTopic(topic) {
@@ -90,39 +39,41 @@ function serializeTopics(topics) {
90
39
  while (topics.length > 0 && topics[topics.length - 1] == null) {
91
40
  topics.pop();
92
41
  }
93
- return topics.map(function (topic) {
42
+ return topics
43
+ .map((topic) => {
94
44
  if (Array.isArray(topic)) {
95
45
  // Only track unique OR-topics
96
- var unique_1 = {};
97
- topic.forEach(function (topic) {
98
- unique_1[checkTopic(topic)] = true;
46
+ const unique = {};
47
+ topic.forEach((topic) => {
48
+ unique[checkTopic(topic)] = true;
99
49
  });
100
50
  // The order of OR-topics does not matter
101
- var sorted = Object.keys(unique_1);
51
+ const sorted = Object.keys(unique);
102
52
  sorted.sort();
103
53
  return sorted.join("|");
104
54
  }
105
55
  else {
106
56
  return checkTopic(topic);
107
57
  }
108
- }).join("&");
58
+ })
59
+ .join("&");
109
60
  }
110
61
  function deserializeTopics(data) {
111
62
  if (data === "") {
112
63
  return [];
113
64
  }
114
- return data.split(/&/g).map(function (topic) {
65
+ return data.split(/&/g).map((topic) => {
115
66
  if (topic === "") {
116
67
  return [];
117
68
  }
118
- var comps = topic.split("|").map(function (topic) {
119
- return ((topic === "null") ? null : topic);
69
+ const comps = topic.split("|").map((topic) => {
70
+ return topic === "null" ? null : topic;
120
71
  });
121
- return ((comps.length === 1) ? comps[0] : comps);
72
+ return comps.length === 1 ? comps[0] : comps;
122
73
  });
123
74
  }
124
75
  function getEventTag(eventName) {
125
- if (typeof (eventName) === "string") {
76
+ if (typeof eventName === "string") {
126
77
  eventName = eventName.toLowerCase();
127
78
  if ((0, bytes_1.hexDataLength)(eventName) === 32) {
128
79
  return "tx:" + eventName;
@@ -138,18 +89,21 @@ function getEventTag(eventName) {
138
89
  logger.warn("not implemented");
139
90
  throw new Error("not implemented");
140
91
  }
141
- else if (eventName && typeof (eventName) === "object") {
142
- return "filter:" + (eventName.address || "*") + ":" + serializeTopics(eventName.topics || []);
92
+ else if (eventName && typeof eventName === "object") {
93
+ return ("filter:" +
94
+ (eventName.address || "*") +
95
+ ":" +
96
+ serializeTopics(eventName.topics || []));
143
97
  }
144
98
  throw new Error("invalid event - " + eventName);
145
99
  }
146
100
  //////////////////////////////
147
101
  // Helper Object
148
102
  function getTime() {
149
- return (new Date()).getTime();
103
+ return new Date().getTime();
150
104
  }
151
105
  function stall(duration) {
152
- return new Promise(function (resolve) {
106
+ return new Promise((resolve) => {
153
107
  setTimeout(resolve, duration);
154
108
  });
155
109
  }
@@ -167,75 +121,57 @@ function stall(duration) {
167
121
  * - topics array
168
122
  * - transaction hash
169
123
  */
170
- var PollableEvents = ["block", "network", "pending", "poll"];
171
- var Event = /** @class */ (function () {
172
- function Event(tag, listener, once) {
124
+ const PollableEvents = ["block", "network", "pending", "poll"];
125
+ class Event {
126
+ constructor(tag, listener, once) {
173
127
  (0, properties_1.defineReadOnly)(this, "tag", tag);
174
128
  (0, properties_1.defineReadOnly)(this, "listener", listener);
175
129
  (0, properties_1.defineReadOnly)(this, "once", once);
176
130
  this._lastBlockNumber = -2;
177
131
  this._inflight = false;
178
132
  }
179
- Object.defineProperty(Event.prototype, "event", {
180
- get: function () {
181
- switch (this.type) {
182
- case "tx":
183
- return this.hash;
184
- case "filter":
185
- return this.filter;
186
- }
187
- return this.tag;
188
- },
189
- enumerable: false,
190
- configurable: true
191
- });
192
- Object.defineProperty(Event.prototype, "type", {
193
- get: function () {
194
- return this.tag.split(":")[0];
195
- },
196
- enumerable: false,
197
- configurable: true
198
- });
199
- Object.defineProperty(Event.prototype, "hash", {
200
- get: function () {
201
- var comps = this.tag.split(":");
202
- if (comps[0] !== "tx") {
203
- return null;
204
- }
205
- return comps[1];
206
- },
207
- enumerable: false,
208
- configurable: true
209
- });
210
- Object.defineProperty(Event.prototype, "filter", {
211
- get: function () {
212
- var comps = this.tag.split(":");
213
- if (comps[0] !== "filter") {
214
- return null;
215
- }
216
- var address = comps[1];
217
- var topics = deserializeTopics(comps[2]);
218
- var filter = {};
219
- if (topics.length > 0) {
220
- filter.topics = topics;
221
- }
222
- if (address && address !== "*") {
223
- filter.address = address;
224
- }
225
- return filter;
226
- },
227
- enumerable: false,
228
- configurable: true
229
- });
230
- Event.prototype.pollable = function () {
133
+ get event() {
134
+ switch (this.type) {
135
+ case "tx":
136
+ return this.hash;
137
+ case "filter":
138
+ return this.filter;
139
+ }
140
+ return this.tag;
141
+ }
142
+ get type() {
143
+ return this.tag.split(":")[0];
144
+ }
145
+ get hash() {
146
+ const comps = this.tag.split(":");
147
+ if (comps[0] !== "tx") {
148
+ return null;
149
+ }
150
+ return comps[1];
151
+ }
152
+ get filter() {
153
+ const comps = this.tag.split(":");
154
+ if (comps[0] !== "filter") {
155
+ return null;
156
+ }
157
+ const address = comps[1];
158
+ const topics = deserializeTopics(comps[2]);
159
+ const filter = {};
160
+ if (topics.length > 0) {
161
+ filter.topics = topics;
162
+ }
163
+ if (address && address !== "*") {
164
+ filter.address = address;
165
+ }
166
+ return filter;
167
+ }
168
+ pollable() {
231
169
  return (this.tag.indexOf(":") >= 0 || PollableEvents.indexOf(this.tag) >= 0);
232
- };
233
- return Event;
234
- }());
170
+ }
171
+ }
235
172
  exports.Event = Event;
236
- ;
237
173
  // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
238
- var coinInfos = {
174
+ const coinInfos = {
239
175
  "0": { symbol: "btc", p2pkh: 0x00, p2sh: 0x05, prefix: "bc" },
240
176
  "2": { symbol: "ltc", p2pkh: 0x30, p2sh: 0x32, prefix: "ltc" },
241
177
  "3": { symbol: "doge", p2pkh: 0x1e, p2sh: 0x16 },
@@ -250,8 +186,8 @@ function bytes32ify(value) {
250
186
  function base58Encode(data) {
251
187
  return basex_1.Base58.encode((0, bytes_1.concat)([data, (0, bytes_1.hexDataSlice)((0, sha2_1.sha256)((0, sha2_1.sha256)(data)), 0, 4)]));
252
188
  }
253
- var matcherIpfs = new RegExp("^(ipfs):/\/(.*)$", "i");
254
- var matchers = [
189
+ const matcherIpfs = new RegExp("^(ipfs):/\/(.*)$", "i");
190
+ const matchers = [
255
191
  new RegExp("^(https):/\/(.*)$", "i"),
256
192
  new RegExp("^(data):(.*)$", "i"),
257
193
  matcherIpfs,
@@ -268,8 +204,8 @@ function _parseBytes(result, start) {
268
204
  if (result === "0x") {
269
205
  return null;
270
206
  }
271
- var offset = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, start, start + 32)).toNumber();
272
- var length = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, offset, offset + 32)).toNumber();
207
+ const offset = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, start, start + 32)).toNumber();
208
+ const length = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, offset, offset + 32)).toNumber();
273
209
  return (0, bytes_1.hexDataSlice)(result, offset + 32, offset + 32 + length);
274
210
  }
275
211
  // Trim off the ipfs:// prefix and return the default gateway URL
@@ -283,36 +219,36 @@ function getIpfsLink(link) {
283
219
  else {
284
220
  logger.throwArgumentError("unsupported IPFS format", "link", link);
285
221
  }
286
- return "https://gateway.ipfs.io/ipfs/" + link;
222
+ return `https:/\/gateway.ipfs.io/ipfs/${link}`;
287
223
  }
288
224
  function numPad(value) {
289
- var result = (0, bytes_1.arrayify)(value);
225
+ const result = (0, bytes_1.arrayify)(value);
290
226
  if (result.length > 32) {
291
227
  throw new Error("internal; should not happen");
292
228
  }
293
- var padded = new Uint8Array(32);
229
+ const padded = new Uint8Array(32);
294
230
  padded.set(result, 32 - result.length);
295
231
  return padded;
296
232
  }
297
233
  function bytesPad(value) {
298
- if ((value.length % 32) === 0) {
234
+ if (value.length % 32 === 0) {
299
235
  return value;
300
236
  }
301
- var result = new Uint8Array(Math.ceil(value.length / 32) * 32);
237
+ const result = new Uint8Array(Math.ceil(value.length / 32) * 32);
302
238
  result.set(value);
303
239
  return result;
304
240
  }
305
241
  // ABI Encodes a series of (bytes, bytes, ...)
306
242
  function encodeBytes(datas) {
307
- var result = [];
308
- var byteCount = 0;
243
+ const result = [];
244
+ let byteCount = 0;
309
245
  // Add place-holders for pointers as we add items
310
- for (var i = 0; i < datas.length; i++) {
246
+ for (let i = 0; i < datas.length; i++) {
311
247
  result.push(null);
312
248
  byteCount += 32;
313
249
  }
314
- for (var i = 0; i < datas.length; i++) {
315
- var data = (0, bytes_1.arrayify)(datas[i]);
250
+ for (let i = 0; i < datas.length; i++) {
251
+ const data = (0, bytes_1.arrayify)(datas[i]);
316
252
  // Update the bytes offset
317
253
  result[i] = numPad(byteCount);
318
254
  // The length and padded value of data
@@ -322,420 +258,401 @@ function encodeBytes(datas) {
322
258
  }
323
259
  return (0, bytes_1.hexConcat)(result);
324
260
  }
325
- var Resolver = /** @class */ (function () {
261
+ class Resolver {
326
262
  // The resolvedAddress is only for creating a ReverseLookup resolver
327
- function Resolver(provider, address, name, resolvedAddress) {
263
+ constructor(provider, address, name, resolvedAddress) {
328
264
  (0, properties_1.defineReadOnly)(this, "provider", provider);
329
265
  (0, properties_1.defineReadOnly)(this, "name", name);
330
266
  (0, properties_1.defineReadOnly)(this, "address", provider.formatter.address(address));
331
267
  (0, properties_1.defineReadOnly)(this, "_resolvedAddress", resolvedAddress);
332
268
  }
333
- Resolver.prototype.supportsWildcard = function () {
334
- var _this = this;
269
+ supportsWildcard() {
335
270
  if (!this._supportsEip2544) {
336
271
  // supportsInterface(bytes4 = selector("resolve(bytes,bytes)"))
337
- this._supportsEip2544 = this.provider.call({
272
+ this._supportsEip2544 = this.provider
273
+ .call({
338
274
  to: this.address,
339
- data: "0x01ffc9a79061b92300000000000000000000000000000000000000000000000000000000"
340
- }).then(function (result) {
275
+ data: "0x01ffc9a79061b92300000000000000000000000000000000000000000000000000000000",
276
+ })
277
+ .then((result) => {
341
278
  return bignumber_1.BigNumber.from(result).eq(1);
342
- }).catch(function (error) {
279
+ })
280
+ .catch((error) => {
343
281
  if (error.code === logger_1.Logger.errors.CALL_EXCEPTION) {
344
282
  return false;
345
283
  }
346
284
  // Rethrow the error: link is down, etc. Let future attempts retry.
347
- _this._supportsEip2544 = null;
285
+ this._supportsEip2544 = null;
348
286
  throw error;
349
287
  });
350
288
  }
351
289
  return this._supportsEip2544;
352
- };
353
- Resolver.prototype._fetch = function (selector, parameters) {
354
- return __awaiter(this, void 0, void 0, function () {
355
- var tx, parseBytes, result, error_1;
356
- return __generator(this, function (_a) {
357
- switch (_a.label) {
358
- case 0:
359
- tx = {
360
- to: this.address,
361
- ccipReadEnabled: true,
362
- data: (0, bytes_1.hexConcat)([selector, (0, hash_1.namehash)(this.name), (parameters || "0x")])
363
- };
364
- parseBytes = false;
365
- return [4 /*yield*/, this.supportsWildcard()];
366
- case 1:
367
- if (_a.sent()) {
368
- parseBytes = true;
369
- // selector("resolve(bytes,bytes)")
370
- tx.data = (0, bytes_1.hexConcat)(["0x9061b923", encodeBytes([(0, hash_1.dnsEncode)(this.name), tx.data])]);
371
- }
372
- _a.label = 2;
373
- case 2:
374
- _a.trys.push([2, 4, , 5]);
375
- return [4 /*yield*/, this.provider.call(tx)];
376
- case 3:
377
- result = _a.sent();
378
- if (((0, bytes_1.arrayify)(result).length % 32) === 4) {
379
- logger.throwError("resolver threw error", logger_1.Logger.errors.CALL_EXCEPTION, {
380
- transaction: tx, data: result
381
- });
382
- }
383
- if (parseBytes) {
384
- result = _parseBytes(result, 0);
385
- }
386
- return [2 /*return*/, result];
387
- case 4:
388
- error_1 = _a.sent();
389
- if (error_1.code === logger_1.Logger.errors.CALL_EXCEPTION) {
390
- return [2 /*return*/, null];
391
- }
392
- throw error_1;
393
- case 5: return [2 /*return*/];
394
- }
395
- });
396
- });
397
- };
398
- Resolver.prototype._fetchBytes = function (selector, parameters) {
399
- return __awaiter(this, void 0, void 0, function () {
400
- var result;
401
- return __generator(this, function (_a) {
402
- switch (_a.label) {
403
- case 0: return [4 /*yield*/, this._fetch(selector, parameters)];
404
- case 1:
405
- result = _a.sent();
406
- if (result != null) {
407
- return [2 /*return*/, _parseBytes(result, 0)];
408
- }
409
- return [2 /*return*/, null];
410
- }
411
- });
412
- });
413
- };
414
- Resolver.prototype._getAddress = function (coinType, hexBytes) {
415
- var coinInfo = coinInfos[String(coinType)];
290
+ }
291
+ async _fetch(selector, parameters) {
292
+ // e.g. keccak256("addr(bytes32,uint256)")
293
+ const tx = {
294
+ to: this.address,
295
+ ccipReadEnabled: true,
296
+ data: (0, bytes_1.hexConcat)([
297
+ selector,
298
+ (0, hash_1.namehash)(this.name),
299
+ parameters || "0x",
300
+ ]),
301
+ };
302
+ // Wildcard support; use EIP-2544 to resolve the request
303
+ let parseBytes = false;
304
+ if (await this.supportsWildcard()) {
305
+ parseBytes = true;
306
+ // selector("resolve(bytes,bytes)")
307
+ tx.data = (0, bytes_1.hexConcat)([
308
+ "0x9061b923",
309
+ encodeBytes([(0, hash_1.dnsEncode)(this.name), tx.data]),
310
+ ]);
311
+ }
312
+ try {
313
+ let result = await this.provider.call(tx);
314
+ if ((0, bytes_1.arrayify)(result).length % 32 === 4) {
315
+ logger.throwError("resolver threw error", logger_1.Logger.errors.CALL_EXCEPTION, {
316
+ transaction: tx,
317
+ data: result,
318
+ });
319
+ }
320
+ if (parseBytes) {
321
+ result = _parseBytes(result, 0);
322
+ }
323
+ return result;
324
+ }
325
+ catch (error) {
326
+ if (error.code === logger_1.Logger.errors.CALL_EXCEPTION) {
327
+ return null;
328
+ }
329
+ throw error;
330
+ }
331
+ }
332
+ async _fetchBytes(selector, parameters) {
333
+ const result = await this._fetch(selector, parameters);
334
+ if (result != null) {
335
+ return _parseBytes(result, 0);
336
+ }
337
+ return null;
338
+ }
339
+ _getAddress(coinType, hexBytes) {
340
+ const coinInfo = coinInfos[String(coinType)];
416
341
  if (coinInfo == null) {
417
- logger.throwError("unsupported coin type: " + coinType, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
418
- operation: "getAddress(" + coinType + ")"
342
+ logger.throwError(`unsupported coin type: ${coinType}`, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
343
+ operation: `getAddress(${coinType})`,
419
344
  });
420
345
  }
421
346
  if (coinInfo.ilk === "eth") {
422
347
  return this.provider.formatter.address(hexBytes);
423
348
  }
424
- var bytes = (0, bytes_1.arrayify)(hexBytes);
349
+ const bytes = (0, bytes_1.arrayify)(hexBytes);
425
350
  // P2PKH: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
426
351
  if (coinInfo.p2pkh != null) {
427
- var p2pkh = hexBytes.match(/^0x76a9([0-9a-f][0-9a-f])([0-9a-f]*)88ac$/);
352
+ const p2pkh = hexBytes.match(/^0x76a9([0-9a-f][0-9a-f])([0-9a-f]*)88ac$/);
428
353
  if (p2pkh) {
429
- var length_1 = parseInt(p2pkh[1], 16);
430
- if (p2pkh[2].length === length_1 * 2 && length_1 >= 1 && length_1 <= 75) {
431
- return base58Encode((0, bytes_1.concat)([[coinInfo.p2pkh], ("0x" + p2pkh[2])]));
354
+ const length = parseInt(p2pkh[1], 16);
355
+ if (p2pkh[2].length === length * 2 &&
356
+ length >= 1 &&
357
+ length <= 75) {
358
+ return base58Encode((0, bytes_1.concat)([[coinInfo.p2pkh], "0x" + p2pkh[2]]));
432
359
  }
433
360
  }
434
361
  }
435
362
  // P2SH: OP_HASH160 <scriptHash> OP_EQUAL
436
363
  if (coinInfo.p2sh != null) {
437
- var p2sh = hexBytes.match(/^0xa9([0-9a-f][0-9a-f])([0-9a-f]*)87$/);
364
+ const p2sh = hexBytes.match(/^0xa9([0-9a-f][0-9a-f])([0-9a-f]*)87$/);
438
365
  if (p2sh) {
439
- var length_2 = parseInt(p2sh[1], 16);
440
- if (p2sh[2].length === length_2 * 2 && length_2 >= 1 && length_2 <= 75) {
441
- return base58Encode((0, bytes_1.concat)([[coinInfo.p2sh], ("0x" + p2sh[2])]));
366
+ const length = parseInt(p2sh[1], 16);
367
+ if (p2sh[2].length === length * 2 &&
368
+ length >= 1 &&
369
+ length <= 75) {
370
+ return base58Encode((0, bytes_1.concat)([[coinInfo.p2sh], "0x" + p2sh[2]]));
442
371
  }
443
372
  }
444
373
  }
445
374
  // Bech32
446
375
  if (coinInfo.prefix != null) {
447
- var length_3 = bytes[1];
376
+ const length = bytes[1];
448
377
  // https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
449
- var version_1 = bytes[0];
450
- if (version_1 === 0x00) {
451
- if (length_3 !== 20 && length_3 !== 32) {
452
- version_1 = -1;
378
+ let version = bytes[0];
379
+ if (version === 0x00) {
380
+ if (length !== 20 && length !== 32) {
381
+ version = -1;
453
382
  }
454
383
  }
455
384
  else {
456
- version_1 = -1;
385
+ version = -1;
457
386
  }
458
- if (version_1 >= 0 && bytes.length === 2 + length_3 && length_3 >= 1 && length_3 <= 75) {
459
- var words = bech32_1.default.toWords(bytes.slice(2));
460
- words.unshift(version_1);
387
+ if (version >= 0 &&
388
+ bytes.length === 2 + length &&
389
+ length >= 1 &&
390
+ length <= 75) {
391
+ const words = bech32_1.default.toWords(bytes.slice(2));
392
+ words.unshift(version);
461
393
  return bech32_1.default.encode(coinInfo.prefix, words);
462
394
  }
463
395
  }
464
396
  return null;
465
- };
466
- Resolver.prototype.getAddress = function (coinType) {
467
- return __awaiter(this, void 0, void 0, function () {
468
- var result, error_2, hexBytes, address;
469
- return __generator(this, function (_a) {
470
- switch (_a.label) {
471
- case 0:
472
- if (coinType == null) {
473
- coinType = 60;
474
- }
475
- if (!(coinType === 60)) return [3 /*break*/, 4];
476
- _a.label = 1;
477
- case 1:
478
- _a.trys.push([1, 3, , 4]);
479
- return [4 /*yield*/, this._fetch("0x3b3b57de")];
480
- case 2:
481
- result = _a.sent();
482
- // No address
483
- if (result === "0x" || result === constants_1.HashZero) {
484
- return [2 /*return*/, null];
485
- }
486
- return [2 /*return*/, this.provider.formatter.callAddress(result)];
487
- case 3:
488
- error_2 = _a.sent();
489
- if (error_2.code === logger_1.Logger.errors.CALL_EXCEPTION) {
490
- return [2 /*return*/, null];
491
- }
492
- throw error_2;
493
- case 4: return [4 /*yield*/, this._fetchBytes("0xf1cb7e06", bytes32ify(coinType))];
494
- case 5:
495
- hexBytes = _a.sent();
496
- // No address
497
- if (hexBytes == null || hexBytes === "0x") {
498
- return [2 /*return*/, null];
499
- }
500
- address = this._getAddress(coinType, hexBytes);
501
- if (address == null) {
502
- logger.throwError("invalid or unsupported coin data", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
503
- operation: "getAddress(" + coinType + ")",
504
- coinType: coinType,
505
- data: hexBytes
506
- });
507
- }
508
- return [2 /*return*/, address];
397
+ }
398
+ async getAddress(coinType) {
399
+ if (coinType == null) {
400
+ coinType = 60;
401
+ }
402
+ // If Ethereum, use the standard `addr(bytes32)`
403
+ if (coinType === 60) {
404
+ try {
405
+ // keccak256("addr(bytes32)")
406
+ const result = await this._fetch("0x3b3b57de");
407
+ // No address
408
+ if (result === "0x" || result === constants_1.HashZero) {
409
+ return null;
410
+ }
411
+ return this.provider.formatter.callAddress(result);
412
+ }
413
+ catch (error) {
414
+ if (error.code === logger_1.Logger.errors.CALL_EXCEPTION) {
415
+ return null;
509
416
  }
417
+ throw error;
418
+ }
419
+ }
420
+ // keccak256("addr(bytes32,uint256")
421
+ const hexBytes = await this._fetchBytes("0xf1cb7e06", bytes32ify(coinType));
422
+ // No address
423
+ if (hexBytes == null || hexBytes === "0x") {
424
+ return null;
425
+ }
426
+ // Compute the address
427
+ const address = this._getAddress(coinType, hexBytes);
428
+ if (address == null) {
429
+ logger.throwError(`invalid or unsupported coin data`, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
430
+ operation: `getAddress(${coinType})`,
431
+ coinType: coinType,
432
+ data: hexBytes,
510
433
  });
511
- });
512
- };
513
- Resolver.prototype.getAvatar = function () {
514
- return __awaiter(this, void 0, void 0, function () {
515
- var linkage, avatar, i, match, scheme, _a, selector, owner, _b, comps, addr, tokenId, tokenOwner, _c, _d, balance, _e, _f, tx, metadataUrl, _g, metadata, imageUrl, ipfs, error_3;
516
- return __generator(this, function (_h) {
517
- switch (_h.label) {
518
- case 0:
519
- linkage = [{ type: "name", content: this.name }];
520
- _h.label = 1;
521
- case 1:
522
- _h.trys.push([1, 19, , 20]);
523
- return [4 /*yield*/, this.getText("avatar")];
524
- case 2:
525
- avatar = _h.sent();
526
- if (avatar == null) {
527
- return [2 /*return*/, null];
528
- }
529
- i = 0;
530
- _h.label = 3;
531
- case 3:
532
- if (!(i < matchers.length)) return [3 /*break*/, 18];
533
- match = avatar.match(matchers[i]);
534
- if (match == null) {
535
- return [3 /*break*/, 17];
536
- }
537
- scheme = match[1].toLowerCase();
538
- _a = scheme;
539
- switch (_a) {
540
- case "https": return [3 /*break*/, 4];
541
- case "data": return [3 /*break*/, 5];
542
- case "ipfs": return [3 /*break*/, 6];
543
- case "erc721": return [3 /*break*/, 7];
544
- case "erc1155": return [3 /*break*/, 7];
545
- }
546
- return [3 /*break*/, 17];
547
- case 4:
434
+ }
435
+ return address;
436
+ }
437
+ async getAvatar() {
438
+ const linkage = [
439
+ { type: "name", content: this.name },
440
+ ];
441
+ try {
442
+ // test data for ricmoo.eth
443
+ //const avatar = "eip155:1/erc721:0x265385c7f4132228A0d54EB1A9e7460b91c0cC68/29233";
444
+ const avatar = await this.getText("avatar");
445
+ if (avatar == null) {
446
+ return null;
447
+ }
448
+ for (let i = 0; i < matchers.length; i++) {
449
+ const match = avatar.match(matchers[i]);
450
+ if (match == null) {
451
+ continue;
452
+ }
453
+ const scheme = match[1].toLowerCase();
454
+ switch (scheme) {
455
+ case "https":
548
456
  linkage.push({ type: "url", content: avatar });
549
- return [2 /*return*/, { linkage: linkage, url: avatar }];
550
- case 5:
457
+ return { linkage, url: avatar };
458
+ case "data":
551
459
  linkage.push({ type: "data", content: avatar });
552
- return [2 /*return*/, { linkage: linkage, url: avatar }];
553
- case 6:
460
+ return { linkage, url: avatar };
461
+ case "ipfs":
554
462
  linkage.push({ type: "ipfs", content: avatar });
555
- return [2 /*return*/, { linkage: linkage, url: getIpfsLink(avatar) }];
556
- case 7:
557
- selector = (scheme === "erc721") ? "0xc87b56dd" : "0x0e89341c";
463
+ return { linkage, url: getIpfsLink(avatar) };
464
+ case "erc721":
465
+ case "erc1155": {
466
+ // Depending on the ERC type, use tokenURI(uint256) or url(uint256)
467
+ const selector = scheme === "erc721" ? "0xc87b56dd" : "0x0e89341c";
558
468
  linkage.push({ type: scheme, content: avatar });
559
- _b = this._resolvedAddress;
560
- if (_b) return [3 /*break*/, 9];
561
- return [4 /*yield*/, this.getAddress()];
562
- case 8:
563
- _b = (_h.sent());
564
- _h.label = 9;
565
- case 9:
566
- owner = (_b);
567
- comps = (match[2] || "").split("/");
469
+ // The owner of this name
470
+ const owner = this._resolvedAddress || (await this.getAddress());
471
+ const comps = (match[2] || "").split("/");
568
472
  if (comps.length !== 2) {
569
- return [2 /*return*/, null];
570
- }
571
- return [4 /*yield*/, this.provider.formatter.address(comps[0])];
572
- case 10:
573
- addr = _h.sent();
574
- tokenId = (0, bytes_1.hexZeroPad)(bignumber_1.BigNumber.from(comps[1]).toHexString(), 32);
575
- if (!(scheme === "erc721")) return [3 /*break*/, 12];
576
- _d = (_c = this.provider.formatter).callAddress;
577
- return [4 /*yield*/, this.provider.call({
578
- to: addr, data: (0, bytes_1.hexConcat)(["0x6352211e", tokenId])
579
- })];
580
- case 11:
581
- tokenOwner = _d.apply(_c, [_h.sent()]);
582
- if (owner !== tokenOwner) {
583
- return [2 /*return*/, null];
473
+ return null;
474
+ }
475
+ const addr = await this.provider.formatter.address(comps[0]);
476
+ const tokenId = (0, bytes_1.hexZeroPad)(bignumber_1.BigNumber.from(comps[1]).toHexString(), 32);
477
+ // Check that this account owns the token
478
+ if (scheme === "erc721") {
479
+ // ownerOf(uint256 tokenId)
480
+ const tokenOwner = this.provider.formatter.callAddress(await this.provider.call({
481
+ to: addr,
482
+ data: (0, bytes_1.hexConcat)([
483
+ "0x6352211e",
484
+ tokenId,
485
+ ]),
486
+ }));
487
+ if (owner !== tokenOwner) {
488
+ return null;
489
+ }
490
+ linkage.push({
491
+ type: "owner",
492
+ content: tokenOwner,
493
+ });
584
494
  }
585
- linkage.push({ type: "owner", content: tokenOwner });
586
- return [3 /*break*/, 14];
587
- case 12:
588
- if (!(scheme === "erc1155")) return [3 /*break*/, 14];
589
- _f = (_e = bignumber_1.BigNumber).from;
590
- return [4 /*yield*/, this.provider.call({
591
- to: addr, data: (0, bytes_1.hexConcat)(["0x00fdd58e", (0, bytes_1.hexZeroPad)(owner, 32), tokenId])
592
- })];
593
- case 13:
594
- balance = _f.apply(_e, [_h.sent()]);
595
- if (balance.isZero()) {
596
- return [2 /*return*/, null];
495
+ else if (scheme === "erc1155") {
496
+ // balanceOf(address owner, uint256 tokenId)
497
+ const balance = bignumber_1.BigNumber.from(await this.provider.call({
498
+ to: addr,
499
+ data: (0, bytes_1.hexConcat)([
500
+ "0x00fdd58e",
501
+ (0, bytes_1.hexZeroPad)(owner, 32),
502
+ tokenId,
503
+ ]),
504
+ }));
505
+ if (balance.isZero()) {
506
+ return null;
507
+ }
508
+ linkage.push({
509
+ type: "balance",
510
+ content: balance.toString(),
511
+ });
597
512
  }
598
- linkage.push({ type: "balance", content: balance.toString() });
599
- _h.label = 14;
600
- case 14:
601
- tx = {
513
+ // Call the token contract for the metadata URL
514
+ const tx = {
602
515
  to: this.provider.formatter.address(comps[0]),
603
- data: (0, bytes_1.hexConcat)([selector, tokenId])
516
+ data: (0, bytes_1.hexConcat)([selector, tokenId]),
604
517
  };
605
- _g = _parseString;
606
- return [4 /*yield*/, this.provider.call(tx)];
607
- case 15:
608
- metadataUrl = _g.apply(void 0, [_h.sent(), 0]);
518
+ let metadataUrl = _parseString(await this.provider.call(tx), 0);
609
519
  if (metadataUrl == null) {
610
- return [2 /*return*/, null];
520
+ return null;
611
521
  }
612
- linkage.push({ type: "metadata-url-base", content: metadataUrl });
522
+ linkage.push({
523
+ type: "metadata-url-base",
524
+ content: metadataUrl,
525
+ });
613
526
  // ERC-1155 allows a generic {id} in the URL
614
527
  if (scheme === "erc1155") {
615
528
  metadataUrl = metadataUrl.replace("{id}", tokenId.substring(2));
616
- linkage.push({ type: "metadata-url-expanded", content: metadataUrl });
529
+ linkage.push({
530
+ type: "metadata-url-expanded",
531
+ content: metadataUrl,
532
+ });
617
533
  }
618
534
  // Transform IPFS metadata links
619
535
  if (metadataUrl.match(/^ipfs:/i)) {
620
536
  metadataUrl = getIpfsLink(metadataUrl);
621
537
  }
622
- linkage.push({ type: "metadata-url", content: metadataUrl });
623
- return [4 /*yield*/, (0, web_1.fetchJson)(metadataUrl)];
624
- case 16:
625
- metadata = _h.sent();
538
+ linkage.push({
539
+ type: "metadata-url",
540
+ content: metadataUrl,
541
+ });
542
+ // Get the token metadata
543
+ const metadata = await (0, web_1.fetchJson)(metadataUrl);
626
544
  if (!metadata) {
627
- return [2 /*return*/, null];
545
+ return null;
628
546
  }
629
- linkage.push({ type: "metadata", content: JSON.stringify(metadata) });
630
- imageUrl = metadata.image;
631
- if (typeof (imageUrl) !== "string") {
632
- return [2 /*return*/, null];
547
+ linkage.push({
548
+ type: "metadata",
549
+ content: JSON.stringify(metadata),
550
+ });
551
+ // Pull the image URL out
552
+ let imageUrl = metadata.image;
553
+ if (typeof imageUrl !== "string") {
554
+ return null;
633
555
  }
634
556
  if (imageUrl.match(/^(https:\/\/|data:)/i)) {
635
557
  // Allow
636
558
  }
637
559
  else {
638
- ipfs = imageUrl.match(matcherIpfs);
560
+ // Transform IPFS link to gateway
561
+ const ipfs = imageUrl.match(matcherIpfs);
639
562
  if (ipfs == null) {
640
- return [2 /*return*/, null];
563
+ return null;
641
564
  }
642
- linkage.push({ type: "url-ipfs", content: imageUrl });
565
+ linkage.push({
566
+ type: "url-ipfs",
567
+ content: imageUrl,
568
+ });
643
569
  imageUrl = getIpfsLink(imageUrl);
644
570
  }
645
571
  linkage.push({ type: "url", content: imageUrl });
646
- return [2 /*return*/, { linkage: linkage, url: imageUrl }];
647
- case 17:
648
- i++;
649
- return [3 /*break*/, 3];
650
- case 18: return [3 /*break*/, 20];
651
- case 19:
652
- error_3 = _h.sent();
653
- return [3 /*break*/, 20];
654
- case 20: return [2 /*return*/, null];
655
- }
656
- });
657
- });
658
- };
659
- Resolver.prototype.getContentHash = function () {
660
- return __awaiter(this, void 0, void 0, function () {
661
- var hexBytes, ipfs, length_4, ipns, length_5, swarm, skynet, urlSafe_1, hash;
662
- return __generator(this, function (_a) {
663
- switch (_a.label) {
664
- case 0: return [4 /*yield*/, this._fetchBytes("0xbc1c58d1")];
665
- case 1:
666
- hexBytes = _a.sent();
667
- // No contenthash
668
- if (hexBytes == null || hexBytes === "0x") {
669
- return [2 /*return*/, null];
670
- }
671
- ipfs = hexBytes.match(/^0xe3010170(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
672
- if (ipfs) {
673
- length_4 = parseInt(ipfs[3], 16);
674
- if (ipfs[4].length === length_4 * 2) {
675
- return [2 /*return*/, "ipfs:/\/" + basex_1.Base58.encode("0x" + ipfs[1])];
676
- }
677
- }
678
- ipns = hexBytes.match(/^0xe5010172(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
679
- if (ipns) {
680
- length_5 = parseInt(ipns[3], 16);
681
- if (ipns[4].length === length_5 * 2) {
682
- return [2 /*return*/, "ipns:/\/" + basex_1.Base58.encode("0x" + ipns[1])];
683
- }
684
- }
685
- swarm = hexBytes.match(/^0xe40101fa011b20([0-9a-f]*)$/);
686
- if (swarm) {
687
- if (swarm[1].length === (32 * 2)) {
688
- return [2 /*return*/, "bzz:/\/" + swarm[1]];
689
- }
690
- }
691
- skynet = hexBytes.match(/^0x90b2c605([0-9a-f]*)$/);
692
- if (skynet) {
693
- if (skynet[1].length === (34 * 2)) {
694
- urlSafe_1 = { "=": "", "+": "-", "/": "_" };
695
- hash = (0, base64_1.encode)("0x" + skynet[1]).replace(/[=+\/]/g, function (a) { return (urlSafe_1[a]); });
696
- return [2 /*return*/, "sia:/\/" + hash];
697
- }
698
- }
699
- return [2 /*return*/, logger.throwError("invalid or unsupported content hash data", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
700
- operation: "getContentHash()",
701
- data: hexBytes
702
- })];
703
- }
704
- });
705
- });
706
- };
707
- Resolver.prototype.getText = function (key) {
708
- return __awaiter(this, void 0, void 0, function () {
709
- var keyBytes, hexBytes;
710
- return __generator(this, function (_a) {
711
- switch (_a.label) {
712
- case 0:
713
- keyBytes = (0, strings_1.toUtf8Bytes)(key);
714
- // The nodehash consumes the first slot, so the string pointer targets
715
- // offset 64, with the length at offset 64 and data starting at offset 96
716
- keyBytes = (0, bytes_1.concat)([bytes32ify(64), bytes32ify(keyBytes.length), keyBytes]);
717
- // Pad to word-size (32 bytes)
718
- if ((keyBytes.length % 32) !== 0) {
719
- keyBytes = (0, bytes_1.concat)([keyBytes, (0, bytes_1.hexZeroPad)("0x", 32 - (key.length % 32))]);
720
- }
721
- return [4 /*yield*/, this._fetchBytes("0x59d1d43c", (0, bytes_1.hexlify)(keyBytes))];
722
- case 1:
723
- hexBytes = _a.sent();
724
- if (hexBytes == null || hexBytes === "0x") {
725
- return [2 /*return*/, null];
726
- }
727
- return [2 /*return*/, (0, strings_1.toUtf8String)(hexBytes)];
572
+ return { linkage, url: imageUrl };
573
+ }
728
574
  }
729
- });
575
+ }
576
+ }
577
+ catch (error) { }
578
+ return null;
579
+ }
580
+ async getContentHash() {
581
+ // keccak256("contenthash()")
582
+ const hexBytes = await this._fetchBytes("0xbc1c58d1");
583
+ // No contenthash
584
+ if (hexBytes == null || hexBytes === "0x") {
585
+ return null;
586
+ }
587
+ // IPFS (CID: 1, Type: DAG-PB)
588
+ const ipfs = hexBytes.match(/^0xe3010170(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
589
+ if (ipfs) {
590
+ const length = parseInt(ipfs[3], 16);
591
+ if (ipfs[4].length === length * 2) {
592
+ return "ipfs:/\/" + basex_1.Base58.encode("0x" + ipfs[1]);
593
+ }
594
+ }
595
+ // IPNS (CID: 1, Type: libp2p-key)
596
+ const ipns = hexBytes.match(/^0xe5010172(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
597
+ if (ipns) {
598
+ const length = parseInt(ipns[3], 16);
599
+ if (ipns[4].length === length * 2) {
600
+ return "ipns:/\/" + basex_1.Base58.encode("0x" + ipns[1]);
601
+ }
602
+ }
603
+ // Swarm (CID: 1, Type: swarm-manifest; hash/length hard-coded to keccak256/32)
604
+ const swarm = hexBytes.match(/^0xe40101fa011b20([0-9a-f]*)$/);
605
+ if (swarm) {
606
+ if (swarm[1].length === 32 * 2) {
607
+ return "bzz:/\/" + swarm[1];
608
+ }
609
+ }
610
+ const skynet = hexBytes.match(/^0x90b2c605([0-9a-f]*)$/);
611
+ if (skynet) {
612
+ if (skynet[1].length === 34 * 2) {
613
+ // URL Safe base64; https://datatracker.ietf.org/doc/html/rfc4648#section-5
614
+ const urlSafe = {
615
+ "=": "",
616
+ "+": "-",
617
+ "/": "_",
618
+ };
619
+ const hash = (0, base64_1.encode)("0x" + skynet[1]).replace(/[=+\/]/g, (a) => urlSafe[a]);
620
+ return "sia:/\/" + hash;
621
+ }
622
+ }
623
+ return logger.throwError(`invalid or unsupported content hash data`, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
624
+ operation: "getContentHash()",
625
+ data: hexBytes,
730
626
  });
731
- };
732
- return Resolver;
733
- }());
627
+ }
628
+ async getText(key) {
629
+ // The key encoded as parameter to fetchBytes
630
+ let keyBytes = (0, strings_1.toUtf8Bytes)(key);
631
+ // The nodehash consumes the first slot, so the string pointer targets
632
+ // offset 64, with the length at offset 64 and data starting at offset 96
633
+ keyBytes = (0, bytes_1.concat)([
634
+ bytes32ify(64),
635
+ bytes32ify(keyBytes.length),
636
+ keyBytes,
637
+ ]);
638
+ // Pad to word-size (32 bytes)
639
+ if (keyBytes.length % 32 !== 0) {
640
+ keyBytes = (0, bytes_1.concat)([
641
+ keyBytes,
642
+ (0, bytes_1.hexZeroPad)("0x", 32 - (key.length % 32)),
643
+ ]);
644
+ }
645
+ const hexBytes = await this._fetchBytes("0x59d1d43c", (0, bytes_1.hexlify)(keyBytes));
646
+ if (hexBytes == null || hexBytes === "0x") {
647
+ return null;
648
+ }
649
+ return (0, strings_1.toUtf8String)(hexBytes);
650
+ }
651
+ }
734
652
  exports.Resolver = Resolver;
735
- var defaultFormatter = null;
736
- var nextPollId = 1;
737
- var BaseProvider = /** @class */ (function (_super) {
738
- __extends(BaseProvider, _super);
653
+ let defaultFormatter = null;
654
+ let nextPollId = 1;
655
+ class BaseProvider extends abstract_provider_1.Provider {
739
656
  /**
740
657
  * ready
741
658
  *
@@ -745,1769 +662,1349 @@ var BaseProvider = /** @class */ (function (_super) {
745
662
  * MUST set this. Standard named networks have a known chainId.
746
663
  *
747
664
  */
748
- function BaseProvider(network) {
749
- var _newTarget = this.constructor;
750
- var _this = _super.call(this) || this;
665
+ constructor(network) {
666
+ super();
751
667
  // Events being listened to
752
- _this._events = [];
753
- _this._emitted = { block: -2 };
754
- _this.disableCcipRead = false;
755
- _this.formatter = _newTarget.getFormatter();
668
+ this._events = [];
669
+ this._emitted = { block: -2 };
670
+ this.disableCcipRead = false;
671
+ this.formatter = new.target.getFormatter();
756
672
  // If network is any, this Provider allows the underlying
757
673
  // network to change dynamically, and we auto-detect the
758
674
  // current network
759
- (0, properties_1.defineReadOnly)(_this, "anyNetwork", (network === "any"));
760
- if (_this.anyNetwork) {
761
- network = _this.detectNetwork();
675
+ (0, properties_1.defineReadOnly)(this, "anyNetwork", network === "any");
676
+ if (this.anyNetwork) {
677
+ network = this.detectNetwork();
762
678
  }
763
679
  if (network instanceof Promise) {
764
- _this._networkPromise = network;
680
+ this._networkPromise = network;
765
681
  // Squash any "unhandled promise" errors; that do not need to be handled
766
- network.catch(function (error) { });
682
+ network.catch((error) => { });
767
683
  // Trigger initial network setting (async)
768
- _this._ready().catch(function (error) { });
684
+ this._ready().catch((error) => { });
769
685
  }
770
686
  else {
771
- var knownNetwork = (0, properties_1.getStatic)(_newTarget, "getNetwork")(network);
687
+ const knownNetwork = (0, properties_1.getStatic)(new.target, "getNetwork")(network);
772
688
  if (knownNetwork) {
773
- (0, properties_1.defineReadOnly)(_this, "_network", knownNetwork);
774
- _this.emit("network", knownNetwork, null);
689
+ (0, properties_1.defineReadOnly)(this, "_network", knownNetwork);
690
+ this.emit("network", knownNetwork, null);
775
691
  }
776
692
  else {
777
693
  logger.throwArgumentError("invalid network", "network", network);
778
694
  }
779
695
  }
780
- _this._maxInternalBlockNumber = -1024;
781
- _this._lastBlockNumber = -2;
782
- _this._maxFilterBlockRange = 10;
783
- _this._pollingInterval = 4000;
784
- _this._fastQueryDate = 0;
785
- return _this;
786
- }
787
- BaseProvider.prototype._ready = function () {
788
- return __awaiter(this, void 0, void 0, function () {
789
- var network, error_4;
790
- return __generator(this, function (_a) {
791
- switch (_a.label) {
792
- case 0:
793
- if (!(this._network == null)) return [3 /*break*/, 7];
794
- network = null;
795
- if (!this._networkPromise) return [3 /*break*/, 4];
796
- _a.label = 1;
797
- case 1:
798
- _a.trys.push([1, 3, , 4]);
799
- return [4 /*yield*/, this._networkPromise];
800
- case 2:
801
- network = _a.sent();
802
- return [3 /*break*/, 4];
803
- case 3:
804
- error_4 = _a.sent();
805
- return [3 /*break*/, 4];
806
- case 4:
807
- if (!(network == null)) return [3 /*break*/, 6];
808
- return [4 /*yield*/, this.detectNetwork()];
809
- case 5:
810
- network = _a.sent();
811
- _a.label = 6;
812
- case 6:
813
- // This should never happen; every Provider sub-class should have
814
- // suggested a network by here (or have thrown).
815
- if (!network) {
816
- logger.throwError("no network detected", logger_1.Logger.errors.UNKNOWN_ERROR, {});
817
- }
818
- // Possible this call stacked so do not call defineReadOnly again
819
- if (this._network == null) {
820
- if (this.anyNetwork) {
821
- this._network = network;
822
- }
823
- else {
824
- (0, properties_1.defineReadOnly)(this, "_network", network);
825
- }
826
- this.emit("network", network, null);
827
- }
828
- _a.label = 7;
829
- case 7: return [2 /*return*/, this._network];
696
+ this._maxInternalBlockNumber = -1024;
697
+ this._lastBlockNumber = -2;
698
+ this._maxFilterBlockRange = 10;
699
+ this._pollingInterval = 4000;
700
+ this._fastQueryDate = 0;
701
+ }
702
+ async _ready() {
703
+ if (this._network == null) {
704
+ let network = null;
705
+ if (this._networkPromise) {
706
+ try {
707
+ network = await this._networkPromise;
708
+ }
709
+ catch (error) { }
710
+ }
711
+ // Try the Provider's network detection (this MUST throw if it cannot)
712
+ if (network == null) {
713
+ network = await this.detectNetwork();
714
+ }
715
+ // This should never happen; every Provider sub-class should have
716
+ // suggested a network by here (or have thrown).
717
+ if (!network) {
718
+ logger.throwError("no network detected", logger_1.Logger.errors.UNKNOWN_ERROR, {});
719
+ }
720
+ // Possible this call stacked so do not call defineReadOnly again
721
+ if (this._network == null) {
722
+ if (this.anyNetwork) {
723
+ this._network = network;
724
+ }
725
+ else {
726
+ (0, properties_1.defineReadOnly)(this, "_network", network);
727
+ }
728
+ this.emit("network", network, null);
729
+ }
730
+ }
731
+ return this._network;
732
+ }
733
+ // This will always return the most recently established network.
734
+ // For "any", this can change (a "network" event is emitted before
735
+ // any change is reflected); otherwise this cannot change
736
+ get ready() {
737
+ return (0, web_1.poll)(() => {
738
+ return this._ready().then((network) => {
739
+ return network;
740
+ }, (error) => {
741
+ // If the network isn't running yet, we will wait
742
+ if (error.code === logger_1.Logger.errors.NETWORK_ERROR &&
743
+ error.event === "noNetwork") {
744
+ return undefined;
830
745
  }
746
+ throw error;
831
747
  });
832
748
  });
833
- };
834
- Object.defineProperty(BaseProvider.prototype, "ready", {
835
- // This will always return the most recently established network.
836
- // For "any", this can change (a "network" event is emitted before
837
- // any change is reflected); otherwise this cannot change
838
- get: function () {
839
- var _this = this;
840
- return (0, web_1.poll)(function () {
841
- return _this._ready().then(function (network) {
842
- return network;
843
- }, function (error) {
844
- // If the network isn't running yet, we will wait
845
- if (error.code === logger_1.Logger.errors.NETWORK_ERROR && error.event === "noNetwork") {
846
- return undefined;
847
- }
848
- throw error;
849
- });
850
- });
851
- },
852
- enumerable: false,
853
- configurable: true
854
- });
749
+ }
855
750
  // @TODO: Remove this and just create a singleton formatter
856
- BaseProvider.getFormatter = function () {
751
+ static getFormatter() {
857
752
  if (defaultFormatter == null) {
858
753
  defaultFormatter = new formatter_1.Formatter();
859
754
  }
860
755
  return defaultFormatter;
861
- };
756
+ }
862
757
  // @TODO: Remove this and just use getNetwork
863
- BaseProvider.getNetwork = function (network) {
864
- return (0, networks_1.getNetwork)((network == null) ? "homestead" : network);
865
- };
866
- BaseProvider.prototype.ccipReadFetch = function (tx, calldata, urls) {
867
- return __awaiter(this, void 0, void 0, function () {
868
- var sender, data, errorMessages, i, url, href, json, result, errorMessage;
869
- return __generator(this, function (_a) {
870
- switch (_a.label) {
871
- case 0:
872
- if (this.disableCcipRead || urls.length === 0) {
873
- return [2 /*return*/, null];
874
- }
875
- sender = tx.to.toLowerCase();
876
- data = calldata.toLowerCase();
877
- errorMessages = [];
878
- i = 0;
879
- _a.label = 1;
880
- case 1:
881
- if (!(i < urls.length)) return [3 /*break*/, 4];
882
- url = urls[i];
883
- href = url.replace("{sender}", sender).replace("{data}", data);
884
- json = (url.indexOf("{data}") >= 0) ? null : JSON.stringify({ data: data, sender: sender });
885
- return [4 /*yield*/, (0, web_1.fetchJson)({ url: href, errorPassThrough: true }, json, function (value, response) {
886
- value.status = response.statusCode;
887
- return value;
888
- })];
889
- case 2:
890
- result = _a.sent();
891
- if (result.data) {
892
- return [2 /*return*/, result.data];
893
- }
894
- errorMessage = (result.message || "unknown error");
895
- // 4xx indicates the result is not present; stop
896
- if (result.status >= 400 && result.status < 500) {
897
- return [2 /*return*/, logger.throwError("response not found during CCIP fetch: " + errorMessage, logger_1.Logger.errors.SERVER_ERROR, { url: url, errorMessage: errorMessage })];
898
- }
899
- // 5xx indicates server issue; try the next url
900
- errorMessages.push(errorMessage);
901
- _a.label = 3;
902
- case 3:
903
- i++;
904
- return [3 /*break*/, 1];
905
- case 4: return [2 /*return*/, logger.throwError("error encountered during CCIP fetch: " + errorMessages.map(function (m) { return JSON.stringify(m); }).join(", "), logger_1.Logger.errors.SERVER_ERROR, {
906
- urls: urls,
907
- errorMessages: errorMessages
908
- })];
909
- }
758
+ static getNetwork(network) {
759
+ return (0, networks_1.getNetwork)(network == null ? "homestead" : network);
760
+ }
761
+ async ccipReadFetch(tx, calldata, urls) {
762
+ if (this.disableCcipRead || urls.length === 0) {
763
+ return null;
764
+ }
765
+ const sender = tx.to.toLowerCase();
766
+ const data = calldata.toLowerCase();
767
+ const errorMessages = [];
768
+ for (let i = 0; i < urls.length; i++) {
769
+ const url = urls[i];
770
+ // URL expansion
771
+ const href = url
772
+ .replace("{sender}", sender)
773
+ .replace("{data}", data);
774
+ // If no {data} is present, use POST; otherwise GET
775
+ const json = url.indexOf("{data}") >= 0
776
+ ? null
777
+ : JSON.stringify({ data, sender });
778
+ const result = await (0, web_1.fetchJson)({ url: href, errorPassThrough: true }, json, (value, response) => {
779
+ value.status = response.statusCode;
780
+ return value;
910
781
  });
782
+ if (result.data) {
783
+ return result.data;
784
+ }
785
+ const errorMessage = result.message || "unknown error";
786
+ // 4xx indicates the result is not present; stop
787
+ if (result.status >= 400 && result.status < 500) {
788
+ return logger.throwError(`response not found during CCIP fetch: ${errorMessage}`, logger_1.Logger.errors.SERVER_ERROR, { url, errorMessage });
789
+ }
790
+ // 5xx indicates server issue; try the next url
791
+ errorMessages.push(errorMessage);
792
+ }
793
+ return logger.throwError(`error encountered during CCIP fetch: ${errorMessages.map((m) => JSON.stringify(m)).join(", ")}`, logger_1.Logger.errors.SERVER_ERROR, {
794
+ urls,
795
+ errorMessages,
911
796
  });
912
- };
797
+ }
913
798
  // Fetches the blockNumber, but will reuse any result that is less
914
799
  // than maxAge old or has been requested since the last request
915
- BaseProvider.prototype._getInternalBlockNumber = function (maxAge) {
916
- return __awaiter(this, void 0, void 0, function () {
917
- var internalBlockNumber, result, error_5, reqTime, checkInternalBlockNumber;
918
- var _this = this;
919
- return __generator(this, function (_a) {
920
- switch (_a.label) {
921
- case 0: return [4 /*yield*/, this._ready()];
922
- case 1:
923
- _a.sent();
924
- if (!(maxAge > 0)) return [3 /*break*/, 7];
925
- _a.label = 2;
926
- case 2:
927
- if (!this._internalBlockNumber) return [3 /*break*/, 7];
928
- internalBlockNumber = this._internalBlockNumber;
929
- _a.label = 3;
930
- case 3:
931
- _a.trys.push([3, 5, , 6]);
932
- return [4 /*yield*/, internalBlockNumber];
933
- case 4:
934
- result = _a.sent();
935
- if ((getTime() - result.respTime) <= maxAge) {
936
- return [2 /*return*/, result.blockNumber];
937
- }
938
- // Too old; fetch a new value
939
- return [3 /*break*/, 7];
940
- case 5:
941
- error_5 = _a.sent();
942
- // The fetch rejected; if we are the first to get the
943
- // rejection, drop through so we replace it with a new
944
- // fetch; all others blocked will then get that fetch
945
- // which won't match the one they "remembered" and loop
946
- if (this._internalBlockNumber === internalBlockNumber) {
947
- return [3 /*break*/, 7];
948
- }
949
- return [3 /*break*/, 6];
950
- case 6: return [3 /*break*/, 2];
951
- case 7:
952
- reqTime = getTime();
953
- checkInternalBlockNumber = (0, properties_1.resolveProperties)({
954
- blockNumber: this.perform("getBlockNumber", {}),
955
- networkError: this.getNetwork().then(function (network) { return (null); }, function (error) { return (error); })
956
- }).then(function (_a) {
957
- var blockNumber = _a.blockNumber, networkError = _a.networkError;
958
- if (networkError) {
959
- // Unremember this bad internal block number
960
- if (_this._internalBlockNumber === checkInternalBlockNumber) {
961
- _this._internalBlockNumber = null;
962
- }
963
- throw networkError;
964
- }
965
- var respTime = getTime();
966
- blockNumber = bignumber_1.BigNumber.from(blockNumber).toNumber();
967
- if (blockNumber < _this._maxInternalBlockNumber) {
968
- blockNumber = _this._maxInternalBlockNumber;
969
- }
970
- _this._maxInternalBlockNumber = blockNumber;
971
- _this._setFastBlockNumber(blockNumber); // @TODO: Still need this?
972
- return { blockNumber: blockNumber, reqTime: reqTime, respTime: respTime };
973
- });
974
- this._internalBlockNumber = checkInternalBlockNumber;
975
- // Swallow unhandled exceptions; if needed they are handled else where
976
- checkInternalBlockNumber.catch(function (error) {
977
- // Don't null the dead (rejected) fetch, if it has already been updated
978
- if (_this._internalBlockNumber === checkInternalBlockNumber) {
979
- _this._internalBlockNumber = null;
980
- }
981
- });
982
- return [4 /*yield*/, checkInternalBlockNumber];
983
- case 8: return [2 /*return*/, (_a.sent()).blockNumber];
800
+ async _getInternalBlockNumber(maxAge) {
801
+ await this._ready();
802
+ // Allowing stale data up to maxAge old
803
+ if (maxAge > 0) {
804
+ // While there are pending internal block requests...
805
+ while (this._internalBlockNumber) {
806
+ // ..."remember" which fetch we started with
807
+ const internalBlockNumber = this._internalBlockNumber;
808
+ try {
809
+ // Check the result is not too stale
810
+ const result = await internalBlockNumber;
811
+ if (getTime() - result.respTime <= maxAge) {
812
+ return result.blockNumber;
813
+ }
814
+ // Too old; fetch a new value
815
+ break;
984
816
  }
985
- });
817
+ catch (error) {
818
+ // The fetch rejected; if we are the first to get the
819
+ // rejection, drop through so we replace it with a new
820
+ // fetch; all others blocked will then get that fetch
821
+ // which won't match the one they "remembered" and loop
822
+ if (this._internalBlockNumber === internalBlockNumber) {
823
+ break;
824
+ }
825
+ }
826
+ }
827
+ }
828
+ const reqTime = getTime();
829
+ const checkInternalBlockNumber = (0, properties_1.resolveProperties)({
830
+ blockNumber: this.perform("getBlockNumber", {}),
831
+ networkError: this.getNetwork().then((network) => null, (error) => error),
832
+ }).then(({ blockNumber, networkError }) => {
833
+ if (networkError) {
834
+ // Unremember this bad internal block number
835
+ if (this._internalBlockNumber === checkInternalBlockNumber) {
836
+ this._internalBlockNumber = null;
837
+ }
838
+ throw networkError;
839
+ }
840
+ const respTime = getTime();
841
+ blockNumber = bignumber_1.BigNumber.from(blockNumber).toNumber();
842
+ if (blockNumber < this._maxInternalBlockNumber) {
843
+ blockNumber = this._maxInternalBlockNumber;
844
+ }
845
+ this._maxInternalBlockNumber = blockNumber;
846
+ this._setFastBlockNumber(blockNumber); // @TODO: Still need this?
847
+ return { blockNumber, reqTime, respTime };
986
848
  });
987
- };
988
- BaseProvider.prototype.poll = function () {
989
- return __awaiter(this, void 0, void 0, function () {
990
- var pollId, runners, blockNumber, error_6, i;
991
- var _this = this;
992
- return __generator(this, function (_a) {
993
- switch (_a.label) {
994
- case 0:
995
- pollId = nextPollId++;
996
- runners = [];
997
- blockNumber = null;
998
- _a.label = 1;
999
- case 1:
1000
- _a.trys.push([1, 3, , 4]);
1001
- return [4 /*yield*/, this._getInternalBlockNumber(100 + this.pollingInterval / 2)];
1002
- case 2:
1003
- blockNumber = _a.sent();
1004
- return [3 /*break*/, 4];
1005
- case 3:
1006
- error_6 = _a.sent();
1007
- this.emit("error", error_6);
1008
- return [2 /*return*/];
1009
- case 4:
1010
- this._setFastBlockNumber(blockNumber);
1011
- // Emit a poll event after we have the latest (fast) block number
1012
- this.emit("poll", pollId, blockNumber);
1013
- // If the block has not changed, meh.
1014
- if (blockNumber === this._lastBlockNumber) {
1015
- this.emit("didPoll", pollId);
1016
- return [2 /*return*/];
1017
- }
1018
- // First polling cycle, trigger a "block" events
1019
- if (this._emitted.block === -2) {
1020
- this._emitted.block = blockNumber - 1;
1021
- }
1022
- if (Math.abs((this._emitted.block) - blockNumber) > 1000) {
1023
- logger.warn("network block skew detected; skipping block events (emitted=" + this._emitted.block + " blockNumber" + blockNumber + ")");
1024
- this.emit("error", logger.makeError("network block skew detected", logger_1.Logger.errors.NETWORK_ERROR, {
1025
- blockNumber: blockNumber,
1026
- event: "blockSkew",
1027
- previousBlockNumber: this._emitted.block
1028
- }));
1029
- this.emit("block", blockNumber);
1030
- }
1031
- else {
1032
- // Notify all listener for each block that has passed
1033
- for (i = this._emitted.block + 1; i <= blockNumber; i++) {
1034
- this.emit("block", i);
849
+ this._internalBlockNumber = checkInternalBlockNumber;
850
+ // Swallow unhandled exceptions; if needed they are handled else where
851
+ checkInternalBlockNumber.catch((error) => {
852
+ // Don't null the dead (rejected) fetch, if it has already been updated
853
+ if (this._internalBlockNumber === checkInternalBlockNumber) {
854
+ this._internalBlockNumber = null;
855
+ }
856
+ });
857
+ return (await checkInternalBlockNumber).blockNumber;
858
+ }
859
+ async poll() {
860
+ const pollId = nextPollId++;
861
+ // Track all running promises, so we can trigger a post-poll once they are complete
862
+ const runners = [];
863
+ let blockNumber = null;
864
+ try {
865
+ blockNumber = await this._getInternalBlockNumber(100 + this.pollingInterval / 2);
866
+ }
867
+ catch (error) {
868
+ this.emit("error", error);
869
+ return;
870
+ }
871
+ this._setFastBlockNumber(blockNumber);
872
+ // Emit a poll event after we have the latest (fast) block number
873
+ this.emit("poll", pollId, blockNumber);
874
+ // If the block has not changed, meh.
875
+ if (blockNumber === this._lastBlockNumber) {
876
+ this.emit("didPoll", pollId);
877
+ return;
878
+ }
879
+ // First polling cycle, trigger a "block" events
880
+ if (this._emitted.block === -2) {
881
+ this._emitted.block = blockNumber - 1;
882
+ }
883
+ if (Math.abs(this._emitted.block - blockNumber) > 1000) {
884
+ logger.warn(`network block skew detected; skipping block events (emitted=${this._emitted.block} blockNumber${blockNumber})`);
885
+ this.emit("error", logger.makeError("network block skew detected", logger_1.Logger.errors.NETWORK_ERROR, {
886
+ blockNumber: blockNumber,
887
+ event: "blockSkew",
888
+ previousBlockNumber: this._emitted.block,
889
+ }));
890
+ this.emit("block", blockNumber);
891
+ }
892
+ else {
893
+ // Notify all listener for each block that has passed
894
+ for (let i = this._emitted.block + 1; i <= blockNumber; i++) {
895
+ this.emit("block", i);
896
+ }
897
+ }
898
+ // The emitted block was updated, check for obsolete events
899
+ if (this._emitted.block !== blockNumber) {
900
+ this._emitted.block = blockNumber;
901
+ Object.keys(this._emitted).forEach((key) => {
902
+ // The block event does not expire
903
+ if (key === "block") {
904
+ return;
905
+ }
906
+ // The block we were at when we emitted this event
907
+ const eventBlockNumber = this._emitted[key];
908
+ // We cannot garbage collect pending transactions or blocks here
909
+ // They should be garbage collected by the Provider when setting
910
+ // "pending" events
911
+ if (eventBlockNumber === "pending") {
912
+ return;
913
+ }
914
+ // Evict any transaction hashes or block hashes over 12 blocks
915
+ // old, since they should not return null anyways
916
+ if (blockNumber - eventBlockNumber > 12) {
917
+ delete this._emitted[key];
918
+ }
919
+ });
920
+ }
921
+ // First polling cycle
922
+ if (this._lastBlockNumber === -2) {
923
+ this._lastBlockNumber = blockNumber - 1;
924
+ }
925
+ // Find all transaction hashes we are waiting on
926
+ this._events.forEach((event) => {
927
+ switch (event.type) {
928
+ case "tx": {
929
+ const hash = event.hash;
930
+ let runner = this.getTransactionReceipt(hash)
931
+ .then((receipt) => {
932
+ if (!receipt || receipt.blockNumber == null) {
933
+ return null;
934
+ }
935
+ this._emitted["t:" + hash] = receipt.blockNumber;
936
+ this.emit(hash, receipt);
937
+ return null;
938
+ })
939
+ .catch((error) => {
940
+ this.emit("error", error);
941
+ });
942
+ runners.push(runner);
943
+ break;
944
+ }
945
+ case "filter": {
946
+ // We only allow a single getLogs to be in-flight at a time
947
+ if (!event._inflight) {
948
+ event._inflight = true;
949
+ // This is the first filter for this event, so we want to
950
+ // restrict events to events that happened no earlier than now
951
+ if (event._lastBlockNumber === -2) {
952
+ event._lastBlockNumber = blockNumber - 1;
953
+ }
954
+ // Filter from the last *known* event; due to load-balancing
955
+ // and some nodes returning updated block numbers before
956
+ // indexing events, a logs result with 0 entries cannot be
957
+ // trusted and we must retry a range which includes it again
958
+ const filter = event.filter;
959
+ filter.fromBlock = event._lastBlockNumber + 1;
960
+ filter.toBlock = blockNumber;
961
+ // Prevent fitler ranges from growing too wild, since it is quite
962
+ // likely there just haven't been any events to move the lastBlockNumber.
963
+ const minFromBlock = filter.toBlock - this._maxFilterBlockRange;
964
+ if (minFromBlock > filter.fromBlock) {
965
+ filter.fromBlock = minFromBlock;
966
+ }
967
+ if (filter.fromBlock < 0) {
968
+ filter.fromBlock = 0;
969
+ }
970
+ const runner = this.getLogs(filter)
971
+ .then((logs) => {
972
+ // Allow the next getLogs
973
+ event._inflight = false;
974
+ if (logs.length === 0) {
975
+ return;
1035
976
  }
1036
- }
1037
- // The emitted block was updated, check for obsolete events
1038
- if (this._emitted.block !== blockNumber) {
1039
- this._emitted.block = blockNumber;
1040
- Object.keys(this._emitted).forEach(function (key) {
1041
- // The block event does not expire
1042
- if (key === "block") {
1043
- return;
1044
- }
1045
- // The block we were at when we emitted this event
1046
- var eventBlockNumber = _this._emitted[key];
1047
- // We cannot garbage collect pending transactions or blocks here
1048
- // They should be garbage collected by the Provider when setting
1049
- // "pending" events
1050
- if (eventBlockNumber === "pending") {
1051
- return;
1052
- }
1053
- // Evict any transaction hashes or block hashes over 12 blocks
1054
- // old, since they should not return null anyways
1055
- if (blockNumber - eventBlockNumber > 12) {
1056
- delete _this._emitted[key];
977
+ logs.forEach((log) => {
978
+ // Only when we get an event for a given block number
979
+ // can we trust the events are indexed
980
+ if (log.blockNumber > event._lastBlockNumber) {
981
+ event._lastBlockNumber =
982
+ log.blockNumber;
1057
983
  }
984
+ // Make sure we stall requests to fetch blocks and txs
985
+ this._emitted["b:" + log.blockHash] =
986
+ log.blockNumber;
987
+ this._emitted["t:" + log.transactionHash] =
988
+ log.blockNumber;
989
+ this.emit(filter, log);
1058
990
  });
1059
- }
1060
- // First polling cycle
1061
- if (this._lastBlockNumber === -2) {
1062
- this._lastBlockNumber = blockNumber - 1;
1063
- }
1064
- // Find all transaction hashes we are waiting on
1065
- this._events.forEach(function (event) {
1066
- switch (event.type) {
1067
- case "tx": {
1068
- var hash_2 = event.hash;
1069
- var runner = _this.getTransactionReceipt(hash_2).then(function (receipt) {
1070
- if (!receipt || receipt.blockNumber == null) {
1071
- return null;
1072
- }
1073
- _this._emitted["t:" + hash_2] = receipt.blockNumber;
1074
- _this.emit(hash_2, receipt);
1075
- return null;
1076
- }).catch(function (error) { _this.emit("error", error); });
1077
- runners.push(runner);
1078
- break;
1079
- }
1080
- case "filter": {
1081
- // We only allow a single getLogs to be in-flight at a time
1082
- if (!event._inflight) {
1083
- event._inflight = true;
1084
- // This is the first filter for this event, so we want to
1085
- // restrict events to events that happened no earlier than now
1086
- if (event._lastBlockNumber === -2) {
1087
- event._lastBlockNumber = blockNumber - 1;
1088
- }
1089
- // Filter from the last *known* event; due to load-balancing
1090
- // and some nodes returning updated block numbers before
1091
- // indexing events, a logs result with 0 entries cannot be
1092
- // trusted and we must retry a range which includes it again
1093
- var filter_1 = event.filter;
1094
- filter_1.fromBlock = event._lastBlockNumber + 1;
1095
- filter_1.toBlock = blockNumber;
1096
- // Prevent fitler ranges from growing too wild, since it is quite
1097
- // likely there just haven't been any events to move the lastBlockNumber.
1098
- var minFromBlock = filter_1.toBlock - _this._maxFilterBlockRange;
1099
- if (minFromBlock > filter_1.fromBlock) {
1100
- filter_1.fromBlock = minFromBlock;
1101
- }
1102
- if (filter_1.fromBlock < 0) {
1103
- filter_1.fromBlock = 0;
1104
- }
1105
- var runner = _this.getLogs(filter_1).then(function (logs) {
1106
- // Allow the next getLogs
1107
- event._inflight = false;
1108
- if (logs.length === 0) {
1109
- return;
1110
- }
1111
- logs.forEach(function (log) {
1112
- // Only when we get an event for a given block number
1113
- // can we trust the events are indexed
1114
- if (log.blockNumber > event._lastBlockNumber) {
1115
- event._lastBlockNumber = log.blockNumber;
1116
- }
1117
- // Make sure we stall requests to fetch blocks and txs
1118
- _this._emitted["b:" + log.blockHash] = log.blockNumber;
1119
- _this._emitted["t:" + log.transactionHash] = log.blockNumber;
1120
- _this.emit(filter_1, log);
1121
- });
1122
- }).catch(function (error) {
1123
- _this.emit("error", error);
1124
- // Allow another getLogs (the range was not updated)
1125
- event._inflight = false;
1126
- });
1127
- runners.push(runner);
1128
- }
1129
- break;
1130
- }
1131
- }
991
+ })
992
+ .catch((error) => {
993
+ this.emit("error", error);
994
+ // Allow another getLogs (the range was not updated)
995
+ event._inflight = false;
1132
996
  });
1133
- this._lastBlockNumber = blockNumber;
1134
- // Once all events for this loop have been processed, emit "didPoll"
1135
- Promise.all(runners).then(function () {
1136
- _this.emit("didPoll", pollId);
1137
- }).catch(function (error) { _this.emit("error", error); });
1138
- return [2 /*return*/];
997
+ runners.push(runner);
998
+ }
999
+ break;
1139
1000
  }
1140
- });
1001
+ }
1002
+ });
1003
+ this._lastBlockNumber = blockNumber;
1004
+ // Once all events for this loop have been processed, emit "didPoll"
1005
+ Promise.all(runners)
1006
+ .then(() => {
1007
+ this.emit("didPoll", pollId);
1008
+ })
1009
+ .catch((error) => {
1010
+ this.emit("error", error);
1141
1011
  });
1142
- };
1012
+ return;
1013
+ }
1143
1014
  // Deprecated; do not use this
1144
- BaseProvider.prototype.resetEventsBlock = function (blockNumber) {
1015
+ resetEventsBlock(blockNumber) {
1145
1016
  this._lastBlockNumber = blockNumber - 1;
1146
1017
  if (this.polling) {
1147
1018
  this.poll();
1148
1019
  }
1149
- };
1150
- Object.defineProperty(BaseProvider.prototype, "network", {
1151
- get: function () {
1152
- return this._network;
1153
- },
1154
- enumerable: false,
1155
- configurable: true
1156
- });
1020
+ }
1021
+ get network() {
1022
+ return this._network;
1023
+ }
1157
1024
  // This method should query the network if the underlying network
1158
1025
  // can change, such as when connected to a JSON-RPC backend
1159
- BaseProvider.prototype.detectNetwork = function () {
1160
- return __awaiter(this, void 0, void 0, function () {
1161
- return __generator(this, function (_a) {
1162
- return [2 /*return*/, logger.throwError("provider does not support network detection", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
1163
- operation: "provider.detectNetwork"
1164
- })];
1165
- });
1166
- });
1167
- };
1168
- BaseProvider.prototype.getNetwork = function () {
1169
- return __awaiter(this, void 0, void 0, function () {
1170
- var network, currentNetwork, error;
1171
- return __generator(this, function (_a) {
1172
- switch (_a.label) {
1173
- case 0: return [4 /*yield*/, this._ready()];
1174
- case 1:
1175
- network = _a.sent();
1176
- return [4 /*yield*/, this.detectNetwork()];
1177
- case 2:
1178
- currentNetwork = _a.sent();
1179
- if (!(network.chainId !== currentNetwork.chainId)) return [3 /*break*/, 5];
1180
- if (!this.anyNetwork) return [3 /*break*/, 4];
1181
- this._network = currentNetwork;
1182
- // Reset all internal block number guards and caches
1183
- this._lastBlockNumber = -2;
1184
- this._fastBlockNumber = null;
1185
- this._fastBlockNumberPromise = null;
1186
- this._fastQueryDate = 0;
1187
- this._emitted.block = -2;
1188
- this._maxInternalBlockNumber = -1024;
1189
- this._internalBlockNumber = null;
1190
- // The "network" event MUST happen before this method resolves
1191
- // so any events have a chance to unregister, so we stall an
1192
- // additional event loop before returning from /this/ call
1193
- this.emit("network", currentNetwork, network);
1194
- return [4 /*yield*/, stall(0)];
1195
- case 3:
1196
- _a.sent();
1197
- return [2 /*return*/, this._network];
1198
- case 4:
1199
- error = logger.makeError("underlying network changed", logger_1.Logger.errors.NETWORK_ERROR, {
1200
- event: "changed",
1201
- network: network,
1202
- detectedNetwork: currentNetwork
1203
- });
1204
- this.emit("error", error);
1205
- throw error;
1206
- case 5: return [2 /*return*/, network];
1207
- }
1208
- });
1026
+ async detectNetwork() {
1027
+ return logger.throwError("provider does not support network detection", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
1028
+ operation: "provider.detectNetwork",
1209
1029
  });
1210
- };
1211
- Object.defineProperty(BaseProvider.prototype, "blockNumber", {
1212
- get: function () {
1213
- var _this = this;
1214
- this._getInternalBlockNumber(100 + this.pollingInterval / 2).then(function (blockNumber) {
1215
- _this._setFastBlockNumber(blockNumber);
1216
- }, function (error) { });
1217
- return (this._fastBlockNumber != null) ? this._fastBlockNumber : -1;
1218
- },
1219
- enumerable: false,
1220
- configurable: true
1221
- });
1222
- Object.defineProperty(BaseProvider.prototype, "polling", {
1223
- get: function () {
1224
- return (this._poller != null);
1225
- },
1226
- set: function (value) {
1227
- var _this = this;
1228
- if (value && !this._poller) {
1229
- this._poller = setInterval(function () { _this.poll(); }, this.pollingInterval);
1230
- if (!this._bootstrapPoll) {
1231
- this._bootstrapPoll = setTimeout(function () {
1232
- _this.poll();
1233
- // We block additional polls until the polling interval
1234
- // is done, to prevent overwhelming the poll function
1235
- _this._bootstrapPoll = setTimeout(function () {
1236
- // If polling was disabled, something may require a poke
1237
- // since starting the bootstrap poll and it was disabled
1238
- if (!_this._poller) {
1239
- _this.poll();
1240
- }
1241
- // Clear out the bootstrap so we can do another
1242
- _this._bootstrapPoll = null;
1243
- }, _this.pollingInterval);
1244
- }, 0);
1245
- }
1030
+ }
1031
+ async getNetwork() {
1032
+ const network = await this._ready();
1033
+ // Make sure we are still connected to the same network; this is
1034
+ // only an external call for backends which can have the underlying
1035
+ // network change spontaneously
1036
+ const currentNetwork = await this.detectNetwork();
1037
+ if (network.chainId !== currentNetwork.chainId) {
1038
+ // We are allowing network changes, things can get complex fast;
1039
+ // make sure you know what you are doing if you use "any"
1040
+ if (this.anyNetwork) {
1041
+ this._network = currentNetwork;
1042
+ // Reset all internal block number guards and caches
1043
+ this._lastBlockNumber = -2;
1044
+ this._fastBlockNumber = null;
1045
+ this._fastBlockNumberPromise = null;
1046
+ this._fastQueryDate = 0;
1047
+ this._emitted.block = -2;
1048
+ this._maxInternalBlockNumber = -1024;
1049
+ this._internalBlockNumber = null;
1050
+ // The "network" event MUST happen before this method resolves
1051
+ // so any events have a chance to unregister, so we stall an
1052
+ // additional event loop before returning from /this/ call
1053
+ this.emit("network", currentNetwork, network);
1054
+ await stall(0);
1055
+ return this._network;
1246
1056
  }
1247
- else if (!value && this._poller) {
1248
- clearInterval(this._poller);
1249
- this._poller = null;
1057
+ const error = logger.makeError("underlying network changed", logger_1.Logger.errors.NETWORK_ERROR, {
1058
+ event: "changed",
1059
+ network: network,
1060
+ detectedNetwork: currentNetwork,
1061
+ });
1062
+ this.emit("error", error);
1063
+ throw error;
1064
+ }
1065
+ return network;
1066
+ }
1067
+ get blockNumber() {
1068
+ this._getInternalBlockNumber(100 + this.pollingInterval / 2).then((blockNumber) => {
1069
+ this._setFastBlockNumber(blockNumber);
1070
+ }, (error) => { });
1071
+ return this._fastBlockNumber != null ? this._fastBlockNumber : -1;
1072
+ }
1073
+ get polling() {
1074
+ return this._poller != null;
1075
+ }
1076
+ set polling(value) {
1077
+ if (value && !this._poller) {
1078
+ this._poller = setInterval(() => {
1079
+ this.poll();
1080
+ }, this.pollingInterval);
1081
+ if (!this._bootstrapPoll) {
1082
+ this._bootstrapPoll = setTimeout(() => {
1083
+ this.poll();
1084
+ // We block additional polls until the polling interval
1085
+ // is done, to prevent overwhelming the poll function
1086
+ this._bootstrapPoll = setTimeout(() => {
1087
+ // If polling was disabled, something may require a poke
1088
+ // since starting the bootstrap poll and it was disabled
1089
+ if (!this._poller) {
1090
+ this.poll();
1091
+ }
1092
+ // Clear out the bootstrap so we can do another
1093
+ this._bootstrapPoll = null;
1094
+ }, this.pollingInterval);
1095
+ }, 0);
1250
1096
  }
1251
- },
1252
- enumerable: false,
1253
- configurable: true
1254
- });
1255
- Object.defineProperty(BaseProvider.prototype, "pollingInterval", {
1256
- get: function () {
1257
- return this._pollingInterval;
1258
- },
1259
- set: function (value) {
1260
- var _this = this;
1261
- if (typeof (value) !== "number" || value <= 0 || parseInt(String(value)) != value) {
1262
- throw new Error("invalid polling interval");
1263
- }
1264
- this._pollingInterval = value;
1265
- if (this._poller) {
1266
- clearInterval(this._poller);
1267
- this._poller = setInterval(function () { _this.poll(); }, this._pollingInterval);
1268
- }
1269
- },
1270
- enumerable: false,
1271
- configurable: true
1272
- });
1273
- BaseProvider.prototype._getFastBlockNumber = function () {
1274
- var _this = this;
1275
- var now = getTime();
1097
+ }
1098
+ else if (!value && this._poller) {
1099
+ clearInterval(this._poller);
1100
+ this._poller = null;
1101
+ }
1102
+ }
1103
+ get pollingInterval() {
1104
+ return this._pollingInterval;
1105
+ }
1106
+ set pollingInterval(value) {
1107
+ if (typeof value !== "number" ||
1108
+ value <= 0 ||
1109
+ parseInt(String(value)) != value) {
1110
+ throw new Error("invalid polling interval");
1111
+ }
1112
+ this._pollingInterval = value;
1113
+ if (this._poller) {
1114
+ clearInterval(this._poller);
1115
+ this._poller = setInterval(() => {
1116
+ this.poll();
1117
+ }, this._pollingInterval);
1118
+ }
1119
+ }
1120
+ _getFastBlockNumber() {
1121
+ const now = getTime();
1276
1122
  // Stale block number, request a newer value
1277
- if ((now - this._fastQueryDate) > 2 * this._pollingInterval) {
1123
+ if (now - this._fastQueryDate > 2 * this._pollingInterval) {
1278
1124
  this._fastQueryDate = now;
1279
- this._fastBlockNumberPromise = this.getBlockNumber().then(function (blockNumber) {
1280
- if (_this._fastBlockNumber == null || blockNumber > _this._fastBlockNumber) {
1281
- _this._fastBlockNumber = blockNumber;
1125
+ this._fastBlockNumberPromise = this.getBlockNumber().then((blockNumber) => {
1126
+ if (this._fastBlockNumber == null ||
1127
+ blockNumber > this._fastBlockNumber) {
1128
+ this._fastBlockNumber = blockNumber;
1282
1129
  }
1283
- return _this._fastBlockNumber;
1130
+ return this._fastBlockNumber;
1284
1131
  });
1285
1132
  }
1286
1133
  return this._fastBlockNumberPromise;
1287
- };
1288
- BaseProvider.prototype._setFastBlockNumber = function (blockNumber) {
1134
+ }
1135
+ _setFastBlockNumber(blockNumber) {
1289
1136
  // Older block, maybe a stale request
1290
- if (this._fastBlockNumber != null && blockNumber < this._fastBlockNumber) {
1137
+ if (this._fastBlockNumber != null &&
1138
+ blockNumber < this._fastBlockNumber) {
1291
1139
  return;
1292
1140
  }
1293
1141
  // Update the time we updated the blocknumber
1294
1142
  this._fastQueryDate = getTime();
1295
1143
  // Newer block number, use it
1296
- if (this._fastBlockNumber == null || blockNumber > this._fastBlockNumber) {
1144
+ if (this._fastBlockNumber == null ||
1145
+ blockNumber > this._fastBlockNumber) {
1297
1146
  this._fastBlockNumber = blockNumber;
1298
1147
  this._fastBlockNumberPromise = Promise.resolve(blockNumber);
1299
1148
  }
1300
- };
1301
- BaseProvider.prototype.waitForTransaction = function (transactionHash, confirmations, timeout) {
1302
- return __awaiter(this, void 0, void 0, function () {
1303
- return __generator(this, function (_a) {
1304
- return [2 /*return*/, this._waitForTransaction(transactionHash, (confirmations == null) ? 1 : confirmations, timeout || 0, null)];
1305
- });
1306
- });
1307
- };
1308
- BaseProvider.prototype._waitForTransaction = function (transactionHash, confirmations, timeout, replaceable) {
1309
- return __awaiter(this, void 0, void 0, function () {
1310
- var receipt;
1311
- var _this = this;
1312
- return __generator(this, function (_a) {
1313
- switch (_a.label) {
1314
- case 0: return [4 /*yield*/, this.getTransactionReceipt(transactionHash)];
1315
- case 1:
1316
- receipt = _a.sent();
1317
- // Receipt is already good
1318
- if ((receipt ? receipt.confirmations : 0) >= confirmations) {
1319
- return [2 /*return*/, receipt];
1320
- }
1321
- // Poll until the receipt is good...
1322
- return [2 /*return*/, new Promise(function (resolve, reject) {
1323
- var cancelFuncs = [];
1324
- var done = false;
1325
- var alreadyDone = function () {
1326
- if (done) {
1327
- return true;
1328
- }
1329
- done = true;
1330
- cancelFuncs.forEach(function (func) { func(); });
1331
- return false;
1332
- };
1333
- var minedHandler = function (receipt) {
1334
- if (receipt.confirmations < confirmations) {
1335
- return;
1336
- }
1337
- if (alreadyDone()) {
1338
- return;
1339
- }
1340
- resolve(receipt);
1341
- };
1342
- _this.on(transactionHash, minedHandler);
1343
- cancelFuncs.push(function () { _this.removeListener(transactionHash, minedHandler); });
1344
- if (replaceable) {
1345
- var lastBlockNumber_1 = replaceable.startBlock;
1346
- var scannedBlock_1 = null;
1347
- var replaceHandler_1 = function (blockNumber) { return __awaiter(_this, void 0, void 0, function () {
1348
- var _this = this;
1349
- return __generator(this, function (_a) {
1350
- switch (_a.label) {
1351
- case 0:
1352
- if (done) {
1353
- return [2 /*return*/];
1354
- }
1355
- // Wait 1 second; this is only used in the case of a fault, so
1356
- // we will trade off a little bit of latency for more consistent
1357
- // results and fewer JSON-RPC calls
1358
- return [4 /*yield*/, stall(1000)];
1359
- case 1:
1360
- // Wait 1 second; this is only used in the case of a fault, so
1361
- // we will trade off a little bit of latency for more consistent
1362
- // results and fewer JSON-RPC calls
1363
- _a.sent();
1364
- this.getTransactionCount(replaceable.from).then(function (nonce) { return __awaiter(_this, void 0, void 0, function () {
1365
- var mined, block, ti, tx, receipt_1, reason;
1366
- return __generator(this, function (_a) {
1367
- switch (_a.label) {
1368
- case 0:
1369
- if (done) {
1370
- return [2 /*return*/];
1371
- }
1372
- if (!(nonce <= replaceable.nonce)) return [3 /*break*/, 1];
1373
- lastBlockNumber_1 = blockNumber;
1374
- return [3 /*break*/, 9];
1375
- case 1: return [4 /*yield*/, this.getTransaction(transactionHash)];
1376
- case 2:
1377
- mined = _a.sent();
1378
- if (mined && mined.blockNumber != null) {
1379
- return [2 /*return*/];
1380
- }
1381
- // First time scanning. We start a little earlier for some
1382
- // wiggle room here to handle the eventually consistent nature
1383
- // of blockchain (e.g. the getTransactionCount was for a
1384
- // different block)
1385
- if (scannedBlock_1 == null) {
1386
- scannedBlock_1 = lastBlockNumber_1 - 3;
1387
- if (scannedBlock_1 < replaceable.startBlock) {
1388
- scannedBlock_1 = replaceable.startBlock;
1389
- }
1390
- }
1391
- _a.label = 3;
1392
- case 3:
1393
- if (!(scannedBlock_1 <= blockNumber)) return [3 /*break*/, 9];
1394
- if (done) {
1395
- return [2 /*return*/];
1396
- }
1397
- return [4 /*yield*/, this.getBlockWithTransactions(scannedBlock_1)];
1398
- case 4:
1399
- block = _a.sent();
1400
- ti = 0;
1401
- _a.label = 5;
1402
- case 5:
1403
- if (!(ti < block.transactions.length)) return [3 /*break*/, 8];
1404
- tx = block.transactions[ti];
1405
- // Successfully mined!
1406
- if (tx.hash === transactionHash) {
1407
- return [2 /*return*/];
1408
- }
1409
- if (!(tx.from === replaceable.from && tx.nonce === replaceable.nonce)) return [3 /*break*/, 7];
1410
- if (done) {
1411
- return [2 /*return*/];
1412
- }
1413
- return [4 /*yield*/, this.waitForTransaction(tx.hash, confirmations)];
1414
- case 6:
1415
- receipt_1 = _a.sent();
1416
- // Already resolved or rejected (prolly a timeout)
1417
- if (alreadyDone()) {
1418
- return [2 /*return*/];
1419
- }
1420
- reason = "replaced";
1421
- if (tx.data === replaceable.data && tx.to === replaceable.to && tx.value.eq(replaceable.value)) {
1422
- reason = "repriced";
1423
- }
1424
- else if (tx.data === "0x" && tx.from === tx.to && tx.value.isZero()) {
1425
- reason = "cancelled";
1426
- }
1427
- // Explain why we were replaced
1428
- reject(logger.makeError("transaction was replaced", logger_1.Logger.errors.TRANSACTION_REPLACED, {
1429
- cancelled: (reason === "replaced" || reason === "cancelled"),
1430
- reason: reason,
1431
- replacement: this._wrapTransaction(tx),
1432
- hash: transactionHash,
1433
- receipt: receipt_1
1434
- }));
1435
- return [2 /*return*/];
1436
- case 7:
1437
- ti++;
1438
- return [3 /*break*/, 5];
1439
- case 8:
1440
- scannedBlock_1++;
1441
- return [3 /*break*/, 3];
1442
- case 9:
1443
- if (done) {
1444
- return [2 /*return*/];
1445
- }
1446
- this.once("block", replaceHandler_1);
1447
- return [2 /*return*/];
1448
- }
1449
- });
1450
- }); }, function (error) {
1451
- if (done) {
1452
- return;
1453
- }
1454
- _this.once("block", replaceHandler_1);
1455
- });
1456
- return [2 /*return*/];
1457
- }
1458
- });
1459
- }); };
1460
- if (done) {
1149
+ }
1150
+ async waitForTransaction(transactionHash, confirmations, timeout) {
1151
+ return this._waitForTransaction(transactionHash, confirmations == null ? 1 : confirmations, timeout || 0, null);
1152
+ }
1153
+ async _waitForTransaction(transactionHash, confirmations, timeout, replaceable) {
1154
+ const receipt = await this.getTransactionReceipt(transactionHash);
1155
+ // Receipt is already good
1156
+ if ((receipt ? receipt.confirmations : 0) >= confirmations) {
1157
+ return receipt;
1158
+ }
1159
+ // Poll until the receipt is good...
1160
+ return new Promise((resolve, reject) => {
1161
+ const cancelFuncs = [];
1162
+ let done = false;
1163
+ const alreadyDone = function () {
1164
+ if (done) {
1165
+ return true;
1166
+ }
1167
+ done = true;
1168
+ cancelFuncs.forEach((func) => {
1169
+ func();
1170
+ });
1171
+ return false;
1172
+ };
1173
+ const minedHandler = (receipt) => {
1174
+ if (receipt.confirmations < confirmations) {
1175
+ return;
1176
+ }
1177
+ if (alreadyDone()) {
1178
+ return;
1179
+ }
1180
+ resolve(receipt);
1181
+ };
1182
+ this.on(transactionHash, minedHandler);
1183
+ cancelFuncs.push(() => {
1184
+ this.removeListener(transactionHash, minedHandler);
1185
+ });
1186
+ if (replaceable) {
1187
+ let lastBlockNumber = replaceable.startBlock;
1188
+ let scannedBlock = null;
1189
+ const replaceHandler = async (blockNumber) => {
1190
+ if (done) {
1191
+ return;
1192
+ }
1193
+ // Wait 1 second; this is only used in the case of a fault, so
1194
+ // we will trade off a little bit of latency for more consistent
1195
+ // results and fewer JSON-RPC calls
1196
+ await stall(1000);
1197
+ this.getTransactionCount(replaceable.from).then(async (nonce) => {
1198
+ if (done) {
1199
+ return;
1200
+ }
1201
+ if (nonce <= replaceable.nonce) {
1202
+ lastBlockNumber = blockNumber;
1203
+ }
1204
+ else {
1205
+ // First check if the transaction was mined
1206
+ {
1207
+ const mined = await this.getTransaction(transactionHash);
1208
+ if (mined && mined.blockNumber != null) {
1209
+ return;
1210
+ }
1211
+ }
1212
+ // First time scanning. We start a little earlier for some
1213
+ // wiggle room here to handle the eventually consistent nature
1214
+ // of blockchain (e.g. the getTransactionCount was for a
1215
+ // different block)
1216
+ if (scannedBlock == null) {
1217
+ scannedBlock = lastBlockNumber - 3;
1218
+ if (scannedBlock < replaceable.startBlock) {
1219
+ scannedBlock = replaceable.startBlock;
1220
+ }
1221
+ }
1222
+ while (scannedBlock <= blockNumber) {
1223
+ if (done) {
1224
+ return;
1225
+ }
1226
+ const block = await this.getBlockWithTransactions(scannedBlock);
1227
+ for (let ti = 0; ti < block.transactions.length; ti++) {
1228
+ const tx = block.transactions[ti];
1229
+ // Successfully mined!
1230
+ if (tx.hash === transactionHash) {
1461
1231
  return;
1462
1232
  }
1463
- _this.once("block", replaceHandler_1);
1464
- cancelFuncs.push(function () {
1465
- _this.removeListener("block", replaceHandler_1);
1466
- });
1467
- }
1468
- if (typeof (timeout) === "number" && timeout > 0) {
1469
- var timer_1 = setTimeout(function () {
1233
+ // Matches our transaction from and nonce; its a replacement
1234
+ if (tx.from === replaceable.from &&
1235
+ tx.nonce === replaceable.nonce) {
1236
+ if (done) {
1237
+ return;
1238
+ }
1239
+ // Get the receipt of the replacement
1240
+ const receipt = await this.waitForTransaction(tx.hash, confirmations);
1241
+ // Already resolved or rejected (prolly a timeout)
1470
1242
  if (alreadyDone()) {
1471
1243
  return;
1472
1244
  }
1473
- reject(logger.makeError("timeout exceeded", logger_1.Logger.errors.TIMEOUT, { timeout: timeout }));
1474
- }, timeout);
1475
- if (timer_1.unref) {
1476
- timer_1.unref();
1245
+ // The reason we were replaced
1246
+ let reason = "replaced";
1247
+ if (tx.data === replaceable.data &&
1248
+ tx.to === replaceable.to &&
1249
+ tx.value.eq(replaceable.value)) {
1250
+ reason = "repriced";
1251
+ }
1252
+ else if (tx.data === "0x" &&
1253
+ tx.from === tx.to &&
1254
+ tx.value.isZero()) {
1255
+ reason = "cancelled";
1256
+ }
1257
+ // Explain why we were replaced
1258
+ reject(logger.makeError("transaction was replaced", logger_1.Logger.errors
1259
+ .TRANSACTION_REPLACED, {
1260
+ cancelled: reason ===
1261
+ "replaced" ||
1262
+ reason ===
1263
+ "cancelled",
1264
+ reason,
1265
+ replacement: this._wrapTransaction(tx),
1266
+ hash: transactionHash,
1267
+ receipt,
1268
+ }));
1269
+ return;
1477
1270
  }
1478
- cancelFuncs.push(function () { clearTimeout(timer_1); });
1479
1271
  }
1480
- })];
1481
- }
1482
- });
1483
- });
1484
- };
1485
- BaseProvider.prototype.getBlockNumber = function () {
1486
- return __awaiter(this, void 0, void 0, function () {
1487
- return __generator(this, function (_a) {
1488
- return [2 /*return*/, this._getInternalBlockNumber(0)];
1489
- });
1490
- });
1491
- };
1492
- BaseProvider.prototype.getGasPrice = function () {
1493
- return __awaiter(this, void 0, void 0, function () {
1494
- var result;
1495
- return __generator(this, function (_a) {
1496
- switch (_a.label) {
1497
- case 0: return [4 /*yield*/, this.getNetwork()];
1498
- case 1:
1499
- _a.sent();
1500
- return [4 /*yield*/, this.perform("getGasPrice", {})];
1501
- case 2:
1502
- result = _a.sent();
1503
- try {
1504
- return [2 /*return*/, bignumber_1.BigNumber.from(result)];
1272
+ scannedBlock++;
1273
+ }
1505
1274
  }
1506
- catch (error) {
1507
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1508
- method: "getGasPrice",
1509
- result: result,
1510
- error: error
1511
- })];
1275
+ if (done) {
1276
+ return;
1512
1277
  }
1513
- return [2 /*return*/];
1514
- }
1515
- });
1516
- });
1517
- };
1518
- BaseProvider.prototype.getBalance = function (addressOrName, blockTag) {
1519
- return __awaiter(this, void 0, void 0, function () {
1520
- var params, result;
1521
- return __generator(this, function (_a) {
1522
- switch (_a.label) {
1523
- case 0: return [4 /*yield*/, this.getNetwork()];
1524
- case 1:
1525
- _a.sent();
1526
- return [4 /*yield*/, (0, properties_1.resolveProperties)({
1527
- address: this._getAddress(addressOrName),
1528
- blockTag: this._getBlockTag(blockTag)
1529
- })];
1530
- case 2:
1531
- params = _a.sent();
1532
- return [4 /*yield*/, this.perform("getBalance", params)];
1533
- case 3:
1534
- result = _a.sent();
1535
- try {
1536
- return [2 /*return*/, bignumber_1.BigNumber.from(result)];
1278
+ this.once("block", replaceHandler);
1279
+ }, (error) => {
1280
+ if (done) {
1281
+ return;
1537
1282
  }
1538
- catch (error) {
1539
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1540
- method: "getBalance",
1541
- params: params,
1542
- result: result,
1543
- error: error
1544
- })];
1545
- }
1546
- return [2 /*return*/];
1283
+ this.once("block", replaceHandler);
1284
+ });
1285
+ };
1286
+ if (done) {
1287
+ return;
1288
+ }
1289
+ this.once("block", replaceHandler);
1290
+ cancelFuncs.push(() => {
1291
+ this.removeListener("block", replaceHandler);
1292
+ });
1293
+ }
1294
+ if (typeof timeout === "number" && timeout > 0) {
1295
+ const timer = setTimeout(() => {
1296
+ if (alreadyDone()) {
1297
+ return;
1298
+ }
1299
+ reject(logger.makeError("timeout exceeded", logger_1.Logger.errors.TIMEOUT, { timeout: timeout }));
1300
+ }, timeout);
1301
+ if (timer.unref) {
1302
+ timer.unref();
1547
1303
  }
1304
+ cancelFuncs.push(() => {
1305
+ clearTimeout(timer);
1306
+ });
1307
+ }
1308
+ });
1309
+ }
1310
+ async getBlockNumber() {
1311
+ return this._getInternalBlockNumber(0);
1312
+ }
1313
+ async getGasPrice() {
1314
+ await this.getNetwork();
1315
+ const result = await this.perform("getGasPrice", {});
1316
+ try {
1317
+ return bignumber_1.BigNumber.from(result);
1318
+ }
1319
+ catch (error) {
1320
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1321
+ method: "getGasPrice",
1322
+ result,
1323
+ error,
1548
1324
  });
1325
+ }
1326
+ }
1327
+ async getBalance(addressOrName, blockTag) {
1328
+ await this.getNetwork();
1329
+ const params = await (0, properties_1.resolveProperties)({
1330
+ address: this._getAddress(addressOrName),
1331
+ blockTag: this._getBlockTag(blockTag),
1549
1332
  });
1550
- };
1551
- BaseProvider.prototype.getTransactionCount = function (addressOrName, blockTag) {
1552
- return __awaiter(this, void 0, void 0, function () {
1553
- var params, result;
1554
- return __generator(this, function (_a) {
1555
- switch (_a.label) {
1556
- case 0: return [4 /*yield*/, this.getNetwork()];
1557
- case 1:
1558
- _a.sent();
1559
- return [4 /*yield*/, (0, properties_1.resolveProperties)({
1560
- address: this._getAddress(addressOrName),
1561
- blockTag: this._getBlockTag(blockTag)
1562
- })];
1563
- case 2:
1564
- params = _a.sent();
1565
- return [4 /*yield*/, this.perform("getTransactionCount", params)];
1566
- case 3:
1567
- result = _a.sent();
1568
- try {
1569
- return [2 /*return*/, bignumber_1.BigNumber.from(result).toNumber()];
1570
- }
1571
- catch (error) {
1572
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1573
- method: "getTransactionCount",
1574
- params: params,
1575
- result: result,
1576
- error: error
1577
- })];
1578
- }
1579
- return [2 /*return*/];
1580
- }
1333
+ const result = await this.perform("getBalance", params);
1334
+ try {
1335
+ return bignumber_1.BigNumber.from(result);
1336
+ }
1337
+ catch (error) {
1338
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1339
+ method: "getBalance",
1340
+ params,
1341
+ result,
1342
+ error,
1581
1343
  });
1344
+ }
1345
+ }
1346
+ async getTransactionCount(addressOrName, blockTag) {
1347
+ await this.getNetwork();
1348
+ const params = await (0, properties_1.resolveProperties)({
1349
+ address: this._getAddress(addressOrName),
1350
+ blockTag: this._getBlockTag(blockTag),
1582
1351
  });
1583
- };
1584
- BaseProvider.prototype.getCode = function (addressOrName, blockTag) {
1585
- return __awaiter(this, void 0, void 0, function () {
1586
- var params, result;
1587
- return __generator(this, function (_a) {
1588
- switch (_a.label) {
1589
- case 0: return [4 /*yield*/, this.getNetwork()];
1590
- case 1:
1591
- _a.sent();
1592
- return [4 /*yield*/, (0, properties_1.resolveProperties)({
1593
- address: this._getAddress(addressOrName),
1594
- blockTag: this._getBlockTag(blockTag)
1595
- })];
1596
- case 2:
1597
- params = _a.sent();
1598
- return [4 /*yield*/, this.perform("getCode", params)];
1599
- case 3:
1600
- result = _a.sent();
1601
- try {
1602
- return [2 /*return*/, (0, bytes_1.hexlify)(result)];
1603
- }
1604
- catch (error) {
1605
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1606
- method: "getCode",
1607
- params: params,
1608
- result: result,
1609
- error: error
1610
- })];
1611
- }
1612
- return [2 /*return*/];
1613
- }
1352
+ const result = await this.perform("getTransactionCount", params);
1353
+ try {
1354
+ return bignumber_1.BigNumber.from(result).toNumber();
1355
+ }
1356
+ catch (error) {
1357
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1358
+ method: "getTransactionCount",
1359
+ params,
1360
+ result,
1361
+ error,
1614
1362
  });
1363
+ }
1364
+ }
1365
+ async getCode(addressOrName, blockTag) {
1366
+ await this.getNetwork();
1367
+ const params = await (0, properties_1.resolveProperties)({
1368
+ address: this._getAddress(addressOrName),
1369
+ blockTag: this._getBlockTag(blockTag),
1615
1370
  });
1616
- };
1617
- BaseProvider.prototype.getStorageAt = function (addressOrName, position, blockTag) {
1618
- return __awaiter(this, void 0, void 0, function () {
1619
- var params, result;
1620
- return __generator(this, function (_a) {
1621
- switch (_a.label) {
1622
- case 0: return [4 /*yield*/, this.getNetwork()];
1623
- case 1:
1624
- _a.sent();
1625
- return [4 /*yield*/, (0, properties_1.resolveProperties)({
1626
- address: this._getAddress(addressOrName),
1627
- blockTag: this._getBlockTag(blockTag),
1628
- position: Promise.resolve(position).then(function (p) { return (0, bytes_1.hexValue)(p); })
1629
- })];
1630
- case 2:
1631
- params = _a.sent();
1632
- return [4 /*yield*/, this.perform("getStorageAt", params)];
1633
- case 3:
1634
- result = _a.sent();
1635
- try {
1636
- return [2 /*return*/, (0, bytes_1.hexlify)(result)];
1637
- }
1638
- catch (error) {
1639
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1640
- method: "getStorageAt",
1641
- params: params,
1642
- result: result,
1643
- error: error
1644
- })];
1645
- }
1646
- return [2 /*return*/];
1647
- }
1371
+ const result = await this.perform("getCode", params);
1372
+ try {
1373
+ return (0, bytes_1.hexlify)(result);
1374
+ }
1375
+ catch (error) {
1376
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1377
+ method: "getCode",
1378
+ params,
1379
+ result,
1380
+ error,
1648
1381
  });
1382
+ }
1383
+ }
1384
+ async getStorageAt(addressOrName, position, blockTag) {
1385
+ await this.getNetwork();
1386
+ const params = await (0, properties_1.resolveProperties)({
1387
+ address: this._getAddress(addressOrName),
1388
+ blockTag: this._getBlockTag(blockTag),
1389
+ position: Promise.resolve(position).then((p) => (0, bytes_1.hexValue)(p)),
1649
1390
  });
1650
- };
1391
+ const result = await this.perform("getStorageAt", params);
1392
+ try {
1393
+ return (0, bytes_1.hexlify)(result);
1394
+ }
1395
+ catch (error) {
1396
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1397
+ method: "getStorageAt",
1398
+ params,
1399
+ result,
1400
+ error,
1401
+ });
1402
+ }
1403
+ }
1651
1404
  // This should be called by any subclass wrapping a TransactionResponse
1652
- BaseProvider.prototype._wrapTransaction = function (tx, hash, startBlock) {
1653
- var _this = this;
1405
+ _wrapTransaction(tx, hash, startBlock) {
1654
1406
  if (hash != null && (0, bytes_1.hexDataLength)(hash) !== 32) {
1655
1407
  throw new Error("invalid response - sendTransaction");
1656
1408
  }
1657
- var result = tx;
1409
+ const result = tx;
1658
1410
  // Check the hash we expect is the same as the hash the server reported
1659
1411
  if (hash != null && tx.hash !== hash) {
1660
1412
  logger.throwError("Transaction hash mismatch from Provider.sendTransaction.", logger_1.Logger.errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
1661
1413
  }
1662
- result.wait = function (confirms, timeout) { return __awaiter(_this, void 0, void 0, function () {
1663
- var replacement, receipt;
1664
- return __generator(this, function (_a) {
1665
- switch (_a.label) {
1666
- case 0:
1667
- if (confirms == null) {
1668
- confirms = 1;
1669
- }
1670
- if (timeout == null) {
1671
- timeout = 0;
1672
- }
1673
- replacement = undefined;
1674
- if (confirms !== 0 && startBlock != null) {
1675
- replacement = {
1676
- data: tx.data,
1677
- from: tx.from,
1678
- nonce: tx.nonce,
1679
- to: tx.to,
1680
- value: tx.value,
1681
- startBlock: startBlock
1682
- };
1683
- }
1684
- return [4 /*yield*/, this._waitForTransaction(tx.hash, confirms, timeout, replacement)];
1685
- case 1:
1686
- receipt = _a.sent();
1687
- if (receipt == null && confirms === 0) {
1688
- return [2 /*return*/, null];
1689
- }
1690
- // No longer pending, allow the polling loop to garbage collect this
1691
- this._emitted["t:" + tx.hash] = receipt.blockNumber;
1692
- if (receipt.status === 0) {
1693
- logger.throwError("transaction failed", logger_1.Logger.errors.CALL_EXCEPTION, {
1694
- transactionHash: tx.hash,
1695
- transaction: tx,
1696
- receipt: receipt
1697
- });
1698
- }
1699
- return [2 /*return*/, receipt];
1700
- }
1701
- });
1702
- }); };
1414
+ result.wait = async (confirms, timeout) => {
1415
+ if (confirms == null) {
1416
+ confirms = 1;
1417
+ }
1418
+ if (timeout == null) {
1419
+ timeout = 0;
1420
+ }
1421
+ // Get the details to detect replacement
1422
+ let replacement = undefined;
1423
+ if (confirms !== 0 && startBlock != null) {
1424
+ replacement = {
1425
+ data: tx.data,
1426
+ from: tx.from,
1427
+ nonce: tx.nonce,
1428
+ to: tx.to,
1429
+ value: tx.value,
1430
+ startBlock,
1431
+ };
1432
+ }
1433
+ const receipt = await this._waitForTransaction(tx.hash, confirms, timeout, replacement);
1434
+ if (receipt == null && confirms === 0) {
1435
+ return null;
1436
+ }
1437
+ // No longer pending, allow the polling loop to garbage collect this
1438
+ this._emitted["t:" + tx.hash] = receipt.blockNumber;
1439
+ if (receipt.status === 0) {
1440
+ logger.throwError("transaction failed", logger_1.Logger.errors.CALL_EXCEPTION, {
1441
+ transactionHash: tx.hash,
1442
+ transaction: tx,
1443
+ receipt: receipt,
1444
+ });
1445
+ }
1446
+ return receipt;
1447
+ };
1703
1448
  return result;
1704
- };
1705
- BaseProvider.prototype.sendTransaction = function (signedTransaction) {
1706
- return __awaiter(this, void 0, void 0, function () {
1707
- var hexTx, tx, blockNumber, hash, error_7;
1708
- return __generator(this, function (_a) {
1709
- switch (_a.label) {
1710
- case 0: return [4 /*yield*/, this.getNetwork()];
1711
- case 1:
1712
- _a.sent();
1713
- return [4 /*yield*/, Promise.resolve(signedTransaction).then(function (t) { return (0, bytes_1.hexlify)(t); })];
1714
- case 2:
1715
- hexTx = _a.sent();
1716
- tx = this.formatter.transaction(signedTransaction);
1717
- if (tx.confirmations == null) {
1718
- tx.confirmations = 0;
1719
- }
1720
- return [4 /*yield*/, this._getInternalBlockNumber(100 + 2 * this.pollingInterval)];
1721
- case 3:
1722
- blockNumber = _a.sent();
1723
- _a.label = 4;
1724
- case 4:
1725
- _a.trys.push([4, 6, , 7]);
1726
- return [4 /*yield*/, this.perform("sendTransaction", { signedTransaction: hexTx })];
1727
- case 5:
1728
- hash = _a.sent();
1729
- return [2 /*return*/, this._wrapTransaction(tx, hash, blockNumber)];
1730
- case 6:
1731
- error_7 = _a.sent();
1732
- error_7.transaction = tx;
1733
- error_7.transactionHash = tx.hash;
1734
- throw error_7;
1735
- case 7: return [2 /*return*/];
1736
- }
1449
+ }
1450
+ async sendTransaction(signedTransaction) {
1451
+ await this.getNetwork();
1452
+ const hexTx = await Promise.resolve(signedTransaction).then((t) => (0, bytes_1.hexlify)(t));
1453
+ const tx = this.formatter.transaction(signedTransaction);
1454
+ if (tx.confirmations == null) {
1455
+ tx.confirmations = 0;
1456
+ }
1457
+ const blockNumber = await this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
1458
+ try {
1459
+ const hash = await this.perform("sendTransaction", {
1460
+ signedTransaction: hexTx,
1737
1461
  });
1462
+ return this._wrapTransaction(tx, hash, blockNumber);
1463
+ }
1464
+ catch (error) {
1465
+ error.transaction = tx;
1466
+ error.transactionHash = tx.hash;
1467
+ throw error;
1468
+ }
1469
+ }
1470
+ async _getTransactionRequest(transaction) {
1471
+ const values = await transaction;
1472
+ const tx = {};
1473
+ ["from", "to"].forEach((key) => {
1474
+ if (values[key] == null) {
1475
+ return;
1476
+ }
1477
+ tx[key] = Promise.resolve(values[key]).then((v) => v ? this._getAddress(v) : null);
1738
1478
  });
1739
- };
1740
- BaseProvider.prototype._getTransactionRequest = function (transaction) {
1741
- return __awaiter(this, void 0, void 0, function () {
1742
- var values, tx, _a, _b;
1743
- var _this = this;
1744
- return __generator(this, function (_c) {
1745
- switch (_c.label) {
1746
- case 0: return [4 /*yield*/, transaction];
1747
- case 1:
1748
- values = _c.sent();
1749
- tx = {};
1750
- ["from", "to"].forEach(function (key) {
1751
- if (values[key] == null) {
1752
- return;
1753
- }
1754
- tx[key] = Promise.resolve(values[key]).then(function (v) { return (v ? _this._getAddress(v) : null); });
1755
- });
1756
- ["gasLimit", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "value"].forEach(function (key) {
1757
- if (values[key] == null) {
1758
- return;
1759
- }
1760
- tx[key] = Promise.resolve(values[key]).then(function (v) { return (v ? bignumber_1.BigNumber.from(v) : null); });
1761
- });
1762
- ["type"].forEach(function (key) {
1763
- if (values[key] == null) {
1764
- return;
1765
- }
1766
- tx[key] = Promise.resolve(values[key]).then(function (v) { return ((v != null) ? v : null); });
1767
- });
1768
- if (values.accessList) {
1769
- tx.accessList = this.formatter.accessList(values.accessList);
1770
- }
1771
- ["data"].forEach(function (key) {
1772
- if (values[key] == null) {
1773
- return;
1774
- }
1775
- tx[key] = Promise.resolve(values[key]).then(function (v) { return (v ? (0, bytes_1.hexlify)(v) : null); });
1776
- });
1777
- _b = (_a = this.formatter).transactionRequest;
1778
- return [4 /*yield*/, (0, properties_1.resolveProperties)(tx)];
1779
- case 2: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
1780
- }
1781
- });
1479
+ [
1480
+ "gasLimit",
1481
+ "gasPrice",
1482
+ "maxFeePerGas",
1483
+ "maxPriorityFeePerGas",
1484
+ "value",
1485
+ ].forEach((key) => {
1486
+ if (values[key] == null) {
1487
+ return;
1488
+ }
1489
+ tx[key] = Promise.resolve(values[key]).then((v) => v ? bignumber_1.BigNumber.from(v) : null);
1782
1490
  });
1783
- };
1784
- BaseProvider.prototype._getFilter = function (filter) {
1785
- return __awaiter(this, void 0, void 0, function () {
1786
- var result, _a, _b;
1787
- var _this = this;
1788
- return __generator(this, function (_c) {
1789
- switch (_c.label) {
1790
- case 0: return [4 /*yield*/, filter];
1791
- case 1:
1792
- filter = _c.sent();
1793
- result = {};
1794
- if (filter.address != null) {
1795
- result.address = this._getAddress(filter.address);
1796
- }
1797
- ["blockHash", "topics"].forEach(function (key) {
1798
- if (filter[key] == null) {
1799
- return;
1800
- }
1801
- result[key] = filter[key];
1802
- });
1803
- ["fromBlock", "toBlock"].forEach(function (key) {
1804
- if (filter[key] == null) {
1805
- return;
1806
- }
1807
- result[key] = _this._getBlockTag(filter[key]);
1491
+ ["type"].forEach((key) => {
1492
+ if (values[key] == null) {
1493
+ return;
1494
+ }
1495
+ tx[key] = Promise.resolve(values[key]).then((v) => v != null ? v : null);
1496
+ });
1497
+ if (values.accessList) {
1498
+ tx.accessList = this.formatter.accessList(values.accessList);
1499
+ }
1500
+ ["data"].forEach((key) => {
1501
+ if (values[key] == null) {
1502
+ return;
1503
+ }
1504
+ tx[key] = Promise.resolve(values[key]).then((v) => v ? (0, bytes_1.hexlify)(v) : null);
1505
+ });
1506
+ return this.formatter.transactionRequest(await (0, properties_1.resolveProperties)(tx));
1507
+ }
1508
+ async _getFilter(filter) {
1509
+ filter = await filter;
1510
+ const result = {};
1511
+ if (filter.address != null) {
1512
+ result.address = this._getAddress(filter.address);
1513
+ }
1514
+ ["blockHash", "topics"].forEach((key) => {
1515
+ if (filter[key] == null) {
1516
+ return;
1517
+ }
1518
+ result[key] = filter[key];
1519
+ });
1520
+ ["fromBlock", "toBlock"].forEach((key) => {
1521
+ if (filter[key] == null) {
1522
+ return;
1523
+ }
1524
+ result[key] = this._getBlockTag(filter[key]);
1525
+ });
1526
+ return this.formatter.filter(await (0, properties_1.resolveProperties)(result));
1527
+ }
1528
+ async _call(transaction, blockTag, attempt) {
1529
+ if (attempt >= MAX_CCIP_REDIRECTS) {
1530
+ logger.throwError("CCIP read exceeded maximum redirections", logger_1.Logger.errors.SERVER_ERROR, {
1531
+ redirects: attempt,
1532
+ transaction,
1533
+ });
1534
+ }
1535
+ const txSender = transaction.to;
1536
+ const result = await this.perform("call", { transaction, blockTag });
1537
+ // CCIP Read request via OffchainLookup(address,string[],bytes,bytes4,bytes)
1538
+ if (attempt >= 0 &&
1539
+ blockTag === "latest" &&
1540
+ txSender != null &&
1541
+ result.substring(0, 10) === "0x556f1830" &&
1542
+ (0, bytes_1.hexDataLength)(result) % 32 === 4) {
1543
+ try {
1544
+ const data = (0, bytes_1.hexDataSlice)(result, 4);
1545
+ // Check the sender of the OffchainLookup matches the transaction
1546
+ const sender = (0, bytes_1.hexDataSlice)(data, 0, 32);
1547
+ if (!bignumber_1.BigNumber.from(sender).eq(txSender)) {
1548
+ logger.throwError("CCIP Read sender did not match", logger_1.Logger.errors.CALL_EXCEPTION, {
1549
+ name: "OffchainLookup",
1550
+ signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1551
+ transaction,
1552
+ data: result,
1553
+ });
1554
+ }
1555
+ // Read the URLs from the response
1556
+ const urls = [];
1557
+ const urlsOffset = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(data, 32, 64)).toNumber();
1558
+ const urlsLength = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(data, urlsOffset, urlsOffset + 32)).toNumber();
1559
+ const urlsData = (0, bytes_1.hexDataSlice)(data, urlsOffset + 32);
1560
+ for (let u = 0; u < urlsLength; u++) {
1561
+ const url = _parseString(urlsData, u * 32);
1562
+ if (url == null) {
1563
+ logger.throwError("CCIP Read contained corrupt URL string", logger_1.Logger.errors.CALL_EXCEPTION, {
1564
+ name: "OffchainLookup",
1565
+ signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1566
+ transaction,
1567
+ data: result,
1808
1568
  });
1809
- _b = (_a = this.formatter).filter;
1810
- return [4 /*yield*/, (0, properties_1.resolveProperties)(result)];
1811
- case 2: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
1569
+ }
1570
+ urls.push(url);
1812
1571
  }
1813
- });
1814
- });
1815
- };
1816
- BaseProvider.prototype._call = function (transaction, blockTag, attempt) {
1817
- return __awaiter(this, void 0, void 0, function () {
1818
- var txSender, result, data, sender, urls, urlsOffset, urlsLength, urlsData, u, url, calldata, callbackSelector, extraData, ccipResult, tx, error_8;
1819
- return __generator(this, function (_a) {
1820
- switch (_a.label) {
1821
- case 0:
1822
- if (attempt >= MAX_CCIP_REDIRECTS) {
1823
- logger.throwError("CCIP read exceeded maximum redirections", logger_1.Logger.errors.SERVER_ERROR, {
1824
- redirects: attempt,
1825
- transaction: transaction
1826
- });
1827
- }
1828
- txSender = transaction.to;
1829
- return [4 /*yield*/, this.perform("call", { transaction: transaction, blockTag: blockTag })];
1830
- case 1:
1831
- result = _a.sent();
1832
- if (!(attempt >= 0 && blockTag === "latest" && txSender != null && result.substring(0, 10) === "0x556f1830" && ((0, bytes_1.hexDataLength)(result) % 32 === 4))) return [3 /*break*/, 5];
1833
- _a.label = 2;
1834
- case 2:
1835
- _a.trys.push([2, 4, , 5]);
1836
- data = (0, bytes_1.hexDataSlice)(result, 4);
1837
- sender = (0, bytes_1.hexDataSlice)(data, 0, 32);
1838
- if (!bignumber_1.BigNumber.from(sender).eq(txSender)) {
1839
- logger.throwError("CCIP Read sender did not match", logger_1.Logger.errors.CALL_EXCEPTION, {
1840
- name: "OffchainLookup",
1841
- signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1842
- transaction: transaction,
1843
- data: result
1844
- });
1845
- }
1846
- urls = [];
1847
- urlsOffset = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(data, 32, 64)).toNumber();
1848
- urlsLength = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(data, urlsOffset, urlsOffset + 32)).toNumber();
1849
- urlsData = (0, bytes_1.hexDataSlice)(data, urlsOffset + 32);
1850
- for (u = 0; u < urlsLength; u++) {
1851
- url = _parseString(urlsData, u * 32);
1852
- if (url == null) {
1853
- logger.throwError("CCIP Read contained corrupt URL string", logger_1.Logger.errors.CALL_EXCEPTION, {
1854
- name: "OffchainLookup",
1855
- signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1856
- transaction: transaction,
1857
- data: result
1858
- });
1859
- }
1860
- urls.push(url);
1861
- }
1862
- calldata = _parseBytes(data, 64);
1863
- // Get the callbackSelector (bytes4)
1864
- if (!bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(data, 100, 128)).isZero()) {
1865
- logger.throwError("CCIP Read callback selector included junk", logger_1.Logger.errors.CALL_EXCEPTION, {
1866
- name: "OffchainLookup",
1867
- signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1868
- transaction: transaction,
1869
- data: result
1870
- });
1871
- }
1872
- callbackSelector = (0, bytes_1.hexDataSlice)(data, 96, 100);
1873
- extraData = _parseBytes(data, 128);
1874
- return [4 /*yield*/, this.ccipReadFetch(transaction, calldata, urls)];
1875
- case 3:
1876
- ccipResult = _a.sent();
1877
- if (ccipResult == null) {
1878
- logger.throwError("CCIP Read disabled or provided no URLs", logger_1.Logger.errors.CALL_EXCEPTION, {
1879
- name: "OffchainLookup",
1880
- signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1881
- transaction: transaction,
1882
- data: result
1883
- });
1884
- }
1885
- tx = {
1886
- to: txSender,
1887
- data: (0, bytes_1.hexConcat)([callbackSelector, encodeBytes([ccipResult, extraData])])
1888
- };
1889
- return [2 /*return*/, this._call(tx, blockTag, attempt + 1)];
1890
- case 4:
1891
- error_8 = _a.sent();
1892
- if (error_8.code === logger_1.Logger.errors.SERVER_ERROR) {
1893
- throw error_8;
1894
- }
1895
- return [3 /*break*/, 5];
1896
- case 5:
1897
- try {
1898
- return [2 /*return*/, (0, bytes_1.hexlify)(result)];
1899
- }
1900
- catch (error) {
1901
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1902
- method: "call",
1903
- params: { transaction: transaction, blockTag: blockTag },
1904
- result: result,
1905
- error: error
1906
- })];
1907
- }
1908
- return [2 /*return*/];
1572
+ // Get the CCIP calldata to forward
1573
+ const calldata = _parseBytes(data, 64);
1574
+ // Get the callbackSelector (bytes4)
1575
+ if (!bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(data, 100, 128)).isZero()) {
1576
+ logger.throwError("CCIP Read callback selector included junk", logger_1.Logger.errors.CALL_EXCEPTION, {
1577
+ name: "OffchainLookup",
1578
+ signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1579
+ transaction,
1580
+ data: result,
1581
+ });
1909
1582
  }
1910
- });
1911
- });
1912
- };
1913
- BaseProvider.prototype.call = function (transaction, blockTag) {
1914
- return __awaiter(this, void 0, void 0, function () {
1915
- var resolved;
1916
- return __generator(this, function (_a) {
1917
- switch (_a.label) {
1918
- case 0: return [4 /*yield*/, this.getNetwork()];
1919
- case 1:
1920
- _a.sent();
1921
- return [4 /*yield*/, (0, properties_1.resolveProperties)({
1922
- transaction: this._getTransactionRequest(transaction),
1923
- blockTag: this._getBlockTag(blockTag),
1924
- ccipReadEnabled: Promise.resolve(transaction.ccipReadEnabled)
1925
- })];
1926
- case 2:
1927
- resolved = _a.sent();
1928
- return [2 /*return*/, this._call(resolved.transaction, resolved.blockTag, resolved.ccipReadEnabled ? 0 : -1)];
1583
+ const callbackSelector = (0, bytes_1.hexDataSlice)(data, 96, 100);
1584
+ // Get the extra data to send back to the contract as context
1585
+ const extraData = _parseBytes(data, 128);
1586
+ const ccipResult = await this.ccipReadFetch(transaction, calldata, urls);
1587
+ if (ccipResult == null) {
1588
+ logger.throwError("CCIP Read disabled or provided no URLs", logger_1.Logger.errors.CALL_EXCEPTION, {
1589
+ name: "OffchainLookup",
1590
+ signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
1591
+ transaction,
1592
+ data: result,
1593
+ });
1929
1594
  }
1930
- });
1931
- });
1932
- };
1933
- BaseProvider.prototype.estimateGas = function (transaction) {
1934
- return __awaiter(this, void 0, void 0, function () {
1935
- var params, result;
1936
- return __generator(this, function (_a) {
1937
- switch (_a.label) {
1938
- case 0: return [4 /*yield*/, this.getNetwork()];
1939
- case 1:
1940
- _a.sent();
1941
- return [4 /*yield*/, (0, properties_1.resolveProperties)({
1942
- transaction: this._getTransactionRequest(transaction)
1943
- })];
1944
- case 2:
1945
- params = _a.sent();
1946
- return [4 /*yield*/, this.perform("estimateGas", params)];
1947
- case 3:
1948
- result = _a.sent();
1949
- try {
1950
- return [2 /*return*/, bignumber_1.BigNumber.from(result)];
1951
- }
1952
- catch (error) {
1953
- return [2 /*return*/, logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1954
- method: "estimateGas",
1955
- params: params,
1956
- result: result,
1957
- error: error
1958
- })];
1959
- }
1960
- return [2 /*return*/];
1595
+ const tx = {
1596
+ to: txSender,
1597
+ data: (0, bytes_1.hexConcat)([
1598
+ callbackSelector,
1599
+ encodeBytes([ccipResult, extraData]),
1600
+ ]),
1601
+ };
1602
+ return this._call(tx, blockTag, attempt + 1);
1603
+ }
1604
+ catch (error) {
1605
+ if (error.code === logger_1.Logger.errors.SERVER_ERROR) {
1606
+ throw error;
1961
1607
  }
1608
+ }
1609
+ }
1610
+ try {
1611
+ return (0, bytes_1.hexlify)(result);
1612
+ }
1613
+ catch (error) {
1614
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1615
+ method: "call",
1616
+ params: { transaction, blockTag },
1617
+ result,
1618
+ error,
1962
1619
  });
1620
+ }
1621
+ }
1622
+ async call(transaction, blockTag) {
1623
+ await this.getNetwork();
1624
+ const resolved = await (0, properties_1.resolveProperties)({
1625
+ transaction: this._getTransactionRequest(transaction),
1626
+ blockTag: this._getBlockTag(blockTag),
1627
+ ccipReadEnabled: Promise.resolve(transaction.ccipReadEnabled),
1963
1628
  });
1964
- };
1965
- BaseProvider.prototype._getAddress = function (addressOrName) {
1966
- return __awaiter(this, void 0, void 0, function () {
1967
- var address;
1968
- return __generator(this, function (_a) {
1969
- switch (_a.label) {
1970
- case 0: return [4 /*yield*/, addressOrName];
1971
- case 1:
1972
- addressOrName = _a.sent();
1973
- if (typeof (addressOrName) !== "string") {
1974
- logger.throwArgumentError("invalid address or ENS name", "name", addressOrName);
1975
- }
1976
- return [4 /*yield*/, this.resolveName(addressOrName)];
1977
- case 2:
1978
- address = _a.sent();
1979
- if (address == null) {
1980
- logger.throwError("ENS name not configured", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
1981
- operation: "resolveName(" + JSON.stringify(addressOrName) + ")"
1982
- });
1983
- }
1984
- return [2 /*return*/, address];
1985
- }
1986
- });
1629
+ return this._call(resolved.transaction, resolved.blockTag, resolved.ccipReadEnabled ? 0 : -1);
1630
+ }
1631
+ async estimateGas(transaction) {
1632
+ await this.getNetwork();
1633
+ const params = await (0, properties_1.resolveProperties)({
1634
+ transaction: this._getTransactionRequest(transaction),
1987
1635
  });
1988
- };
1989
- BaseProvider.prototype._getBlock = function (blockHashOrBlockTag, includeTransactions) {
1990
- return __awaiter(this, void 0, void 0, function () {
1991
- var blockNumber, params, _a, error_9;
1992
- var _this = this;
1993
- return __generator(this, function (_b) {
1994
- switch (_b.label) {
1995
- case 0: return [4 /*yield*/, this.getNetwork()];
1996
- case 1:
1997
- _b.sent();
1998
- return [4 /*yield*/, blockHashOrBlockTag];
1999
- case 2:
2000
- blockHashOrBlockTag = _b.sent();
2001
- blockNumber = -128;
2002
- params = {
2003
- includeTransactions: !!includeTransactions
2004
- };
2005
- if (!(0, bytes_1.isHexString)(blockHashOrBlockTag, 32)) return [3 /*break*/, 3];
2006
- params.blockHash = blockHashOrBlockTag;
2007
- return [3 /*break*/, 6];
2008
- case 3:
2009
- _b.trys.push([3, 5, , 6]);
2010
- _a = params;
2011
- return [4 /*yield*/, this._getBlockTag(blockHashOrBlockTag)];
2012
- case 4:
2013
- _a.blockTag = _b.sent();
2014
- if ((0, bytes_1.isHexString)(params.blockTag)) {
2015
- blockNumber = parseInt(params.blockTag.substring(2), 16);
2016
- }
2017
- return [3 /*break*/, 6];
2018
- case 5:
2019
- error_9 = _b.sent();
2020
- logger.throwArgumentError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
2021
- return [3 /*break*/, 6];
2022
- case 6: return [2 /*return*/, (0, web_1.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
2023
- var block, blockNumber_1, i, tx, confirmations, blockWithTxs;
2024
- var _this = this;
2025
- return __generator(this, function (_a) {
2026
- switch (_a.label) {
2027
- case 0: return [4 /*yield*/, this.perform("getBlock", params)];
2028
- case 1:
2029
- block = _a.sent();
2030
- // Block was not found
2031
- if (block == null) {
2032
- // For blockhashes, if we didn't say it existed, that blockhash may
2033
- // not exist. If we did see it though, perhaps from a log, we know
2034
- // it exists, and this node is just not caught up yet.
2035
- if (params.blockHash != null) {
2036
- if (this._emitted["b:" + params.blockHash] == null) {
2037
- return [2 /*return*/, null];
2038
- }
2039
- }
2040
- // For block tags, if we are asking for a future block, we return null
2041
- if (params.blockTag != null) {
2042
- if (blockNumber > this._emitted.block) {
2043
- return [2 /*return*/, null];
2044
- }
2045
- }
2046
- // Retry on the next block
2047
- return [2 /*return*/, undefined];
2048
- }
2049
- if (!includeTransactions) return [3 /*break*/, 8];
2050
- blockNumber_1 = null;
2051
- i = 0;
2052
- _a.label = 2;
2053
- case 2:
2054
- if (!(i < block.transactions.length)) return [3 /*break*/, 7];
2055
- tx = block.transactions[i];
2056
- if (!(tx.blockNumber == null)) return [3 /*break*/, 3];
2057
- tx.confirmations = 0;
2058
- return [3 /*break*/, 6];
2059
- case 3:
2060
- if (!(tx.confirmations == null)) return [3 /*break*/, 6];
2061
- if (!(blockNumber_1 == null)) return [3 /*break*/, 5];
2062
- return [4 /*yield*/, this._getInternalBlockNumber(100 + 2 * this.pollingInterval)];
2063
- case 4:
2064
- blockNumber_1 = _a.sent();
2065
- _a.label = 5;
2066
- case 5:
2067
- confirmations = (blockNumber_1 - tx.blockNumber) + 1;
2068
- if (confirmations <= 0) {
2069
- confirmations = 1;
2070
- }
2071
- tx.confirmations = confirmations;
2072
- _a.label = 6;
2073
- case 6:
2074
- i++;
2075
- return [3 /*break*/, 2];
2076
- case 7:
2077
- blockWithTxs = this.formatter.blockWithTransactions(block);
2078
- blockWithTxs.transactions = blockWithTxs.transactions.map(function (tx) { return _this._wrapTransaction(tx); });
2079
- return [2 /*return*/, blockWithTxs];
2080
- case 8: return [2 /*return*/, this.formatter.block(block)];
2081
- }
2082
- });
2083
- }); }, { oncePoll: this })];
2084
- }
1636
+ const result = await this.perform("estimateGas", params);
1637
+ try {
1638
+ return bignumber_1.BigNumber.from(result);
1639
+ }
1640
+ catch (error) {
1641
+ return logger.throwError("bad result from backend", logger_1.Logger.errors.SERVER_ERROR, {
1642
+ method: "estimateGas",
1643
+ params,
1644
+ result,
1645
+ error,
2085
1646
  });
2086
- });
2087
- };
2088
- BaseProvider.prototype.getBlock = function (blockHashOrBlockTag) {
2089
- return (this._getBlock(blockHashOrBlockTag, false));
2090
- };
2091
- BaseProvider.prototype.getBlockWithTransactions = function (blockHashOrBlockTag) {
2092
- return (this._getBlock(blockHashOrBlockTag, true));
2093
- };
2094
- BaseProvider.prototype.getTransaction = function (transactionHash) {
2095
- return __awaiter(this, void 0, void 0, function () {
2096
- var params;
2097
- var _this = this;
2098
- return __generator(this, function (_a) {
2099
- switch (_a.label) {
2100
- case 0: return [4 /*yield*/, this.getNetwork()];
2101
- case 1:
2102
- _a.sent();
2103
- return [4 /*yield*/, transactionHash];
2104
- case 2:
2105
- transactionHash = _a.sent();
2106
- params = { transactionHash: this.formatter.hash(transactionHash, true) };
2107
- return [2 /*return*/, (0, web_1.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
2108
- var result, tx, blockNumber, confirmations;
2109
- return __generator(this, function (_a) {
2110
- switch (_a.label) {
2111
- case 0: return [4 /*yield*/, this.perform("getTransaction", params)];
2112
- case 1:
2113
- result = _a.sent();
2114
- if (result == null) {
2115
- if (this._emitted["t:" + transactionHash] == null) {
2116
- return [2 /*return*/, null];
2117
- }
2118
- return [2 /*return*/, undefined];
2119
- }
2120
- tx = this.formatter.transactionResponse(result);
2121
- if (!(tx.blockNumber == null)) return [3 /*break*/, 2];
2122
- tx.confirmations = 0;
2123
- return [3 /*break*/, 4];
2124
- case 2:
2125
- if (!(tx.confirmations == null)) return [3 /*break*/, 4];
2126
- return [4 /*yield*/, this._getInternalBlockNumber(100 + 2 * this.pollingInterval)];
2127
- case 3:
2128
- blockNumber = _a.sent();
2129
- confirmations = (blockNumber - tx.blockNumber) + 1;
2130
- if (confirmations <= 0) {
2131
- confirmations = 1;
2132
- }
2133
- tx.confirmations = confirmations;
2134
- _a.label = 4;
2135
- case 4: return [2 /*return*/, this._wrapTransaction(tx)];
2136
- }
2137
- });
2138
- }); }, { oncePoll: this })];
2139
- }
1647
+ }
1648
+ }
1649
+ async _getAddress(addressOrName) {
1650
+ addressOrName = await addressOrName;
1651
+ if (typeof addressOrName !== "string") {
1652
+ logger.throwArgumentError("invalid address or ENS name", "name", addressOrName);
1653
+ }
1654
+ const address = await this.resolveName(addressOrName);
1655
+ if (address == null) {
1656
+ logger.throwError("ENS name not configured", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
1657
+ operation: `resolveName(${JSON.stringify(addressOrName)})`,
2140
1658
  });
2141
- });
2142
- };
2143
- BaseProvider.prototype.getTransactionReceipt = function (transactionHash) {
2144
- return __awaiter(this, void 0, void 0, function () {
2145
- var params;
2146
- var _this = this;
2147
- return __generator(this, function (_a) {
2148
- switch (_a.label) {
2149
- case 0: return [4 /*yield*/, this.getNetwork()];
2150
- case 1:
2151
- _a.sent();
2152
- return [4 /*yield*/, transactionHash];
2153
- case 2:
2154
- transactionHash = _a.sent();
2155
- params = { transactionHash: this.formatter.hash(transactionHash, true) };
2156
- return [2 /*return*/, (0, web_1.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
2157
- var result, receipt, blockNumber, confirmations;
2158
- return __generator(this, function (_a) {
2159
- switch (_a.label) {
2160
- case 0: return [4 /*yield*/, this.perform("getTransactionReceipt", params)];
2161
- case 1:
2162
- result = _a.sent();
2163
- if (result == null) {
2164
- if (this._emitted["t:" + transactionHash] == null) {
2165
- return [2 /*return*/, null];
2166
- }
2167
- return [2 /*return*/, undefined];
2168
- }
2169
- // "geth-etc" returns receipts before they are ready
2170
- if (result.blockHash == null) {
2171
- return [2 /*return*/, undefined];
2172
- }
2173
- receipt = this.formatter.receipt(result);
2174
- if (!(receipt.blockNumber == null)) return [3 /*break*/, 2];
2175
- receipt.confirmations = 0;
2176
- return [3 /*break*/, 4];
2177
- case 2:
2178
- if (!(receipt.confirmations == null)) return [3 /*break*/, 4];
2179
- return [4 /*yield*/, this._getInternalBlockNumber(100 + 2 * this.pollingInterval)];
2180
- case 3:
2181
- blockNumber = _a.sent();
2182
- confirmations = (blockNumber - receipt.blockNumber) + 1;
2183
- if (confirmations <= 0) {
2184
- confirmations = 1;
2185
- }
2186
- receipt.confirmations = confirmations;
2187
- _a.label = 4;
2188
- case 4: return [2 /*return*/, receipt];
2189
- }
2190
- });
2191
- }); }, { oncePoll: this })];
1659
+ }
1660
+ return address;
1661
+ }
1662
+ async _getBlock(blockHashOrBlockTag, includeTransactions) {
1663
+ await this.getNetwork();
1664
+ blockHashOrBlockTag = await blockHashOrBlockTag;
1665
+ // If blockTag is a number (not "latest", etc), this is the block number
1666
+ let blockNumber = -128;
1667
+ const params = {
1668
+ includeTransactions: !!includeTransactions,
1669
+ };
1670
+ if ((0, bytes_1.isHexString)(blockHashOrBlockTag, 32)) {
1671
+ params.blockHash = blockHashOrBlockTag;
1672
+ }
1673
+ else {
1674
+ try {
1675
+ params.blockTag = await this._getBlockTag(blockHashOrBlockTag);
1676
+ if ((0, bytes_1.isHexString)(params.blockTag)) {
1677
+ blockNumber = parseInt(params.blockTag.substring(2), 16);
2192
1678
  }
2193
- });
2194
- });
2195
- };
2196
- BaseProvider.prototype.getLogs = function (filter) {
2197
- return __awaiter(this, void 0, void 0, function () {
2198
- var params, logs;
2199
- return __generator(this, function (_a) {
2200
- switch (_a.label) {
2201
- case 0: return [4 /*yield*/, this.getNetwork()];
2202
- case 1:
2203
- _a.sent();
2204
- return [4 /*yield*/, (0, properties_1.resolveProperties)({ filter: this._getFilter(filter) })];
2205
- case 2:
2206
- params = _a.sent();
2207
- return [4 /*yield*/, this.perform("getLogs", params)];
2208
- case 3:
2209
- logs = _a.sent();
2210
- logs.forEach(function (log) {
2211
- if (log.removed == null) {
2212
- log.removed = false;
2213
- }
2214
- });
2215
- return [2 /*return*/, formatter_1.Formatter.arrayOf(this.formatter.filterLog.bind(this.formatter))(logs)];
1679
+ }
1680
+ catch (error) {
1681
+ logger.throwArgumentError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
1682
+ }
1683
+ }
1684
+ return (0, web_1.poll)(async () => {
1685
+ const block = await this.perform("getBlock", params);
1686
+ // Block was not found
1687
+ if (block == null) {
1688
+ // For blockhashes, if we didn't say it existed, that blockhash may
1689
+ // not exist. If we did see it though, perhaps from a log, we know
1690
+ // it exists, and this node is just not caught up yet.
1691
+ if (params.blockHash != null) {
1692
+ if (this._emitted["b:" + params.blockHash] == null) {
1693
+ return null;
1694
+ }
2216
1695
  }
2217
- });
2218
- });
2219
- };
2220
- BaseProvider.prototype.getEtherPrice = function () {
2221
- return __awaiter(this, void 0, void 0, function () {
2222
- return __generator(this, function (_a) {
2223
- switch (_a.label) {
2224
- case 0: return [4 /*yield*/, this.getNetwork()];
2225
- case 1:
2226
- _a.sent();
2227
- return [2 /*return*/, this.perform("getEtherPrice", {})];
1696
+ // For block tags, if we are asking for a future block, we return null
1697
+ if (params.blockTag != null) {
1698
+ if (blockNumber > this._emitted.block) {
1699
+ return null;
1700
+ }
2228
1701
  }
2229
- });
2230
- });
2231
- };
2232
- BaseProvider.prototype._getBlockTag = function (blockTag) {
2233
- return __awaiter(this, void 0, void 0, function () {
2234
- var blockNumber;
2235
- return __generator(this, function (_a) {
2236
- switch (_a.label) {
2237
- case 0: return [4 /*yield*/, blockTag];
2238
- case 1:
2239
- blockTag = _a.sent();
2240
- if (!(typeof (blockTag) === "number" && blockTag < 0)) return [3 /*break*/, 3];
2241
- if (blockTag % 1) {
2242
- logger.throwArgumentError("invalid BlockTag", "blockTag", blockTag);
1702
+ // Retry on the next block
1703
+ return undefined;
1704
+ }
1705
+ // Add transactions
1706
+ if (includeTransactions) {
1707
+ let blockNumber = null;
1708
+ for (let i = 0; i < block.transactions.length; i++) {
1709
+ const tx = block.transactions[i];
1710
+ if (tx.blockNumber == null) {
1711
+ tx.confirmations = 0;
1712
+ }
1713
+ else if (tx.confirmations == null) {
1714
+ if (blockNumber == null) {
1715
+ blockNumber =
1716
+ await this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
2243
1717
  }
2244
- return [4 /*yield*/, this._getInternalBlockNumber(100 + 2 * this.pollingInterval)];
2245
- case 2:
2246
- blockNumber = _a.sent();
2247
- blockNumber += blockTag;
2248
- if (blockNumber < 0) {
2249
- blockNumber = 0;
1718
+ // Add the confirmations using the fast block number (pessimistic)
1719
+ let confirmations = blockNumber - tx.blockNumber + 1;
1720
+ if (confirmations <= 0) {
1721
+ confirmations = 1;
2250
1722
  }
2251
- return [2 /*return*/, this.formatter.blockTag(blockNumber)];
2252
- case 3: return [2 /*return*/, this.formatter.blockTag(blockTag)];
1723
+ tx.confirmations = confirmations;
1724
+ }
2253
1725
  }
2254
- });
2255
- });
2256
- };
2257
- BaseProvider.prototype.getResolver = function (name) {
2258
- return __awaiter(this, void 0, void 0, function () {
2259
- var currentName, addr, resolver, _a;
2260
- return __generator(this, function (_b) {
2261
- switch (_b.label) {
2262
- case 0:
2263
- currentName = name;
2264
- _b.label = 1;
2265
- case 1:
2266
- if (!true) return [3 /*break*/, 6];
2267
- if (currentName === "" || currentName === ".") {
2268
- return [2 /*return*/, null];
2269
- }
2270
- // Optimization since the eth node cannot change and does
2271
- // not have a wildcard resolver
2272
- if (name !== "eth" && currentName === "eth") {
2273
- return [2 /*return*/, null];
2274
- }
2275
- return [4 /*yield*/, this._getResolver(currentName, "getResolver")];
2276
- case 2:
2277
- addr = _b.sent();
2278
- if (!(addr != null)) return [3 /*break*/, 5];
2279
- resolver = new Resolver(this, addr, name);
2280
- _a = currentName !== name;
2281
- if (!_a) return [3 /*break*/, 4];
2282
- return [4 /*yield*/, resolver.supportsWildcard()];
2283
- case 3:
2284
- _a = !(_b.sent());
2285
- _b.label = 4;
2286
- case 4:
2287
- // Legacy resolver found, using EIP-2544 so it isn't safe to use
2288
- if (_a) {
2289
- return [2 /*return*/, null];
2290
- }
2291
- return [2 /*return*/, resolver];
2292
- case 5:
2293
- // Get the parent node
2294
- currentName = currentName.split(".").slice(1).join(".");
2295
- return [3 /*break*/, 1];
2296
- case 6: return [2 /*return*/];
1726
+ const blockWithTxs = this.formatter.blockWithTransactions(block);
1727
+ blockWithTxs.transactions = blockWithTxs.transactions.map((tx) => this._wrapTransaction(tx));
1728
+ return blockWithTxs;
1729
+ }
1730
+ return this.formatter.block(block);
1731
+ }, { oncePoll: this });
1732
+ }
1733
+ getBlock(blockHashOrBlockTag) {
1734
+ return this._getBlock(blockHashOrBlockTag, false);
1735
+ }
1736
+ getBlockWithTransactions(blockHashOrBlockTag) {
1737
+ return (this._getBlock(blockHashOrBlockTag, true));
1738
+ }
1739
+ async getTransaction(transactionHash) {
1740
+ await this.getNetwork();
1741
+ transactionHash = await transactionHash;
1742
+ const params = {
1743
+ transactionHash: this.formatter.hash(transactionHash, true),
1744
+ };
1745
+ return (0, web_1.poll)(async () => {
1746
+ const result = await this.perform("getTransaction", params);
1747
+ if (result == null) {
1748
+ if (this._emitted["t:" + transactionHash] == null) {
1749
+ return null;
2297
1750
  }
2298
- });
2299
- });
2300
- };
2301
- BaseProvider.prototype._getResolver = function (name, operation) {
2302
- return __awaiter(this, void 0, void 0, function () {
2303
- var network, addrData, error_10;
2304
- return __generator(this, function (_a) {
2305
- switch (_a.label) {
2306
- case 0:
2307
- if (operation == null) {
2308
- operation = "ENS";
2309
- }
2310
- return [4 /*yield*/, this.getNetwork()];
2311
- case 1:
2312
- network = _a.sent();
2313
- // No ENS...
2314
- if (!network.ensAddress) {
2315
- logger.throwError("network does not support ENS", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { operation: operation, network: network.name });
2316
- }
2317
- _a.label = 2;
2318
- case 2:
2319
- _a.trys.push([2, 4, , 5]);
2320
- return [4 /*yield*/, this.call({
2321
- to: network.ensAddress,
2322
- data: ("0x0178b8bf" + (0, hash_1.namehash)(name).substring(2))
2323
- })];
2324
- case 3:
2325
- addrData = _a.sent();
2326
- return [2 /*return*/, this.formatter.callAddress(addrData)];
2327
- case 4:
2328
- error_10 = _a.sent();
2329
- return [3 /*break*/, 5];
2330
- case 5: return [2 /*return*/, null];
1751
+ return undefined;
1752
+ }
1753
+ const tx = this.formatter.transactionResponse(result);
1754
+ if (tx.blockNumber == null) {
1755
+ tx.confirmations = 0;
1756
+ }
1757
+ else if (tx.confirmations == null) {
1758
+ const blockNumber = await this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
1759
+ // Add the confirmations using the fast block number (pessimistic)
1760
+ let confirmations = blockNumber - tx.blockNumber + 1;
1761
+ if (confirmations <= 0) {
1762
+ confirmations = 1;
2331
1763
  }
2332
- });
2333
- });
2334
- };
2335
- BaseProvider.prototype.resolveName = function (name) {
2336
- return __awaiter(this, void 0, void 0, function () {
2337
- var resolver;
2338
- return __generator(this, function (_a) {
2339
- switch (_a.label) {
2340
- case 0: return [4 /*yield*/, name];
2341
- case 1:
2342
- name = _a.sent();
2343
- // If it is already an address, nothing to resolve
2344
- try {
2345
- return [2 /*return*/, Promise.resolve(this.formatter.address(name))];
2346
- }
2347
- catch (error) {
2348
- // If is is a hexstring, the address is bad (See #694)
2349
- if ((0, bytes_1.isHexString)(name)) {
2350
- throw error;
2351
- }
2352
- }
2353
- if (typeof (name) !== "string") {
2354
- logger.throwArgumentError("invalid ENS name", "name", name);
2355
- }
2356
- return [4 /*yield*/, this.getResolver(name)];
2357
- case 2:
2358
- resolver = _a.sent();
2359
- if (!resolver) {
2360
- return [2 /*return*/, null];
2361
- }
2362
- return [4 /*yield*/, resolver.getAddress()];
2363
- case 3: return [2 /*return*/, _a.sent()];
1764
+ tx.confirmations = confirmations;
1765
+ }
1766
+ return this._wrapTransaction(tx);
1767
+ }, { oncePoll: this });
1768
+ }
1769
+ async getTransactionReceipt(transactionHash) {
1770
+ await this.getNetwork();
1771
+ transactionHash = await transactionHash;
1772
+ const params = {
1773
+ transactionHash: this.formatter.hash(transactionHash, true),
1774
+ };
1775
+ return (0, web_1.poll)(async () => {
1776
+ const result = await this.perform("getTransactionReceipt", params);
1777
+ if (result == null) {
1778
+ if (this._emitted["t:" + transactionHash] == null) {
1779
+ return null;
2364
1780
  }
2365
- });
2366
- });
2367
- };
2368
- BaseProvider.prototype.lookupAddress = function (address) {
2369
- return __awaiter(this, void 0, void 0, function () {
2370
- var node, resolverAddr, name, _a, addr;
2371
- return __generator(this, function (_b) {
2372
- switch (_b.label) {
2373
- case 0: return [4 /*yield*/, address];
2374
- case 1:
2375
- address = _b.sent();
2376
- address = this.formatter.address(address);
2377
- node = address.substring(2).toLowerCase() + ".addr.reverse";
2378
- return [4 /*yield*/, this._getResolver(node, "lookupAddress")];
2379
- case 2:
2380
- resolverAddr = _b.sent();
2381
- if (resolverAddr == null) {
2382
- return [2 /*return*/, null];
2383
- }
2384
- _a = _parseString;
2385
- return [4 /*yield*/, this.call({
2386
- to: resolverAddr,
2387
- data: ("0x691f3431" + (0, hash_1.namehash)(node).substring(2))
2388
- })];
2389
- case 3:
2390
- name = _a.apply(void 0, [_b.sent(), 0]);
2391
- return [4 /*yield*/, this.resolveName(name)];
2392
- case 4:
2393
- addr = _b.sent();
2394
- if (addr != address) {
2395
- return [2 /*return*/, null];
2396
- }
2397
- return [2 /*return*/, name];
1781
+ return undefined;
1782
+ }
1783
+ // "geth-etc" returns receipts before they are ready
1784
+ if (result.blockHash == null) {
1785
+ return undefined;
1786
+ }
1787
+ const receipt = this.formatter.receipt(result);
1788
+ if (receipt.blockNumber == null) {
1789
+ receipt.confirmations = 0;
1790
+ }
1791
+ else if (receipt.confirmations == null) {
1792
+ const blockNumber = await this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
1793
+ // Add the confirmations using the fast block number (pessimistic)
1794
+ let confirmations = blockNumber - receipt.blockNumber + 1;
1795
+ if (confirmations <= 0) {
1796
+ confirmations = 1;
2398
1797
  }
2399
- });
1798
+ receipt.confirmations = confirmations;
1799
+ }
1800
+ return receipt;
1801
+ }, { oncePoll: this });
1802
+ }
1803
+ async getLogs(filter) {
1804
+ await this.getNetwork();
1805
+ const params = await (0, properties_1.resolveProperties)({
1806
+ filter: this._getFilter(filter),
2400
1807
  });
2401
- };
2402
- BaseProvider.prototype.getAvatar = function (nameOrAddress) {
2403
- return __awaiter(this, void 0, void 0, function () {
2404
- var resolver, address, node, resolverAddress, avatar_1, error_11, name_1, _a, error_12, avatar;
2405
- return __generator(this, function (_b) {
2406
- switch (_b.label) {
2407
- case 0:
2408
- resolver = null;
2409
- if (!(0, bytes_1.isHexString)(nameOrAddress)) return [3 /*break*/, 10];
2410
- address = this.formatter.address(nameOrAddress);
2411
- node = address.substring(2).toLowerCase() + ".addr.reverse";
2412
- return [4 /*yield*/, this._getResolver(node, "getAvatar")];
2413
- case 1:
2414
- resolverAddress = _b.sent();
2415
- if (!resolverAddress) {
2416
- return [2 /*return*/, null];
2417
- }
2418
- // Try resolving the avatar against the addr.reverse resolver
2419
- resolver = new Resolver(this, resolverAddress, node);
2420
- _b.label = 2;
2421
- case 2:
2422
- _b.trys.push([2, 4, , 5]);
2423
- return [4 /*yield*/, resolver.getAvatar()];
2424
- case 3:
2425
- avatar_1 = _b.sent();
2426
- if (avatar_1) {
2427
- return [2 /*return*/, avatar_1.url];
2428
- }
2429
- return [3 /*break*/, 5];
2430
- case 4:
2431
- error_11 = _b.sent();
2432
- if (error_11.code !== logger_1.Logger.errors.CALL_EXCEPTION) {
2433
- throw error_11;
2434
- }
2435
- return [3 /*break*/, 5];
2436
- case 5:
2437
- _b.trys.push([5, 8, , 9]);
2438
- _a = _parseString;
2439
- return [4 /*yield*/, this.call({
2440
- to: resolverAddress,
2441
- data: ("0x691f3431" + (0, hash_1.namehash)(node).substring(2))
2442
- })];
2443
- case 6:
2444
- name_1 = _a.apply(void 0, [_b.sent(), 0]);
2445
- return [4 /*yield*/, this.getResolver(name_1)];
2446
- case 7:
2447
- resolver = _b.sent();
2448
- return [3 /*break*/, 9];
2449
- case 8:
2450
- error_12 = _b.sent();
2451
- if (error_12.code !== logger_1.Logger.errors.CALL_EXCEPTION) {
2452
- throw error_12;
2453
- }
2454
- return [2 /*return*/, null];
2455
- case 9: return [3 /*break*/, 12];
2456
- case 10: return [4 /*yield*/, this.getResolver(nameOrAddress)];
2457
- case 11:
2458
- // ENS name; forward lookup with wildcard
2459
- resolver = _b.sent();
2460
- if (!resolver) {
2461
- return [2 /*return*/, null];
2462
- }
2463
- _b.label = 12;
2464
- case 12: return [4 /*yield*/, resolver.getAvatar()];
2465
- case 13:
2466
- avatar = _b.sent();
2467
- if (avatar == null) {
2468
- return [2 /*return*/, null];
2469
- }
2470
- return [2 /*return*/, avatar.url];
1808
+ const logs = await this.perform("getLogs", params);
1809
+ logs.forEach((log) => {
1810
+ if (log.removed == null) {
1811
+ log.removed = false;
1812
+ }
1813
+ });
1814
+ return formatter_1.Formatter.arrayOf(this.formatter.filterLog.bind(this.formatter))(logs);
1815
+ }
1816
+ async getEtherPrice() {
1817
+ await this.getNetwork();
1818
+ return this.perform("getEtherPrice", {});
1819
+ }
1820
+ async _getBlockTag(blockTag) {
1821
+ blockTag = await blockTag;
1822
+ if (typeof blockTag === "number" && blockTag < 0) {
1823
+ if (blockTag % 1) {
1824
+ logger.throwArgumentError("invalid BlockTag", "blockTag", blockTag);
1825
+ }
1826
+ let blockNumber = await this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
1827
+ blockNumber += blockTag;
1828
+ if (blockNumber < 0) {
1829
+ blockNumber = 0;
1830
+ }
1831
+ return this.formatter.blockTag(blockNumber);
1832
+ }
1833
+ return this.formatter.blockTag(blockTag);
1834
+ }
1835
+ async getResolver(name) {
1836
+ let currentName = name;
1837
+ while (true) {
1838
+ if (currentName === "" || currentName === ".") {
1839
+ return null;
1840
+ }
1841
+ // Optimization since the eth node cannot change and does
1842
+ // not have a wildcard resolver
1843
+ if (name !== "eth" && currentName === "eth") {
1844
+ return null;
1845
+ }
1846
+ // Check the current node for a resolver
1847
+ const addr = await this._getResolver(currentName, "getResolver");
1848
+ // Found a resolver!
1849
+ if (addr != null) {
1850
+ const resolver = new Resolver(this, addr, name);
1851
+ // Legacy resolver found, using EIP-2544 so it isn't safe to use
1852
+ if (currentName !== name &&
1853
+ !(await resolver.supportsWildcard())) {
1854
+ return null;
2471
1855
  }
1856
+ return resolver;
1857
+ }
1858
+ // Get the parent node
1859
+ currentName = currentName.split(".").slice(1).join(".");
1860
+ }
1861
+ }
1862
+ async _getResolver(name, operation) {
1863
+ if (operation == null) {
1864
+ operation = "ENS";
1865
+ }
1866
+ const network = await this.getNetwork();
1867
+ // No ENS...
1868
+ if (!network.ensAddress) {
1869
+ logger.throwError("network does not support ENS", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { operation, network: network.name });
1870
+ }
1871
+ try {
1872
+ // keccak256("resolver(bytes32)")
1873
+ const addrData = await this.call({
1874
+ to: network.ensAddress,
1875
+ data: "0x0178b8bf" + (0, hash_1.namehash)(name).substring(2),
2472
1876
  });
2473
- });
2474
- };
2475
- BaseProvider.prototype.perform = function (method, params) {
1877
+ return this.formatter.callAddress(addrData);
1878
+ }
1879
+ catch (error) {
1880
+ // ENS registry cannot throw errors on resolver(bytes32)
1881
+ }
1882
+ return null;
1883
+ }
1884
+ async resolveName(name) {
1885
+ name = await name;
1886
+ // If it is already an address, nothing to resolve
1887
+ try {
1888
+ return Promise.resolve(this.formatter.address(name));
1889
+ }
1890
+ catch (error) {
1891
+ // If is is a hexstring, the address is bad (See #694)
1892
+ if ((0, bytes_1.isHexString)(name)) {
1893
+ throw error;
1894
+ }
1895
+ }
1896
+ if (typeof name !== "string") {
1897
+ logger.throwArgumentError("invalid ENS name", "name", name);
1898
+ }
1899
+ // Get the addr from the resolver
1900
+ const resolver = await this.getResolver(name);
1901
+ if (!resolver) {
1902
+ return null;
1903
+ }
1904
+ return await resolver.getAddress();
1905
+ }
1906
+ async lookupAddress(address) {
1907
+ address = await address;
1908
+ address = this.formatter.address(address);
1909
+ const node = address.substring(2).toLowerCase() + ".addr.reverse";
1910
+ const resolverAddr = await this._getResolver(node, "lookupAddress");
1911
+ if (resolverAddr == null) {
1912
+ return null;
1913
+ }
1914
+ // keccak("name(bytes32)")
1915
+ const name = _parseString(await this.call({
1916
+ to: resolverAddr,
1917
+ data: "0x691f3431" + (0, hash_1.namehash)(node).substring(2),
1918
+ }), 0);
1919
+ const addr = await this.resolveName(name);
1920
+ if (addr != address) {
1921
+ return null;
1922
+ }
1923
+ return name;
1924
+ }
1925
+ async getAvatar(nameOrAddress) {
1926
+ let resolver = null;
1927
+ if ((0, bytes_1.isHexString)(nameOrAddress)) {
1928
+ // Address; reverse lookup
1929
+ const address = this.formatter.address(nameOrAddress);
1930
+ const node = address.substring(2).toLowerCase() + ".addr.reverse";
1931
+ const resolverAddress = await this._getResolver(node, "getAvatar");
1932
+ if (!resolverAddress) {
1933
+ return null;
1934
+ }
1935
+ // Try resolving the avatar against the addr.reverse resolver
1936
+ resolver = new Resolver(this, resolverAddress, node);
1937
+ try {
1938
+ const avatar = await resolver.getAvatar();
1939
+ if (avatar) {
1940
+ return avatar.url;
1941
+ }
1942
+ }
1943
+ catch (error) {
1944
+ if (error.code !== logger_1.Logger.errors.CALL_EXCEPTION) {
1945
+ throw error;
1946
+ }
1947
+ }
1948
+ // Try getting the name and performing forward lookup; allowing wildcards
1949
+ try {
1950
+ // keccak("name(bytes32)")
1951
+ const name = _parseString(await this.call({
1952
+ to: resolverAddress,
1953
+ data: "0x691f3431" + (0, hash_1.namehash)(node).substring(2),
1954
+ }), 0);
1955
+ resolver = await this.getResolver(name);
1956
+ }
1957
+ catch (error) {
1958
+ if (error.code !== logger_1.Logger.errors.CALL_EXCEPTION) {
1959
+ throw error;
1960
+ }
1961
+ return null;
1962
+ }
1963
+ }
1964
+ else {
1965
+ // ENS name; forward lookup with wildcard
1966
+ resolver = await this.getResolver(nameOrAddress);
1967
+ if (!resolver) {
1968
+ return null;
1969
+ }
1970
+ }
1971
+ const avatar = await resolver.getAvatar();
1972
+ if (avatar == null) {
1973
+ return null;
1974
+ }
1975
+ return avatar.url;
1976
+ }
1977
+ perform(method, params) {
2476
1978
  return logger.throwError(method + " not implemented", logger_1.Logger.errors.NOT_IMPLEMENTED, { operation: method });
2477
- };
2478
- BaseProvider.prototype._startEvent = function (event) {
2479
- this.polling = (this._events.filter(function (e) { return e.pollable(); }).length > 0);
2480
- };
2481
- BaseProvider.prototype._stopEvent = function (event) {
2482
- this.polling = (this._events.filter(function (e) { return e.pollable(); }).length > 0);
2483
- };
2484
- BaseProvider.prototype._addEventListener = function (eventName, listener, once) {
2485
- var event = new Event(getEventTag(eventName), listener, once);
1979
+ }
1980
+ _startEvent(event) {
1981
+ this.polling = this._events.filter((e) => e.pollable()).length > 0;
1982
+ }
1983
+ _stopEvent(event) {
1984
+ this.polling = this._events.filter((e) => e.pollable()).length > 0;
1985
+ }
1986
+ _addEventListener(eventName, listener, once) {
1987
+ const event = new Event(getEventTag(eventName), listener, once);
2486
1988
  this._events.push(event);
2487
1989
  this._startEvent(event);
2488
1990
  return this;
2489
- };
2490
- BaseProvider.prototype.on = function (eventName, listener) {
1991
+ }
1992
+ on(eventName, listener) {
2491
1993
  return this._addEventListener(eventName, listener, false);
2492
- };
2493
- BaseProvider.prototype.once = function (eventName, listener) {
1994
+ }
1995
+ once(eventName, listener) {
2494
1996
  return this._addEventListener(eventName, listener, true);
2495
- };
2496
- BaseProvider.prototype.emit = function (eventName) {
2497
- var _this = this;
2498
- var args = [];
2499
- for (var _i = 1; _i < arguments.length; _i++) {
2500
- args[_i - 1] = arguments[_i];
2501
- }
2502
- var result = false;
2503
- var stopped = [];
2504
- var eventTag = getEventTag(eventName);
2505
- this._events = this._events.filter(function (event) {
1997
+ }
1998
+ emit(eventName, ...args) {
1999
+ let result = false;
2000
+ let stopped = [];
2001
+ let eventTag = getEventTag(eventName);
2002
+ this._events = this._events.filter((event) => {
2506
2003
  if (event.tag !== eventTag) {
2507
2004
  return true;
2508
2005
  }
2509
- setTimeout(function () {
2510
- event.listener.apply(_this, args);
2006
+ setTimeout(() => {
2007
+ event.listener.apply(this, args);
2511
2008
  }, 0);
2512
2009
  result = true;
2513
2010
  if (event.once) {
@@ -2516,36 +2013,37 @@ var BaseProvider = /** @class */ (function (_super) {
2516
2013
  }
2517
2014
  return true;
2518
2015
  });
2519
- stopped.forEach(function (event) { _this._stopEvent(event); });
2016
+ stopped.forEach((event) => {
2017
+ this._stopEvent(event);
2018
+ });
2520
2019
  return result;
2521
- };
2522
- BaseProvider.prototype.listenerCount = function (eventName) {
2020
+ }
2021
+ listenerCount(eventName) {
2523
2022
  if (!eventName) {
2524
2023
  return this._events.length;
2525
2024
  }
2526
- var eventTag = getEventTag(eventName);
2527
- return this._events.filter(function (event) {
2528
- return (event.tag === eventTag);
2025
+ let eventTag = getEventTag(eventName);
2026
+ return this._events.filter((event) => {
2027
+ return event.tag === eventTag;
2529
2028
  }).length;
2530
- };
2531
- BaseProvider.prototype.listeners = function (eventName) {
2029
+ }
2030
+ listeners(eventName) {
2532
2031
  if (eventName == null) {
2533
- return this._events.map(function (event) { return event.listener; });
2032
+ return this._events.map((event) => event.listener);
2534
2033
  }
2535
- var eventTag = getEventTag(eventName);
2034
+ let eventTag = getEventTag(eventName);
2536
2035
  return this._events
2537
- .filter(function (event) { return (event.tag === eventTag); })
2538
- .map(function (event) { return event.listener; });
2539
- };
2540
- BaseProvider.prototype.off = function (eventName, listener) {
2541
- var _this = this;
2036
+ .filter((event) => event.tag === eventTag)
2037
+ .map((event) => event.listener);
2038
+ }
2039
+ off(eventName, listener) {
2542
2040
  if (listener == null) {
2543
2041
  return this.removeAllListeners(eventName);
2544
2042
  }
2545
- var stopped = [];
2546
- var found = false;
2547
- var eventTag = getEventTag(eventName);
2548
- this._events = this._events.filter(function (event) {
2043
+ const stopped = [];
2044
+ let found = false;
2045
+ let eventTag = getEventTag(eventName);
2046
+ this._events = this._events.filter((event) => {
2549
2047
  if (event.tag !== eventTag || event.listener != listener) {
2550
2048
  return true;
2551
2049
  }
@@ -2556,30 +2054,32 @@ var BaseProvider = /** @class */ (function (_super) {
2556
2054
  stopped.push(event);
2557
2055
  return false;
2558
2056
  });
2559
- stopped.forEach(function (event) { _this._stopEvent(event); });
2057
+ stopped.forEach((event) => {
2058
+ this._stopEvent(event);
2059
+ });
2560
2060
  return this;
2561
- };
2562
- BaseProvider.prototype.removeAllListeners = function (eventName) {
2563
- var _this = this;
2564
- var stopped = [];
2061
+ }
2062
+ removeAllListeners(eventName) {
2063
+ let stopped = [];
2565
2064
  if (eventName == null) {
2566
2065
  stopped = this._events;
2567
2066
  this._events = [];
2568
2067
  }
2569
2068
  else {
2570
- var eventTag_1 = getEventTag(eventName);
2571
- this._events = this._events.filter(function (event) {
2572
- if (event.tag !== eventTag_1) {
2069
+ const eventTag = getEventTag(eventName);
2070
+ this._events = this._events.filter((event) => {
2071
+ if (event.tag !== eventTag) {
2573
2072
  return true;
2574
2073
  }
2575
2074
  stopped.push(event);
2576
2075
  return false;
2577
2076
  });
2578
2077
  }
2579
- stopped.forEach(function (event) { _this._stopEvent(event); });
2078
+ stopped.forEach((event) => {
2079
+ this._stopEvent(event);
2080
+ });
2580
2081
  return this;
2581
- };
2582
- return BaseProvider;
2583
- }(abstract_provider_1.Provider));
2082
+ }
2083
+ }
2584
2084
  exports.BaseProvider = BaseProvider;
2585
2085
  //# sourceMappingURL=base-provider.js.map