@drift-labs/sdk 2.96.0-beta.1 → 2.96.0-beta.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/VERSION +1 -1
- package/lib/accounts/types.d.ts +0 -8
- package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +3 -3
- package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +1 -1
- package/lib/driftClient.js +14 -35
- package/lib/driftClientConfig.d.ts +0 -6
- package/lib/events/eventSubscriber.d.ts +7 -0
- package/lib/events/eventSubscriber.js +69 -32
- package/lib/events/eventsServerLogProvider.d.ts +21 -0
- package/lib/events/eventsServerLogProvider.js +121 -0
- package/lib/events/pollingLogProvider.js +1 -1
- package/lib/events/types.d.ts +12 -5
- package/lib/events/types.js +5 -1
- package/lib/events/webSocketLogProvider.js +2 -2
- package/lib/orderSubscriber/OrderSubscriber.d.ts +1 -2
- package/lib/orderSubscriber/OrderSubscriber.js +4 -19
- package/lib/orderSubscriber/types.d.ts +0 -9
- package/lib/user.js +4 -11
- package/lib/userConfig.d.ts +1 -6
- package/lib/userMap/userMap.js +0 -14
- package/lib/userMap/userMapConfig.d.ts +0 -7
- package/lib/userStatsConfig.d.ts +0 -6
- package/package.json +1 -3
- package/src/accounts/types.ts +0 -9
- package/src/accounts/webSocketAccountSubscriber.ts +1 -1
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +3 -3
- package/src/accounts/webSocketProgramAccountSubscriber.ts +1 -1
- package/src/driftClient.ts +0 -28
- package/src/driftClientConfig.ts +0 -7
- package/src/events/eventSubscriber.ts +125 -54
- package/src/events/eventsServerLogProvider.ts +152 -0
- package/src/events/pollingLogProvider.ts +1 -1
- package/src/events/types.ts +29 -6
- package/src/events/webSocketLogProvider.ts +4 -4
- package/src/orderSubscriber/OrderSubscriber.ts +1 -15
- package/src/orderSubscriber/types.ts +0 -10
- package/src/user.ts +0 -11
- package/src/userConfig.ts +1 -7
- package/src/userMap/userMap.ts +1 -17
- package/src/userMap/userMapConfig.ts +0 -8
- package/src/userStatsConfig.ts +0 -7
- package/lib/accounts/grpcAccountSubscriber.d.ts +0 -16
- package/lib/accounts/grpcAccountSubscriber.js +0 -155
- package/lib/accounts/grpcDriftClientAccountSubscriber.d.ts +0 -13
- package/lib/accounts/grpcDriftClientAccountSubscriber.js +0 -96
- package/lib/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +0 -10
- package/lib/accounts/grpcInsuranceFundStakeAccountSubscriber.js +0 -30
- package/lib/accounts/grpcProgramAccountSubscriber.d.ts +0 -19
- package/lib/accounts/grpcProgramAccountSubscriber.js +0 -161
- package/lib/accounts/grpcUserAccountSubscriber.d.ts +0 -10
- package/lib/accounts/grpcUserAccountSubscriber.js +0 -28
- package/lib/accounts/grpcUserStatsAccountSubscriber.d.ts +0 -10
- package/lib/accounts/grpcUserStatsAccountSubscriber.js +0 -28
- package/lib/orderSubscriber/grpcSubscription.d.ts +0 -25
- package/lib/orderSubscriber/grpcSubscription.js +0 -68
- package/lib/userMap/grpcSubscription.d.ts +0 -26
- package/lib/userMap/grpcSubscription.js +0 -42
- package/src/accounts/grpcAccountSubscriber.ts +0 -158
- package/src/accounts/grpcDriftClientAccountSubscriber.ts +0 -196
- package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -62
- package/src/accounts/grpcProgramAccountSubscriber.ts +0 -181
- package/src/accounts/grpcUserAccountSubscriber.ts +0 -48
- package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -51
- package/src/orderSubscriber/grpcSubscription.ts +0 -126
- package/src/userMap/grpcSubscription.ts +0 -83
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// import WebSocket from 'ws';
|
|
2
|
+
import { logProviderCallback, EventType, LogProvider } from './types';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
|
|
5
|
+
// browser support
|
|
6
|
+
let WebSocketImpl: typeof WebSocket;
|
|
7
|
+
if (typeof window !== 'undefined' && window.WebSocket) {
|
|
8
|
+
WebSocketImpl = window.WebSocket;
|
|
9
|
+
} else {
|
|
10
|
+
WebSocketImpl = require('ws');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const EVENT_SERVER_HEARTBEAT_INTERVAL_MS = 5000;
|
|
14
|
+
const ALLOWED_MISSED_HEARTBEATS = 3;
|
|
15
|
+
|
|
16
|
+
export class EventsServerLogProvider implements LogProvider {
|
|
17
|
+
private ws?: WebSocket;
|
|
18
|
+
private callback?: logProviderCallback;
|
|
19
|
+
private isUnsubscribing = false;
|
|
20
|
+
private externalUnsubscribe = false;
|
|
21
|
+
private lastHeartbeat = 0;
|
|
22
|
+
private timeoutId?: NodeJS.Timeout;
|
|
23
|
+
private reconnectAttempts = 0;
|
|
24
|
+
eventEmitter?: EventEmitter;
|
|
25
|
+
|
|
26
|
+
public constructor(
|
|
27
|
+
private readonly url: string,
|
|
28
|
+
private readonly eventTypes: EventType[],
|
|
29
|
+
private readonly userAccount?: string
|
|
30
|
+
) {
|
|
31
|
+
this.eventEmitter = new EventEmitter();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public isSubscribed(): boolean {
|
|
35
|
+
return this.ws !== undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public async subscribe(callback: logProviderCallback): Promise<boolean> {
|
|
39
|
+
if (this.ws !== undefined) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
this.ws = new WebSocketImpl(this.url);
|
|
43
|
+
|
|
44
|
+
this.callback = callback;
|
|
45
|
+
this.ws.addEventListener('open', () => {
|
|
46
|
+
for (const channel of this.eventTypes) {
|
|
47
|
+
const subscribeMessage = {
|
|
48
|
+
type: 'subscribe',
|
|
49
|
+
channel: channel,
|
|
50
|
+
};
|
|
51
|
+
if (this.userAccount) {
|
|
52
|
+
subscribeMessage['user'] = this.userAccount;
|
|
53
|
+
}
|
|
54
|
+
this.ws.send(JSON.stringify(subscribeMessage));
|
|
55
|
+
}
|
|
56
|
+
this.reconnectAttempts = 0;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
this.ws.addEventListener('message', (data) => {
|
|
60
|
+
try {
|
|
61
|
+
if (!this.isUnsubscribing) {
|
|
62
|
+
clearTimeout(this.timeoutId);
|
|
63
|
+
this.setTimeout();
|
|
64
|
+
if (this.reconnectAttempts > 0) {
|
|
65
|
+
console.log(
|
|
66
|
+
'eventsServerLogProvider: Resetting reconnect attempts to 0'
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
this.reconnectAttempts = 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const parsedData = JSON.parse(data.data.toString());
|
|
73
|
+
if (parsedData.channel === 'heartbeat') {
|
|
74
|
+
this.lastHeartbeat = Date.now();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (parsedData.message !== undefined) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const event = JSON.parse(parsedData.data);
|
|
81
|
+
this.callback(
|
|
82
|
+
event.txSig,
|
|
83
|
+
event.slot,
|
|
84
|
+
[
|
|
85
|
+
'Program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH invoke [1]',
|
|
86
|
+
event.rawLog,
|
|
87
|
+
'Program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH success',
|
|
88
|
+
],
|
|
89
|
+
undefined,
|
|
90
|
+
event.txSigIndex
|
|
91
|
+
);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error('Error parsing message:', error);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
this.ws.addEventListener('close', () => {
|
|
98
|
+
console.log('eventsServerLogProvider: WebSocket closed');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this.ws.addEventListener('error', (error) => {
|
|
102
|
+
console.error('eventsServerLogProvider: WebSocket error:', error);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
this.setTimeout();
|
|
106
|
+
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public async unsubscribe(external = false): Promise<boolean> {
|
|
111
|
+
this.isUnsubscribing = true;
|
|
112
|
+
this.externalUnsubscribe = external;
|
|
113
|
+
if (this.timeoutId) {
|
|
114
|
+
clearInterval(this.timeoutId);
|
|
115
|
+
this.timeoutId = undefined;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (this.ws !== undefined) {
|
|
119
|
+
this.ws.close();
|
|
120
|
+
this.ws = undefined;
|
|
121
|
+
return true;
|
|
122
|
+
} else {
|
|
123
|
+
this.isUnsubscribing = false;
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private setTimeout(): void {
|
|
129
|
+
this.timeoutId = setTimeout(async () => {
|
|
130
|
+
if (this.isUnsubscribing || this.externalUnsubscribe) {
|
|
131
|
+
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeat;
|
|
136
|
+
if (
|
|
137
|
+
timeSinceLastHeartbeat >
|
|
138
|
+
EVENT_SERVER_HEARTBEAT_INTERVAL_MS * ALLOWED_MISSED_HEARTBEATS
|
|
139
|
+
) {
|
|
140
|
+
console.log(
|
|
141
|
+
`eventServerLogProvider: No heartbeat in ${timeSinceLastHeartbeat}ms, resubscribing on attempt ${
|
|
142
|
+
this.reconnectAttempts + 1
|
|
143
|
+
}`
|
|
144
|
+
);
|
|
145
|
+
await this.unsubscribe();
|
|
146
|
+
this.reconnectAttempts++;
|
|
147
|
+
this.eventEmitter.emit('reconnect', this.reconnectAttempts);
|
|
148
|
+
this.subscribe(this.callback);
|
|
149
|
+
}
|
|
150
|
+
}, EVENT_SERVER_HEARTBEAT_INTERVAL_MS * 2);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -60,7 +60,7 @@ export class PollingLogProvider implements LogProvider {
|
|
|
60
60
|
const { mostRecentTx, transactionLogs } = response;
|
|
61
61
|
|
|
62
62
|
for (const { txSig, slot, logs } of transactionLogs) {
|
|
63
|
-
callback(txSig, slot, logs, response.mostRecentBlockTime);
|
|
63
|
+
callback(txSig, slot, logs, response.mostRecentBlockTime, undefined);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
this.mostRecentSeenTx = mostRecentTx;
|
package/src/events/types.ts
CHANGED
|
@@ -56,7 +56,11 @@ export const DefaultEventSubscriptionOptions: EventSubscriptionOptions = {
|
|
|
56
56
|
commitment: 'confirmed',
|
|
57
57
|
maxTx: 4096,
|
|
58
58
|
logProviderConfig: {
|
|
59
|
-
type: '
|
|
59
|
+
type: 'events-server',
|
|
60
|
+
url: 'wss://events.drift.trade/ws',
|
|
61
|
+
maxReconnectAttempts: 5,
|
|
62
|
+
fallbackFrequency: 1000,
|
|
63
|
+
fallbackBatchSize: 100,
|
|
60
64
|
},
|
|
61
65
|
};
|
|
62
66
|
|
|
@@ -126,7 +130,8 @@ export type logProviderCallback = (
|
|
|
126
130
|
txSig: TransactionSignature,
|
|
127
131
|
slot: number,
|
|
128
132
|
logs: string[],
|
|
129
|
-
mostRecentBlockTime: number | undefined
|
|
133
|
+
mostRecentBlockTime: number | undefined,
|
|
134
|
+
txSigIndex: number | undefined
|
|
130
135
|
) => void;
|
|
131
136
|
|
|
132
137
|
export interface LogProvider {
|
|
@@ -139,20 +144,38 @@ export interface LogProvider {
|
|
|
139
144
|
eventEmitter?: EventEmitter;
|
|
140
145
|
}
|
|
141
146
|
|
|
142
|
-
export type
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
export type LogProviderType = 'websocket' | 'polling' | 'events-server';
|
|
148
|
+
|
|
149
|
+
export type StreamingLogProviderConfig = {
|
|
150
|
+
/// Max number of times to try reconnecting before failing over to fallback provider
|
|
145
151
|
maxReconnectAttempts?: number;
|
|
152
|
+
/// used for PollingLogProviderConfig on fallback
|
|
146
153
|
fallbackFrequency?: number;
|
|
154
|
+
/// used for PollingLogProviderConfig on fallback
|
|
147
155
|
fallbackBatchSize?: number;
|
|
148
156
|
};
|
|
149
157
|
|
|
158
|
+
export type WebSocketLogProviderConfig = StreamingLogProviderConfig & {
|
|
159
|
+
type: 'websocket';
|
|
160
|
+
/// Max time to wait before resubscribing
|
|
161
|
+
resubTimeoutMs?: number;
|
|
162
|
+
};
|
|
163
|
+
|
|
150
164
|
export type PollingLogProviderConfig = {
|
|
151
165
|
type: 'polling';
|
|
166
|
+
/// frequency to poll for new events
|
|
152
167
|
frequency: number;
|
|
168
|
+
/// max number of events to fetch per poll
|
|
153
169
|
batchSize?: number;
|
|
154
170
|
};
|
|
155
171
|
|
|
172
|
+
export type EventsServerLogProviderConfig = StreamingLogProviderConfig & {
|
|
173
|
+
type: 'events-server';
|
|
174
|
+
/// url of the events server
|
|
175
|
+
url: string;
|
|
176
|
+
};
|
|
177
|
+
|
|
156
178
|
export type LogProviderConfig =
|
|
157
179
|
| WebSocketLogProviderConfig
|
|
158
|
-
| PollingLogProviderConfig
|
|
180
|
+
| PollingLogProviderConfig
|
|
181
|
+
| EventsServerLogProviderConfig;
|
|
@@ -64,7 +64,7 @@ export class WebSocketLogProvider implements LogProvider {
|
|
|
64
64
|
if (logs.err !== null) {
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
|
-
callback(logs.signature, ctx.slot, logs.logs, undefined);
|
|
67
|
+
callback(logs.signature, ctx.slot, logs.logs, undefined, undefined);
|
|
68
68
|
},
|
|
69
69
|
this.commitment
|
|
70
70
|
);
|
|
@@ -106,9 +106,9 @@ export class WebSocketLogProvider implements LogProvider {
|
|
|
106
106
|
|
|
107
107
|
if (this.receivingData) {
|
|
108
108
|
console.log(
|
|
109
|
-
`No log data in ${
|
|
110
|
-
this.
|
|
111
|
-
}`
|
|
109
|
+
`webSocketLogProvider: No log data in ${
|
|
110
|
+
this.resubTimeoutMs
|
|
111
|
+
}ms, resubscribing on attempt ${this.reconnectAttempts + 1}`
|
|
112
112
|
);
|
|
113
113
|
await this.unsubscribe();
|
|
114
114
|
this.receivingData = false;
|
|
@@ -11,12 +11,11 @@ import StrictEventEmitter from 'strict-event-emitter-types';
|
|
|
11
11
|
import { EventEmitter } from 'events';
|
|
12
12
|
import { BN } from '../index';
|
|
13
13
|
import { decodeUser } from '../decode/user';
|
|
14
|
-
import { grpcSubscription } from './grpcSubscription';
|
|
15
14
|
|
|
16
15
|
export class OrderSubscriber {
|
|
17
16
|
driftClient: DriftClient;
|
|
18
17
|
usersAccounts = new Map<string, { slot: number; userAccount: UserAccount }>();
|
|
19
|
-
subscription: PollingSubscription | WebsocketSubscription
|
|
18
|
+
subscription: PollingSubscription | WebsocketSubscription;
|
|
20
19
|
commitment: Commitment;
|
|
21
20
|
eventEmitter: StrictEventEmitter<EventEmitter, OrderSubscriberEvents>;
|
|
22
21
|
|
|
@@ -35,19 +34,6 @@ export class OrderSubscriber {
|
|
|
35
34
|
orderSubscriber: this,
|
|
36
35
|
frequency: config.subscriptionConfig.frequency,
|
|
37
36
|
});
|
|
38
|
-
} else if (config.subscriptionConfig.type === 'grpc') {
|
|
39
|
-
this.subscription = new grpcSubscription({
|
|
40
|
-
grpcConfigs: config.subscriptionConfig.configs,
|
|
41
|
-
orderSubscriber: this,
|
|
42
|
-
commitment: this.commitment,
|
|
43
|
-
skipInitialLoad: config.subscriptionConfig.skipInitialLoad,
|
|
44
|
-
resubOpts: {
|
|
45
|
-
resubTimeoutMs: config.subscriptionConfig?.resubTimeoutMs,
|
|
46
|
-
logResubMessages: config.subscriptionConfig?.logResubMessages,
|
|
47
|
-
},
|
|
48
|
-
resyncIntervalMs: config.subscriptionConfig.resyncIntervalMs,
|
|
49
|
-
decoded: config.decodeData,
|
|
50
|
-
});
|
|
51
37
|
} else {
|
|
52
38
|
this.subscription = new WebsocketSubscription({
|
|
53
39
|
orderSubscriber: this,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { Order, UserAccount } from '../types';
|
|
3
3
|
import { DriftClient } from '../driftClient';
|
|
4
|
-
import { GrpcConfigs } from '../accounts/types';
|
|
5
4
|
|
|
6
5
|
export type OrderSubscriberConfig = {
|
|
7
6
|
driftClient: DriftClient;
|
|
@@ -11,15 +10,6 @@ export type OrderSubscriberConfig = {
|
|
|
11
10
|
frequency: number;
|
|
12
11
|
commitment?: Commitment;
|
|
13
12
|
}
|
|
14
|
-
| {
|
|
15
|
-
type: 'grpc';
|
|
16
|
-
skipInitialLoad?: boolean;
|
|
17
|
-
resubTimeoutMs?: number;
|
|
18
|
-
logResubMessages?: boolean;
|
|
19
|
-
resyncIntervalMs?: number;
|
|
20
|
-
configs: GrpcConfigs;
|
|
21
|
-
commitment?: Commitment;
|
|
22
|
-
}
|
|
23
13
|
| {
|
|
24
14
|
type: 'websocket';
|
|
25
15
|
skipInitialLoad?: boolean;
|
package/src/user.ts
CHANGED
|
@@ -98,7 +98,6 @@ import {
|
|
|
98
98
|
calculatePerpFuelBonus,
|
|
99
99
|
calculateInsuranceFuelBonus,
|
|
100
100
|
} from './math/fuel';
|
|
101
|
-
import { grpcUserAccountSubscriber } from './accounts/grpcUserAccountSubscriber';
|
|
102
101
|
|
|
103
102
|
export class User {
|
|
104
103
|
driftClient: DriftClient;
|
|
@@ -129,16 +128,6 @@ export class User {
|
|
|
129
128
|
);
|
|
130
129
|
} else if (config.accountSubscription?.type === 'custom') {
|
|
131
130
|
this.accountSubscriber = config.accountSubscription.userAccountSubscriber;
|
|
132
|
-
} else if (config.accountSubscription?.type === 'grpc') {
|
|
133
|
-
this.accountSubscriber = new grpcUserAccountSubscriber(
|
|
134
|
-
config.accountSubscription.configs,
|
|
135
|
-
config.driftClient.program,
|
|
136
|
-
config.userAccountPublicKey,
|
|
137
|
-
{
|
|
138
|
-
resubTimeoutMs: config.accountSubscription?.resubTimeoutMs,
|
|
139
|
-
logResubMessages: config.accountSubscription?.logResubMessages,
|
|
140
|
-
}
|
|
141
|
-
);
|
|
142
131
|
} else {
|
|
143
132
|
this.accountSubscriber = new WebSocketUserAccountSubscriber(
|
|
144
133
|
config.driftClient.program,
|
package/src/userConfig.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DriftClient } from './driftClient';
|
|
2
2
|
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
3
3
|
import { BulkAccountLoader } from './accounts/bulkAccountLoader';
|
|
4
|
-
import {
|
|
4
|
+
import { UserAccountSubscriber } from './accounts/types';
|
|
5
5
|
|
|
6
6
|
export type UserConfig = {
|
|
7
7
|
accountSubscription?: UserSubscriptionConfig;
|
|
@@ -23,10 +23,4 @@ export type UserSubscriptionConfig =
|
|
|
23
23
|
| {
|
|
24
24
|
type: 'custom';
|
|
25
25
|
userAccountSubscriber: UserAccountSubscriber;
|
|
26
|
-
}
|
|
27
|
-
| {
|
|
28
|
-
type: 'grpc';
|
|
29
|
-
resubTimeoutMs?: number;
|
|
30
|
-
logResubMessages?: boolean;
|
|
31
|
-
configs: GrpcConfigs;
|
|
32
26
|
};
|
package/src/userMap/userMap.ts
CHANGED
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
import { WebsocketSubscription } from './WebsocketSubscription';
|
|
37
37
|
import { PollingSubscription } from './PollingSubscription';
|
|
38
38
|
import { decodeUser } from '../decode/user';
|
|
39
|
-
import { grpcSubscription } from './grpcSubscription';
|
|
40
39
|
|
|
41
40
|
const MAX_USER_ACCOUNT_SIZE_BYTES = 4376;
|
|
42
41
|
|
|
@@ -76,10 +75,7 @@ export class UserMap implements UserMapInterface {
|
|
|
76
75
|
private includeIdle: boolean;
|
|
77
76
|
private disableSyncOnTotalAccountsChange: boolean;
|
|
78
77
|
private lastNumberOfSubAccounts: BN;
|
|
79
|
-
private subscription:
|
|
80
|
-
| PollingSubscription
|
|
81
|
-
| WebsocketSubscription
|
|
82
|
-
| grpcSubscription;
|
|
78
|
+
private subscription: PollingSubscription | WebsocketSubscription;
|
|
83
79
|
private stateAccountUpdateCallback = async (state: StateAccount) => {
|
|
84
80
|
if (!state.numberOfSubAccounts.eq(this.lastNumberOfSubAccounts)) {
|
|
85
81
|
await this.sync();
|
|
@@ -126,18 +122,6 @@ export class UserMap implements UserMapInterface {
|
|
|
126
122
|
frequency: config.subscriptionConfig.frequency,
|
|
127
123
|
skipInitialLoad: config.skipInitialLoad,
|
|
128
124
|
});
|
|
129
|
-
} else if (config.subscriptionConfig.type === 'grpc') {
|
|
130
|
-
this.subscription = new grpcSubscription({
|
|
131
|
-
configs: config.subscriptionConfig.configs,
|
|
132
|
-
userMap: this,
|
|
133
|
-
commitment: this.commitment,
|
|
134
|
-
resubOpts: {
|
|
135
|
-
resubTimeoutMs: config.subscriptionConfig.resubTimeoutMs,
|
|
136
|
-
logResubMessages: config.subscriptionConfig.logResubMessages,
|
|
137
|
-
},
|
|
138
|
-
skipInitialLoad: config.skipInitialLoad,
|
|
139
|
-
decodeFn,
|
|
140
|
-
});
|
|
141
125
|
} else {
|
|
142
126
|
this.subscription = new WebsocketSubscription({
|
|
143
127
|
userMap: this,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Commitment, Connection } from '@solana/web3.js';
|
|
2
2
|
import { DriftClient } from '../driftClient';
|
|
3
|
-
import { GrpcConfigs } from '../accounts/types';
|
|
4
3
|
|
|
5
4
|
// passed into UserMap.getUniqueAuthorities to filter users
|
|
6
5
|
export type UserAccountFilterCriteria = {
|
|
@@ -28,13 +27,6 @@ export type UserMapConfig = {
|
|
|
28
27
|
frequency: number;
|
|
29
28
|
commitment?: Commitment;
|
|
30
29
|
}
|
|
31
|
-
| {
|
|
32
|
-
type: 'grpc';
|
|
33
|
-
configs: GrpcConfigs;
|
|
34
|
-
resubTimeoutMs?: number;
|
|
35
|
-
logResubMessages?: boolean;
|
|
36
|
-
commitment?: Commitment;
|
|
37
|
-
}
|
|
38
30
|
| {
|
|
39
31
|
type: 'websocket';
|
|
40
32
|
resubTimeoutMs?: number;
|
package/src/userStatsConfig.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DriftClient } from './driftClient';
|
|
2
2
|
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
3
3
|
import { BulkAccountLoader } from './accounts/bulkAccountLoader';
|
|
4
|
-
import { GrpcConfigs } from './accounts/types';
|
|
5
4
|
|
|
6
5
|
export type UserStatsConfig = {
|
|
7
6
|
accountSubscription?: UserStatsSubscriptionConfig;
|
|
@@ -22,10 +21,4 @@ export type UserStatsSubscriptionConfig =
|
|
|
22
21
|
}
|
|
23
22
|
| {
|
|
24
23
|
type: 'custom';
|
|
25
|
-
}
|
|
26
|
-
| {
|
|
27
|
-
type: 'grpc';
|
|
28
|
-
resubTimeoutMs?: number;
|
|
29
|
-
logResubMessages?: boolean;
|
|
30
|
-
configs: GrpcConfigs;
|
|
31
24
|
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { ResubOpts, GrpcConfigs } from './types';
|
|
3
|
-
import { Program } from '@coral-xyz/anchor';
|
|
4
|
-
import { PublicKey } from '@solana/web3.js';
|
|
5
|
-
import { ClientDuplexStream } from '@grpc/grpc-js';
|
|
6
|
-
import Client, { CommitmentLevel, SubscribeRequest, SubscribeUpdate } from '@triton-one/yellowstone-grpc';
|
|
7
|
-
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
8
|
-
export declare class grpcAccountSubscriber<T> extends WebSocketAccountSubscriber<T> {
|
|
9
|
-
client: Client;
|
|
10
|
-
stream: ClientDuplexStream<SubscribeRequest, SubscribeUpdate>;
|
|
11
|
-
commitmentLevel: CommitmentLevel;
|
|
12
|
-
listenerId?: number;
|
|
13
|
-
constructor(grpcConfigs: GrpcConfigs, accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T, resubOpts?: ResubOpts);
|
|
14
|
-
subscribe(onChange: (data: T) => void): Promise<void>;
|
|
15
|
-
unsubscribe(onResub?: boolean): Promise<void>;
|
|
16
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.grpcAccountSubscriber = void 0;
|
|
27
|
-
const web3_js_1 = require("@solana/web3.js");
|
|
28
|
-
const Buffer = __importStar(require("buffer"));
|
|
29
|
-
const yellowstone_grpc_1 = __importStar(require("@triton-one/yellowstone-grpc"));
|
|
30
|
-
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
31
|
-
class grpcAccountSubscriber extends webSocketAccountSubscriber_1.WebSocketAccountSubscriber {
|
|
32
|
-
constructor(grpcConfigs, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
|
|
33
|
-
var _a, _b;
|
|
34
|
-
super(accountName, program, accountPublicKey, decodeBuffer, resubOpts);
|
|
35
|
-
this.client = new yellowstone_grpc_1.default(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
|
|
36
|
-
this.commitmentLevel =
|
|
37
|
-
(_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : yellowstone_grpc_1.CommitmentLevel.CONFIRMED;
|
|
38
|
-
}
|
|
39
|
-
async subscribe(onChange) {
|
|
40
|
-
if (this.listenerId != null || this.isUnsubscribing) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
this.onChange = onChange;
|
|
44
|
-
if (!this.dataAndSlot) {
|
|
45
|
-
await this.fetch();
|
|
46
|
-
}
|
|
47
|
-
// Subscribe with grpc
|
|
48
|
-
this.stream = await this.client.subscribe();
|
|
49
|
-
const request = {
|
|
50
|
-
slots: {
|
|
51
|
-
slots: {},
|
|
52
|
-
},
|
|
53
|
-
accounts: {
|
|
54
|
-
account: {
|
|
55
|
-
account: [this.accountPublicKey.toString()],
|
|
56
|
-
owner: [],
|
|
57
|
-
filters: [],
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
transactions: {},
|
|
61
|
-
blocks: {},
|
|
62
|
-
blocksMeta: {},
|
|
63
|
-
accountsDataSlice: [],
|
|
64
|
-
commitment: this.commitmentLevel,
|
|
65
|
-
entry: {},
|
|
66
|
-
transactionsStatus: {},
|
|
67
|
-
};
|
|
68
|
-
this.stream.on('data', (chunk) => {
|
|
69
|
-
var _a;
|
|
70
|
-
if (!chunk.account) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
const slot = Number(chunk.account.slot);
|
|
74
|
-
const accountInfo = {
|
|
75
|
-
owner: new web3_js_1.PublicKey(chunk.account.account.owner),
|
|
76
|
-
lamports: Number(chunk.account.account.lamports),
|
|
77
|
-
data: Buffer.Buffer.from(chunk.account.account.data),
|
|
78
|
-
executable: chunk.account.account.executable,
|
|
79
|
-
rentEpoch: Number(chunk.account.account.rentEpoch),
|
|
80
|
-
};
|
|
81
|
-
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
|
|
82
|
-
this.receivingData = true;
|
|
83
|
-
clearTimeout(this.timeoutId);
|
|
84
|
-
this.handleRpcResponse({
|
|
85
|
-
slot,
|
|
86
|
-
}, accountInfo);
|
|
87
|
-
this.setTimeout();
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
this.handleRpcResponse({
|
|
91
|
-
slot,
|
|
92
|
-
}, accountInfo);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
return new Promise((resolve, reject) => {
|
|
96
|
-
this.stream.write(request, (err) => {
|
|
97
|
-
var _a;
|
|
98
|
-
if (err === null || err === undefined) {
|
|
99
|
-
this.listenerId = 1;
|
|
100
|
-
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
|
|
101
|
-
this.receivingData = true;
|
|
102
|
-
this.setTimeout();
|
|
103
|
-
}
|
|
104
|
-
resolve();
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
reject(err);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
}).catch((reason) => {
|
|
111
|
-
console.error(reason);
|
|
112
|
-
throw reason;
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
async unsubscribe(onResub = false) {
|
|
116
|
-
if (!onResub && this.resubOpts) {
|
|
117
|
-
this.resubOpts.resubTimeoutMs = undefined;
|
|
118
|
-
}
|
|
119
|
-
this.isUnsubscribing = true;
|
|
120
|
-
clearTimeout(this.timeoutId);
|
|
121
|
-
this.timeoutId = undefined;
|
|
122
|
-
if (this.listenerId != null) {
|
|
123
|
-
const promise = new Promise((resolve, reject) => {
|
|
124
|
-
const request = {
|
|
125
|
-
slots: {},
|
|
126
|
-
accounts: {},
|
|
127
|
-
transactions: {},
|
|
128
|
-
blocks: {},
|
|
129
|
-
blocksMeta: {},
|
|
130
|
-
accountsDataSlice: [],
|
|
131
|
-
entry: {},
|
|
132
|
-
transactionsStatus: {},
|
|
133
|
-
};
|
|
134
|
-
this.stream.write(request, (err) => {
|
|
135
|
-
if (err === null || err === undefined) {
|
|
136
|
-
this.listenerId = undefined;
|
|
137
|
-
this.isUnsubscribing = false;
|
|
138
|
-
resolve();
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
reject(err);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}).catch((reason) => {
|
|
145
|
-
console.error(reason);
|
|
146
|
-
throw reason;
|
|
147
|
-
});
|
|
148
|
-
return promise;
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
this.isUnsubscribing = false;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
exports.grpcAccountSubscriber = grpcAccountSubscriber;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { WebSocketDriftClientAccountSubscriber } from './webSocketDriftClientAccountSubscriber';
|
|
2
|
-
import { OracleInfo } from '../oracles/types';
|
|
3
|
-
import { Program } from '@coral-xyz/anchor';
|
|
4
|
-
import { GrpcConfigs, ResubOpts } from './types';
|
|
5
|
-
import { Commitment } from '@solana/web3.js';
|
|
6
|
-
export declare class gprcDriftClientAccountSubscriber extends WebSocketDriftClientAccountSubscriber {
|
|
7
|
-
private grpcConfigs;
|
|
8
|
-
constructor(grpcConfigs: GrpcConfigs, program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, resubOpts?: ResubOpts, commitment?: Commitment);
|
|
9
|
-
subscribe(): Promise<boolean>;
|
|
10
|
-
subscribeToSpotMarketAccount(marketIndex: number): Promise<boolean>;
|
|
11
|
-
subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean>;
|
|
12
|
-
subscribeToOracle(oracleInfo: OracleInfo): Promise<boolean>;
|
|
13
|
-
}
|