@qevm/providers 1.0.1
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/LICENSE.md +21 -0
- package/README.md +78 -0
- package/lib/_version.d.ts +2 -0
- package/lib/_version.d.ts.map +1 -0
- package/lib/_version.js +5 -0
- package/lib/_version.js.map +1 -0
- package/lib/alchemy-provider.d.ts +17 -0
- package/lib/alchemy-provider.d.ts.map +1 -0
- package/lib/alchemy-provider.js +112 -0
- package/lib/alchemy-provider.js.map +1 -0
- package/lib/ankr-provider.d.ts +10 -0
- package/lib/ankr-provider.d.ts.map +1 -0
- package/lib/ankr-provider.js +79 -0
- package/lib/ankr-provider.js.map +1 -0
- package/lib/base-provider.d.ts +156 -0
- package/lib/base-provider.d.ts.map +1 -0
- package/lib/base-provider.js +2585 -0
- package/lib/base-provider.js.map +1 -0
- package/lib/browser-ipc-provider.d.ts +3 -0
- package/lib/browser-ipc-provider.d.ts.map +1 -0
- package/lib/browser-ipc-provider.js +6 -0
- package/lib/browser-ipc-provider.js.map +1 -0
- package/lib/browser-net.d.ts +2 -0
- package/lib/browser-net.d.ts.map +1 -0
- package/lib/browser-net.js +6 -0
- package/lib/browser-net.js.map +1 -0
- package/lib/browser-ws.d.ts +3 -0
- package/lib/browser-ws.d.ts.map +1 -0
- package/lib/browser-ws.js +22 -0
- package/lib/browser-ws.js.map +1 -0
- package/lib/cloudflare-provider.d.ts +8 -0
- package/lib/cloudflare-provider.d.ts.map +1 -0
- package/lib/cloudflare-provider.js +100 -0
- package/lib/cloudflare-provider.js.map +1 -0
- package/lib/etherscan-provider.d.ts +18 -0
- package/lib/etherscan-provider.d.ts.map +1 -0
- package/lib/etherscan-provider.js +528 -0
- package/lib/etherscan-provider.js.map +1 -0
- package/lib/fallback-provider.d.ts +20 -0
- package/lib/fallback-provider.d.ts.map +1 -0
- package/lib/fallback-provider.js +699 -0
- package/lib/fallback-provider.js.map +1 -0
- package/lib/formatter.d.ts +60 -0
- package/lib/formatter.d.ts.map +1 -0
- package/lib/formatter.js +452 -0
- package/lib/formatter.js.map +1 -0
- package/lib/index.d.ts +23 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +97 -0
- package/lib/index.js.map +1 -0
- package/lib/infura-provider.d.ts +21 -0
- package/lib/infura-provider.d.ts.map +1 -0
- package/lib/infura-provider.js +141 -0
- package/lib/infura-provider.js.map +1 -0
- package/lib/ipc-provider.d.ts +8 -0
- package/lib/ipc-provider.d.ts.map +1 -0
- package/lib/ipc-provider.js +77 -0
- package/lib/ipc-provider.js.map +1 -0
- package/lib/json-rpc-batch-provider.d.ts +17 -0
- package/lib/json-rpc-batch-provider.d.ts.map +1 -0
- package/lib/json-rpc-batch-provider.js +99 -0
- package/lib/json-rpc-batch-provider.js.map +1 -0
- package/lib/json-rpc-provider.d.ts +54 -0
- package/lib/json-rpc-provider.d.ts.map +1 -0
- package/lib/json-rpc-provider.js +855 -0
- package/lib/json-rpc-provider.js.map +1 -0
- package/lib/nodesmith-provider.d.ts +7 -0
- package/lib/nodesmith-provider.d.ts.map +1 -0
- package/lib/nodesmith-provider.js +64 -0
- package/lib/nodesmith-provider.js.map +1 -0
- package/lib/pocket-provider.d.ts +12 -0
- package/lib/pocket-provider.d.ts.map +1 -0
- package/lib/pocket-provider.js +98 -0
- package/lib/pocket-provider.js.map +1 -0
- package/lib/url-json-rpc-provider.d.ts +18 -0
- package/lib/url-json-rpc-provider.d.ts.map +1 -0
- package/lib/url-json-rpc-provider.js +153 -0
- package/lib/url-json-rpc-provider.js.map +1 -0
- package/lib/web3-provider.d.ts +28 -0
- package/lib/web3-provider.d.ts.map +1 -0
- package/lib/web3-provider.js +155 -0
- package/lib/web3-provider.js.map +1 -0
- package/lib/websocket-provider.d.ts +48 -0
- package/lib/websocket-provider.d.ts.map +1 -0
- package/lib/websocket-provider.js +384 -0
- package/lib/websocket-provider.js.map +1 -0
- package/lib/ws.d.ts +3 -0
- package/lib/ws.d.ts.map +1 -0
- package/lib/ws.js +9 -0
- package/lib/ws.js.map +1 -0
- package/package.json +57 -0
- package/src.ts/_version.ts +1 -0
- package/src.ts/alchemy-provider.ts +101 -0
- package/src.ts/ankr-provider.ts +68 -0
- package/src.ts/base-provider.ts +2216 -0
- package/src.ts/browser-ipc-provider.ts +7 -0
- package/src.ts/browser-net.ts +3 -0
- package/src.ts/browser-ws.ts +21 -0
- package/src.ts/cloudflare-provider.ts +42 -0
- package/src.ts/etherscan-provider.ts +454 -0
- package/src.ts/fallback-provider.ts +654 -0
- package/src.ts/formatter.ts +522 -0
- package/src.ts/index.ts +178 -0
- package/src.ts/infura-provider.ts +143 -0
- package/src.ts/ipc-provider.ts +72 -0
- package/src.ts/json-rpc-batch-provider.ts +97 -0
- package/src.ts/json-rpc-provider.ts +742 -0
- package/src.ts/nodesmith-provider.ts +50 -0
- package/src.ts/pocket-provider.ts +93 -0
- package/src.ts/url-json-rpc-provider.ts +106 -0
- package/src.ts/web3-provider.ts +169 -0
- package/src.ts/websocket-provider.ts +350 -0
- package/src.ts/ws.ts +3 -0
- package/thirdparty.d.ts +10 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Network, Networkish } from "@ethersproject/networks";
|
|
4
|
+
import { defineReadOnly } from "@ethersproject/properties";
|
|
5
|
+
import { ConnectionInfo } from "@ethersproject/web";
|
|
6
|
+
|
|
7
|
+
import { WebSocketProvider } from "./websocket-provider";
|
|
8
|
+
import { CommunityResourcable, showThrottleMessage } from "./formatter";
|
|
9
|
+
|
|
10
|
+
import { Logger } from "@ethersproject/logger";
|
|
11
|
+
import { version } from "./_version";
|
|
12
|
+
const logger = new Logger(version);
|
|
13
|
+
|
|
14
|
+
import { UrlJsonRpcProvider } from "./url-json-rpc-provider";
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const defaultProjectId = "84842078b09946638c03157f83405213"
|
|
18
|
+
|
|
19
|
+
export class InfuraWebSocketProvider extends WebSocketProvider implements CommunityResourcable {
|
|
20
|
+
readonly apiKey: string;
|
|
21
|
+
readonly projectId: string;
|
|
22
|
+
readonly projectSecret: string;
|
|
23
|
+
|
|
24
|
+
constructor(network?: Networkish, apiKey?: any) {
|
|
25
|
+
const provider = new InfuraProvider(network, apiKey);
|
|
26
|
+
const connection = provider.connection;
|
|
27
|
+
if (connection.password) {
|
|
28
|
+
logger.throwError("INFURA WebSocket project secrets unsupported", Logger.errors.UNSUPPORTED_OPERATION, {
|
|
29
|
+
operation: "InfuraProvider.getWebSocketProvider()"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const url = connection.url.replace(/^http/i, "ws").replace("/v3/", "/ws/v3/");
|
|
34
|
+
super(url, network);
|
|
35
|
+
|
|
36
|
+
defineReadOnly(this, "apiKey", provider.projectId);
|
|
37
|
+
defineReadOnly(this, "projectId", provider.projectId);
|
|
38
|
+
defineReadOnly(this, "projectSecret", provider.projectSecret);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
isCommunityResource(): boolean {
|
|
42
|
+
return (this.projectId === defaultProjectId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class InfuraProvider extends UrlJsonRpcProvider {
|
|
47
|
+
readonly projectId: string;
|
|
48
|
+
readonly projectSecret: string;
|
|
49
|
+
|
|
50
|
+
static getWebSocketProvider(network?: Networkish, apiKey?: any): InfuraWebSocketProvider {
|
|
51
|
+
return new InfuraWebSocketProvider(network, apiKey);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static getApiKey(apiKey: any): any {
|
|
55
|
+
const apiKeyObj: { apiKey: string, projectId: string, projectSecret: string } = {
|
|
56
|
+
apiKey: defaultProjectId,
|
|
57
|
+
projectId: defaultProjectId,
|
|
58
|
+
projectSecret: null
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (apiKey == null) { return apiKeyObj; }
|
|
62
|
+
|
|
63
|
+
if (typeof(apiKey) === "string") {
|
|
64
|
+
apiKeyObj.projectId = apiKey;
|
|
65
|
+
|
|
66
|
+
} else if (apiKey.projectSecret != null) {
|
|
67
|
+
logger.assertArgument((typeof(apiKey.projectId) === "string"),
|
|
68
|
+
"projectSecret requires a projectId", "projectId", apiKey.projectId);
|
|
69
|
+
logger.assertArgument((typeof(apiKey.projectSecret) === "string"),
|
|
70
|
+
"invalid projectSecret", "projectSecret", "[REDACTED]");
|
|
71
|
+
|
|
72
|
+
apiKeyObj.projectId = apiKey.projectId;
|
|
73
|
+
apiKeyObj.projectSecret = apiKey.projectSecret;
|
|
74
|
+
|
|
75
|
+
} else if (apiKey.projectId) {
|
|
76
|
+
apiKeyObj.projectId = apiKey.projectId;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
apiKeyObj.apiKey = apiKeyObj.projectId;
|
|
80
|
+
|
|
81
|
+
return apiKeyObj;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static getUrl(network: Network, apiKey: any): ConnectionInfo {
|
|
85
|
+
let host: string = null;
|
|
86
|
+
switch(network ? network.name: "unknown") {
|
|
87
|
+
case "homestead":
|
|
88
|
+
host = "mainnet.infura.io";
|
|
89
|
+
break;
|
|
90
|
+
case "goerli":
|
|
91
|
+
host = "goerli.infura.io";
|
|
92
|
+
break;
|
|
93
|
+
case "sepolia":
|
|
94
|
+
host = "sepolia.infura.io";
|
|
95
|
+
break;
|
|
96
|
+
case "matic":
|
|
97
|
+
host = "polygon-mainnet.infura.io";
|
|
98
|
+
break;
|
|
99
|
+
case "maticmum":
|
|
100
|
+
host = "polygon-mumbai.infura.io";
|
|
101
|
+
break;
|
|
102
|
+
case "optimism":
|
|
103
|
+
host = "optimism-mainnet.infura.io";
|
|
104
|
+
break;
|
|
105
|
+
case "optimism-goerli":
|
|
106
|
+
host = "optimism-goerli.infura.io";
|
|
107
|
+
break;
|
|
108
|
+
case "arbitrum":
|
|
109
|
+
host = "arbitrum-mainnet.infura.io";
|
|
110
|
+
break;
|
|
111
|
+
case "arbitrum-goerli":
|
|
112
|
+
host = "arbitrum-goerli.infura.io";
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
logger.throwError("unsupported network", Logger.errors.INVALID_ARGUMENT, {
|
|
116
|
+
argument: "network",
|
|
117
|
+
value: network
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const connection: ConnectionInfo = {
|
|
122
|
+
allowGzip: true,
|
|
123
|
+
url: ("https:/" + "/" + host + "/v3/" + apiKey.projectId),
|
|
124
|
+
throttleCallback: (attempt: number, url: string) => {
|
|
125
|
+
if (apiKey.projectId === defaultProjectId) {
|
|
126
|
+
showThrottleMessage();
|
|
127
|
+
}
|
|
128
|
+
return Promise.resolve(true);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if (apiKey.projectSecret != null) {
|
|
133
|
+
connection.user = "";
|
|
134
|
+
connection.password = apiKey.projectSecret
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return connection;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
isCommunityResource(): boolean {
|
|
141
|
+
return (this.projectId === defaultProjectId);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { connect } from "net";
|
|
4
|
+
|
|
5
|
+
import { defineReadOnly } from "@ethersproject/properties";
|
|
6
|
+
import { Networkish } from "@ethersproject/networks";
|
|
7
|
+
|
|
8
|
+
import { Logger } from "@ethersproject/logger";
|
|
9
|
+
import { version } from "./_version";
|
|
10
|
+
const logger = new Logger(version);
|
|
11
|
+
|
|
12
|
+
import { JsonRpcProvider } from "./json-rpc-provider";
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export class IpcProvider extends JsonRpcProvider {
|
|
16
|
+
readonly path: string;
|
|
17
|
+
|
|
18
|
+
constructor(path: string, network?: Networkish) {
|
|
19
|
+
if (path == null) {
|
|
20
|
+
logger.throwError("missing path", Logger.errors.MISSING_ARGUMENT, { arg: "path" });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
super("ipc://" + path, network);
|
|
24
|
+
|
|
25
|
+
defineReadOnly(this, "path", path);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// @TODO: Create a connection to the IPC path and use filters instead of polling for block
|
|
29
|
+
|
|
30
|
+
send(method: string, params: Array<any>): Promise<any> {
|
|
31
|
+
// This method is very simple right now. We create a new socket
|
|
32
|
+
// connection each time, which may be slower, but the main
|
|
33
|
+
// advantage we are aiming for now is security. This simplifies
|
|
34
|
+
// multiplexing requests (since we do not need to multiplex).
|
|
35
|
+
|
|
36
|
+
let payload = JSON.stringify({
|
|
37
|
+
method: method,
|
|
38
|
+
params: params,
|
|
39
|
+
id: 42,
|
|
40
|
+
jsonrpc: "2.0"
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
let response = Buffer.alloc(0);
|
|
45
|
+
|
|
46
|
+
let stream = connect(this.path);
|
|
47
|
+
|
|
48
|
+
stream.on("data", (data) => {
|
|
49
|
+
response = Buffer.concat([ response, data ]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
stream.on("end", () => {
|
|
53
|
+
try {
|
|
54
|
+
resolve(JSON.parse(response.toString()).result);
|
|
55
|
+
// @TODO: Better pull apart the error
|
|
56
|
+
stream.destroy();
|
|
57
|
+
} catch (error) {
|
|
58
|
+
reject(error);
|
|
59
|
+
stream.destroy();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
stream.on("error", (error) => {
|
|
64
|
+
reject(error);
|
|
65
|
+
stream.destroy();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
stream.write(payload);
|
|
69
|
+
stream.end();
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
import { deepCopy } from "@ethersproject/properties";
|
|
3
|
+
import { fetchJson } from "@ethersproject/web";
|
|
4
|
+
|
|
5
|
+
import { JsonRpcProvider } from "./json-rpc-provider";
|
|
6
|
+
|
|
7
|
+
// Experimental
|
|
8
|
+
|
|
9
|
+
export class JsonRpcBatchProvider extends JsonRpcProvider {
|
|
10
|
+
_pendingBatchAggregator: NodeJS.Timer;
|
|
11
|
+
_pendingBatch: Array<{
|
|
12
|
+
request: { method: string, params: Array<any>, id: number, jsonrpc: "2.0" },
|
|
13
|
+
resolve: (result: any) => void,
|
|
14
|
+
reject: (error: Error) => void
|
|
15
|
+
}>;
|
|
16
|
+
|
|
17
|
+
send(method: string, params: Array<any>): Promise<any> {
|
|
18
|
+
const request = {
|
|
19
|
+
method: method,
|
|
20
|
+
params: params,
|
|
21
|
+
id: (this._nextId++),
|
|
22
|
+
jsonrpc: "2.0"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (this._pendingBatch == null) {
|
|
26
|
+
this._pendingBatch = [ ];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const inflightRequest: any = { request, resolve: null, reject: null };
|
|
30
|
+
|
|
31
|
+
const promise = new Promise((resolve, reject) => {
|
|
32
|
+
inflightRequest.resolve = resolve;
|
|
33
|
+
inflightRequest.reject = reject;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this._pendingBatch.push(inflightRequest);
|
|
37
|
+
|
|
38
|
+
if (!this._pendingBatchAggregator) {
|
|
39
|
+
// Schedule batch for next event loop + short duration
|
|
40
|
+
this._pendingBatchAggregator = setTimeout(() => {
|
|
41
|
+
|
|
42
|
+
// Get teh current batch and clear it, so new requests
|
|
43
|
+
// go into the next batch
|
|
44
|
+
const batch = this._pendingBatch;
|
|
45
|
+
this._pendingBatch = null;
|
|
46
|
+
this._pendingBatchAggregator = null;
|
|
47
|
+
|
|
48
|
+
// Get the request as an array of requests
|
|
49
|
+
const request = batch.map((inflight) => inflight.request);
|
|
50
|
+
|
|
51
|
+
this.emit("debug", {
|
|
52
|
+
action: "requestBatch",
|
|
53
|
+
request: deepCopy(request),
|
|
54
|
+
provider: this
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return fetchJson(this.connection, JSON.stringify(request)).then((result) => {
|
|
58
|
+
this.emit("debug", {
|
|
59
|
+
action: "response",
|
|
60
|
+
request: request,
|
|
61
|
+
response: result,
|
|
62
|
+
provider: this
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// For each result, feed it to the correct Promise, depending
|
|
66
|
+
// on whether it was a success or error
|
|
67
|
+
batch.forEach((inflightRequest, index) => {
|
|
68
|
+
const payload = result[index];
|
|
69
|
+
if (payload.error) {
|
|
70
|
+
const error = new Error(payload.error.message);
|
|
71
|
+
(<any>error).code = payload.error.code;
|
|
72
|
+
(<any>error).data = payload.error.data;
|
|
73
|
+
inflightRequest.reject(error);
|
|
74
|
+
} else {
|
|
75
|
+
inflightRequest.resolve(payload.result);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
}, (error) => {
|
|
80
|
+
this.emit("debug", {
|
|
81
|
+
action: "response",
|
|
82
|
+
error: error,
|
|
83
|
+
request: request,
|
|
84
|
+
provider: this
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
batch.forEach((inflightRequest) => {
|
|
88
|
+
inflightRequest.reject(error);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
}, 10);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return promise;
|
|
96
|
+
}
|
|
97
|
+
}
|