@qevm/providers 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/alchemy-provider.d.ts +1 -1
- package/lib/alchemy-provider.d.ts.map +1 -1
- package/lib/alchemy-provider.js +29 -53
- package/lib/alchemy-provider.js.map +1 -1
- package/lib/ankr-provider.d.ts +1 -1
- package/lib/ankr-provider.d.ts.map +1 -1
- package/lib/ankr-provider.js +16 -36
- package/lib/ankr-provider.js.map +1 -1
- package/lib/base-provider.d.ts +3 -4
- package/lib/base-provider.d.ts.map +1 -1
- package/lib/base-provider.js +1477 -2132
- package/lib/base-provider.js.map +1 -1
- package/lib/browser-ipc-provider.js +1 -1
- package/lib/browser-ipc-provider.js.map +1 -1
- package/lib/browser-net.js +1 -2
- package/lib/browser-net.js.map +1 -1
- package/lib/browser-ws.js +5 -5
- package/lib/browser-ws.js.map +1 -1
- package/lib/cloudflare-provider.js +20 -83
- package/lib/cloudflare-provider.js.map +1 -1
- package/lib/etherscan-provider.js +237 -357
- package/lib/etherscan-provider.js.map +1 -1
- package/lib/fallback-provider.js +301 -430
- package/lib/fallback-provider.js.map +1 -1
- package/lib/formatter.d.ts +4 -4
- package/lib/formatter.d.ts.map +1 -1
- package/lib/formatter.js +107 -110
- package/lib/formatter.js.map +1 -1
- package/lib/index.js +25 -25
- package/lib/index.js.map +1 -1
- package/lib/infura-provider.d.ts +1 -1
- package/lib/infura-provider.d.ts.map +1 -1
- package/lib/infura-provider.js +34 -58
- package/lib/infura-provider.js.map +1 -1
- package/lib/ipc-provider.js +20 -40
- package/lib/ipc-provider.js.map +1 -1
- package/lib/json-rpc-batch-provider.d.ts +0 -1
- package/lib/json-rpc-batch-provider.d.ts.map +1 -1
- package/lib/json-rpc-batch-provider.js +27 -48
- package/lib/json-rpc-batch-provider.js.map +1 -1
- package/lib/json-rpc-provider.d.ts +1 -1
- package/lib/json-rpc-provider.d.ts.map +1 -1
- package/lib/json-rpc-provider.js +283 -482
- package/lib/json-rpc-provider.js.map +1 -1
- package/lib/nodesmith-provider.js +12 -32
- package/lib/nodesmith-provider.js.map +1 -1
- package/lib/pocket-provider.d.ts +1 -1
- package/lib/pocket-provider.d.ts.map +1 -1
- package/lib/pocket-provider.js +17 -37
- package/lib/pocket-provider.js.map +1 -1
- package/lib/url-json-rpc-provider.d.ts +1 -1
- package/lib/url-json-rpc-provider.d.ts.map +1 -1
- package/lib/url-json-rpc-provider.js +45 -116
- package/lib/url-json-rpc-provider.js.map +1 -1
- package/lib/web3-provider.d.ts +2 -2
- package/lib/web3-provider.d.ts.map +1 -1
- package/lib/web3-provider.js +49 -70
- package/lib/web3-provider.js.map +1 -1
- package/lib/websocket-provider.d.ts +2 -2
- package/lib/websocket-provider.d.ts.map +1 -1
- package/lib/websocket-provider.js +128 -225
- package/lib/websocket-provider.js.map +1 -1
- package/lib/ws.js +1 -1
- package/lib/ws.js.map +1 -1
- package/package.json +17 -14
- package/src.ts/alchemy-provider.ts +1 -1
- package/src.ts/ankr-provider.ts +1 -1
- package/src.ts/base-provider.ts +9 -9
- package/src.ts/etherscan-provider.ts +1 -1
- package/src.ts/fallback-provider.ts +4 -4
- package/src.ts/formatter.ts +2 -2
- package/src.ts/infura-provider.ts +1 -1
- package/src.ts/json-rpc-batch-provider.ts +1 -1
- package/src.ts/json-rpc-provider.ts +3 -3
- package/src.ts/pocket-provider.ts +1 -1
- package/src.ts/url-json-rpc-provider.ts +1 -1
- package/src.ts/websocket-provider.ts +1 -1
|
@@ -1,74 +1,23 @@
|
|
|
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
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
3
|
exports.EtherscanProvider = void 0;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
4
|
+
const bytes_1 = require("@qevm/bytes");
|
|
5
|
+
const properties_1 = require("@ethersproject/properties");
|
|
6
|
+
const transactions_1 = require("@qevm/transactions");
|
|
7
|
+
const web_1 = require("@qevm/web");
|
|
8
|
+
const formatter_1 = require("./formatter");
|
|
9
|
+
const logger_1 = require("@ethersproject/logger");
|
|
10
|
+
const _version_1 = require("./_version");
|
|
11
|
+
const logger = new logger_1.Logger(_version_1.version);
|
|
12
|
+
const base_provider_1 = require("./base-provider");
|
|
64
13
|
// The transaction has already been sanitized by the calls in Provider
|
|
65
14
|
function getTransactionPostData(transaction) {
|
|
66
|
-
|
|
67
|
-
for (
|
|
15
|
+
const result = {};
|
|
16
|
+
for (let key in transaction) {
|
|
68
17
|
if (transaction[key] == null) {
|
|
69
18
|
continue;
|
|
70
19
|
}
|
|
71
|
-
|
|
20
|
+
let value = transaction[key];
|
|
72
21
|
if (key === "type" && value === 0) {
|
|
73
22
|
continue;
|
|
74
23
|
}
|
|
@@ -77,8 +26,8 @@ function getTransactionPostData(transaction) {
|
|
|
77
26
|
value = (0, bytes_1.hexValue)((0, bytes_1.hexlify)(value));
|
|
78
27
|
}
|
|
79
28
|
else if (key === "accessList") {
|
|
80
|
-
value = "[" + (0, transactions_1.accessListify)(value).map(
|
|
81
|
-
return
|
|
29
|
+
value = "[" + (0, transactions_1.accessListify)(value).map((set) => {
|
|
30
|
+
return `{address:"${set.address}",storageKeys:["${set.storageKeys.join('","')}"]}`;
|
|
82
31
|
}).join(",") + "]";
|
|
83
32
|
}
|
|
84
33
|
else {
|
|
@@ -94,7 +43,7 @@ function getResult(result) {
|
|
|
94
43
|
return result.result;
|
|
95
44
|
}
|
|
96
45
|
if (result.status != 1 || typeof (result.message) !== "string" || !result.message.match(/^OK/)) {
|
|
97
|
-
|
|
46
|
+
const error = new Error("invalid response");
|
|
98
47
|
error.result = JSON.stringify(result);
|
|
99
48
|
if ((result.result || "").toLowerCase().indexOf("rate limit") >= 0) {
|
|
100
49
|
error.throttleRetry = true;
|
|
@@ -106,20 +55,20 @@ function getResult(result) {
|
|
|
106
55
|
function getJsonResult(result) {
|
|
107
56
|
// This response indicates we are being throttled
|
|
108
57
|
if (result && result.status == 0 && result.message == "NOTOK" && (result.result || "").toLowerCase().indexOf("rate limit") >= 0) {
|
|
109
|
-
|
|
58
|
+
const error = new Error("throttled response");
|
|
110
59
|
error.result = JSON.stringify(result);
|
|
111
60
|
error.throttleRetry = true;
|
|
112
61
|
throw error;
|
|
113
62
|
}
|
|
114
63
|
if (result.jsonrpc != "2.0") {
|
|
115
64
|
// @TODO: not any
|
|
116
|
-
|
|
65
|
+
const error = new Error("invalid response");
|
|
117
66
|
error.result = JSON.stringify(result);
|
|
118
67
|
throw error;
|
|
119
68
|
}
|
|
120
69
|
if (result.error) {
|
|
121
70
|
// @TODO: not any
|
|
122
|
-
|
|
71
|
+
const error = new Error(result.error.message || "unknown error");
|
|
123
72
|
if (result.error.code) {
|
|
124
73
|
error.code = result.error.code;
|
|
125
74
|
}
|
|
@@ -144,11 +93,11 @@ function checkError(method, error, transaction) {
|
|
|
144
93
|
// Undo the "convenience" some nodes are attempting to prevent backwards
|
|
145
94
|
// incompatibility; maybe for v6 consider forwarding reverts as errors
|
|
146
95
|
if (method === "call" && error.code === logger_1.Logger.errors.SERVER_ERROR) {
|
|
147
|
-
|
|
96
|
+
const e = error.error;
|
|
148
97
|
// Etherscan keeps changing their string
|
|
149
98
|
if (e && (e.message.match(/reverted/i) || e.message.match(/VM execution error/i))) {
|
|
150
99
|
// Etherscan prefixes the data like "Reverted 0x1234"
|
|
151
|
-
|
|
100
|
+
let data = e.data;
|
|
152
101
|
if (data) {
|
|
153
102
|
data = "0x" + data.replace(/^.*0x/i, "");
|
|
154
103
|
}
|
|
@@ -156,13 +105,12 @@ function checkError(method, error, transaction) {
|
|
|
156
105
|
return data;
|
|
157
106
|
}
|
|
158
107
|
logger.throwError("missing revert data in call exception", logger_1.Logger.errors.CALL_EXCEPTION, {
|
|
159
|
-
error:
|
|
160
|
-
data: "0x"
|
|
108
|
+
error, data: "0x"
|
|
161
109
|
});
|
|
162
110
|
}
|
|
163
111
|
}
|
|
164
112
|
// Get the message from any nested error structure
|
|
165
|
-
|
|
113
|
+
let message = error.message;
|
|
166
114
|
if (error.code === logger_1.Logger.errors.SERVER_ERROR) {
|
|
167
115
|
if (error.error && typeof (error.error.message) === "string") {
|
|
168
116
|
message = error.error.message;
|
|
@@ -178,45 +126,35 @@ function checkError(method, error, transaction) {
|
|
|
178
126
|
// "Insufficient funds. The account you tried to send transaction from does not have enough funds. Required 21464000000000 and got: 0"
|
|
179
127
|
if (message.match(/insufficient funds/)) {
|
|
180
128
|
logger.throwError("insufficient funds for intrinsic transaction cost", logger_1.Logger.errors.INSUFFICIENT_FUNDS, {
|
|
181
|
-
error
|
|
182
|
-
method: method,
|
|
183
|
-
transaction: transaction
|
|
129
|
+
error, method, transaction
|
|
184
130
|
});
|
|
185
131
|
}
|
|
186
132
|
// "Transaction with the same hash was already imported."
|
|
187
133
|
if (message.match(/same hash was already imported|transaction nonce is too low|nonce too low/)) {
|
|
188
134
|
logger.throwError("nonce has already been used", logger_1.Logger.errors.NONCE_EXPIRED, {
|
|
189
|
-
error
|
|
190
|
-
method: method,
|
|
191
|
-
transaction: transaction
|
|
135
|
+
error, method, transaction
|
|
192
136
|
});
|
|
193
137
|
}
|
|
194
138
|
// "Transaction gas price is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce."
|
|
195
139
|
if (message.match(/another transaction with same nonce/)) {
|
|
196
140
|
logger.throwError("replacement fee too low", logger_1.Logger.errors.REPLACEMENT_UNDERPRICED, {
|
|
197
|
-
error
|
|
198
|
-
method: method,
|
|
199
|
-
transaction: transaction
|
|
141
|
+
error, method, transaction
|
|
200
142
|
});
|
|
201
143
|
}
|
|
202
144
|
if (message.match(/execution failed due to an exception|execution reverted/)) {
|
|
203
145
|
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", logger_1.Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
|
204
|
-
error
|
|
205
|
-
method: method,
|
|
206
|
-
transaction: transaction
|
|
146
|
+
error, method, transaction
|
|
207
147
|
});
|
|
208
148
|
}
|
|
209
149
|
throw error;
|
|
210
150
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
(0, properties_1.defineReadOnly)(
|
|
216
|
-
(0, properties_1.defineReadOnly)(_this, "apiKey", apiKey || null);
|
|
217
|
-
return _this;
|
|
151
|
+
class EtherscanProvider extends base_provider_1.BaseProvider {
|
|
152
|
+
constructor(network, apiKey) {
|
|
153
|
+
super(network);
|
|
154
|
+
(0, properties_1.defineReadOnly)(this, "baseUrl", this.getBaseUrl());
|
|
155
|
+
(0, properties_1.defineReadOnly)(this, "apiKey", apiKey || null);
|
|
218
156
|
}
|
|
219
|
-
|
|
157
|
+
getBaseUrl() {
|
|
220
158
|
switch (this.network ? this.network.name : "invalid") {
|
|
221
159
|
case "homestead":
|
|
222
160
|
return "https:/\/api.etherscan.io";
|
|
@@ -239,290 +177,232 @@ var EtherscanProvider = /** @class */ (function (_super) {
|
|
|
239
177
|
default:
|
|
240
178
|
}
|
|
241
179
|
return logger.throwArgumentError("unsupported network", "network", this.network.name);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
180
|
+
}
|
|
181
|
+
getUrl(module, params) {
|
|
182
|
+
const query = Object.keys(params).reduce((accum, key) => {
|
|
183
|
+
const value = params[key];
|
|
246
184
|
if (value != null) {
|
|
247
|
-
accum +=
|
|
185
|
+
accum += `&${key}=${value}`;
|
|
248
186
|
}
|
|
249
187
|
return accum;
|
|
250
188
|
}, "");
|
|
251
|
-
|
|
252
|
-
return this.baseUrl
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return this.baseUrl
|
|
256
|
-
}
|
|
257
|
-
|
|
189
|
+
const apiKey = ((this.apiKey) ? `&apikey=${this.apiKey}` : "");
|
|
190
|
+
return `${this.baseUrl}/api?module=${module}${query}${apiKey}`;
|
|
191
|
+
}
|
|
192
|
+
getPostUrl() {
|
|
193
|
+
return `${this.baseUrl}/api`;
|
|
194
|
+
}
|
|
195
|
+
getPostData(module, params) {
|
|
258
196
|
params.module = module;
|
|
259
197
|
params.apikey = this.apiKey;
|
|
260
198
|
return params;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
payload = (post ? this.getPostData(module, params) : null);
|
|
271
|
-
procFunc = (module === "proxy") ? getJsonResult : getResult;
|
|
272
|
-
this.emit("debug", {
|
|
273
|
-
action: "request",
|
|
274
|
-
request: url,
|
|
275
|
-
provider: this
|
|
276
|
-
});
|
|
277
|
-
connection = {
|
|
278
|
-
url: url,
|
|
279
|
-
throttleSlotInterval: 1000,
|
|
280
|
-
throttleCallback: function (attempt, url) {
|
|
281
|
-
if (_this.isCommunityResource()) {
|
|
282
|
-
(0, formatter_1.showThrottleMessage)();
|
|
283
|
-
}
|
|
284
|
-
return Promise.resolve(true);
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
payloadStr = null;
|
|
288
|
-
if (payload) {
|
|
289
|
-
connection.headers = { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" };
|
|
290
|
-
payloadStr = Object.keys(payload).map(function (key) {
|
|
291
|
-
return key + "=" + payload[key];
|
|
292
|
-
}).join("&");
|
|
293
|
-
}
|
|
294
|
-
return [4 /*yield*/, (0, web_1.fetchJson)(connection, payloadStr, procFunc || getJsonResult)];
|
|
295
|
-
case 1:
|
|
296
|
-
result = _a.sent();
|
|
297
|
-
this.emit("debug", {
|
|
298
|
-
action: "response",
|
|
299
|
-
request: url,
|
|
300
|
-
response: (0, properties_1.deepCopy)(result),
|
|
301
|
-
provider: this
|
|
302
|
-
});
|
|
303
|
-
return [2 /*return*/, result];
|
|
304
|
-
}
|
|
305
|
-
});
|
|
199
|
+
}
|
|
200
|
+
async fetch(module, params, post) {
|
|
201
|
+
const url = (post ? this.getPostUrl() : this.getUrl(module, params));
|
|
202
|
+
const payload = (post ? this.getPostData(module, params) : null);
|
|
203
|
+
const procFunc = (module === "proxy") ? getJsonResult : getResult;
|
|
204
|
+
this.emit("debug", {
|
|
205
|
+
action: "request",
|
|
206
|
+
request: url,
|
|
207
|
+
provider: this
|
|
306
208
|
});
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
209
|
+
const connection = {
|
|
210
|
+
url: url,
|
|
211
|
+
throttleSlotInterval: 1000,
|
|
212
|
+
throttleCallback: (attempt, url) => {
|
|
213
|
+
if (this.isCommunityResource()) {
|
|
214
|
+
(0, formatter_1.showThrottleMessage)();
|
|
215
|
+
}
|
|
216
|
+
return Promise.resolve(true);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
let payloadStr = null;
|
|
220
|
+
if (payload) {
|
|
221
|
+
connection.headers = { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" };
|
|
222
|
+
payloadStr = Object.keys(payload).map((key) => {
|
|
223
|
+
return `${key}=${payload[key]}`;
|
|
224
|
+
}).join("&");
|
|
225
|
+
}
|
|
226
|
+
const result = await (0, web_1.fetchJson)(connection, payloadStr, procFunc || getJsonResult);
|
|
227
|
+
this.emit("debug", {
|
|
228
|
+
action: "response",
|
|
229
|
+
request: url,
|
|
230
|
+
response: (0, properties_1.deepCopy)(result),
|
|
231
|
+
provider: this
|
|
313
232
|
});
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (params.filter.address) {
|
|
423
|
-
args.address = params.filter.address;
|
|
424
|
-
}
|
|
425
|
-
// @TODO: We can handle slightly more complicated logs using the logs API
|
|
426
|
-
if (params.filter.topics && params.filter.topics.length > 0) {
|
|
427
|
-
if (params.filter.topics.length > 1) {
|
|
428
|
-
logger.throwError("unsupported topic count", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { topics: params.filter.topics });
|
|
429
|
-
}
|
|
430
|
-
if (params.filter.topics.length === 1) {
|
|
431
|
-
topic0 = params.filter.topics[0];
|
|
432
|
-
if (typeof (topic0) !== "string" || topic0.length !== 66) {
|
|
433
|
-
logger.throwError("unsupported topic format", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { topic0: topic0 });
|
|
434
|
-
}
|
|
435
|
-
args.topic0 = topic0;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return [4 /*yield*/, this.fetch("logs", args)];
|
|
439
|
-
case 20:
|
|
440
|
-
logs = _c.sent();
|
|
441
|
-
blocks = {};
|
|
442
|
-
i = 0;
|
|
443
|
-
_c.label = 21;
|
|
444
|
-
case 21:
|
|
445
|
-
if (!(i < logs.length)) return [3 /*break*/, 25];
|
|
446
|
-
log = logs[i];
|
|
447
|
-
if (log.blockHash != null) {
|
|
448
|
-
return [3 /*break*/, 24];
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
async detectNetwork() {
|
|
236
|
+
return this.network;
|
|
237
|
+
}
|
|
238
|
+
async perform(method, params) {
|
|
239
|
+
switch (method) {
|
|
240
|
+
case "getBlockNumber":
|
|
241
|
+
return this.fetch("proxy", { action: "eth_blockNumber" });
|
|
242
|
+
case "getGasPrice":
|
|
243
|
+
return this.fetch("proxy", { action: "eth_gasPrice" });
|
|
244
|
+
case "getBalance":
|
|
245
|
+
// Returns base-10 result
|
|
246
|
+
return this.fetch("account", {
|
|
247
|
+
action: "balance",
|
|
248
|
+
address: params.address,
|
|
249
|
+
tag: params.blockTag
|
|
250
|
+
});
|
|
251
|
+
case "getTransactionCount":
|
|
252
|
+
return this.fetch("proxy", {
|
|
253
|
+
action: "eth_getTransactionCount",
|
|
254
|
+
address: params.address,
|
|
255
|
+
tag: params.blockTag
|
|
256
|
+
});
|
|
257
|
+
case "getCode":
|
|
258
|
+
return this.fetch("proxy", {
|
|
259
|
+
action: "eth_getCode",
|
|
260
|
+
address: params.address,
|
|
261
|
+
tag: params.blockTag
|
|
262
|
+
});
|
|
263
|
+
case "getStorageAt":
|
|
264
|
+
return this.fetch("proxy", {
|
|
265
|
+
action: "eth_getStorageAt",
|
|
266
|
+
address: params.address,
|
|
267
|
+
position: params.position,
|
|
268
|
+
tag: params.blockTag
|
|
269
|
+
});
|
|
270
|
+
case "sendTransaction":
|
|
271
|
+
return this.fetch("proxy", {
|
|
272
|
+
action: "eth_sendRawTransaction",
|
|
273
|
+
hex: params.signedTransaction
|
|
274
|
+
}, true).catch((error) => {
|
|
275
|
+
return checkError("sendTransaction", error, params.signedTransaction);
|
|
276
|
+
});
|
|
277
|
+
case "getBlock":
|
|
278
|
+
if (params.blockTag) {
|
|
279
|
+
return this.fetch("proxy", {
|
|
280
|
+
action: "eth_getBlockByNumber",
|
|
281
|
+
tag: params.blockTag,
|
|
282
|
+
boolean: (params.includeTransactions ? "true" : "false")
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
throw new Error("getBlock by blockHash not implemented");
|
|
286
|
+
case "getTransaction":
|
|
287
|
+
return this.fetch("proxy", {
|
|
288
|
+
action: "eth_getTransactionByHash",
|
|
289
|
+
txhash: params.transactionHash
|
|
290
|
+
});
|
|
291
|
+
case "getTransactionReceipt":
|
|
292
|
+
return this.fetch("proxy", {
|
|
293
|
+
action: "eth_getTransactionReceipt",
|
|
294
|
+
txhash: params.transactionHash
|
|
295
|
+
});
|
|
296
|
+
case "call": {
|
|
297
|
+
if (params.blockTag !== "latest") {
|
|
298
|
+
throw new Error("EtherscanProvider does not support blockTag for call");
|
|
299
|
+
}
|
|
300
|
+
const postData = getTransactionPostData(params.transaction);
|
|
301
|
+
postData.module = "proxy";
|
|
302
|
+
postData.action = "eth_call";
|
|
303
|
+
try {
|
|
304
|
+
return await this.fetch("proxy", postData, true);
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
return checkError("call", error, params.transaction);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
case "estimateGas": {
|
|
311
|
+
const postData = getTransactionPostData(params.transaction);
|
|
312
|
+
postData.module = "proxy";
|
|
313
|
+
postData.action = "eth_estimateGas";
|
|
314
|
+
try {
|
|
315
|
+
return await this.fetch("proxy", postData, true);
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
return checkError("estimateGas", error, params.transaction);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
case "getLogs": {
|
|
322
|
+
const args = { action: "getLogs" };
|
|
323
|
+
if (params.filter.fromBlock) {
|
|
324
|
+
args.fromBlock = checkLogTag(params.filter.fromBlock);
|
|
325
|
+
}
|
|
326
|
+
if (params.filter.toBlock) {
|
|
327
|
+
args.toBlock = checkLogTag(params.filter.toBlock);
|
|
328
|
+
}
|
|
329
|
+
if (params.filter.address) {
|
|
330
|
+
args.address = params.filter.address;
|
|
331
|
+
}
|
|
332
|
+
// @TODO: We can handle slightly more complicated logs using the logs API
|
|
333
|
+
if (params.filter.topics && params.filter.topics.length > 0) {
|
|
334
|
+
if (params.filter.topics.length > 1) {
|
|
335
|
+
logger.throwError("unsupported topic count", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { topics: params.filter.topics });
|
|
336
|
+
}
|
|
337
|
+
if (params.filter.topics.length === 1) {
|
|
338
|
+
const topic0 = params.filter.topics[0];
|
|
339
|
+
if (typeof (topic0) !== "string" || topic0.length !== 66) {
|
|
340
|
+
logger.throwError("unsupported topic format", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { topic0: topic0 });
|
|
449
341
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
342
|
+
args.topic0 = topic0;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const logs = await this.fetch("logs", args);
|
|
346
|
+
// Cache txHash => blockHash
|
|
347
|
+
let blocks = {};
|
|
348
|
+
// Add any missing blockHash to the logs
|
|
349
|
+
for (let i = 0; i < logs.length; i++) {
|
|
350
|
+
const log = logs[i];
|
|
351
|
+
if (log.blockHash != null) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
if (blocks[log.blockNumber] == null) {
|
|
355
|
+
const block = await this.getBlock(log.blockNumber);
|
|
454
356
|
if (block) {
|
|
455
357
|
blocks[log.blockNumber] = block.hash;
|
|
456
358
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
log.blockHash = blocks[log.blockNumber];
|
|
460
|
-
_c.label = 24;
|
|
461
|
-
case 24:
|
|
462
|
-
i++;
|
|
463
|
-
return [3 /*break*/, 21];
|
|
464
|
-
case 25: return [2 /*return*/, logs];
|
|
465
|
-
case 26:
|
|
466
|
-
if (this.network.name !== "homestead") {
|
|
467
|
-
return [2 /*return*/, 0.0];
|
|
468
|
-
}
|
|
469
|
-
_b = parseFloat;
|
|
470
|
-
return [4 /*yield*/, this.fetch("stats", { action: "ethprice" })];
|
|
471
|
-
case 27: return [2 /*return*/, _b.apply(void 0, [(_c.sent()).ethusd])];
|
|
472
|
-
case 28: return [3 /*break*/, 29];
|
|
473
|
-
case 29: return [2 /*return*/, _super.prototype.perform.call(this, method, params)];
|
|
359
|
+
}
|
|
360
|
+
log.blockHash = blocks[log.blockNumber];
|
|
474
361
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
362
|
+
return logs;
|
|
363
|
+
}
|
|
364
|
+
case "getEtherPrice":
|
|
365
|
+
if (this.network.name !== "homestead") {
|
|
366
|
+
return 0.0;
|
|
367
|
+
}
|
|
368
|
+
return parseFloat((await this.fetch("stats", { action: "ethprice" })).ethusd);
|
|
369
|
+
default:
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
return super.perform(method, params);
|
|
373
|
+
}
|
|
478
374
|
// Note: The `page` page parameter only allows pagination within the
|
|
479
375
|
// 10,000 window available without a page and offset parameter
|
|
480
376
|
// Error: Result window is too large, PageNo x Offset size must
|
|
481
377
|
// be less than or equal to 10000
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
params = (_a.address = (_b.sent()),
|
|
496
|
-
_a.startblock = ((startBlock == null) ? 0 : startBlock),
|
|
497
|
-
_a.endblock = ((endBlock == null) ? 99999999 : endBlock),
|
|
498
|
-
_a.sort = "asc",
|
|
499
|
-
_a);
|
|
500
|
-
return [4 /*yield*/, this.fetch("account", params)];
|
|
501
|
-
case 2:
|
|
502
|
-
result = _b.sent();
|
|
503
|
-
return [2 /*return*/, result.map(function (tx) {
|
|
504
|
-
["contractAddress", "to"].forEach(function (key) {
|
|
505
|
-
if (tx[key] == "") {
|
|
506
|
-
delete tx[key];
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
if (tx.creates == null && tx.contractAddress != null) {
|
|
510
|
-
tx.creates = tx.contractAddress;
|
|
511
|
-
}
|
|
512
|
-
var item = _this.formatter.transactionResponse(tx);
|
|
513
|
-
if (tx.timeStamp) {
|
|
514
|
-
item.timestamp = parseInt(tx.timeStamp);
|
|
515
|
-
}
|
|
516
|
-
return item;
|
|
517
|
-
})];
|
|
378
|
+
async getHistory(addressOrName, startBlock, endBlock) {
|
|
379
|
+
const params = {
|
|
380
|
+
action: "txlist",
|
|
381
|
+
address: (await this.resolveName(addressOrName)),
|
|
382
|
+
startblock: ((startBlock == null) ? 0 : startBlock),
|
|
383
|
+
endblock: ((endBlock == null) ? 99999999 : endBlock),
|
|
384
|
+
sort: "asc"
|
|
385
|
+
};
|
|
386
|
+
const result = await this.fetch("account", params);
|
|
387
|
+
return result.map((tx) => {
|
|
388
|
+
["contractAddress", "to"].forEach(function (key) {
|
|
389
|
+
if (tx[key] == "") {
|
|
390
|
+
delete tx[key];
|
|
518
391
|
}
|
|
519
392
|
});
|
|
393
|
+
if (tx.creates == null && tx.contractAddress != null) {
|
|
394
|
+
tx.creates = tx.contractAddress;
|
|
395
|
+
}
|
|
396
|
+
const item = this.formatter.transactionResponse(tx);
|
|
397
|
+
if (tx.timeStamp) {
|
|
398
|
+
item.timestamp = parseInt(tx.timeStamp);
|
|
399
|
+
}
|
|
400
|
+
return item;
|
|
520
401
|
});
|
|
521
|
-
}
|
|
522
|
-
|
|
402
|
+
}
|
|
403
|
+
isCommunityResource() {
|
|
523
404
|
return (this.apiKey == null);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
}(base_provider_1.BaseProvider));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
527
407
|
exports.EtherscanProvider = EtherscanProvider;
|
|
528
408
|
//# sourceMappingURL=etherscan-provider.js.map
|