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