@drift-labs/sdk 2.142.0-beta.1 → 2.142.0-beta.11

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 (48) hide show
  1. package/VERSION +1 -1
  2. package/bun.lock +25 -10
  3. package/lib/browser/accounts/grpcAccountSubscriber.d.ts +2 -1
  4. package/lib/browser/accounts/grpcAccountSubscriber.js +4 -2
  5. package/lib/browser/accounts/grpcDriftClientAccountSubscriber.d.ts +1 -1
  6. package/lib/browser/accounts/grpcDriftClientAccountSubscriber.js +3 -3
  7. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.d.ts +24 -0
  8. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.js +251 -0
  9. package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +34 -0
  10. package/lib/browser/accounts/grpcMultiAccountSubscriber.js +284 -0
  11. package/lib/browser/constants/spotMarkets.js +4 -4
  12. package/lib/browser/driftClient.js +11 -10
  13. package/lib/browser/driftClientConfig.d.ts +3 -0
  14. package/lib/browser/types.d.ts +3 -1
  15. package/lib/node/accounts/grpcAccountSubscriber.d.ts +2 -1
  16. package/lib/node/accounts/grpcAccountSubscriber.d.ts.map +1 -1
  17. package/lib/node/accounts/grpcAccountSubscriber.js +4 -2
  18. package/lib/node/accounts/grpcDriftClientAccountSubscriber.d.ts +1 -1
  19. package/lib/node/accounts/grpcDriftClientAccountSubscriber.js +3 -3
  20. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts +25 -0
  21. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts.map +1 -0
  22. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.js +251 -0
  23. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +35 -0
  24. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -0
  25. package/lib/node/accounts/grpcMultiAccountSubscriber.js +284 -0
  26. package/lib/node/constants/spotMarkets.js +4 -4
  27. package/lib/node/driftClient.d.ts.map +1 -1
  28. package/lib/node/driftClient.js +11 -10
  29. package/lib/node/driftClientConfig.d.ts +3 -0
  30. package/lib/node/driftClientConfig.d.ts.map +1 -1
  31. package/lib/node/isomorphic/grpc.d.ts +5 -3
  32. package/lib/node/isomorphic/grpc.js +1 -3
  33. package/lib/node/isomorphic/grpc.node.d.ts +5 -3
  34. package/lib/node/isomorphic/grpc.node.d.ts.map +1 -1
  35. package/lib/node/isomorphic/grpc.node.js +1 -3
  36. package/lib/node/types.d.ts +3 -1
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/package.json +10 -4
  39. package/scripts/client-test.ts +214 -0
  40. package/src/accounts/grpcAccountSubscriber.ts +9 -6
  41. package/src/accounts/grpcDriftClientAccountSubscriber.ts +1 -1
  42. package/src/accounts/grpcDriftClientAccountSubscriberV2.ts +426 -0
  43. package/src/accounts/grpcMultiAccountSubscriber.ts +343 -0
  44. package/src/constants/spotMarkets.ts +4 -4
  45. package/src/driftClient.ts +5 -2
  46. package/src/driftClientConfig.ts +13 -0
  47. package/src/isomorphic/grpc.node.ts +11 -7
  48. package/src/types.ts +4 -2
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.grpcDriftClientAccountSubscriberV2 = void 0;
4
+ const webSocketDriftClientAccountSubscriber_1 = require("./webSocketDriftClientAccountSubscriber");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const config_1 = require("../config");
7
+ const pda_1 = require("../addresses/pda");
8
+ const grpcAccountSubscriber_1 = require("./grpcAccountSubscriber");
9
+ const grpcMultiAccountSubscriber_1 = require("./grpcMultiAccountSubscriber");
10
+ const oracleId_1 = require("../oracles/oracleId");
11
+ class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber {
12
+ constructor(grpcConfigs, program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, delistedMarketSetting, resubOpts) {
13
+ super(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, delistedMarketSetting, resubOpts);
14
+ this.perpMarketIndexToAccountPubkeyMap = new Map();
15
+ this.spotMarketIndexToAccountPubkeyMap = new Map();
16
+ this.grpcConfigs = grpcConfigs;
17
+ }
18
+ async subscribe() {
19
+ if (this.isSubscribed) {
20
+ return true;
21
+ }
22
+ if (this.isSubscribing) {
23
+ return await this.subscriptionPromise;
24
+ }
25
+ this.isSubscribing = true;
26
+ this.subscriptionPromise = new Promise((res) => {
27
+ this.subscriptionPromiseResolver = res;
28
+ });
29
+ if (this.shouldFindAllMarketsAndOracles) {
30
+ const { perpMarketIndexes, perpMarketAccounts, spotMarketIndexes, spotMarketAccounts, oracleInfos, } = await (0, config_1.findAllMarketAndOracles)(this.program);
31
+ this.perpMarketIndexes = perpMarketIndexes;
32
+ this.spotMarketIndexes = spotMarketIndexes;
33
+ this.oracleInfos = oracleInfos;
34
+ // front run and set the initial data here to save extra gma call in set initial data
35
+ this.initialPerpMarketAccountData = new Map(perpMarketAccounts.map((market) => [market.marketIndex, market]));
36
+ this.initialSpotMarketAccountData = new Map(spotMarketAccounts.map((market) => [market.marketIndex, market]));
37
+ }
38
+ const statePublicKey = await (0, pda_1.getDriftStateAccountPublicKey)(this.program.programId);
39
+ // create and activate main state account subscription
40
+ this.stateAccountSubscriber =
41
+ await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'state', this.program, statePublicKey, undefined, undefined);
42
+ await this.stateAccountSubscriber.subscribe((data) => {
43
+ this.eventEmitter.emit('stateAccountUpdate', data);
44
+ this.eventEmitter.emit('update');
45
+ });
46
+ // set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
47
+ await this.setInitialData();
48
+ // subscribe to perp + spot markets (separate) and oracles
49
+ await Promise.all([
50
+ this.subscribeToPerpMarketAccounts(),
51
+ this.subscribeToSpotMarketAccounts(),
52
+ this.subscribeToOracles(),
53
+ ]);
54
+ this.eventEmitter.emit('update');
55
+ await this.handleDelistedMarkets();
56
+ await Promise.all([this.setPerpOracleMap(), this.setSpotOracleMap()]);
57
+ this.subscriptionPromiseResolver(true);
58
+ this.isSubscribing = false;
59
+ this.isSubscribed = true;
60
+ // delete initial data
61
+ this.removeInitialData();
62
+ return true;
63
+ }
64
+ getMarketAccountAndSlot(marketIndex) {
65
+ var _a;
66
+ return (_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountData(this.perpMarketIndexToAccountPubkeyMap.get(marketIndex));
67
+ }
68
+ getSpotMarketAccountAndSlot(marketIndex) {
69
+ var _a;
70
+ return (_a = this.spotMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountData(this.spotMarketIndexToAccountPubkeyMap.get(marketIndex));
71
+ }
72
+ async setPerpOracleMap() {
73
+ var _a;
74
+ const perpMarketsMap = (_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap();
75
+ const perpMarkets = Array.from(perpMarketsMap.values());
76
+ const addOraclePromises = [];
77
+ for (const perpMarket of perpMarkets) {
78
+ if (!perpMarket || !perpMarket.data) {
79
+ continue;
80
+ }
81
+ const perpMarketAccount = perpMarket.data;
82
+ const perpMarketIndex = perpMarketAccount.marketIndex;
83
+ const oracle = perpMarketAccount.amm.oracle;
84
+ const oracleId = (0, oracleId_1.getOracleId)(oracle, perpMarket.data.amm.oracleSource);
85
+ if (!this.oracleSubscribers.has(oracleId)) {
86
+ addOraclePromises.push(this.addOracle({
87
+ publicKey: oracle,
88
+ source: perpMarket.data.amm.oracleSource,
89
+ }));
90
+ }
91
+ this.perpOracleMap.set(perpMarketIndex, oracle);
92
+ this.perpOracleStringMap.set(perpMarketIndex, oracleId);
93
+ }
94
+ await Promise.all(addOraclePromises);
95
+ }
96
+ async setSpotOracleMap() {
97
+ var _a;
98
+ const spotMarketsMap = (_a = this.spotMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap();
99
+ const spotMarkets = Array.from(spotMarketsMap.values());
100
+ const addOraclePromises = [];
101
+ for (const spotMarket of spotMarkets) {
102
+ if (!spotMarket || !spotMarket.data) {
103
+ continue;
104
+ }
105
+ const spotMarketAccount = spotMarket.data;
106
+ const spotMarketIndex = spotMarketAccount.marketIndex;
107
+ const oracle = spotMarketAccount.oracle;
108
+ const oracleId = (0, oracleId_1.getOracleId)(oracle, spotMarketAccount.oracleSource);
109
+ if (!this.oracleSubscribers.has(oracleId)) {
110
+ addOraclePromises.push(this.addOracle({
111
+ publicKey: oracle,
112
+ source: spotMarketAccount.oracleSource,
113
+ }));
114
+ }
115
+ this.spotOracleMap.set(spotMarketIndex, oracle);
116
+ this.spotOracleStringMap.set(spotMarketIndex, oracleId);
117
+ }
118
+ await Promise.all(addOraclePromises);
119
+ }
120
+ async subscribeToPerpMarketAccounts() {
121
+ const perpMarketIndexToAccountPubkeys = await Promise.all(this.perpMarketIndexes.map(async (marketIndex) => [
122
+ marketIndex,
123
+ await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex),
124
+ ]));
125
+ for (const [marketIndex, accountPubkey,] of perpMarketIndexToAccountPubkeys) {
126
+ this.perpMarketIndexToAccountPubkeyMap.set(marketIndex, accountPubkey.toBase58());
127
+ }
128
+ const perpMarketPubkeys = perpMarketIndexToAccountPubkeys.map(([_, accountPubkey]) => accountPubkey);
129
+ this.perpMarketsSubscriber =
130
+ await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'perpMarket', this.program, undefined, this.resubOpts, undefined, async () => {
131
+ var _a;
132
+ try {
133
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
134
+ console.log('[grpcDriftClientAccountSubscriberV2] perp markets subscriber unsubscribed; resubscribing');
135
+ }
136
+ await this.subscribeToPerpMarketAccounts();
137
+ }
138
+ catch (e) {
139
+ console.error('Perp markets resubscribe failed:', e);
140
+ }
141
+ });
142
+ for (const data of this.initialPerpMarketAccountData.values()) {
143
+ this.perpMarketsSubscriber.setAccountData(data.pubkey.toBase58(), data);
144
+ }
145
+ await this.perpMarketsSubscriber.subscribe(perpMarketPubkeys, (_accountId, data) => {
146
+ this.eventEmitter.emit('perpMarketAccountUpdate', data);
147
+ this.eventEmitter.emit('update');
148
+ });
149
+ return true;
150
+ }
151
+ async subscribeToSpotMarketAccounts() {
152
+ const spotMarketIndexToAccountPubkeys = await Promise.all(this.spotMarketIndexes.map(async (marketIndex) => [
153
+ marketIndex,
154
+ await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex),
155
+ ]));
156
+ for (const [marketIndex, accountPubkey,] of spotMarketIndexToAccountPubkeys) {
157
+ this.spotMarketIndexToAccountPubkeyMap.set(marketIndex, accountPubkey.toBase58());
158
+ }
159
+ const spotMarketPubkeys = spotMarketIndexToAccountPubkeys.map(([_, accountPubkey]) => accountPubkey);
160
+ this.spotMarketsSubscriber =
161
+ await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'spotMarket', this.program, undefined, this.resubOpts, undefined, async () => {
162
+ var _a;
163
+ try {
164
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
165
+ console.log('[grpcDriftClientAccountSubscriberV2] spot markets subscriber unsubscribed; resubscribing');
166
+ }
167
+ await this.subscribeToSpotMarketAccounts();
168
+ }
169
+ catch (e) {
170
+ console.error('Spot markets resubscribe failed:', e);
171
+ }
172
+ });
173
+ for (const data of this.initialSpotMarketAccountData.values()) {
174
+ this.spotMarketsSubscriber.setAccountData(data.pubkey.toBase58(), data);
175
+ }
176
+ await this.spotMarketsSubscriber.subscribe(spotMarketPubkeys, (_accountId, data) => {
177
+ this.eventEmitter.emit('spotMarketAccountUpdate', data);
178
+ this.eventEmitter.emit('update');
179
+ });
180
+ return true;
181
+ }
182
+ async subscribeToOracles() {
183
+ const pubkeyToSources = new Map();
184
+ for (const info of this.oracleInfos) {
185
+ if (info.publicKey.equals(web3_js_1.PublicKey.default)) {
186
+ continue;
187
+ }
188
+ const key = info.publicKey.toBase58();
189
+ let sources = pubkeyToSources.get(key);
190
+ if (!sources) {
191
+ sources = new Set();
192
+ pubkeyToSources.set(key, sources);
193
+ }
194
+ sources.add(info.source);
195
+ }
196
+ const oraclePubkeys = Array.from(pubkeyToSources.keys()).map((k) => new web3_js_1.PublicKey(k));
197
+ this.oracleMultiSubscriber =
198
+ await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'oracle', this.program, (buffer, pubkey) => {
199
+ if (!pubkey) {
200
+ throw new Error('Oracle pubkey missing in decode');
201
+ }
202
+ const sources = pubkeyToSources.get(pubkey);
203
+ if (!sources || sources.size === 0) {
204
+ throw new Error('Oracle sources missing for pubkey in decode');
205
+ }
206
+ const primarySource = sources.values().next().value;
207
+ const client = this.oracleClientCache.get(primarySource, this.program.provider.connection, this.program);
208
+ return client.getOraclePriceDataFromBuffer(buffer);
209
+ }, this.resubOpts, undefined, async () => {
210
+ var _a;
211
+ try {
212
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
213
+ console.log('[grpcDriftClientAccountSubscriberV2] oracle subscriber unsubscribed; resubscribing');
214
+ }
215
+ await this.subscribeToOracles();
216
+ }
217
+ catch (e) {
218
+ console.error('Oracle resubscribe failed:', e);
219
+ }
220
+ });
221
+ for (const data of this.initialOraclePriceData.entries()) {
222
+ const { publicKey } = (0, oracleId_1.getPublicKeyAndSourceFromOracleId)(data[0]);
223
+ this.oracleMultiSubscriber.setAccountData(publicKey.toBase58(), data[1]);
224
+ }
225
+ await this.oracleMultiSubscriber.subscribe(oraclePubkeys, (accountId, data) => {
226
+ const sources = pubkeyToSources.get(accountId.toBase58());
227
+ if (sources) {
228
+ for (const source of sources.values()) {
229
+ this.eventEmitter.emit('oraclePriceUpdate', accountId, source, data);
230
+ }
231
+ }
232
+ this.eventEmitter.emit('update');
233
+ });
234
+ return true;
235
+ }
236
+ async unsubscribeFromOracles() {
237
+ if (this.oracleMultiSubscriber) {
238
+ await this.oracleMultiSubscriber.unsubscribe();
239
+ this.oracleMultiSubscriber = undefined;
240
+ return;
241
+ }
242
+ await super.unsubscribeFromOracles();
243
+ }
244
+ async unsubscribe() {
245
+ if (this.isSubscribed) {
246
+ return;
247
+ }
248
+ await this.stateAccountSubscriber.unsubscribe();
249
+ }
250
+ }
251
+ exports.grpcDriftClientAccountSubscriberV2 = grpcDriftClientAccountSubscriberV2;
@@ -0,0 +1,35 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Program } from '@coral-xyz/anchor';
4
+ import { Context, PublicKey } from '@solana/web3.js';
5
+ import { Client } from '../isomorphic/grpc';
6
+ import { DataAndSlot, GrpcConfigs, ResubOpts } from './types';
7
+ export declare class grpcMultiAccountSubscriber<T> {
8
+ private client;
9
+ private stream;
10
+ private commitmentLevel;
11
+ private program;
12
+ private accountName;
13
+ private decodeBufferFn?;
14
+ private resubOpts?;
15
+ private onUnsubscribe?;
16
+ listenerId?: number;
17
+ isUnsubscribing: boolean;
18
+ private timeoutId?;
19
+ private receivingData;
20
+ private subscribedAccounts;
21
+ private onChangeMap;
22
+ private dataMap;
23
+ private constructor();
24
+ static create<U>(grpcConfigs: GrpcConfigs, accountName: string, program: Program, decodeBuffer?: (buffer: Buffer, pubkey?: string) => U, resubOpts?: ResubOpts, clientProp?: Client, onUnsubscribe?: () => Promise<void>): Promise<grpcMultiAccountSubscriber<U>>;
25
+ setAccountData(accountPubkey: string, data: T, slot?: number): void;
26
+ getAccountData(accountPubkey: string): DataAndSlot<T> | undefined;
27
+ getAccountDataMap(): Map<string, DataAndSlot<T>>;
28
+ subscribe(accounts: PublicKey[], onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
29
+ addAccounts(accounts: PublicKey[]): Promise<void>;
30
+ removeAccounts(accounts: PublicKey[]): Promise<void>;
31
+ unsubscribe(): Promise<void>;
32
+ private setTimeout;
33
+ private capitalize;
34
+ }
35
+ //# sourceMappingURL=grpcMultiAccountSubscriber.d.ts.map
@@ -0,0 +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,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAU9D,qBAAa,0BAA0B,CAAC,CAAC;IACxC,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,CAAyC;IAChE,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;IAEpD,OAAO;WAkBa,MAAM,CAAC,CAAC,EAC3B,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC,EACrD,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACjC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;IAuBzC,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,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,KACV,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IAgGV,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"}
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.grpcMultiAccountSubscriber = void 0;
30
+ const web3_js_1 = require("@solana/web3.js");
31
+ const Buffer = __importStar(require("buffer"));
32
+ const bs58_1 = __importDefault(require("bs58"));
33
+ const grpc_1 = require("../isomorphic/grpc");
34
+ class grpcMultiAccountSubscriber {
35
+ constructor(client, commitmentLevel, accountName, program, decodeBuffer, resubOpts, onUnsubscribe) {
36
+ this.isUnsubscribing = false;
37
+ this.receivingData = false;
38
+ this.subscribedAccounts = new Set();
39
+ this.onChangeMap = new Map();
40
+ this.dataMap = new Map();
41
+ this.client = client;
42
+ this.commitmentLevel = commitmentLevel;
43
+ this.accountName = accountName;
44
+ this.program = program;
45
+ this.decodeBufferFn = decodeBuffer;
46
+ this.resubOpts = resubOpts;
47
+ this.onUnsubscribe = onUnsubscribe;
48
+ }
49
+ static async create(grpcConfigs, accountName, program, decodeBuffer, resubOpts, clientProp, onUnsubscribe) {
50
+ var _a, _b;
51
+ const client = clientProp
52
+ ? clientProp
53
+ : await (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
54
+ const commitmentLevel =
55
+ // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
56
+ (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : grpc_1.CommitmentLevel.CONFIRMED;
57
+ return new grpcMultiAccountSubscriber(client, commitmentLevel, accountName, program, decodeBuffer, resubOpts, onUnsubscribe);
58
+ }
59
+ setAccountData(accountPubkey, data, slot) {
60
+ this.dataMap.set(accountPubkey, { data, slot });
61
+ }
62
+ getAccountData(accountPubkey) {
63
+ return this.dataMap.get(accountPubkey);
64
+ }
65
+ getAccountDataMap() {
66
+ return this.dataMap;
67
+ }
68
+ async subscribe(accounts, onChange) {
69
+ if (this.listenerId != null || this.isUnsubscribing) {
70
+ return;
71
+ }
72
+ // Track accounts and single onChange for all
73
+ for (const pk of accounts) {
74
+ const key = pk.toBase58();
75
+ this.subscribedAccounts.add(key);
76
+ this.onChangeMap.set(key, (data, ctx, buffer) => {
77
+ this.setAccountData(key, data, ctx.slot);
78
+ onChange(new web3_js_1.PublicKey(key), data, ctx, buffer);
79
+ });
80
+ }
81
+ this.stream =
82
+ (await this.client.subscribe());
83
+ const request = {
84
+ slots: {},
85
+ accounts: {
86
+ account: {
87
+ account: accounts.map((a) => a.toBase58()),
88
+ owner: [],
89
+ filters: [],
90
+ },
91
+ },
92
+ transactions: {},
93
+ blocks: {},
94
+ blocksMeta: {},
95
+ accountsDataSlice: [],
96
+ commitment: this.commitmentLevel,
97
+ entry: {},
98
+ transactionsStatus: {},
99
+ };
100
+ this.stream.on('data', (chunk) => {
101
+ var _a;
102
+ if (!chunk.account) {
103
+ return;
104
+ }
105
+ const slot = Number(chunk.account.slot);
106
+ const accountPubkeyBytes = chunk.account.account.pubkey;
107
+ const accountPubkey = bs58_1.default.encode(accountPubkeyBytes);
108
+ if (!accountPubkey || !this.subscribedAccounts.has(accountPubkey)) {
109
+ return;
110
+ }
111
+ const accountInfo = {
112
+ owner: new web3_js_1.PublicKey(chunk.account.account.owner),
113
+ lamports: Number(chunk.account.account.lamports),
114
+ data: Buffer.Buffer.from(chunk.account.account.data),
115
+ executable: chunk.account.account.executable,
116
+ rentEpoch: Number(chunk.account.account.rentEpoch),
117
+ };
118
+ const context = { slot };
119
+ const buffer = accountInfo.data;
120
+ const data = this.decodeBufferFn
121
+ ? this.decodeBufferFn(buffer, accountPubkey)
122
+ : this.program.account[this.accountName].coder.accounts.decode(this.capitalize(this.accountName), buffer);
123
+ const handler = this.onChangeMap.get(accountPubkey);
124
+ if (handler) {
125
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
126
+ this.receivingData = true;
127
+ clearTimeout(this.timeoutId);
128
+ handler(data, context, buffer);
129
+ this.setTimeout();
130
+ }
131
+ else {
132
+ handler(data, context, buffer);
133
+ }
134
+ }
135
+ });
136
+ return new Promise((resolve, reject) => {
137
+ this.stream.write(request, (err) => {
138
+ var _a;
139
+ if (err === null || err === undefined) {
140
+ this.listenerId = 1;
141
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
142
+ this.receivingData = true;
143
+ this.setTimeout();
144
+ }
145
+ resolve();
146
+ }
147
+ else {
148
+ reject(err);
149
+ }
150
+ });
151
+ }).catch((reason) => {
152
+ console.error(reason);
153
+ throw reason;
154
+ });
155
+ }
156
+ async addAccounts(accounts) {
157
+ for (const pk of accounts) {
158
+ this.subscribedAccounts.add(pk.toBase58());
159
+ }
160
+ const request = {
161
+ slots: {},
162
+ accounts: {
163
+ account: {
164
+ account: Array.from(this.subscribedAccounts.values()),
165
+ owner: [],
166
+ filters: [],
167
+ },
168
+ },
169
+ transactions: {},
170
+ blocks: {},
171
+ blocksMeta: {},
172
+ accountsDataSlice: [],
173
+ commitment: this.commitmentLevel,
174
+ entry: {},
175
+ transactionsStatus: {},
176
+ };
177
+ await new Promise((resolve, reject) => {
178
+ this.stream.write(request, (err) => {
179
+ if (err === null || err === undefined) {
180
+ resolve();
181
+ }
182
+ else {
183
+ reject(err);
184
+ }
185
+ });
186
+ });
187
+ }
188
+ async removeAccounts(accounts) {
189
+ for (const pk of accounts) {
190
+ const k = pk.toBase58();
191
+ this.subscribedAccounts.delete(k);
192
+ this.onChangeMap.delete(k);
193
+ }
194
+ const request = {
195
+ slots: {},
196
+ accounts: {
197
+ account: {
198
+ account: Array.from(this.subscribedAccounts.values()),
199
+ owner: [],
200
+ filters: [],
201
+ },
202
+ },
203
+ transactions: {},
204
+ blocks: {},
205
+ blocksMeta: {},
206
+ accountsDataSlice: [],
207
+ commitment: this.commitmentLevel,
208
+ entry: {},
209
+ transactionsStatus: {},
210
+ };
211
+ await new Promise((resolve, reject) => {
212
+ this.stream.write(request, (err) => {
213
+ if (err === null || err === undefined) {
214
+ resolve();
215
+ }
216
+ else {
217
+ reject(err);
218
+ }
219
+ });
220
+ });
221
+ }
222
+ async unsubscribe() {
223
+ this.isUnsubscribing = true;
224
+ clearTimeout(this.timeoutId);
225
+ this.timeoutId = undefined;
226
+ if (this.listenerId != null) {
227
+ const promise = new Promise((resolve, reject) => {
228
+ const request = {
229
+ slots: {},
230
+ accounts: {},
231
+ transactions: {},
232
+ blocks: {},
233
+ blocksMeta: {},
234
+ accountsDataSlice: [],
235
+ entry: {},
236
+ transactionsStatus: {},
237
+ };
238
+ this.stream.write(request, (err) => {
239
+ if (err === null || err === undefined) {
240
+ this.listenerId = undefined;
241
+ this.isUnsubscribing = false;
242
+ resolve();
243
+ }
244
+ else {
245
+ reject(err);
246
+ }
247
+ });
248
+ }).catch((reason) => {
249
+ console.error(reason);
250
+ throw reason;
251
+ });
252
+ return promise;
253
+ }
254
+ else {
255
+ this.isUnsubscribing = false;
256
+ }
257
+ if (this.onUnsubscribe) {
258
+ try {
259
+ await this.onUnsubscribe();
260
+ }
261
+ catch (e) {
262
+ console.error(e);
263
+ }
264
+ }
265
+ }
266
+ setTimeout() {
267
+ var _a;
268
+ this.timeoutId = setTimeout(async () => {
269
+ if (this.isUnsubscribing) {
270
+ return;
271
+ }
272
+ if (this.receivingData) {
273
+ await this.unsubscribe();
274
+ this.receivingData = false;
275
+ }
276
+ }, (_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs);
277
+ }
278
+ capitalize(value) {
279
+ if (!value)
280
+ return value;
281
+ return value.charAt(0).toUpperCase() + value.slice(1);
282
+ }
283
+ }
284
+ exports.grpcMultiAccountSubscriber = grpcMultiAccountSubscriber;
@@ -11,8 +11,8 @@ exports.DevnetSpotMarkets = [
11
11
  symbol: 'USDC',
12
12
  marketIndex: 0,
13
13
  poolId: 0,
14
- oracle: new web3_js_1.PublicKey('En8hkHLkRe9d9DraYmBTrus518BvmVH448YcvmrFM6Ce'),
15
- oracleSource: types_1.OracleSource.PYTH_STABLE_COIN_PULL,
14
+ oracle: new web3_js_1.PublicKey('9VCioxmni2gDLv11qufWzT3RDERhQE4iY5Gf7NTfYyAV'),
15
+ oracleSource: types_1.OracleSource.PYTH_LAZER_STABLE_COIN,
16
16
  mint: new web3_js_1.PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
17
17
  precision: new anchor_1.BN(10).pow(numericConstants_1.SIX),
18
18
  precisionExp: numericConstants_1.SIX,
@@ -23,8 +23,8 @@ exports.DevnetSpotMarkets = [
23
23
  symbol: 'SOL',
24
24
  marketIndex: 1,
25
25
  poolId: 0,
26
- oracle: new web3_js_1.PublicKey('BAtFj4kQttZRVep3UZS2aZRDixkGYgWsbqTBVDbnSsPF'),
27
- oracleSource: types_1.OracleSource.PYTH_PULL,
26
+ oracle: new web3_js_1.PublicKey('3m6i4RFWEDw2Ft4tFHPJtYgmpPe21k56M3FHeWYrgGBz'),
27
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
28
28
  mint: new web3_js_1.PublicKey(exports.WRAPPED_SOL_MINT),
29
29
  precision: numericConstants_1.LAMPORTS_PRECISION,
30
30
  precisionExp: numericConstants_1.LAMPORTS_EXP,