@drift-labs/sdk 2.142.0-beta.9 → 2.142.0

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.
Files changed (58) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.d.ts +46 -5
  3. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.js +242 -41
  4. package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +6 -3
  5. package/lib/browser/accounts/grpcMultiAccountSubscriber.js +112 -19
  6. package/lib/browser/adminClient.d.ts +4 -0
  7. package/lib/browser/adminClient.js +34 -0
  8. package/lib/browser/constants/perpMarkets.js +35 -0
  9. package/lib/browser/constants/spotMarkets.js +4 -4
  10. package/lib/browser/driftClient.d.ts +35 -5
  11. package/lib/browser/driftClient.js +41 -14
  12. package/lib/browser/events/parse.d.ts +2 -0
  13. package/lib/browser/events/parse.js +94 -1
  14. package/lib/browser/events/types.d.ts +22 -3
  15. package/lib/browser/idl/drift.json +105 -6
  16. package/lib/browser/math/amm.d.ts +1 -0
  17. package/lib/browser/math/amm.js +28 -4
  18. package/lib/browser/types.d.ts +20 -0
  19. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts +46 -5
  20. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts.map +1 -1
  21. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.js +242 -41
  22. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +6 -3
  23. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
  24. package/lib/node/accounts/grpcMultiAccountSubscriber.js +112 -19
  25. package/lib/node/adminClient.d.ts +4 -0
  26. package/lib/node/adminClient.d.ts.map +1 -1
  27. package/lib/node/adminClient.js +34 -0
  28. package/lib/node/constants/perpMarkets.d.ts.map +1 -1
  29. package/lib/node/constants/perpMarkets.js +35 -0
  30. package/lib/node/constants/spotMarkets.js +4 -4
  31. package/lib/node/driftClient.d.ts +35 -5
  32. package/lib/node/driftClient.d.ts.map +1 -1
  33. package/lib/node/driftClient.js +41 -14
  34. package/lib/node/events/parse.d.ts +2 -0
  35. package/lib/node/events/parse.d.ts.map +1 -1
  36. package/lib/node/events/parse.js +94 -1
  37. package/lib/node/events/types.d.ts +22 -3
  38. package/lib/node/events/types.d.ts.map +1 -1
  39. package/lib/node/idl/drift.json +105 -6
  40. package/lib/node/math/amm.d.ts +1 -0
  41. package/lib/node/math/amm.d.ts.map +1 -1
  42. package/lib/node/math/amm.js +28 -4
  43. package/lib/node/types.d.ts +20 -0
  44. package/lib/node/types.d.ts.map +1 -1
  45. package/package.json +2 -1
  46. package/scripts/client-test.ts +294 -135
  47. package/src/accounts/grpcDriftClientAccountSubscriberV2.ts +398 -72
  48. package/src/accounts/grpcMultiAccountSubscriber.ts +163 -31
  49. package/src/adminClient.ts +74 -0
  50. package/src/constants/perpMarkets.ts +37 -0
  51. package/src/constants/spotMarkets.ts +4 -4
  52. package/src/driftClient.ts +65 -14
  53. package/src/events/parse.ts +115 -0
  54. package/src/events/types.ts +26 -2
  55. package/src/idl/drift.json +105 -6
  56. package/src/math/amm.ts +52 -8
  57. package/src/types.ts +22 -0
  58. package/tests/events/parseLogsForCuUsage.ts +139 -0
@@ -1,12 +1,14 @@
1
1
  import { DriftClient } from '../src/driftClient';
2
2
  import { grpcDriftClientAccountSubscriberV2 } from '../src/accounts/grpcDriftClientAccountSubscriberV2';
3
+ import { grpcDriftClientAccountSubscriber } from '../src/accounts/grpcDriftClientAccountSubscriber';
3
4
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
4
5
  import { DriftClientConfig } from '../src/driftClientConfig';
5
6
  import {
6
- decodeName,
7
7
  DRIFT_PROGRAM_ID,
8
8
  PerpMarketAccount,
9
+ SpotMarketAccount,
9
10
  Wallet,
11
+ OracleInfo,
10
12
  } from '../src';
11
13
  import { CommitmentLevel } from '@triton-one/yellowstone-grpc';
12
14
  import dotenv from 'dotenv';
@@ -17,12 +19,14 @@ import {
17
19
  ProgramAccount,
18
20
  } from '@coral-xyz/anchor';
19
21
  import driftIDL from '../src/idl/drift.json';
22
+ import assert from 'assert';
20
23
 
21
24
  const GRPC_ENDPOINT = process.env.GRPC_ENDPOINT;
22
25
  const TOKEN = process.env.TOKEN;
26
+ const RPC_ENDPOINT = process.env.RPC_ENDPOINT;
23
27
 
24
- async function initializeGrpcDriftClientV2() {
25
- const connection = new Connection('https://api.mainnet-beta.solana.com');
28
+ async function initializeGrpcDriftClientV2VersusV1() {
29
+ const connection = new Connection(RPC_ENDPOINT);
26
30
  const wallet = new Wallet(new Keypair());
27
31
  dotenv.config({ path: '../' });
28
32
 
@@ -32,183 +36,338 @@ async function initializeGrpcDriftClientV2() {
32
36
  // @ts-ignore
33
37
  wallet,
34
38
  {
35
- commitment: 'confirmed',
39
+ commitment: 'processed',
36
40
  }
37
41
  );
38
42
 
39
43
  const program = new Program(driftIDL as Idl, programId, provider);
40
44
 
41
- const perpMarketProgramAccounts =
45
+ const allPerpMarketProgramAccounts =
42
46
  (await program.account.perpMarket.all()) as ProgramAccount<PerpMarketAccount>[];
43
- const solPerpMarket = perpMarketProgramAccounts.find(
44
- (account) => account.account.marketIndex === 0
47
+ const perpMarketProgramAccounts = allPerpMarketProgramAccounts.filter((val) =>
48
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].includes(
49
+ val.account.marketIndex
50
+ )
45
51
  );
46
- const solOracleInfo = {
47
- publicKey: solPerpMarket.account.amm.oracle,
48
- source: solPerpMarket.account.amm.oracleSource,
49
- };
50
- const ethPerpMarket = perpMarketProgramAccounts.find(
51
- (account) => account.account.marketIndex === 2
52
+ const perpMarketIndexes = perpMarketProgramAccounts.map(
53
+ (val) => val.account.marketIndex
52
54
  );
53
- const ethOracleInfo = {
54
- publicKey: ethPerpMarket.account.amm.oracle,
55
- source: ethPerpMarket.account.amm.oracleSource,
56
- };
57
- const btcPerpMarket = perpMarketProgramAccounts.find(
58
- (account) => account.account.marketIndex === 1
55
+
56
+ const allSpotMarketProgramAccounts =
57
+ (await program.account.spotMarket.all()) as ProgramAccount<SpotMarketAccount>[];
58
+ const spotMarketProgramAccounts = allSpotMarketProgramAccounts.filter((val) =>
59
+ [0, 1, 2, 3, 4, 5].includes(val.account.marketIndex)
59
60
  );
60
- const btcOracleInfo = {
61
- publicKey: btcPerpMarket.account.amm.oracle,
62
- source: btcPerpMarket.account.amm.oracleSource,
61
+ const spotMarketIndexes = spotMarketProgramAccounts.map(
62
+ (val) => val.account.marketIndex
63
+ );
64
+
65
+ const seen = new Set<string>();
66
+ const oracleInfos: OracleInfo[] = [];
67
+ for (const acct of perpMarketProgramAccounts) {
68
+ const key = `${acct.account.amm.oracle.toBase58()}-${
69
+ Object.keys(acct.account.amm.oracleSource)[0]
70
+ }`;
71
+ if (!seen.has(key)) {
72
+ seen.add(key);
73
+ oracleInfos.push({
74
+ publicKey: acct.account.amm.oracle,
75
+ source: acct.account.amm.oracleSource,
76
+ });
77
+ }
78
+ }
79
+ for (const acct of spotMarketProgramAccounts) {
80
+ const key = `${acct.account.oracle.toBase58()}-${
81
+ Object.keys(acct.account.oracleSource)[0]
82
+ }`;
83
+ if (!seen.has(key)) {
84
+ seen.add(key);
85
+ oracleInfos.push({
86
+ publicKey: acct.account.oracle,
87
+ source: acct.account.oracleSource,
88
+ });
89
+ }
90
+ }
91
+
92
+ const baseAccountSubscription = {
93
+ type: 'grpc' as const,
94
+ grpcConfigs: {
95
+ endpoint: GRPC_ENDPOINT,
96
+ token: TOKEN,
97
+ commitmentLevel: CommitmentLevel.PROCESSED,
98
+ channelOptions: {
99
+ 'grpc.keepalive_time_ms': 10_000,
100
+ 'grpc.keepalive_timeout_ms': 1_000,
101
+ 'grpc.keepalive_permit_without_calls': 1,
102
+ },
103
+ },
63
104
  };
64
105
 
65
- const config: DriftClientConfig = {
106
+ const configV2: DriftClientConfig = {
66
107
  connection,
67
108
  wallet,
68
109
  programID: new PublicKey(DRIFT_PROGRAM_ID),
69
110
  accountSubscription: {
70
- type: 'grpc',
71
- grpcConfigs: {
72
- endpoint: GRPC_ENDPOINT,
73
- token: TOKEN,
74
- commitmentLevel: 'confirmed' as unknown as CommitmentLevel,
75
- channelOptions: {
76
- 'grpc.keepalive_time_ms': 10_000,
77
- 'grpc.keepalive_timeout_ms': 1_000,
78
- 'grpc.keepalive_permit_without_calls': 1,
79
- },
80
- },
111
+ ...baseAccountSubscription,
81
112
  driftClientAccountSubscriber: grpcDriftClientAccountSubscriberV2,
82
113
  },
83
- perpMarketIndexes: [0, 1, 2],
84
- spotMarketIndexes: [0, 1, 2],
85
- oracleInfos: [solOracleInfo, ethOracleInfo, btcOracleInfo],
114
+ perpMarketIndexes,
115
+ spotMarketIndexes,
116
+ oracleInfos,
117
+ };
118
+
119
+ const configV1: DriftClientConfig = {
120
+ connection,
121
+ wallet,
122
+ programID: new PublicKey(DRIFT_PROGRAM_ID),
123
+ accountSubscription: {
124
+ ...baseAccountSubscription,
125
+ driftClientAccountSubscriber: grpcDriftClientAccountSubscriber,
126
+ },
127
+ perpMarketIndexes,
128
+ spotMarketIndexes,
129
+ oracleInfos,
86
130
  };
87
131
 
88
- const driftClient = new DriftClient(config);
89
-
90
- let perpMarketUpdateCount = 0;
91
- let spotMarketUpdateCount = 0;
92
- let oraclePriceUpdateCount = 0;
93
- let userAccountUpdateCount = 0;
94
-
95
- const updatePromise = new Promise<void>((resolve) => {
96
- driftClient.accountSubscriber.eventEmitter.on(
97
- 'perpMarketAccountUpdate',
98
- (data) => {
99
- console.log(
100
- 'Perp market account update:',
101
- decodeName(data.name),
102
- 'mmOracleSequenceId:',
103
- data.amm.mmOracleSequenceId.toString()
132
+ const clientV2 = new DriftClient(configV2);
133
+ const clientV1 = new DriftClient(configV1);
134
+
135
+ await Promise.all([clientV1.subscribe(), clientV2.subscribe()]);
136
+ const compare = () => {
137
+ try {
138
+ // 1. Test getStateAccountAndSlot
139
+ const state1 = clientV1.accountSubscriber.getStateAccountAndSlot();
140
+ const state2 = clientV2.accountSubscriber.getStateAccountAndSlot();
141
+ assert.deepStrictEqual(
142
+ state1.data,
143
+ state2.data,
144
+ 'State accounts should match'
145
+ );
146
+ if (
147
+ state1.slot !== undefined &&
148
+ state2.slot !== undefined &&
149
+ state2.slot < state1.slot
150
+ ) {
151
+ console.error(
152
+ `State account slot regression: v2 slot ${state2.slot} < v1 slot ${state1.slot}`
104
153
  );
105
- // const perpMarketData = driftClient.getPerpMarketAccount(
106
- // data.marketIndex
107
- // );
108
- // console.log(
109
- // 'Perp market data market index:',
110
- // perpMarketData?.marketIndex
154
+ }
155
+
156
+ // 2. Test getMarketAccountsAndSlots (all perp markets) - sorted comparison
157
+ const allPerpMarkets1 = clientV1.accountSubscriber
158
+ .getMarketAccountsAndSlots()
159
+ .sort((a, b) => a.data.marketIndex - b.data.marketIndex);
160
+ const allPerpMarkets2 = clientV2.accountSubscriber
161
+ .getMarketAccountsAndSlots()
162
+ .sort((a, b) => a.data.marketIndex - b.data.marketIndex);
163
+ assert.strictEqual(
164
+ allPerpMarkets1.length,
165
+ allPerpMarkets2.length,
166
+ 'Number of perp markets should match'
167
+ );
168
+
169
+ // Compare each perp market in the sorted arrays
170
+ for (let i = 0; i < allPerpMarkets1.length; i++) {
171
+ const market1 = allPerpMarkets1[i];
172
+ const market2 = allPerpMarkets2[i];
173
+ assert.strictEqual(
174
+ market1.data.marketIndex,
175
+ market2.data.marketIndex,
176
+ `Perp market at position ${i} should have same marketIndex`
177
+ );
178
+ // assert.deepStrictEqual(
179
+ // market1.data,
180
+ // market2.data,
181
+ // `Perp market ${market1.data.marketIndex} (from getMarketAccountsAndSlots) should match`
111
182
  // );
112
- // const oracle = driftClient.getOracleDataForPerpMarket(data.marketIndex);
113
- // const mmOracle = driftClient.getMMOracleDataForPerpMarket(
114
- // data.marketIndex
183
+ }
184
+
185
+ // 3. Test getMarketAccountAndSlot for each perp market
186
+ for (const idx of perpMarketIndexes) {
187
+ const market1 = clientV1.accountSubscriber.getMarketAccountAndSlot(idx);
188
+ const market2 = clientV2.accountSubscriber.getMarketAccountAndSlot(idx);
189
+ // assert.deepStrictEqual(
190
+ // market1?.data,
191
+ // market2?.data,
192
+ // `Perp market ${idx} data should match`
115
193
  // );
116
- // console.log('Perp oracle price:', oracle.price.toString());
117
- // console.log('Perp MM oracle price:', mmOracle.price.toString());
118
- // console.log(
119
- // 'Perp MM oracle sequence id:',
120
- // perpMarketData?.amm?.mmOracleSequenceId?.toString()
194
+ // assert.strictEqual(
195
+ // market1?.slot,
196
+ // market2?.slot,
197
+ // `Perp market ${idx} slot should match`
121
198
  // );
122
- perpMarketUpdateCount++;
123
199
  if (
124
- perpMarketUpdateCount >= 10 &&
125
- spotMarketUpdateCount >= 10 &&
126
- oraclePriceUpdateCount >= 10 &&
127
- userAccountUpdateCount >= 2
200
+ market1?.slot !== undefined &&
201
+ market2?.slot !== undefined &&
202
+ market2.slot < market1.slot
203
+ ) {
204
+ console.error(
205
+ `Perp market ${idx} slot regression: v2 slot ${market2.slot} < v1 slot ${market1.slot}`
206
+ );
207
+ } else if (
208
+ market1?.slot !== undefined &&
209
+ market2?.slot !== undefined &&
210
+ market2.slot > market1.slot
128
211
  ) {
129
- resolve();
212
+ console.info(
213
+ `Perp market ${idx} slot is FASTER! v2: ${market2.slot}, v1: ${market1.slot}`
214
+ );
130
215
  }
131
216
  }
132
- );
133
-
134
- driftClient.accountSubscriber.eventEmitter.on(
135
- 'spotMarketAccountUpdate',
136
- (data) => {
137
- console.log('Spot market account update:', decodeName(data.name));
138
- const spotMarketData = driftClient.getSpotMarketAccount(
139
- data.marketIndex
140
- );
141
- console.log(
142
- 'Spot market data market index:',
143
- spotMarketData?.marketIndex
217
+
218
+ // 4. Test getSpotMarketAccountsAndSlots (all spot markets) - sorted comparison
219
+ const allSpotMarkets1 = clientV1.accountSubscriber
220
+ .getSpotMarketAccountsAndSlots()
221
+ .sort((a, b) => a.data.marketIndex - b.data.marketIndex);
222
+ const allSpotMarkets2 = clientV2.accountSubscriber
223
+ .getSpotMarketAccountsAndSlots()
224
+ .sort((a, b) => a.data.marketIndex - b.data.marketIndex);
225
+ assert.strictEqual(
226
+ allSpotMarkets1.length,
227
+ allSpotMarkets2.length,
228
+ 'Number of spot markets should match'
229
+ );
230
+
231
+ // Compare each spot market in the sorted arrays
232
+ for (let i = 0; i < allSpotMarkets1.length; i++) {
233
+ const market1 = allSpotMarkets1[i];
234
+ const market2 = allSpotMarkets2[i];
235
+ assert.strictEqual(
236
+ market1.data.marketIndex,
237
+ market2.data.marketIndex,
238
+ `Spot market at position ${i} should have same marketIndex`
144
239
  );
145
- const oracle = driftClient.getOracleDataForSpotMarket(data.marketIndex);
146
- console.log('Spot oracle price:', oracle.price.toString());
147
- spotMarketUpdateCount++;
240
+ // assert.deepStrictEqual(
241
+ // market1.data,
242
+ // market2.data,
243
+ // `Spot market ${market1.data.marketIndex} (from getSpotMarketAccountsAndSlots) should match`
244
+ // );
245
+ }
246
+
247
+ // 5. Test getSpotMarketAccountAndSlot for each spot market
248
+ for (const idx of spotMarketIndexes) {
249
+ const market1 =
250
+ clientV1.accountSubscriber.getSpotMarketAccountAndSlot(idx);
251
+ const market2 =
252
+ clientV2.accountSubscriber.getSpotMarketAccountAndSlot(idx);
253
+ // assert.deepStrictEqual(
254
+ // market1?.data,
255
+ // market2?.data,
256
+ // `Spot market ${idx} data should match`
257
+ // );
258
+ // assert.strictEqual(
259
+ // market1?.slot,
260
+ // market2?.slot,
261
+ // `Spot market ${idx} slot should match`
262
+ // );
148
263
  if (
149
- perpMarketUpdateCount >= 10 &&
150
- spotMarketUpdateCount >= 10 &&
151
- oraclePriceUpdateCount >= 10 &&
152
- userAccountUpdateCount >= 2
264
+ market1?.slot !== undefined &&
265
+ market2?.slot !== undefined &&
266
+ market2.slot < market1.slot
267
+ ) {
268
+ console.error(
269
+ `Spot market ${idx} slot regression: v2 slot ${market2.slot} < v1 slot ${market1.slot}`
270
+ );
271
+ } else if (
272
+ market1?.slot !== undefined &&
273
+ market2?.slot !== undefined &&
274
+ market2.slot > market1.slot
153
275
  ) {
154
- resolve();
276
+ console.info(
277
+ `Spot market ${idx} slot is FASTER! v2: ${market2.slot}, v1: ${market1.slot}`
278
+ );
155
279
  }
156
280
  }
157
- );
158
281
 
159
- driftClient.accountSubscriber.eventEmitter.on(
160
- 'oraclePriceUpdate',
161
- (data) => {
162
- console.log('Oracle price update:', data.toBase58());
163
- oraclePriceUpdateCount++;
282
+ // 6. Test getOraclePriceDataAndSlotForPerpMarket
283
+ for (const idx of perpMarketIndexes) {
284
+ const oracle1 =
285
+ clientV1.accountSubscriber.getOraclePriceDataAndSlotForPerpMarket(
286
+ idx
287
+ );
288
+ const oracle2 =
289
+ clientV2.accountSubscriber.getOraclePriceDataAndSlotForPerpMarket(
290
+ idx
291
+ );
292
+ // assert.deepStrictEqual(
293
+ // oracle1?.data,
294
+ // oracle2?.data,
295
+ // `Perp market ${idx} oracle data should match`
296
+ // );
297
+ // Note: slots might differ slightly due to timing, so we can optionally skip this check or be lenient
298
+ // assert.strictEqual(oracle1?.slot, oracle2?.slot, `Perp market ${idx} oracle slot should match`);
164
299
  if (
165
- perpMarketUpdateCount >= 10 &&
166
- spotMarketUpdateCount >= 10 &&
167
- oraclePriceUpdateCount >= 10 &&
168
- userAccountUpdateCount >= 2
300
+ oracle1?.slot !== undefined &&
301
+ oracle2?.slot !== undefined &&
302
+ oracle2.slot < oracle1.slot
169
303
  ) {
170
- resolve();
304
+ console.error(
305
+ `Perp market ${idx} oracle slot regression: v2 slot ${oracle2.slot} < v1 slot ${oracle1.slot}`
306
+ );
307
+ } else if (
308
+ oracle1?.slot !== undefined &&
309
+ oracle2?.slot !== undefined &&
310
+ oracle2.slot > oracle1.slot
311
+ ) {
312
+ console.info(
313
+ `Perp market ${idx} oracle slot is FASTER! v2: ${oracle2.slot}, v1: ${oracle1.slot}`
314
+ );
171
315
  }
172
316
  }
173
- );
174
317
 
175
- driftClient.accountSubscriber.eventEmitter.on(
176
- 'userAccountUpdate',
177
- (data) => {
178
- console.log('User account update:', decodeName(data.name));
179
- userAccountUpdateCount++;
318
+ // 7. Test getOraclePriceDataAndSlotForSpotMarket
319
+ for (const idx of spotMarketIndexes) {
320
+ const oracle1 =
321
+ clientV1.accountSubscriber.getOraclePriceDataAndSlotForSpotMarket(
322
+ idx
323
+ );
324
+ const oracle2 =
325
+ clientV2.accountSubscriber.getOraclePriceDataAndSlotForSpotMarket(
326
+ idx
327
+ );
328
+ // assert.deepStrictEqual(
329
+ // oracle1?.data,
330
+ // oracle2?.data,
331
+ // `Spot market ${idx} oracle data should match`
332
+ // );
333
+ // Note: slots might differ slightly due to timing
334
+ // assert.strictEqual(oracle1?.slot, oracle2?.slot, `Spot market ${idx} oracle slot should match`);
180
335
  if (
181
- perpMarketUpdateCount >= 10 &&
182
- spotMarketUpdateCount >= 10 &&
183
- oraclePriceUpdateCount >= 10 &&
184
- userAccountUpdateCount >= 2
336
+ oracle1?.slot !== undefined &&
337
+ oracle2?.slot !== undefined &&
338
+ oracle2.slot < oracle1.slot
339
+ ) {
340
+ console.error(
341
+ `Spot market ${idx} oracle slot regression: v2 slot ${oracle2.slot} < v1 slot ${oracle1.slot}`
342
+ );
343
+ } else if (
344
+ oracle1?.slot !== undefined &&
345
+ oracle2?.slot !== undefined &&
346
+ oracle2.slot > oracle1.slot
185
347
  ) {
186
- resolve();
348
+ console.info(
349
+ `Spot market ${idx} oracle slot is FASTER! v2: ${oracle2.slot}, v1: ${oracle1.slot}`
350
+ );
187
351
  }
188
352
  }
189
- );
190
- });
191
353
 
192
- await driftClient.subscribe();
193
- console.log('DriftClient initialized and listening for updates.');
194
-
195
- for (const marketIndex of config.perpMarketIndexes) {
196
- const oracle = driftClient.getOracleDataForPerpMarket(marketIndex);
197
- const mmOracle = driftClient.getMMOracleDataForPerpMarket(marketIndex);
198
- console.log('Initial perp oracle price:', oracle.price.toString());
199
- console.log('Initial perp MM oracle price:', mmOracle.price.toString());
200
- }
354
+ console.log('✓ All comparisons passed');
355
+ } catch (error) {
356
+ console.error('✗ Comparison failed:', error);
357
+ }
358
+ };
201
359
 
202
- for (const marketIndex of config.spotMarketIndexes) {
203
- const oracle = driftClient.getOracleDataForSpotMarket(marketIndex);
204
- console.log('Initial spot oracle price:', oracle.price.toString());
205
- }
360
+ compare();
361
+ const interval = setInterval(compare, 1000);
206
362
 
207
- const stateAccount = driftClient.getStateAccount();
208
- console.log('Initial state account:', stateAccount.toString());
363
+ const cleanup = async () => {
364
+ clearInterval(interval);
365
+ await Promise.all([clientV1.unsubscribe(), clientV2.unsubscribe()]);
366
+ process.exit(0);
367
+ };
209
368
 
210
- await updatePromise;
211
- console.log('Received required number of updates.');
369
+ process.on('SIGINT', cleanup);
370
+ process.on('SIGTERM', cleanup);
212
371
  }
213
372
 
214
- initializeGrpcDriftClientV2().catch(console.error);
373
+ initializeGrpcDriftClientV2VersusV1().catch(console.error);