Skip to content

Commit 325d2e9

Browse files
committed
fix: methods for getting market and slot data bombing
1 parent a793dee commit 325d2e9

File tree

3 files changed

+195
-74
lines changed

3 files changed

+195
-74
lines changed

sdk/scripts/client-test.ts

Lines changed: 111 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,78 +10,125 @@ const GRPC_ENDPOINT = process.env.GRPC_ENDPOINT;
1010
const TOKEN = process.env.TOKEN;
1111

1212
async function initializeGrpcDriftClientV2() {
13-
const connection = new Connection('https://api.mainnet-beta.solana.com');
14-
const wallet = new Wallet(new Keypair());
15-
dotenv.config({ path: '../' });
16-
const config: DriftClientConfig = {
17-
connection,
18-
wallet,
19-
programID: new PublicKey(DRIFT_PROGRAM_ID),
20-
accountSubscription: {
21-
type: 'grpc',
22-
grpcConfigs: {
23-
endpoint: GRPC_ENDPOINT,
24-
token: TOKEN,
25-
commitmentLevel: 'confirmed' as unknown as CommitmentLevel,
26-
channelOptions: {
27-
'grpc.keepalive_time_ms': 10_000,
28-
'grpc.keepalive_timeout_ms': 1_000,
29-
'grpc.keepalive_permit_without_calls': 1,
30-
},
31-
},
32-
driftClientAccountSubscriber: grpcDriftClientAccountSubscriberV2,
33-
},
34-
perpMarketIndexes: [0, 1, 2], // Example market indexes
35-
spotMarketIndexes: [0, 1, 2], // Example market indexes
36-
oracleInfos: [], // Add oracle information if needed
37-
};
13+
const connection = new Connection('https://api.mainnet-beta.solana.com');
14+
const wallet = new Wallet(new Keypair());
15+
dotenv.config({ path: '../' });
16+
const config: DriftClientConfig = {
17+
connection,
18+
wallet,
19+
programID: new PublicKey(DRIFT_PROGRAM_ID),
20+
accountSubscription: {
21+
type: 'grpc',
22+
grpcConfigs: {
23+
endpoint: GRPC_ENDPOINT,
24+
token: TOKEN,
25+
commitmentLevel: 'confirmed' as unknown as CommitmentLevel,
26+
channelOptions: {
27+
'grpc.keepalive_time_ms': 10_000,
28+
'grpc.keepalive_timeout_ms': 1_000,
29+
'grpc.keepalive_permit_without_calls': 1,
30+
},
31+
},
32+
driftClientAccountSubscriber: grpcDriftClientAccountSubscriberV2,
33+
},
34+
perpMarketIndexes: [0, 1, 2], // Example market indexes
35+
spotMarketIndexes: [0, 1, 2], // Example market indexes
36+
oracleInfos: [], // Add oracle information if needed
37+
};
3838

39-
const driftClient = new DriftClient(config);
39+
const driftClient = new DriftClient(config);
4040

41-
let perpMarketUpdateCount = 0;
42-
let spotMarketUpdateCount = 0;
43-
let oraclePriceUpdateCount = 0;
44-
let userAccountUpdateCount = 0;
41+
let perpMarketUpdateCount = 0;
42+
let spotMarketUpdateCount = 0;
43+
let oraclePriceUpdateCount = 0;
44+
let userAccountUpdateCount = 0;
4545

46-
const updatePromise = new Promise<void>((resolve) => {
47-
driftClient.accountSubscriber.eventEmitter.on('perpMarketAccountUpdate', (data) => {
48-
console.log('Perp market account update:', decodeName(data.name));
49-
perpMarketUpdateCount++;
50-
if (perpMarketUpdateCount >= 10 && spotMarketUpdateCount >= 10 && oraclePriceUpdateCount >= 10 && userAccountUpdateCount >= 2) {
51-
resolve();
52-
}
53-
});
46+
const updatePromise = new Promise<void>((resolve) => {
47+
driftClient.accountSubscriber.eventEmitter.on(
48+
'perpMarketAccountUpdate',
49+
(data) => {
50+
console.log('Perp market account update:', decodeName(data.name));
51+
const perpMarketData = driftClient.getPerpMarketAccount(
52+
data.marketIndex
53+
);
54+
console.log(
55+
'Perp market data market index:',
56+
perpMarketData?.marketIndex
57+
);
58+
perpMarketUpdateCount++;
59+
if (
60+
perpMarketUpdateCount >= 10 &&
61+
spotMarketUpdateCount >= 10 &&
62+
oraclePriceUpdateCount >= 10 &&
63+
userAccountUpdateCount >= 2
64+
) {
65+
resolve();
66+
}
67+
}
68+
);
5469

55-
driftClient.accountSubscriber.eventEmitter.on('spotMarketAccountUpdate', (data) => {
56-
console.log('Spot market account update:', decodeName(data.name));
57-
spotMarketUpdateCount++;
58-
if (perpMarketUpdateCount >= 10 && spotMarketUpdateCount >= 10 && oraclePriceUpdateCount >= 10 && userAccountUpdateCount >= 2) {
59-
resolve();
60-
}
61-
});
70+
driftClient.accountSubscriber.eventEmitter.on(
71+
'spotMarketAccountUpdate',
72+
(data) => {
73+
console.log('Spot market account update:', decodeName(data.name));
74+
const spotMarketData = driftClient.getSpotMarketAccount(
75+
data.marketIndex
76+
);
77+
console.log(
78+
'Spot market data market index:',
79+
spotMarketData?.marketIndex
80+
);
81+
spotMarketUpdateCount++;
82+
if (
83+
perpMarketUpdateCount >= 10 &&
84+
spotMarketUpdateCount >= 10 &&
85+
oraclePriceUpdateCount >= 10 &&
86+
userAccountUpdateCount >= 2
87+
) {
88+
resolve();
89+
}
90+
}
91+
);
6292

63-
driftClient.accountSubscriber.eventEmitter.on('oraclePriceUpdate', (data) => {
64-
console.log('Oracle price update:', data.toBase58());
65-
oraclePriceUpdateCount++;
66-
if (perpMarketUpdateCount >= 10 && spotMarketUpdateCount >= 10 && oraclePriceUpdateCount >= 10 && userAccountUpdateCount >= 2) {
67-
resolve();
68-
}
69-
});
93+
driftClient.accountSubscriber.eventEmitter.on(
94+
'oraclePriceUpdate',
95+
(data) => {
96+
console.log('Oracle price update:', data.toBase58());
97+
oraclePriceUpdateCount++;
98+
if (
99+
perpMarketUpdateCount >= 10 &&
100+
spotMarketUpdateCount >= 10 &&
101+
oraclePriceUpdateCount >= 10 &&
102+
userAccountUpdateCount >= 2
103+
) {
104+
resolve();
105+
}
106+
}
107+
);
70108

71-
driftClient.accountSubscriber.eventEmitter.on('userAccountUpdate', (data) => {
72-
console.log('User account update:', decodeName(data.name));
73-
userAccountUpdateCount++;
74-
if (perpMarketUpdateCount >= 10 && spotMarketUpdateCount >= 10 && oraclePriceUpdateCount >= 10 && userAccountUpdateCount >= 2) {
75-
resolve();
76-
}
77-
});
78-
});
109+
driftClient.accountSubscriber.eventEmitter.on(
110+
'userAccountUpdate',
111+
(data) => {
112+
console.log('User account update:', decodeName(data.name));
113+
userAccountUpdateCount++;
79114

80-
await driftClient.subscribe();
81-
console.log('DriftClient initialized and listening for updates.');
115+
if (
116+
perpMarketUpdateCount >= 10 &&
117+
spotMarketUpdateCount >= 10 &&
118+
oraclePriceUpdateCount >= 10 &&
119+
userAccountUpdateCount >= 2
120+
) {
121+
resolve();
122+
}
123+
}
124+
);
125+
});
82126

83-
await updatePromise;
84-
console.log('Received required number of updates.');
127+
await driftClient.subscribe();
128+
console.log('DriftClient initialized and listening for updates.');
129+
130+
await updatePromise;
131+
console.log('Received required number of updates.');
85132
}
86133

87134
initializeGrpcDriftClientV2().catch(console.error);

sdk/src/accounts/grpcDriftClientAccountSubscriberV2.ts

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import {
88
getPerpMarketPublicKey,
99
getSpotMarketPublicKey,
1010
} from '../addresses/pda';
11-
import { DelistedMarketSetting, GrpcConfigs, ResubOpts } from './types';
11+
import {
12+
DataAndSlot,
13+
DelistedMarketSetting,
14+
GrpcConfigs,
15+
ResubOpts,
16+
} from './types';
1217
import { grpcAccountSubscriber } from './grpcAccountSubscriber';
1318
import { grpcMultiAccountSubscriber } from './grpcMultiAccountSubscriber';
1419
import { PerpMarketAccount, SpotMarketAccount, StateAccount } from '../types';
@@ -19,6 +24,8 @@ export class grpcDriftClientAccountSubscriberV2 extends WebSocketDriftClientAcco
1924
private perpMarketsSubscriber?: grpcMultiAccountSubscriber<PerpMarketAccount>;
2025
private spotMarketsSubscriber?: grpcMultiAccountSubscriber<SpotMarketAccount>;
2126
private oracleMultiSubscriber?: grpcMultiAccountSubscriber<OraclePriceData>;
27+
private perpMarketIndexToAccountPubkeyMap = new Map<number, PublicKey>();
28+
private spotMarketIndexToAccountPubkeyMap = new Map<number, PublicKey>();
2229

2330
constructor(
2431
grpcConfigs: GrpcConfigs,
@@ -123,11 +130,39 @@ export class grpcDriftClientAccountSubscriberV2 extends WebSocketDriftClientAcco
123130
return true;
124131
}
125132

133+
override getMarketAccountAndSlot(
134+
marketIndex: number
135+
): DataAndSlot<PerpMarketAccount> | undefined {
136+
return this.perpMarketsSubscriber?.getAccountData(
137+
this.perpMarketIndexToAccountPubkeyMap.get(marketIndex)
138+
);
139+
}
140+
141+
override getSpotMarketAccountAndSlot(
142+
marketIndex: number
143+
): DataAndSlot<SpotMarketAccount> | undefined {
144+
return this.spotMarketsSubscriber?.getAccountData(
145+
this.spotMarketIndexToAccountPubkeyMap.get(marketIndex)
146+
);
147+
}
148+
126149
override async subscribeToPerpMarketAccounts(): Promise<boolean> {
127-
const perpMarketPubkeys = await Promise.all(
128-
this.perpMarketIndexes.map((marketIndex) =>
129-
getPerpMarketPublicKey(this.program.programId, marketIndex)
130-
)
150+
const perpMarketIndexToAccountPubkeys: Array<[number, PublicKey]> =
151+
await Promise.all(
152+
this.perpMarketIndexes.map(async (marketIndex) => [
153+
marketIndex,
154+
await getPerpMarketPublicKey(this.program.programId, marketIndex),
155+
])
156+
);
157+
for (const [
158+
marketIndex,
159+
accountPubkey,
160+
] of perpMarketIndexToAccountPubkeys) {
161+
this.perpMarketIndexToAccountPubkeyMap.set(marketIndex, accountPubkey);
162+
}
163+
164+
const perpMarketPubkeys = perpMarketIndexToAccountPubkeys.map(
165+
([_, accountPubkey]) => accountPubkey
131166
);
132167

133168
this.perpMarketsSubscriber =
@@ -151,6 +186,11 @@ export class grpcDriftClientAccountSubscriberV2 extends WebSocketDriftClientAcco
151186
}
152187
}
153188
);
189+
190+
for (const data of this.initialPerpMarketAccountData.values()) {
191+
this.perpMarketsSubscriber.setAccountData(data.pubkey, data);
192+
}
193+
154194
await this.perpMarketsSubscriber.subscribe(
155195
perpMarketPubkeys,
156196
(_accountId, data) => {
@@ -166,10 +206,22 @@ export class grpcDriftClientAccountSubscriberV2 extends WebSocketDriftClientAcco
166206
}
167207

168208
override async subscribeToSpotMarketAccounts(): Promise<boolean> {
169-
const spotMarketPubkeys = await Promise.all(
170-
this.spotMarketIndexes.map((marketIndex) =>
171-
getSpotMarketPublicKey(this.program.programId, marketIndex)
172-
)
209+
const spotMarketIndexToAccountPubkeys: Array<[number, PublicKey]> =
210+
await Promise.all(
211+
this.spotMarketIndexes.map(async (marketIndex) => [
212+
marketIndex,
213+
await getSpotMarketPublicKey(this.program.programId, marketIndex),
214+
])
215+
);
216+
for (const [
217+
marketIndex,
218+
accountPubkey,
219+
] of spotMarketIndexToAccountPubkeys) {
220+
this.spotMarketIndexToAccountPubkeyMap.set(marketIndex, accountPubkey);
221+
}
222+
223+
const spotMarketPubkeys = spotMarketIndexToAccountPubkeys.map(
224+
([_, accountPubkey]) => accountPubkey
173225
);
174226

175227
this.spotMarketsSubscriber =
@@ -193,6 +245,11 @@ export class grpcDriftClientAccountSubscriberV2 extends WebSocketDriftClientAcco
193245
}
194246
}
195247
);
248+
249+
for (const data of this.initialSpotMarketAccountData.values()) {
250+
this.spotMarketsSubscriber.setAccountData(data.pubkey, data);
251+
}
252+
196253
await this.spotMarketsSubscriber.subscribe(
197254
spotMarketPubkeys,
198255
(_accountId, data) => {
@@ -263,6 +320,13 @@ export class grpcDriftClientAccountSubscriberV2 extends WebSocketDriftClientAcco
263320
}
264321
);
265322

323+
for (const data of this.initialOraclePriceData.entries()) {
324+
this.oracleMultiSubscriber.setAccountData(
325+
new PublicKey(data[0]),
326+
data[1]
327+
);
328+
}
329+
266330
await this.oracleMultiSubscriber.subscribe(
267331
oraclePubkeys,
268332
(accountId, data) => {

sdk/src/accounts/grpcMultiAccountSubscriber.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
SubscribeUpdate,
1212
createClient,
1313
} from '../isomorphic/grpc';
14-
import { GrpcConfigs, ResubOpts } from './types';
14+
import { DataAndSlot, GrpcConfigs, ResubOpts } from './types';
1515

1616
interface AccountInfoLike {
1717
owner: PublicKey;
@@ -42,6 +42,8 @@ export class grpcMultiAccountSubscriber<T> {
4242
(data: T, context: Context, buffer: Buffer) => void
4343
>();
4444

45+
private dataMap = new Map<string, DataAndSlot<T>>();
46+
4547
private constructor(
4648
client: Client,
4749
commitmentLevel: CommitmentLevel,
@@ -91,6 +93,14 @@ export class grpcMultiAccountSubscriber<T> {
9193
);
9294
}
9395

96+
setAccountData(accountPubkey: PublicKey, data: T, slot?: number): void {
97+
this.dataMap.set(accountPubkey.toBase58(), { data, slot });
98+
}
99+
100+
getAccountData(accountPubkey: PublicKey): DataAndSlot<T> | undefined {
101+
return this.dataMap.get(accountPubkey.toBase58());
102+
}
103+
94104
async subscribe(
95105
accounts: PublicKey[],
96106
onChange: (

0 commit comments

Comments
 (0)