@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.
@@ -0,0 +1,74 @@
1
+ import { Connection, PublicKey } from '@solana/web3.js';
2
+ import { PRICE_PRECISION, TEN } from '../constants/numericConstants';
3
+ import { OracleClient, OraclePriceData } from './types';
4
+ import switchboardV2Idl from '../idl/switchboard.json';
5
+ import { BorshAccountsCoder, BN, Idl } from '@coral-xyz/anchor';
6
+
7
+ type SwitchboardDecimal = {
8
+ scale: number;
9
+ mantissa: BN;
10
+ };
11
+
12
+ type AggregatorAccountData = {
13
+ latestConfirmedRound: {
14
+ result: SwitchboardDecimal;
15
+ stdDeviation: SwitchboardDecimal;
16
+ numSuccess: number;
17
+ roundOpenSlot: BN;
18
+ };
19
+ minOracleResults: number;
20
+ };
21
+
22
+ export class SwitchboardClient implements OracleClient {
23
+ connection: Connection;
24
+ coder: BorshAccountsCoder;
25
+
26
+ public constructor(connection: Connection) {
27
+ this.connection = connection;
28
+ this.coder = new BorshAccountsCoder(switchboardV2Idl as Idl);
29
+ }
30
+
31
+ public async getOraclePriceData(
32
+ pricePublicKey: PublicKey
33
+ ): Promise<OraclePriceData> {
34
+ const accountInfo = await this.connection.getAccountInfo(pricePublicKey);
35
+ return this.getOraclePriceDataFromBuffer(accountInfo.data);
36
+ }
37
+
38
+ public getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData {
39
+ const aggregatorAccountData = this.coder.decodeUnchecked(
40
+ 'AggregatorAccountData',
41
+ buffer
42
+ ) as AggregatorAccountData;
43
+
44
+ const price = convertSwitchboardDecimal(
45
+ aggregatorAccountData.latestConfirmedRound.result
46
+ );
47
+
48
+ const confidence = convertSwitchboardDecimal(
49
+ aggregatorAccountData.latestConfirmedRound.stdDeviation
50
+ );
51
+
52
+ const hasSufficientNumberOfDataPoints =
53
+ aggregatorAccountData.latestConfirmedRound.numSuccess >=
54
+ aggregatorAccountData.minOracleResults;
55
+
56
+ const slot: BN = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
57
+ return {
58
+ price,
59
+ slot,
60
+ confidence,
61
+ hasSufficientNumberOfDataPoints,
62
+ };
63
+ }
64
+ }
65
+
66
+ function convertSwitchboardDecimal(switchboardDecimal: {
67
+ scale: number;
68
+ mantissa: BN;
69
+ }): BN {
70
+ const switchboardPrecision = TEN.pow(new BN(switchboardDecimal.scale));
71
+ return switchboardDecimal.mantissa
72
+ .mul(PRICE_PRECISION)
73
+ .div(switchboardPrecision);
74
+ }
package/src/types.ts CHANGED
@@ -93,7 +93,7 @@ export class OracleSource {
93
93
  static readonly PYTH = { pyth: {} };
94
94
  static readonly PYTH_1K = { pyth1K: {} };
95
95
  static readonly PYTH_1M = { pyth1M: {} };
96
- // static readonly SWITCHBOARD = { switchboard: {} };
96
+ static readonly SWITCHBOARD = { switchboard: {} };
97
97
  static readonly QUOTE_ASSET = { quoteAsset: {} };
98
98
  static readonly PYTH_STABLE_COIN = { pythStableCoin: {} };
99
99
  }
package/src/user.ts CHANGED
@@ -1307,9 +1307,9 @@ export class User {
1307
1307
  const quoteSpotMarket = this.driftClient.getSpotMarketAccount(
1308
1308
  market.quoteSpotMarketIndex
1309
1309
  );
1310
- const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(
1311
- quoteSpotMarket.oracle
1312
- ).data;
1310
+ const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(
1311
+ QUOTE_SPOT_MARKET_INDEX
1312
+ );
1313
1313
 
1314
1314
  let quotePrice;
1315
1315
  if (strict) {
@@ -2205,7 +2205,7 @@ export class User {
2205
2205
  if (signedTokenAmount.gt(ZERO)) {
2206
2206
  const assetWeight = calculateAssetWeight(
2207
2207
  signedTokenAmount,
2208
- this.driftClient.getOraclePriceDataAndSlot(market.oracle).data.price,
2208
+ this.driftClient.getOracleDataForSpotMarket(market.marketIndex).price,
2209
2209
  market,
2210
2210
  marginCategory
2211
2211
  );
@@ -2388,9 +2388,8 @@ export class User {
2388
2388
  currentSpotMarketNetValue?: BN
2389
2389
  ): BN {
2390
2390
  const market = this.driftClient.getSpotMarketAccount(targetMarketIndex);
2391
- const oraclePrice = this.driftClient.getOraclePriceDataAndSlot(
2392
- market.oracle
2393
- ).data.price;
2391
+ const oraclePrice =
2392
+ this.driftClient.getOracleDataForSpotMarket(targetMarketIndex).price;
2394
2393
 
2395
2394
  currentQuoteAssetValue = this.getSpotMarketAssetValue(
2396
2395
  QUOTE_SPOT_MARKET_INDEX
@@ -3401,9 +3400,9 @@ export class User {
3401
3400
  const perpMarket = this.driftClient.getPerpMarketAccount(
3402
3401
  perpPosition.marketIndex
3403
3402
  );
3404
- const oraclePriceData = this.driftClient.getOraclePriceDataAndSlot(
3405
- perpMarket.amm.oracle
3406
- ).data;
3403
+ const oraclePriceData = this.driftClient.getOracleDataForPerpMarket(
3404
+ perpMarket.marketIndex
3405
+ );
3407
3406
  const oraclePrice = oraclePriceData.price;
3408
3407
  const worstCaseBaseAmount =
3409
3408
  calculateWorstCaseBaseAssetAmount(settledLpPosition);
@@ -3420,9 +3419,9 @@ export class User {
3420
3419
  const quoteSpotMarket = this.driftClient.getSpotMarketAccount(
3421
3420
  perpMarket.quoteSpotMarketIndex
3422
3421
  );
3423
- const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(
3424
- quoteSpotMarket.oracle
3425
- ).data;
3422
+ const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(
3423
+ QUOTE_SPOT_MARKET_INDEX
3424
+ );
3426
3425
 
3427
3426
  const baseAssetValue = worstCaseBaseAmount
3428
3427
  .abs()
@@ -3645,20 +3644,10 @@ export class User {
3645
3644
  }
3646
3645
 
3647
3646
  private getOracleDataForPerpMarket(marketIndex: number): OraclePriceData {
3648
- const oracleKey =
3649
- this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
3650
- const oracleData =
3651
- this.driftClient.getOraclePriceDataAndSlot(oracleKey).data;
3652
-
3653
- return oracleData;
3647
+ return this.driftClient.getOracleDataForPerpMarket(marketIndex);
3654
3648
  }
3655
3649
 
3656
3650
  private getOracleDataForSpotMarket(marketIndex: number): OraclePriceData {
3657
- const oracleKey = this.driftClient.getSpotMarketAccount(marketIndex).oracle;
3658
-
3659
- const oracleData =
3660
- this.driftClient.getOraclePriceDataAndSlot(oracleKey).data;
3661
-
3662
- return oracleData;
3651
+ return this.driftClient.getOracleDataForSpotMarket(marketIndex);
3663
3652
  }
3664
3653
  }