@drift-labs/sdk 2.142.0-beta.16 → 2.142.0-beta.18

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 CHANGED
@@ -1 +1 @@
1
- 2.142.0-beta.16
1
+ 2.142.0-beta.18
@@ -97,6 +97,10 @@ class grpcDriftClientAccountSubscriberV2 {
97
97
  return true;
98
98
  }
99
99
  async addOracle(oracleInfo) {
100
+ var _a, _c;
101
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
102
+ console.log('[grpcDriftClientAccountSubscriberV2] addOracle');
103
+ }
100
104
  if (oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
101
105
  return true;
102
106
  }
@@ -105,10 +109,7 @@ class grpcDriftClientAccountSubscriberV2 {
105
109
  if (!exists) {
106
110
  this.oracleInfos = this.oracleInfos.concat(oracleInfo);
107
111
  }
108
- if (this.oracleMultiSubscriber) {
109
- await this.unsubscribeFromOracles();
110
- await this.subscribeToOracles();
111
- }
112
+ (_c = this.oracleMultiSubscriber) === null || _c === void 0 ? void 0 : _c.addAccounts([oracleInfo.publicKey]);
112
113
  return true;
113
114
  }
114
115
  async subscribe() {
@@ -272,6 +273,10 @@ class grpcDriftClientAccountSubscriberV2 {
272
273
  await Promise.all(addOraclePromises);
273
274
  }
274
275
  async subscribeToPerpMarketAccounts() {
276
+ var _a;
277
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
278
+ console.log('[grpcDriftClientAccountSubscriberV2] subscribeToPerpMarketAccounts');
279
+ }
275
280
  const perpMarketIndexToAccountPubkeys = await Promise.all(this.perpMarketIndexes.map(async (marketIndex) => [
276
281
  marketIndex,
277
282
  await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex),
@@ -303,6 +308,10 @@ class grpcDriftClientAccountSubscriberV2 {
303
308
  return true;
304
309
  }
305
310
  async subscribeToSpotMarketAccounts() {
311
+ var _a;
312
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
313
+ console.log('[grpcDriftClientAccountSubscriberV2] subscribeToSpotMarketAccounts');
314
+ }
306
315
  const spotMarketIndexToAccountPubkeys = await Promise.all(this.spotMarketIndexes.map(async (marketIndex) => [
307
316
  marketIndex,
308
317
  await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex),
@@ -334,6 +343,10 @@ class grpcDriftClientAccountSubscriberV2 {
334
343
  return true;
335
344
  }
336
345
  async subscribeToOracles() {
346
+ var _a;
347
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
348
+ console.log('grpcDriftClientAccountSubscriberV2 subscribeToOracles');
349
+ }
337
350
  const oraclePubkeyToInfosMap = new Map();
338
351
  for (const info of this.oracleInfos) {
339
352
  const pubkey = info.publicKey.toBase58();
@@ -101,8 +101,11 @@ class grpcMultiAccountSubscriber {
101
101
  const accountId = chunk[i];
102
102
  const accountInfo = rpcResponse[i];
103
103
  if (accountInfo) {
104
- const perpMarket = this.program.coder.accounts.decode('PerpMarket', accountInfo.data);
105
- this.setAccountData(accountId, perpMarket, currentSlot);
104
+ const existingData = this.getAccountData(accountId);
105
+ if (!existingData || currentSlot > existingData.slot) {
106
+ const accountDecoded = this.program.coder.accounts.decode(this.capitalize(this.accountName), accountInfo.data);
107
+ this.setAccountData(accountId, accountDecoded, currentSlot);
108
+ }
106
109
  }
107
110
  }
108
111
  }));
@@ -114,6 +117,10 @@ class grpcMultiAccountSubscriber {
114
117
  }
115
118
  }
116
119
  async subscribe(accounts, onChange) {
120
+ var _a;
121
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
122
+ console.log(`[${this.accountName}] grpcMultiAccountSubscriber subscribe`);
123
+ }
117
124
  if (this.listenerId != null || this.isUnsubscribing) {
118
125
  return;
119
126
  }
@@ -156,6 +163,11 @@ class grpcMultiAccountSubscriber {
156
163
  if (!accountPubkey || !this.subscribedAccounts.has(accountPubkey)) {
157
164
  return;
158
165
  }
166
+ // Skip processing if we already have data for this account at an equal or newer slot
167
+ const existing = this.dataMap.get(accountPubkey);
168
+ if ((existing === null || existing === void 0 ? void 0 : existing.slot) !== undefined && existing.slot >= slot) {
169
+ return;
170
+ }
159
171
  const accountInfo = {
160
172
  owner: new web3_js_1.PublicKey(chunk.account.account.owner),
161
173
  lamports: Number(chunk.account.account.lamports),
@@ -1 +1 @@
1
- {"version":3,"file":"grpcDriftClientAccountSubscriberV2.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcDriftClientAccountSubscriberV2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grpcDriftClientAccountSubscriberV2.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcDriftClientAccountSubscriberV2.ts"],"names":[],"mappings":"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"}
@@ -97,6 +97,10 @@ class grpcDriftClientAccountSubscriberV2 {
97
97
  return true;
98
98
  }
99
99
  async addOracle(oracleInfo) {
100
+ var _a, _c;
101
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
102
+ console.log('[grpcDriftClientAccountSubscriberV2] addOracle');
103
+ }
100
104
  if (oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
101
105
  return true;
102
106
  }
@@ -105,10 +109,7 @@ class grpcDriftClientAccountSubscriberV2 {
105
109
  if (!exists) {
106
110
  this.oracleInfos = this.oracleInfos.concat(oracleInfo);
107
111
  }
108
- if (this.oracleMultiSubscriber) {
109
- await this.unsubscribeFromOracles();
110
- await this.subscribeToOracles();
111
- }
112
+ (_c = this.oracleMultiSubscriber) === null || _c === void 0 ? void 0 : _c.addAccounts([oracleInfo.publicKey]);
112
113
  return true;
113
114
  }
114
115
  async subscribe() {
@@ -272,6 +273,10 @@ class grpcDriftClientAccountSubscriberV2 {
272
273
  await Promise.all(addOraclePromises);
273
274
  }
274
275
  async subscribeToPerpMarketAccounts() {
276
+ var _a;
277
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
278
+ console.log('[grpcDriftClientAccountSubscriberV2] subscribeToPerpMarketAccounts');
279
+ }
275
280
  const perpMarketIndexToAccountPubkeys = await Promise.all(this.perpMarketIndexes.map(async (marketIndex) => [
276
281
  marketIndex,
277
282
  await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex),
@@ -303,6 +308,10 @@ class grpcDriftClientAccountSubscriberV2 {
303
308
  return true;
304
309
  }
305
310
  async subscribeToSpotMarketAccounts() {
311
+ var _a;
312
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
313
+ console.log('[grpcDriftClientAccountSubscriberV2] subscribeToSpotMarketAccounts');
314
+ }
306
315
  const spotMarketIndexToAccountPubkeys = await Promise.all(this.spotMarketIndexes.map(async (marketIndex) => [
307
316
  marketIndex,
308
317
  await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex),
@@ -334,6 +343,10 @@ class grpcDriftClientAccountSubscriberV2 {
334
343
  return true;
335
344
  }
336
345
  async subscribeToOracles() {
346
+ var _a;
347
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
348
+ console.log('grpcDriftClientAccountSubscriberV2 subscribeToOracles');
349
+ }
337
350
  const oraclePubkeyToInfosMap = new Map();
338
351
  for (const info of this.oracleInfos) {
339
352
  const pubkey = info.publicKey.toBase58();
@@ -1 +1 @@
1
- {"version":3,"file":"grpcMultiAccountSubscriber.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcMultiAccountSubscriber.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAc,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjE,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAyB9D,qBAAa,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAwD;IACtE,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAIhB;IACP,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAsB;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,UAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAGf;IAEJ,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,eAAe,CAAmC;IAE1D,OAAO;WAoBa,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EAC1C,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,EACvE,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAwB5C,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAInE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAIjE,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDtB,SAAS,CACd,QAAQ,EAAE,SAAS,EAAE,EACrB,QAAQ,EAAE,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,CAAC,KACX,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IA+GV,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCjD,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA4ClC,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,UAAU;CAIlB"}
1
+ {"version":3,"file":"grpcMultiAccountSubscriber.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcMultiAccountSubscriber.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAc,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjE,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAyB9D,qBAAa,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAwD;IACtE,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAIhB;IACP,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAsB;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,UAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAGf;IAEJ,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,eAAe,CAAmC;IAE1D,OAAO;WAoBa,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EAC1C,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,EACvE,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAwB5C,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAInE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAIjE,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDtB,SAAS,CACd,QAAQ,EAAE,SAAS,EAAE,EACrB,QAAQ,EAAE,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,CAAC,KACX,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IAwHV,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCjD,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA4ClC,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,UAAU;CAIlB"}
@@ -101,8 +101,11 @@ class grpcMultiAccountSubscriber {
101
101
  const accountId = chunk[i];
102
102
  const accountInfo = rpcResponse[i];
103
103
  if (accountInfo) {
104
- const perpMarket = this.program.coder.accounts.decode('PerpMarket', accountInfo.data);
105
- this.setAccountData(accountId, perpMarket, currentSlot);
104
+ const existingData = this.getAccountData(accountId);
105
+ if (!existingData || currentSlot > existingData.slot) {
106
+ const accountDecoded = this.program.coder.accounts.decode(this.capitalize(this.accountName), accountInfo.data);
107
+ this.setAccountData(accountId, accountDecoded, currentSlot);
108
+ }
106
109
  }
107
110
  }
108
111
  }));
@@ -114,6 +117,10 @@ class grpcMultiAccountSubscriber {
114
117
  }
115
118
  }
116
119
  async subscribe(accounts, onChange) {
120
+ var _a;
121
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
122
+ console.log(`[${this.accountName}] grpcMultiAccountSubscriber subscribe`);
123
+ }
117
124
  if (this.listenerId != null || this.isUnsubscribing) {
118
125
  return;
119
126
  }
@@ -156,6 +163,11 @@ class grpcMultiAccountSubscriber {
156
163
  if (!accountPubkey || !this.subscribedAccounts.has(accountPubkey)) {
157
164
  return;
158
165
  }
166
+ // Skip processing if we already have data for this account at an equal or newer slot
167
+ const existing = this.dataMap.get(accountPubkey);
168
+ if ((existing === null || existing === void 0 ? void 0 : existing.slot) !== undefined && existing.slot >= slot) {
169
+ return;
170
+ }
159
171
  const accountInfo = {
160
172
  owner: new web3_js_1.PublicKey(chunk.account.account.owner),
161
173
  lamports: Number(chunk.account.account.lamports),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.142.0-beta.16",
3
+ "version": "2.142.0-beta.18",
4
4
  "main": "lib/node/index.js",
5
5
  "types": "lib/node/index.d.ts",
6
6
  "module": "./lib/browser/index.js",
@@ -19,12 +19,14 @@ import {
19
19
  ProgramAccount,
20
20
  } from '@coral-xyz/anchor';
21
21
  import driftIDL from '../src/idl/drift.json';
22
+ import assert from 'assert';
22
23
 
23
24
  const GRPC_ENDPOINT = process.env.GRPC_ENDPOINT;
24
25
  const TOKEN = process.env.TOKEN;
26
+ const RPC_ENDPOINT = process.env.RPC_ENDPOINT;
25
27
 
26
28
  async function initializeGrpcDriftClientV2VersusV1() {
27
- const connection = new Connection('');
29
+ const connection = new Connection(RPC_ENDPOINT);
28
30
  const wallet = new Wallet(new Keypair());
29
31
  dotenv.config({ path: '../' });
30
32
 
@@ -34,49 +36,38 @@ async function initializeGrpcDriftClientV2VersusV1() {
34
36
  // @ts-ignore
35
37
  wallet,
36
38
  {
37
- commitment: 'confirmed',
39
+ commitment: 'processed',
38
40
  }
39
41
  );
40
42
 
41
43
  const program = new Program(driftIDL as Idl, programId, provider);
42
44
 
43
- const perpMarketIndexes = [4];
44
- const spotMarketIndexes = [32];
45
-
46
- const perpMarketProgramAccounts = (
47
- await program.account.perpMarket.all()
48
- ).filter((a) =>
49
- perpMarketIndexes.includes(a.account.marketIndex as number)
50
- ) as ProgramAccount<PerpMarketAccount>[];
51
- const spotMarketProgramAccounts = (
52
- await program.account.spotMarket.all()
53
- ).filter((a) =>
54
- spotMarketIndexes.includes(a.account.marketIndex as number)
55
- ) as ProgramAccount<SpotMarketAccount>[];
56
-
57
- // const perpMarketIndexes = perpMarketProgramAccounts.map(
58
- // (a) => a.account.marketIndex
59
- // );
60
- // const spotMarketIndexes = spotMarketProgramAccounts.map(
61
- // (a) => a.account.marketIndex
62
- // );
63
- // const oracleInfos = [
64
- // {
65
- // publicKey: new PublicKey('BERaNi6cpEresbq6HC1EQGaB1H1UjvEo4NGnmYSSJof4'),
66
- // source: OracleSource.PYTH_LAZER,
67
- // },
68
- // {
69
- // publicKey: new PublicKey('BERaNi6cpEresbq6HC1EQGaB1H1UjvEo4NGnmYSSJof4'),
70
- // source: OracleSource.PYTH_LAZER_1M,
71
- // },
72
- // ];
45
+ const allPerpMarketProgramAccounts =
46
+ (await program.account.perpMarket.all()) as ProgramAccount<PerpMarketAccount>[];
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
+ )
51
+ );
52
+ const perpMarketIndexes = perpMarketProgramAccounts.map(
53
+ (val) => val.account.marketIndex
54
+ );
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)
60
+ );
61
+ const spotMarketIndexes = spotMarketProgramAccounts.map(
62
+ (val) => val.account.marketIndex
63
+ );
73
64
 
74
65
  const seen = new Set<string>();
75
66
  const oracleInfos: OracleInfo[] = [];
76
67
  for (const acct of perpMarketProgramAccounts) {
77
- const key = `${acct.account.amm.oracle.toBase58()}-${Object.keys(
78
- acct.account.amm.oracleSource ?? {}
79
- )?.[0]}`;
68
+ const key = `${acct.account.amm.oracle.toBase58()}-${
69
+ Object.keys(acct.account.amm.oracleSource)[0]
70
+ }`;
80
71
  if (!seen.has(key)) {
81
72
  seen.add(key);
82
73
  oracleInfos.push({
@@ -86,9 +77,9 @@ async function initializeGrpcDriftClientV2VersusV1() {
86
77
  }
87
78
  }
88
79
  for (const acct of spotMarketProgramAccounts) {
89
- const key = `${acct.account.oracle.toBase58()}-${Object.keys(
90
- acct.account.oracleSource ?? {}
91
- )?.[0]}`;
80
+ const key = `${acct.account.oracle.toBase58()}-${
81
+ Object.keys(acct.account.oracleSource)[0]
82
+ }`;
92
83
  if (!seen.has(key)) {
93
84
  seen.add(key);
94
85
  oracleInfos.push({
@@ -103,7 +94,7 @@ async function initializeGrpcDriftClientV2VersusV1() {
103
94
  grpcConfigs: {
104
95
  endpoint: GRPC_ENDPOINT,
105
96
  token: TOKEN,
106
- commitmentLevel: 'confirmed' as unknown as CommitmentLevel,
97
+ commitmentLevel: CommitmentLevel.PROCESSED,
107
98
  channelOptions: {
108
99
  'grpc.keepalive_time_ms': 10_000,
109
100
  'grpc.keepalive_timeout_ms': 1_000,
@@ -143,19 +134,226 @@ async function initializeGrpcDriftClientV2VersusV1() {
143
134
 
144
135
  await Promise.all([clientV1.subscribe(), clientV2.subscribe()]);
145
136
  const compare = () => {
146
- for (const idx of perpMarketIndexes) {
147
- const p1 = clientV1.getOracleDataForPerpMarket(idx).price;
148
- const p2 = clientV2.getOracleDataForPerpMarket(idx).price;
149
- console.log(
150
- `perp mkt ${idx} | v1 ${p1.toString()} | v2 ${p2.toString()}`
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'
151
145
  );
152
- }
153
- for (const idx of spotMarketIndexes) {
154
- const s1 = clientV1.getOracleDataForSpotMarket(idx).price;
155
- const s2 = clientV2.getOracleDataForSpotMarket(idx).price;
156
- console.log(
157
- `spot mkt ${idx} | v1 ${s1.toString()} | v2 ${s2.toString()}`
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}`
153
+ );
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`
182
+ // );
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`
193
+ // );
194
+ // assert.strictEqual(
195
+ // market1?.slot,
196
+ // market2?.slot,
197
+ // `Perp market ${idx} slot should match`
198
+ // );
199
+ if (
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
211
+ ) {
212
+ console.info(
213
+ `Perp market ${idx} slot is FASTER! v2: ${market2.slot}, v1: ${market1.slot}`
214
+ );
215
+ }
216
+ }
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'
158
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`
239
+ );
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
+ // );
263
+ if (
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
275
+ ) {
276
+ console.info(
277
+ `Spot market ${idx} slot is FASTER! v2: ${market2.slot}, v1: ${market1.slot}`
278
+ );
279
+ }
280
+ }
281
+
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`);
299
+ if (
300
+ oracle1?.slot !== undefined &&
301
+ oracle2?.slot !== undefined &&
302
+ oracle2.slot < oracle1.slot
303
+ ) {
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
+ );
315
+ }
316
+ }
317
+
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`);
335
+ if (
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
347
+ ) {
348
+ console.info(
349
+ `Spot market ${idx} oracle slot is FASTER! v2: ${oracle2.slot}, v1: ${oracle1.slot}`
350
+ );
351
+ }
352
+ }
353
+
354
+ console.log('✓ All comparisons passed');
355
+ } catch (error) {
356
+ console.error('✗ Comparison failed:', error);
159
357
  }
160
358
  };
161
359
 
@@ -215,6 +215,9 @@ export class grpcDriftClientAccountSubscriberV2
215
215
  }
216
216
 
217
217
  async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
218
+ if (this.resubOpts?.logResubMessages) {
219
+ console.log('[grpcDriftClientAccountSubscriberV2] addOracle');
220
+ }
218
221
  if (oracleInfo.publicKey.equals(PublicKey.default)) {
219
222
  return true;
220
223
  }
@@ -228,10 +231,7 @@ export class grpcDriftClientAccountSubscriberV2
228
231
  this.oracleInfos = this.oracleInfos.concat(oracleInfo);
229
232
  }
230
233
 
231
- if (this.oracleMultiSubscriber) {
232
- await this.unsubscribeFromOracles();
233
- await this.subscribeToOracles();
234
- }
234
+ this.oracleMultiSubscriber?.addAccounts([oracleInfo.publicKey]);
235
235
 
236
236
  return true;
237
237
  }
@@ -461,6 +461,11 @@ export class grpcDriftClientAccountSubscriberV2
461
461
  }
462
462
 
463
463
  async subscribeToPerpMarketAccounts(): Promise<boolean> {
464
+ if (this.resubOpts?.logResubMessages) {
465
+ console.log(
466
+ '[grpcDriftClientAccountSubscriberV2] subscribeToPerpMarketAccounts'
467
+ );
468
+ }
464
469
  const perpMarketIndexToAccountPubkeys: Array<[number, PublicKey]> =
465
470
  await Promise.all(
466
471
  this.perpMarketIndexes.map(async (marketIndex) => [
@@ -523,6 +528,11 @@ export class grpcDriftClientAccountSubscriberV2
523
528
  }
524
529
 
525
530
  async subscribeToSpotMarketAccounts(): Promise<boolean> {
531
+ if (this.resubOpts?.logResubMessages) {
532
+ console.log(
533
+ '[grpcDriftClientAccountSubscriberV2] subscribeToSpotMarketAccounts'
534
+ );
535
+ }
526
536
  const spotMarketIndexToAccountPubkeys: Array<[number, PublicKey]> =
527
537
  await Promise.all(
528
538
  this.spotMarketIndexes.map(async (marketIndex) => [
@@ -585,6 +595,9 @@ export class grpcDriftClientAccountSubscriberV2
585
595
  }
586
596
 
587
597
  async subscribeToOracles(): Promise<boolean> {
598
+ if (this.resubOpts?.logResubMessages) {
599
+ console.log('grpcDriftClientAccountSubscriberV2 subscribeToOracles');
600
+ }
588
601
  const oraclePubkeyToInfosMap = new Map<string, OracleInfo[]>();
589
602
  for (const info of this.oracleInfos) {
590
603
  const pubkey = info.publicKey.toBase58();
@@ -160,11 +160,14 @@ export class grpcMultiAccountSubscriber<T, U = undefined> {
160
160
  const accountId = chunk[i];
161
161
  const accountInfo = rpcResponse[i];
162
162
  if (accountInfo) {
163
- const perpMarket = this.program.coder.accounts.decode(
164
- 'PerpMarket',
165
- accountInfo.data
166
- );
167
- this.setAccountData(accountId, perpMarket, currentSlot);
163
+ const existingData = this.getAccountData(accountId);
164
+ if (!existingData || currentSlot > existingData.slot) {
165
+ const accountDecoded = this.program.coder.accounts.decode(
166
+ this.capitalize(this.accountName),
167
+ accountInfo.data
168
+ );
169
+ this.setAccountData(accountId, accountDecoded, currentSlot);
170
+ }
168
171
  }
169
172
  }
170
173
  })
@@ -189,6 +192,9 @@ export class grpcMultiAccountSubscriber<T, U = undefined> {
189
192
  accountProps: U
190
193
  ) => void
191
194
  ): Promise<void> {
195
+ if (this.resubOpts?.logResubMessages) {
196
+ console.log(`[${this.accountName}] grpcMultiAccountSubscriber subscribe`);
197
+ }
192
198
  if (this.listenerId != null || this.isUnsubscribing) {
193
199
  return;
194
200
  }
@@ -235,6 +241,12 @@ export class grpcMultiAccountSubscriber<T, U = undefined> {
235
241
  if (!accountPubkey || !this.subscribedAccounts.has(accountPubkey)) {
236
242
  return;
237
243
  }
244
+
245
+ // Skip processing if we already have data for this account at an equal or newer slot
246
+ const existing = this.dataMap.get(accountPubkey);
247
+ if (existing?.slot !== undefined && existing.slot >= slot) {
248
+ return;
249
+ }
238
250
  const accountInfo: AccountInfoLike = {
239
251
  owner: new PublicKey(chunk.account.account.owner),
240
252
  lamports: Number(chunk.account.account.lamports),