-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprovider.js
164 lines (135 loc) Β· 4.16 KB
/
provider.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
const ethers = require('ethers');
const {
MAINNET_WEBSOCKET,
MAINNET_API,
MAINNET_PASS,
MAINNET_USER,
MAINNET_API_PUBLIC,
USE_TESTNET,
TESTNET_WEBSOCKET,
TESTNET_API
} = require('./constants');
const httpApiUrl = USE_TESTNET ? TESTNET_API : MAINNET_API;
const httpApiPublic = USE_TESTNET ? TESTNET_API : MAINNET_API_PUBLIC;
const wssApiUrl = USE_TESTNET ? TESTNET_WEBSOCKET : MAINNET_WEBSOCKET;
let wsProvider = null;
let apiProvider = null;
let apiPublicProvider = null;
let retries = 0;
let autoReconnect = true;
const connectProvider = async onConnect => {
try {
autoReconnect = true;
if (httpApiUrl && !apiProvider) {
let apiConnectInfo = httpApiUrl;
if (MAINNET_PASS && MAINNET_USER && !USE_TESTNET) {
apiConnectInfo = {
url: MAINNET_API,
user: MAINNET_USER,
password: MAINNET_PASS
};
}
apiProvider = new ethers.providers.StaticJsonRpcProvider(apiConnectInfo);
await apiProvider.ready;
console.log('π₯ Http provider info:', apiConnectInfo);
if (httpApiPublic) {
apiPublicProvider = new ethers.providers.StaticJsonRpcProvider(httpApiPublic);
console.log('π₯ Public http provider info:', httpApiPublic);
await apiPublicProvider.ready;
}
}
wsProvider = new ethers.providers.WebSocketProvider(wssApiUrl);
console.log('π₯ Ws provider info:', wssApiUrl);
keepAlive({ onConnect });
await wsProvider.ready;
retries = 0;
} catch (e) {
console.log('Error while connecting to provider.');
console.log('π₯', e);
if (retries < 5) {
retries += 1;
console.log('π₯', 'Retrying connecting to provider');
connectProvider(onConnect);
}
}
};
const keepAlive = ({ onDisconnect, onConnect, expectedPongBack = 15000, checkInterval = 7500 }) => {
let pingTimeout = null;
let keepAliveInterval = null;
wsProvider._websocket.on('open', () => {
console.log('π₯', 'Sockets connected.');
onConnect && onConnect();
keepAliveInterval = setInterval(() => {
wsProvider._websocket.ping();
// Use `WebSocket#terminate()`, which immediately destroys the connection,
// instead of `WebSocket#close()`, which waits for the close timer.
// Delay should be equal to the interval at which your server
// sends out pings plus a conservative assumption of the latency.
pingTimeout = setTimeout(() => {
wsProvider._websocket.terminate();
}, expectedPongBack);
}, checkInterval);
});
wsProvider._websocket.on('close', err => {
if (keepAliveInterval) {
clearInterval(keepAliveInterval);
}
if (pingTimeout) {
clearTimeout(pingTimeout);
}
wsProvider = null;
onDisconnect && onDisconnect(err);
if (autoReconnect) {
console.log('π₯', 'Sockets disconnected, reconnecting...');
connectProvider(onConnect);
}
});
wsProvider._websocket.on('pong', () => {
if (pingTimeout) {
clearInterval(pingTimeout);
}
});
};
const disconnectSockets = () => {
console.log('π₯', 'Manually shutting down sockets.');
autoReconnect = false;
try {
wsProvider._websocket.terminate();
// eslint-disable-next-line no-empty
} catch (e) {}
};
const getHttpProvider = () => {
if (!apiProvider) {
console.log('π₯', 'Trying to use api provider that is not initialized!');
}
return apiProvider;
};
const getPublicHttpProvider = () => {
if (!apiPublicProvider) {
console.log('π₯', 'Trying to use public api provider that is not initialized!');
return getHttpProvider();
}
return apiPublicProvider;
};
const getWsProvider = () => {
if (!wsProvider) {
console.log('π₯', 'Trying to use wss provider that is not initialized!');
}
return wsProvider;
};
const getProvider = (connectionType = 'wss') => {
if (connectionType === 'public') {
const apiProvider = getPublicHttpProvider();
if (apiProvider) {
return apiProvider;
}
}
if (connectionType === 'http') {
const apiProvider = getHttpProvider();
if (apiProvider) {
return apiProvider;
}
}
return getWsProvider();
};
module.exports = { getProvider, connectProvider, disconnectSockets };