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