@corpus-core/colibri-stateless 0.2.1 → 0.2.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/c4w.js +1 -1
- package/connectionState.d.ts +23 -0
- package/connectionState.js +109 -0
- package/eventEmitter.d.ts +6 -0
- package/eventEmitter.js +28 -0
- package/index.d.ts +13 -44
- package/index.js +95 -32
- package/package.json +1 -1
- package/subscriptionManager.d.ts +35 -0
- package/subscriptionManager.js +289 -0
- package/types.d.ts +50 -0
- package/types.js +45 -0
- package/server.d.ts +0 -8
- package/server.js +0 -177
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EventEmitter } from './eventEmitter.js';
|
|
2
|
+
import { ProviderRpcError } from './types.js';
|
|
3
|
+
interface ConnectionStateConfig {
|
|
4
|
+
chainId: number;
|
|
5
|
+
debug?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class ConnectionState {
|
|
8
|
+
private _isConnected;
|
|
9
|
+
private _currentChainId;
|
|
10
|
+
private _initialConnectionAttempted;
|
|
11
|
+
private config;
|
|
12
|
+
private fetchRpcChainIdCallback;
|
|
13
|
+
private eventEmitter;
|
|
14
|
+
private formatChainIdFunc;
|
|
15
|
+
constructor(config: ConnectionStateConfig, fetchRpcChainIdCallback: () => Promise<any>, eventEmitter: EventEmitter, formatChainIdFunc: (value: any, debug?: boolean) => string | null);
|
|
16
|
+
get isConnected(): boolean;
|
|
17
|
+
get currentChainId(): string | null;
|
|
18
|
+
get initialConnectionAttempted(): boolean;
|
|
19
|
+
attemptInitialConnection(): Promise<void>;
|
|
20
|
+
processSuccessfulRequest(requestMethod: string, requestResult: any): void;
|
|
21
|
+
processFailedRequest(error: ProviderRpcError): void;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ProviderRpcError } from './types.js';
|
|
2
|
+
export class ConnectionState {
|
|
3
|
+
_isConnected = false;
|
|
4
|
+
_currentChainId = null;
|
|
5
|
+
_initialConnectionAttempted = false;
|
|
6
|
+
config;
|
|
7
|
+
fetchRpcChainIdCallback;
|
|
8
|
+
eventEmitter;
|
|
9
|
+
formatChainIdFunc;
|
|
10
|
+
constructor(config, fetchRpcChainIdCallback, eventEmitter, formatChainIdFunc) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.fetchRpcChainIdCallback = fetchRpcChainIdCallback;
|
|
13
|
+
this.eventEmitter = eventEmitter;
|
|
14
|
+
this.formatChainIdFunc = formatChainIdFunc;
|
|
15
|
+
this._currentChainId = this.formatChainIdFunc(this.config.chainId, this.config.debug);
|
|
16
|
+
}
|
|
17
|
+
get isConnected() {
|
|
18
|
+
return this._isConnected;
|
|
19
|
+
}
|
|
20
|
+
get currentChainId() {
|
|
21
|
+
return this._currentChainId;
|
|
22
|
+
}
|
|
23
|
+
get initialConnectionAttempted() {
|
|
24
|
+
return this._initialConnectionAttempted;
|
|
25
|
+
}
|
|
26
|
+
async attemptInitialConnection() {
|
|
27
|
+
if (this._initialConnectionAttempted)
|
|
28
|
+
return;
|
|
29
|
+
this._initialConnectionAttempted = true;
|
|
30
|
+
if (this.config.debug) {
|
|
31
|
+
console.log('[CS] Attempting initial connection...');
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const result = await this.fetchRpcChainIdCallback();
|
|
35
|
+
const formattedChainId = this.formatChainIdFunc(result, this.config.debug);
|
|
36
|
+
if (formattedChainId) {
|
|
37
|
+
this._isConnected = true;
|
|
38
|
+
this._currentChainId = formattedChainId;
|
|
39
|
+
if (this.config.debug) {
|
|
40
|
+
console.log('[CS] Initial connection successful. ChainId:', this._currentChainId);
|
|
41
|
+
}
|
|
42
|
+
this.eventEmitter.emit('connect', { chainId: this._currentChainId });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this._isConnected = false;
|
|
46
|
+
if (this.config.debug) {
|
|
47
|
+
console.warn('[CS] Initial eth_chainId did not return a valid format or was null:', result, ". Client remains disconnected but uses configured chainId.");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this._isConnected = false;
|
|
53
|
+
if (this.config.debug) {
|
|
54
|
+
console.error('[CS] Initial connection check failed:', error);
|
|
55
|
+
if (error instanceof ProviderRpcError) {
|
|
56
|
+
console.error('[CS] ProviderRpcError during initial connection check:', error.code, error.message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
processSuccessfulRequest(requestMethod, requestResult) {
|
|
62
|
+
if (!this._isConnected) {
|
|
63
|
+
this._isConnected = true;
|
|
64
|
+
const updateAndEmitConnect = async () => {
|
|
65
|
+
let determinedChainId = null;
|
|
66
|
+
if (requestMethod === 'eth_chainId') {
|
|
67
|
+
determinedChainId = this.formatChainIdFunc(requestResult, this.config.debug);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
try {
|
|
71
|
+
const chainIdResult = await this.fetchRpcChainIdCallback();
|
|
72
|
+
determinedChainId = this.formatChainIdFunc(chainIdResult, this.config.debug);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
if (this.config.debug)
|
|
76
|
+
console.warn('[CS] Failed to fetch chainId for connect event, using current _currentChainId as fallback.', e);
|
|
77
|
+
determinedChainId = this._currentChainId;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this._currentChainId = determinedChainId || this.formatChainIdFunc(this.config.chainId, this.config.debug);
|
|
81
|
+
this.eventEmitter.emit('connect', { chainId: this._currentChainId });
|
|
82
|
+
};
|
|
83
|
+
updateAndEmitConnect().catch(err => {
|
|
84
|
+
if (this.config.debug)
|
|
85
|
+
console.error("[CS] Error during background processing for connect event:", err);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else if (requestMethod === 'eth_chainId') {
|
|
89
|
+
const newChainId = this.formatChainIdFunc(requestResult, this.config.debug);
|
|
90
|
+
if (newChainId && this._currentChainId !== newChainId) {
|
|
91
|
+
const oldChainId = this._currentChainId;
|
|
92
|
+
this._currentChainId = newChainId;
|
|
93
|
+
if (this.config.debug) {
|
|
94
|
+
console.log('[CS] ChainId changed from', oldChainId, 'to', this._currentChainId);
|
|
95
|
+
}
|
|
96
|
+
this.eventEmitter.emit('chainChanged', this._currentChainId);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
processFailedRequest(error) {
|
|
101
|
+
if (error.code === 4900 && this._isConnected) {
|
|
102
|
+
this._isConnected = false;
|
|
103
|
+
if (this.config.debug) {
|
|
104
|
+
console.log('[CS] Disconnected due to error 4900.');
|
|
105
|
+
}
|
|
106
|
+
this.eventEmitter.emit('disconnect', error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
package/eventEmitter.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export class EventEmitter {
|
|
2
|
+
listeners = {};
|
|
3
|
+
on(event, callback) {
|
|
4
|
+
if (!this.listeners[event]) {
|
|
5
|
+
this.listeners[event] = [];
|
|
6
|
+
}
|
|
7
|
+
this.listeners[event].push(callback);
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
removeListener(event, callback) {
|
|
11
|
+
if (this.listeners[event]) {
|
|
12
|
+
this.listeners[event] = this.listeners[event].filter(listener => listener !== callback);
|
|
13
|
+
}
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
emit(event, data) {
|
|
17
|
+
if (this.listeners[event]) {
|
|
18
|
+
this.listeners[event].forEach(listener => {
|
|
19
|
+
try {
|
|
20
|
+
listener(data);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
console.error(`Error in event listener for ${event}:`, e);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1,44 +1,14 @@
|
|
|
1
1
|
import { Storage as C4Storage } from "./wasm.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
interface RequestArguments {
|
|
8
|
-
readonly method: string;
|
|
9
|
-
readonly params?: readonly unknown[] | object;
|
|
10
|
-
}
|
|
11
|
-
export interface Config {
|
|
12
|
-
chainId: number;
|
|
13
|
-
beacon_apis: string[];
|
|
14
|
-
rpcs: string[];
|
|
15
|
-
proofer?: string[];
|
|
16
|
-
trusted_block_hashes: string[];
|
|
17
|
-
cache?: Cache;
|
|
18
|
-
debug?: boolean;
|
|
19
|
-
include_code?: boolean;
|
|
20
|
-
verify?: (method: string, args: any[]) => boolean;
|
|
21
|
-
}
|
|
22
|
-
export interface DataRequest {
|
|
23
|
-
method: string;
|
|
24
|
-
chain_id: number;
|
|
25
|
-
encoding: string;
|
|
26
|
-
type: string;
|
|
27
|
-
exclude_mask: number;
|
|
28
|
-
url: string;
|
|
29
|
-
payload: any;
|
|
30
|
-
req_ptr: number;
|
|
31
|
-
}
|
|
32
|
-
export declare enum MethodType {
|
|
33
|
-
PROOFABLE = 1,
|
|
34
|
-
UNPROOFABLE = 2,
|
|
35
|
-
NOT_SUPPORTED = 3,
|
|
36
|
-
LOCAL = 4
|
|
37
|
-
}
|
|
38
|
-
export declare function handle_request(req: DataRequest, conf: Config): Promise<void>;
|
|
2
|
+
import { ProviderRpcError, RequestArguments, Cache, Config as C4Config, DataRequest, MethodType as C4MethodType, ProviderMessage } from './types.js';
|
|
3
|
+
import { EthSubscribeSubscriptionType, EthNewFilterType } from './subscriptionManager.js';
|
|
4
|
+
export { ProviderRpcError, RequestArguments, Cache, C4Config, DataRequest, C4MethodType as MethodType, ProviderMessage, EthSubscribeSubscriptionType, EthNewFilterType };
|
|
5
|
+
export declare function handle_request(req: DataRequest, conf: C4Config): Promise<void>;
|
|
39
6
|
export default class C4Client {
|
|
40
|
-
config:
|
|
41
|
-
|
|
7
|
+
config: C4Config;
|
|
8
|
+
private eventEmitter;
|
|
9
|
+
private connectionState;
|
|
10
|
+
private subscriptionManager;
|
|
11
|
+
constructor(config?: Partial<C4Config>);
|
|
42
12
|
private getProoferConfig;
|
|
43
13
|
private get flags();
|
|
44
14
|
/**
|
|
@@ -46,7 +16,7 @@ export default class C4Client {
|
|
|
46
16
|
* @param method - The method to check
|
|
47
17
|
* @returns The method type
|
|
48
18
|
*/
|
|
49
|
-
getMethodSupport(method: string): Promise<
|
|
19
|
+
getMethodSupport(method: string): Promise<C4MethodType>;
|
|
50
20
|
/**
|
|
51
21
|
* creates a proof for the given method and arguments
|
|
52
22
|
* @param method - The method to create a proof for
|
|
@@ -73,8 +43,7 @@ export default class C4Client {
|
|
|
73
43
|
*/
|
|
74
44
|
rpc(method: string, args: any[]): Promise<any>;
|
|
75
45
|
static register_storage(storage: C4Storage): Promise<void>;
|
|
76
|
-
request(args: RequestArguments): Promise<
|
|
77
|
-
on(event: string, callback: (data: any) => void):
|
|
78
|
-
removeListener(event: string, callback: (data: any) => void):
|
|
46
|
+
request(args: RequestArguments): Promise<unknown>;
|
|
47
|
+
on(event: string, callback: (data: any) => void): this;
|
|
48
|
+
removeListener(event: string, callback: (data: any) => void): this;
|
|
79
49
|
}
|
|
80
|
-
export {};
|
package/index.js
CHANGED
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
// Import the Emscripten-generated module
|
|
2
2
|
import { as_bytes, as_char_ptr, as_json, copy_to_c, getC4w } from "./wasm.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
import { EventEmitter } from './eventEmitter.js';
|
|
4
|
+
import { ConnectionState } from './connectionState.js';
|
|
5
|
+
import { ProviderRpcError, MethodType as C4MethodType } from './types.js';
|
|
6
|
+
import { SubscriptionManager } from './subscriptionManager.js';
|
|
7
|
+
// Re-export types needed by consumers of the C4Client module
|
|
8
|
+
export { ProviderRpcError, C4MethodType as MethodType };
|
|
9
|
+
// Helper function for chain ID formatting (can be used by ConnectionManager and C4Client)
|
|
10
|
+
function formatChainId(value, debug) {
|
|
11
|
+
if (typeof value === 'string') {
|
|
12
|
+
if (value.startsWith('0x')) {
|
|
13
|
+
return value.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
const parsed = parseInt(value, 10);
|
|
16
|
+
if (!isNaN(parsed)) {
|
|
17
|
+
return '0x' + parsed.toString(16);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (typeof value === 'number') {
|
|
21
|
+
return '0x' + value.toString(16);
|
|
22
|
+
}
|
|
23
|
+
if (debug) {
|
|
24
|
+
console.warn('Could not format chainId:', value);
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
13
27
|
}
|
|
14
28
|
async function fetch_rpc(urls, payload, as_proof = false) {
|
|
15
29
|
let last_error = "All nodes failed";
|
|
16
30
|
for (const url of urls) {
|
|
31
|
+
console.log({ url, payload });
|
|
17
32
|
const response = await fetch(url, {
|
|
18
33
|
method: 'POST',
|
|
19
34
|
body: JSON.stringify({ id: 1, jsonrpc: "2.0", ...payload }),
|
|
@@ -111,23 +126,38 @@ function check_trusted_blockhashes(trusted_block_hashes, c4w, chainId) {
|
|
|
111
126
|
}
|
|
112
127
|
export default class C4Client {
|
|
113
128
|
config;
|
|
129
|
+
eventEmitter;
|
|
130
|
+
connectionState;
|
|
131
|
+
subscriptionManager;
|
|
114
132
|
constructor(config) {
|
|
115
133
|
this.config = {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
...
|
|
134
|
+
// Defaults including pollingInterval if not provided
|
|
135
|
+
chainId: 1,
|
|
136
|
+
beacon_apis: ["https://lodestar-mainnet.chainsafe.io"],
|
|
137
|
+
rpcs: ["https://rpc.ankr.com/eth"],
|
|
138
|
+
trusted_block_hashes: [],
|
|
139
|
+
proofer: ["https://mainnet.colibri-proof.tech"],
|
|
140
|
+
pollingInterval: 12000, // Default here, can be overridden by user config
|
|
141
|
+
// ... other defaults like debug: false etc. might be useful
|
|
142
|
+
...config // User config overrides defaults
|
|
124
143
|
};
|
|
144
|
+
this.eventEmitter = new EventEmitter();
|
|
145
|
+
// Specific callback for ConnectionState for eth_chainId
|
|
146
|
+
const fetchChainIdForConnectionState = async () => this.rpc('eth_chainId', []);
|
|
147
|
+
// General RpcCaller for SubscriptionManager
|
|
148
|
+
const generalRpcCaller = async (method, params) => {
|
|
149
|
+
return this.rpc(method, params);
|
|
150
|
+
};
|
|
151
|
+
this.connectionState = new ConnectionState({ chainId: this.config.chainId, debug: this.config.debug }, fetchChainIdForConnectionState, // Use the specific callback
|
|
152
|
+
this.eventEmitter, formatChainId);
|
|
153
|
+
this.subscriptionManager = new SubscriptionManager(generalRpcCaller, // Use the general rpc caller
|
|
154
|
+
this.eventEmitter, { debug: this.config.debug, pollingInterval: this.config.pollingInterval });
|
|
125
155
|
}
|
|
126
156
|
async getProoferConfig() {
|
|
127
157
|
const c4w = await getC4w();
|
|
128
158
|
if (!c4w.storage)
|
|
129
159
|
return '0x';
|
|
130
|
-
const state = c4w.storage.get('
|
|
160
|
+
const state = c4w.storage.get('states_' + this.config.chainId);
|
|
131
161
|
return '0x' + (state ? Array.from(state).map(_ => _.toString(16).padStart(2, '0')).join('') : '');
|
|
132
162
|
}
|
|
133
163
|
get flags() {
|
|
@@ -224,36 +254,69 @@ export default class C4Client {
|
|
|
224
254
|
* @returns The result
|
|
225
255
|
*/
|
|
226
256
|
async rpc(method, args) {
|
|
257
|
+
// eth_subscribe and eth_unsubscribe are handled by C4Client.request before this method is called.
|
|
258
|
+
// This rpc method is for the underlying data fetching/proving.
|
|
227
259
|
const method_type = await this.getMethodSupport(method);
|
|
228
|
-
let proof = new Uint8Array();
|
|
229
260
|
switch (method_type) {
|
|
230
|
-
case
|
|
231
|
-
if (this.config.verify && !this.config.verify(method, args))
|
|
261
|
+
case C4MethodType.PROOFABLE: {
|
|
262
|
+
if (this.config.verify && !this.config.verify(method, args)) {
|
|
232
263
|
return await fetch_rpc(this.config.rpcs, { method, params: args }, false);
|
|
233
|
-
|
|
264
|
+
}
|
|
265
|
+
const proof = this.config.proofer && this.config.proofer.length
|
|
234
266
|
? await fetch_rpc(this.config.proofer, { method, params: args, c4: await this.getProoferConfig() }, true)
|
|
235
267
|
: await this.createProof(method, args);
|
|
236
|
-
|
|
268
|
+
return this.verifyProof(method, args, proof);
|
|
237
269
|
}
|
|
238
|
-
case
|
|
270
|
+
case C4MethodType.UNPROOFABLE:
|
|
239
271
|
return await fetch_rpc(this.config.rpcs, { method, params: args }, false);
|
|
240
|
-
case
|
|
241
|
-
throw new
|
|
242
|
-
case
|
|
243
|
-
|
|
272
|
+
case C4MethodType.NOT_SUPPORTED:
|
|
273
|
+
throw new ProviderRpcError(4200, `Method ${method} is not supported by C4Client.rpc core`);
|
|
274
|
+
case C4MethodType.LOCAL:
|
|
275
|
+
return this.verifyProof(method, args, new Uint8Array());
|
|
244
276
|
}
|
|
245
|
-
|
|
277
|
+
// Should be unreachable if MethodType enum is comprehensive and handled
|
|
278
|
+
throw new ProviderRpcError(-32603, `Internal error: Unhandled method type for ${method} in C4Client.rpc core`);
|
|
246
279
|
}
|
|
247
280
|
static async register_storage(storage) {
|
|
248
281
|
const c4w = await getC4w();
|
|
249
282
|
c4w.storage = storage;
|
|
250
283
|
}
|
|
251
284
|
async request(args) {
|
|
252
|
-
|
|
253
|
-
|
|
285
|
+
if (!this.connectionState.initialConnectionAttempted) {
|
|
286
|
+
await this.connectionState.attemptInitialConnection();
|
|
287
|
+
}
|
|
288
|
+
const { method, params } = args;
|
|
289
|
+
const paramsArray = Array.isArray(params) ? params : (params ? [params] : []);
|
|
290
|
+
// Attempt to handle with SubscriptionManager first
|
|
291
|
+
const subscriptionResult = this.subscriptionManager.handleRequest(method, paramsArray);
|
|
292
|
+
if (subscriptionResult !== null) {
|
|
293
|
+
// If handleRequest returns a Promise, it means it's handling the request
|
|
294
|
+
return subscriptionResult;
|
|
295
|
+
}
|
|
296
|
+
// If not handled by SubscriptionManager, proceed with standard RPC call logic
|
|
297
|
+
try {
|
|
298
|
+
const result = await this.rpc(method, paramsArray);
|
|
299
|
+
this.connectionState.processSuccessfulRequest(method, result);
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
const providerError = ProviderRpcError.createError(error);
|
|
304
|
+
this.connectionState.processFailedRequest(providerError);
|
|
305
|
+
throw providerError;
|
|
306
|
+
}
|
|
254
307
|
}
|
|
255
308
|
on(event, callback) {
|
|
309
|
+
this.eventEmitter.on(event, callback);
|
|
310
|
+
if ((event === 'connect' || event === 'disconnect') && !this.connectionState.initialConnectionAttempted) {
|
|
311
|
+
this.connectionState.attemptInitialConnection().catch(err => {
|
|
312
|
+
if (this.config.debug)
|
|
313
|
+
console.error("[C4Client] Error during lazy initial connection attempt triggered by 'on':", err);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return this;
|
|
256
317
|
}
|
|
257
318
|
removeListener(event, callback) {
|
|
319
|
+
this.eventEmitter.removeListener(event, callback);
|
|
320
|
+
return this;
|
|
258
321
|
}
|
|
259
322
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corpus-core/colibri-stateless",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Colibri is a stateless and trustless ethereum client, which is optimized for the mobile apps or embedded devices, because it does not hols the state, but verifies on demand.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EventEmitter } from './eventEmitter.js';
|
|
2
|
+
export type EthSubscribeSubscriptionType = 'newHeads' | 'logs';
|
|
3
|
+
export type EthNewFilterType = 'block' | 'pendingTransaction' | 'log';
|
|
4
|
+
export interface Subscription {
|
|
5
|
+
id: string;
|
|
6
|
+
subscriptionMethod: 'eth_subscribe' | 'eth_newFilter';
|
|
7
|
+
kind: EthSubscribeSubscriptionType | EthNewFilterType;
|
|
8
|
+
params?: any;
|
|
9
|
+
lastPolledBlockNumber?: bigint;
|
|
10
|
+
timeoutId?: number;
|
|
11
|
+
}
|
|
12
|
+
interface SubscriptionManagerConfig {
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
pollingInterval?: number;
|
|
15
|
+
}
|
|
16
|
+
export type RpcCaller = (method: string, params: any[]) => Promise<any>;
|
|
17
|
+
export declare class SubscriptionManager {
|
|
18
|
+
private activeSubscriptions;
|
|
19
|
+
private eventEmitter;
|
|
20
|
+
private rpcCall;
|
|
21
|
+
private config;
|
|
22
|
+
private nextSubscriptionId;
|
|
23
|
+
constructor(rpcCallCallback: RpcCaller, eventEmitter: EventEmitter, config?: SubscriptionManagerConfig);
|
|
24
|
+
handleRequest(method: string, paramsArray: any[]): Promise<any> | null;
|
|
25
|
+
private generateSubscriptionId;
|
|
26
|
+
subscribe(kind: EthSubscribeSubscriptionType, params?: any[]): Promise<string>;
|
|
27
|
+
newFilter(kind: EthNewFilterType, params?: any[]): Promise<string>;
|
|
28
|
+
getFilterChanges(filterId: string): Promise<any[]>;
|
|
29
|
+
uninstallFilter(filterId: string): Promise<boolean>;
|
|
30
|
+
private executePollLogic;
|
|
31
|
+
private schedulePoll;
|
|
32
|
+
private pollSubscriptionAndEmit;
|
|
33
|
+
unsubscribe(subscriptionId: string): Promise<boolean>;
|
|
34
|
+
}
|
|
35
|
+
export {};
|