@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 +1 -1
- package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.js +17 -4
- package/lib/browser/accounts/grpcMultiAccountSubscriber.js +14 -2
- package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.js +17 -4
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcMultiAccountSubscriber.js +14 -2
- package/package.json +1 -1
- package/scripts/client-test.ts +248 -50
- package/src/accounts/grpcDriftClientAccountSubscriberV2.ts +17 -4
- package/src/accounts/grpcMultiAccountSubscriber.ts +17 -5
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.142.0-beta.
|
|
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
|
-
|
|
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
|
|
105
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
|
105
|
-
|
|
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
package/scripts/client-test.ts
CHANGED
|
@@ -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: '
|
|
39
|
+
commitment: 'processed',
|
|
38
40
|
}
|
|
39
41
|
);
|
|
40
42
|
|
|
41
43
|
const program = new Program(driftIDL as Idl, programId, provider);
|
|
42
44
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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()}-${
|
|
78
|
-
acct.account.amm.oracleSource
|
|
79
|
-
|
|
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()}-${
|
|
90
|
-
acct.account.oracleSource
|
|
91
|
-
|
|
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:
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
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
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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),
|