@drift-labs/sdk 2.67.0-beta.0 → 2.67.0-beta.2
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/accounts/pollingDriftClientAccountSubscriber.d.ts +6 -0
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +58 -0
- package/lib/accounts/types.d.ts +2 -0
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +6 -0
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +68 -2
- package/lib/driftClient.js +7 -8
- package/lib/factory/oracleClient.js +4 -3
- package/lib/idl/switchboard.json +8354 -0
- package/lib/oracles/switchboardClient.d.ts +11 -0
- package/lib/oracles/switchboardClient.js +40 -0
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -1
- package/lib/user.js +7 -11
- package/package.json +1 -1
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +70 -0
- package/src/accounts/types.ts +6 -0
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +81 -2
- package/src/driftClient.ts +12 -10
- package/src/factory/oracleClient.ts +4 -3
- package/src/idl/switchboard.json +8354 -0
- package/src/oracles/switchboardClient.ts +74 -0
- package/src/types.ts +1 -1
- package/src/user.ts +14 -25
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { OracleClient, OraclePriceData } from './types';
|
|
4
|
+
import { BorshAccountsCoder } from '@coral-xyz/anchor';
|
|
5
|
+
export declare class SwitchboardClient implements OracleClient {
|
|
6
|
+
connection: Connection;
|
|
7
|
+
coder: BorshAccountsCoder;
|
|
8
|
+
constructor(connection: Connection);
|
|
9
|
+
getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
|
|
10
|
+
getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData;
|
|
11
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SwitchboardClient = void 0;
|
|
7
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
8
|
+
const switchboard_json_1 = __importDefault(require("../idl/switchboard.json"));
|
|
9
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
10
|
+
class SwitchboardClient {
|
|
11
|
+
constructor(connection) {
|
|
12
|
+
this.connection = connection;
|
|
13
|
+
this.coder = new anchor_1.BorshAccountsCoder(switchboard_json_1.default);
|
|
14
|
+
}
|
|
15
|
+
async getOraclePriceData(pricePublicKey) {
|
|
16
|
+
const accountInfo = await this.connection.getAccountInfo(pricePublicKey);
|
|
17
|
+
return this.getOraclePriceDataFromBuffer(accountInfo.data);
|
|
18
|
+
}
|
|
19
|
+
getOraclePriceDataFromBuffer(buffer) {
|
|
20
|
+
const aggregatorAccountData = this.coder.decodeUnchecked('AggregatorAccountData', buffer);
|
|
21
|
+
const price = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.result);
|
|
22
|
+
const confidence = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.stdDeviation);
|
|
23
|
+
const hasSufficientNumberOfDataPoints = aggregatorAccountData.latestConfirmedRound.numSuccess >=
|
|
24
|
+
aggregatorAccountData.minOracleResults;
|
|
25
|
+
const slot = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
|
|
26
|
+
return {
|
|
27
|
+
price,
|
|
28
|
+
slot,
|
|
29
|
+
confidence,
|
|
30
|
+
hasSufficientNumberOfDataPoints,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.SwitchboardClient = SwitchboardClient;
|
|
35
|
+
function convertSwitchboardDecimal(switchboardDecimal) {
|
|
36
|
+
const switchboardPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(switchboardDecimal.scale));
|
|
37
|
+
return switchboardDecimal.mantissa
|
|
38
|
+
.mul(numericConstants_1.PRICE_PRECISION)
|
|
39
|
+
.div(switchboardPrecision);
|
|
40
|
+
}
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
|
@@ -95,7 +95,7 @@ exports.OracleSource = OracleSource;
|
|
|
95
95
|
OracleSource.PYTH = { pyth: {} };
|
|
96
96
|
OracleSource.PYTH_1K = { pyth1K: {} };
|
|
97
97
|
OracleSource.PYTH_1M = { pyth1M: {} };
|
|
98
|
-
|
|
98
|
+
OracleSource.SWITCHBOARD = { switchboard: {} };
|
|
99
99
|
OracleSource.QUOTE_ASSET = { quoteAsset: {} };
|
|
100
100
|
OracleSource.PYTH_STABLE_COIN = { pythStableCoin: {} };
|
|
101
101
|
class OrderType {
|
package/lib/user.js
CHANGED
|
@@ -717,7 +717,7 @@ class User {
|
|
|
717
717
|
marginRatio = numericConstants_1.ZERO;
|
|
718
718
|
}
|
|
719
719
|
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
|
|
720
|
-
const quoteOraclePriceData = this.driftClient.
|
|
720
|
+
const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
721
721
|
let quotePrice;
|
|
722
722
|
if (strict) {
|
|
723
723
|
quotePrice = _1.BN.max(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min);
|
|
@@ -1198,7 +1198,7 @@ class User {
|
|
|
1198
1198
|
calculateFreeCollateralDeltaForSpot(market, signedTokenAmount, marginCategory = 'Maintenance') {
|
|
1199
1199
|
const tokenPrecision = new _1.BN(Math.pow(10, market.decimals));
|
|
1200
1200
|
if (signedTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
1201
|
-
const assetWeight = (0, spotBalance_1.calculateAssetWeight)(signedTokenAmount, this.driftClient.
|
|
1201
|
+
const assetWeight = (0, spotBalance_1.calculateAssetWeight)(signedTokenAmount, this.driftClient.getOracleDataForSpotMarket(market.marketIndex).price, market, marginCategory);
|
|
1202
1202
|
return numericConstants_1.QUOTE_PRECISION.mul(assetWeight)
|
|
1203
1203
|
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
1204
1204
|
.mul(signedTokenAmount)
|
|
@@ -1320,7 +1320,7 @@ class User {
|
|
|
1320
1320
|
*/
|
|
1321
1321
|
getMaxTradeSizeUSDCForSpot(targetMarketIndex, direction, currentQuoteAssetValue, currentSpotMarketNetValue) {
|
|
1322
1322
|
const market = this.driftClient.getSpotMarketAccount(targetMarketIndex);
|
|
1323
|
-
const oraclePrice = this.driftClient.
|
|
1323
|
+
const oraclePrice = this.driftClient.getOracleDataForSpotMarket(targetMarketIndex).price;
|
|
1324
1324
|
currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
1325
1325
|
currentSpotMarketNetValue =
|
|
1326
1326
|
currentSpotMarketNetValue !== null && currentSpotMarketNetValue !== void 0 ? currentSpotMarketNetValue : this.getSpotPositionValue(targetMarketIndex);
|
|
@@ -1872,12 +1872,12 @@ class User {
|
|
|
1872
1872
|
for (const perpPosition of this.getActivePerpPositions()) {
|
|
1873
1873
|
const settledLpPosition = this.getPerpPositionWithLPSettle(perpPosition.marketIndex, perpPosition)[0];
|
|
1874
1874
|
const perpMarket = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
|
|
1875
|
-
const oraclePriceData = this.driftClient.
|
|
1875
|
+
const oraclePriceData = this.driftClient.getOracleDataForPerpMarket(perpMarket.marketIndex);
|
|
1876
1876
|
const oraclePrice = oraclePriceData.price;
|
|
1877
1877
|
const worstCaseBaseAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(settledLpPosition);
|
|
1878
1878
|
const marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(perpMarket, worstCaseBaseAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio));
|
|
1879
1879
|
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(perpMarket.quoteSpotMarketIndex);
|
|
1880
|
-
const quoteOraclePriceData = this.driftClient.
|
|
1880
|
+
const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
1881
1881
|
const baseAssetValue = worstCaseBaseAmount
|
|
1882
1882
|
.abs()
|
|
1883
1883
|
.mul(oraclePrice)
|
|
@@ -1999,14 +1999,10 @@ class User {
|
|
|
1999
1999
|
return this.getTotalPerpPositionValue(marginCategory, liquidationBuffer, includeOpenOrders).sub(currentPerpPositionValueUSDC);
|
|
2000
2000
|
}
|
|
2001
2001
|
getOracleDataForPerpMarket(marketIndex) {
|
|
2002
|
-
|
|
2003
|
-
const oracleData = this.driftClient.getOraclePriceDataAndSlot(oracleKey).data;
|
|
2004
|
-
return oracleData;
|
|
2002
|
+
return this.driftClient.getOracleDataForPerpMarket(marketIndex);
|
|
2005
2003
|
}
|
|
2006
2004
|
getOracleDataForSpotMarket(marketIndex) {
|
|
2007
|
-
|
|
2008
|
-
const oracleData = this.driftClient.getOraclePriceDataAndSlot(oracleKey).data;
|
|
2009
|
-
return oracleData;
|
|
2005
|
+
return this.driftClient.getOracleDataForSpotMarket(marketIndex);
|
|
2010
2006
|
}
|
|
2011
2007
|
}
|
|
2012
2008
|
exports.User = User;
|
package/package.json
CHANGED
|
@@ -49,7 +49,9 @@ export class PollingDriftClientAccountSubscriber
|
|
|
49
49
|
|
|
50
50
|
state?: DataAndSlot<StateAccount>;
|
|
51
51
|
perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
|
|
52
|
+
perpOracleMap = new Map<number, PublicKey>();
|
|
52
53
|
spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
|
|
54
|
+
spotOracleMap = new Map<number, PublicKey>();
|
|
53
55
|
oracles = new Map<string, DataAndSlot<OraclePriceData>>();
|
|
54
56
|
user?: DataAndSlot<UserAccount>;
|
|
55
57
|
|
|
@@ -114,6 +116,9 @@ export class PollingDriftClientAccountSubscriber
|
|
|
114
116
|
this.eventEmitter.emit('update');
|
|
115
117
|
}
|
|
116
118
|
|
|
119
|
+
this.setPerpOracleMap();
|
|
120
|
+
this.setSpotOracleMap();
|
|
121
|
+
|
|
117
122
|
this.isSubscribing = false;
|
|
118
123
|
this.isSubscribed = subscriptionSucceeded;
|
|
119
124
|
this.subscriptionPromiseResolver(subscriptionSucceeded);
|
|
@@ -367,6 +372,7 @@ export class PollingDriftClientAccountSubscriber
|
|
|
367
372
|
const accountToPoll = this.accountsToPoll.get(marketPublicKey.toString());
|
|
368
373
|
|
|
369
374
|
await this.addAccountToAccountLoader(accountToPoll);
|
|
375
|
+
this.setSpotOracleMap();
|
|
370
376
|
return true;
|
|
371
377
|
}
|
|
372
378
|
|
|
@@ -383,6 +389,7 @@ export class PollingDriftClientAccountSubscriber
|
|
|
383
389
|
await this.addPerpMarketAccountToPoll(marketIndex);
|
|
384
390
|
const accountToPoll = this.accountsToPoll.get(marketPublicKey.toString());
|
|
385
391
|
await this.addAccountToAccountLoader(accountToPoll);
|
|
392
|
+
this.setPerpOracleMap();
|
|
386
393
|
return true;
|
|
387
394
|
}
|
|
388
395
|
|
|
@@ -402,6 +409,26 @@ export class PollingDriftClientAccountSubscriber
|
|
|
402
409
|
return true;
|
|
403
410
|
}
|
|
404
411
|
|
|
412
|
+
private setPerpOracleMap() {
|
|
413
|
+
const perpMarkets = this.getMarketAccountsAndSlots();
|
|
414
|
+
for (const perpMarket of perpMarkets) {
|
|
415
|
+
const perpMarketAccount = perpMarket.data;
|
|
416
|
+
const perpMarketIndex = perpMarketAccount.marketIndex;
|
|
417
|
+
const oracle = perpMarketAccount.amm.oracle;
|
|
418
|
+
this.perpOracleMap.set(perpMarketIndex, oracle);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
private setSpotOracleMap() {
|
|
423
|
+
const spotMarkets = this.getSpotMarketAccountsAndSlots();
|
|
424
|
+
for (const spotMarket of spotMarkets) {
|
|
425
|
+
const spotMarketAccount = spotMarket.data;
|
|
426
|
+
const spotMarketIndex = spotMarketAccount.marketIndex;
|
|
427
|
+
const oracle = spotMarketAccount.oracle;
|
|
428
|
+
this.spotOracleMap.set(spotMarketIndex, oracle);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
405
432
|
assertIsSubscribed(): void {
|
|
406
433
|
if (!this.isSubscribed) {
|
|
407
434
|
throw new NotSubscribedError(
|
|
@@ -449,6 +476,49 @@ export class PollingDriftClientAccountSubscriber
|
|
|
449
476
|
return this.oracles.get(oraclePublicKey.toString());
|
|
450
477
|
}
|
|
451
478
|
|
|
479
|
+
public getOraclePriceDataAndSlotForPerpMarket(
|
|
480
|
+
marketIndex: number
|
|
481
|
+
): DataAndSlot<OraclePriceData> | undefined {
|
|
482
|
+
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
|
|
483
|
+
const oracle = this.perpOracleMap.get(marketIndex);
|
|
484
|
+
if (!perpMarketAccount || !oracle) {
|
|
485
|
+
return undefined;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (!perpMarketAccount.data.amm.oracle.equals(oracle)) {
|
|
489
|
+
// If the oracle has changed, we need to update the oracle map in background
|
|
490
|
+
this.addOracle({
|
|
491
|
+
source: perpMarketAccount.data.amm.oracleSource,
|
|
492
|
+
publicKey: perpMarketAccount.data.amm.oracle,
|
|
493
|
+
}).then(() => {
|
|
494
|
+
this.setPerpOracleMap();
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
public getOraclePriceDataAndSlotForSpotMarket(
|
|
502
|
+
marketIndex: number
|
|
503
|
+
): DataAndSlot<OraclePriceData> | undefined {
|
|
504
|
+
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
|
|
505
|
+
const oracle = this.spotOracleMap.get(marketIndex);
|
|
506
|
+
if (!spotMarketAccount || !oracle) {
|
|
507
|
+
return undefined;
|
|
508
|
+
}
|
|
509
|
+
if (!spotMarketAccount.data.oracle.equals(oracle)) {
|
|
510
|
+
// If the oracle has changed, we need to update the oracle map in background
|
|
511
|
+
this.addOracle({
|
|
512
|
+
source: spotMarketAccount.data.oracleSource,
|
|
513
|
+
publicKey: spotMarketAccount.data.oracle,
|
|
514
|
+
}).then(() => {
|
|
515
|
+
this.setSpotOracleMap();
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
520
|
+
}
|
|
521
|
+
|
|
452
522
|
public updateAccountLoaderPollingFrequency(pollingFrequency: number): void {
|
|
453
523
|
this.accountLoader.updatePollingFrequency(pollingFrequency);
|
|
454
524
|
}
|
package/src/accounts/types.ts
CHANGED
|
@@ -71,6 +71,12 @@ export interface DriftClientAccountSubscriber {
|
|
|
71
71
|
getOraclePriceDataAndSlot(
|
|
72
72
|
oraclePublicKey: PublicKey
|
|
73
73
|
): DataAndSlot<OraclePriceData> | undefined;
|
|
74
|
+
getOraclePriceDataAndSlotForPerpMarket(
|
|
75
|
+
marketIndex: number
|
|
76
|
+
): DataAndSlot<OraclePriceData> | undefined;
|
|
77
|
+
getOraclePriceDataAndSlotForSpotMarket(
|
|
78
|
+
marketIndex: number
|
|
79
|
+
): DataAndSlot<OraclePriceData> | undefined;
|
|
74
80
|
|
|
75
81
|
updateAccountLoaderPollingFrequency?: (pollingFrequency: number) => void;
|
|
76
82
|
}
|
|
@@ -41,10 +41,12 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
41
41
|
number,
|
|
42
42
|
AccountSubscriber<PerpMarketAccount>
|
|
43
43
|
>();
|
|
44
|
+
perpOracleMap = new Map<number, PublicKey>();
|
|
44
45
|
spotMarketAccountSubscribers = new Map<
|
|
45
46
|
number,
|
|
46
47
|
AccountSubscriber<SpotMarketAccount>
|
|
47
48
|
>();
|
|
49
|
+
spotOracleMap = new Map<number, PublicKey>();
|
|
48
50
|
oracleSubscribers = new Map<string, AccountSubscriber<OraclePriceData>>();
|
|
49
51
|
|
|
50
52
|
private isSubscribing = false;
|
|
@@ -123,6 +125,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
123
125
|
|
|
124
126
|
this.eventEmitter.emit('update');
|
|
125
127
|
|
|
128
|
+
this.setPerpOracleMap();
|
|
129
|
+
this.setSpotOracleMap();
|
|
130
|
+
|
|
126
131
|
this.isSubscribing = false;
|
|
127
132
|
this.isSubscribed = true;
|
|
128
133
|
this.subscriptionPromiseResolver(true);
|
|
@@ -280,14 +285,18 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
280
285
|
if (this.spotMarketAccountSubscribers.has(marketIndex)) {
|
|
281
286
|
return true;
|
|
282
287
|
}
|
|
283
|
-
|
|
288
|
+
const subscriptionSuccess = this.subscribeToSpotMarketAccount(marketIndex);
|
|
289
|
+
this.setSpotOracleMap();
|
|
290
|
+
return subscriptionSuccess;
|
|
284
291
|
}
|
|
285
292
|
|
|
286
293
|
async addPerpMarket(marketIndex: number): Promise<boolean> {
|
|
287
294
|
if (this.perpMarketAccountSubscribers.has(marketIndex)) {
|
|
288
295
|
return true;
|
|
289
296
|
}
|
|
290
|
-
|
|
297
|
+
const subscriptionSuccess = this.subscribeToPerpMarketAccount(marketIndex);
|
|
298
|
+
this.setPerpOracleMap();
|
|
299
|
+
return subscriptionSuccess;
|
|
291
300
|
}
|
|
292
301
|
|
|
293
302
|
async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
|
|
@@ -302,6 +311,32 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
302
311
|
return this.subscribeToOracle(oracleInfo);
|
|
303
312
|
}
|
|
304
313
|
|
|
314
|
+
private setPerpOracleMap() {
|
|
315
|
+
const perpMarkets = this.getMarketAccountsAndSlots();
|
|
316
|
+
for (const perpMarket of perpMarkets) {
|
|
317
|
+
if (!perpMarket) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
const perpMarketAccount = perpMarket.data;
|
|
321
|
+
const perpMarketIndex = perpMarketAccount.marketIndex;
|
|
322
|
+
const oracle = perpMarketAccount.amm.oracle;
|
|
323
|
+
this.perpOracleMap.set(perpMarketIndex, oracle);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private setSpotOracleMap() {
|
|
328
|
+
const spotMarkets = this.getSpotMarketAccountsAndSlots();
|
|
329
|
+
for (const spotMarket of spotMarkets) {
|
|
330
|
+
if (!spotMarket) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const spotMarketAccount = spotMarket.data;
|
|
334
|
+
const spotMarketIndex = spotMarketAccount.marketIndex;
|
|
335
|
+
const oracle = spotMarketAccount.oracle;
|
|
336
|
+
this.spotOracleMap.set(spotMarketIndex, oracle);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
305
340
|
assertIsSubscribed(): void {
|
|
306
341
|
if (!this.isSubscribed) {
|
|
307
342
|
throw new NotSubscribedError(
|
|
@@ -353,4 +388,48 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
353
388
|
}
|
|
354
389
|
return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
|
|
355
390
|
}
|
|
391
|
+
|
|
392
|
+
public getOraclePriceDataAndSlotForPerpMarket(
|
|
393
|
+
marketIndex: number
|
|
394
|
+
): DataAndSlot<OraclePriceData> | undefined {
|
|
395
|
+
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
|
|
396
|
+
const oracle = this.perpOracleMap.get(marketIndex);
|
|
397
|
+
if (!perpMarketAccount || !oracle) {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (!perpMarketAccount.data.amm.oracle.equals(oracle)) {
|
|
402
|
+
// If the oracle has changed, we need to update the oracle map in background
|
|
403
|
+
this.addOracle({
|
|
404
|
+
source: perpMarketAccount.data.amm.oracleSource,
|
|
405
|
+
publicKey: perpMarketAccount.data.amm.oracle,
|
|
406
|
+
}).then(() => {
|
|
407
|
+
this.setPerpOracleMap();
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
public getOraclePriceDataAndSlotForSpotMarket(
|
|
415
|
+
marketIndex: number
|
|
416
|
+
): DataAndSlot<OraclePriceData> | undefined {
|
|
417
|
+
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
|
|
418
|
+
const oracle = this.spotOracleMap.get(marketIndex);
|
|
419
|
+
if (!spotMarketAccount || !oracle) {
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (!spotMarketAccount.data.oracle.equals(oracle)) {
|
|
424
|
+
// If the oracle has changed, we need to update the oracle map in background
|
|
425
|
+
this.addOracle({
|
|
426
|
+
source: spotMarketAccount.data.oracleSource,
|
|
427
|
+
publicKey: spotMarketAccount.data.oracle,
|
|
428
|
+
}).then(() => {
|
|
429
|
+
this.setSpotOracleMap();
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return this.getOraclePriceDataAndSlot(oracle);
|
|
434
|
+
}
|
|
356
435
|
}
|
package/src/driftClient.ts
CHANGED
|
@@ -5873,17 +5873,15 @@ export class DriftClient {
|
|
|
5873
5873
|
}
|
|
5874
5874
|
|
|
5875
5875
|
public getOracleDataForPerpMarket(marketIndex: number): OraclePriceData {
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
return oracleData;
|
|
5876
|
+
return this.accountSubscriber.getOraclePriceDataAndSlotForPerpMarket(
|
|
5877
|
+
marketIndex
|
|
5878
|
+
).data;
|
|
5880
5879
|
}
|
|
5881
5880
|
|
|
5882
5881
|
public getOracleDataForSpotMarket(marketIndex: number): OraclePriceData {
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
return oracleData;
|
|
5882
|
+
return this.accountSubscriber.getOraclePriceDataAndSlotForSpotMarket(
|
|
5883
|
+
marketIndex
|
|
5884
|
+
).data;
|
|
5887
5885
|
}
|
|
5888
5886
|
|
|
5889
5887
|
public async initializeInsuranceFundStake(
|
|
@@ -6185,9 +6183,13 @@ export class DriftClient {
|
|
|
6185
6183
|
}
|
|
6186
6184
|
}
|
|
6187
6185
|
|
|
6186
|
+
const userAccountExists =
|
|
6187
|
+
!!this.getUser()?.accountSubscriber?.isSubscribed &&
|
|
6188
|
+
(await this.checkIfAccountExists(this.getUser().userAccountPublicKey));
|
|
6189
|
+
|
|
6188
6190
|
const remainingAccounts = this.getRemainingAccounts({
|
|
6189
|
-
userAccounts: [this.getUserAccount()],
|
|
6190
|
-
useMarketLastSlotCache:
|
|
6191
|
+
userAccounts: userAccountExists ? [this.getUserAccount()] : [],
|
|
6192
|
+
useMarketLastSlotCache: false,
|
|
6191
6193
|
writableSpotMarketIndexes: [marketIndex],
|
|
6192
6194
|
});
|
|
6193
6195
|
|
|
@@ -5,6 +5,7 @@ import { PythClient } from '../oracles/pythClient';
|
|
|
5
5
|
// import { SwitchboardClient } from '../oracles/switchboardClient';
|
|
6
6
|
import { QuoteAssetOracleClient } from '../oracles/quoteAssetOracleClient';
|
|
7
7
|
import { BN } from '@coral-xyz/anchor';
|
|
8
|
+
import { SwitchboardClient } from '../oracles/switchboardClient';
|
|
8
9
|
|
|
9
10
|
export function getOracleClient(
|
|
10
11
|
oracleSource: OracleSource,
|
|
@@ -26,9 +27,9 @@ export function getOracleClient(
|
|
|
26
27
|
return new PythClient(connection, undefined, true);
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (isVariant(oracleSource, 'switchboard')) {
|
|
31
|
+
return new SwitchboardClient(connection);
|
|
32
|
+
}
|
|
32
33
|
|
|
33
34
|
if (isVariant(oracleSource, 'quoteAsset')) {
|
|
34
35
|
return new QuoteAssetOracleClient();
|