@drift-labs/sdk 0.1.23-master.3 → 0.1.25-master.0

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 (61) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +2 -0
  2. package/lib/accounts/bulkAccountLoader.js +26 -11
  3. package/lib/addresses.js +5 -1
  4. package/lib/admin.d.ts +2 -2
  5. package/lib/admin.js +11 -5
  6. package/lib/clearingHouse.js +7 -1
  7. package/lib/clearingHouseUser.d.ts +12 -17
  8. package/lib/clearingHouseUser.js +114 -217
  9. package/lib/constants/markets.d.ts +4 -4
  10. package/lib/constants/markets.js +22 -0
  11. package/lib/constants/numericConstants.d.ts +2 -2
  12. package/lib/constants/numericConstants.js +3 -3
  13. package/lib/factory/oracleClient.d.ts +5 -0
  14. package/lib/factory/oracleClient.js +16 -0
  15. package/lib/idl/clearing_house.json +53 -5
  16. package/lib/idl/switchboard_v2.json +4663 -0
  17. package/lib/index.d.ts +4 -1
  18. package/lib/index.js +9 -2
  19. package/lib/math/funding.d.ts +6 -6
  20. package/lib/math/funding.js +4 -16
  21. package/lib/math/orders.d.ts +1 -0
  22. package/lib/math/orders.js +19 -1
  23. package/lib/mockUSDCFaucet.js +5 -1
  24. package/lib/oracles/pythClient.d.ts +14 -0
  25. package/lib/oracles/pythClient.js +53 -0
  26. package/lib/oracles/switchboardClient.d.ts +13 -0
  27. package/lib/oracles/switchboardClient.js +76 -0
  28. package/lib/oracles/types.d.ts +15 -0
  29. package/lib/oracles/types.js +2 -0
  30. package/lib/orderParams.d.ts +1 -1
  31. package/lib/orderParams.js +2 -2
  32. package/lib/orders.js +1 -1
  33. package/lib/types.d.ts +5 -1
  34. package/package.json +2 -1
  35. package/src/accounts/bulkAccountLoader.ts +37 -13
  36. package/src/accounts/types.js +10 -0
  37. package/src/accounts/utils.js +7 -0
  38. package/src/accounts/webSocketAccountSubscriber.js +76 -0
  39. package/src/addresses.js +83 -0
  40. package/src/admin.ts +15 -4
  41. package/src/clearingHouse.ts +2 -0
  42. package/src/clearingHouseUser.ts +161 -330
  43. package/src/constants/markets.ts +26 -3
  44. package/src/constants/numericConstants.ts +2 -2
  45. package/src/factory/oracleClient.ts +22 -0
  46. package/src/idl/clearing_house.json +53 -5
  47. package/src/idl/switchboard_v2.json +4663 -0
  48. package/src/index.ts +4 -1
  49. package/src/math/funding.ts +9 -25
  50. package/src/math/orders.ts +28 -0
  51. package/src/mockUSDCFaucet.js +171 -0
  52. package/src/oracles/pythClient.ts +49 -0
  53. package/src/oracles/switchboardClient.ts +87 -0
  54. package/src/oracles/types.ts +15 -0
  55. package/src/orderParams.ts +3 -2
  56. package/src/orders.ts +1 -1
  57. package/src/types.js +60 -0
  58. package/src/types.ts +6 -1
  59. package/lib/pythClient.d.ts +0 -7
  60. package/lib/pythClient.js +0 -25
  61. package/src/pythClient.ts +0 -15
package/lib/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import { PublicKey } from '@solana/web3.js';
3
3
  export * from './mockUSDCFaucet';
4
- export * from './pythClient';
4
+ export * from './oracles/types';
5
+ export * from './oracles/pythClient';
6
+ export * from './oracles/switchboardClient';
5
7
  export * from './types';
6
8
  export * from './constants/markets';
7
9
  export * from './accounts/webSocketClearingHouseAccountSubscriber';
@@ -16,6 +18,7 @@ export * from './clearingHouseUser';
16
18
  export * from './clearingHouse';
17
19
  export * from './factory/clearingHouse';
18
20
  export * from './factory/clearingHouseUser';
21
+ export * from './factory/oracleClient';
19
22
  export * from './math/conversion';
20
23
  export * from './math/funding';
21
24
  export * from './math/insuranceFund';
package/lib/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -16,7 +20,9 @@ Object.defineProperty(exports, "BN", { enumerable: true, get: function () { retu
16
20
  const web3_js_1 = require("@solana/web3.js");
17
21
  Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return web3_js_1.PublicKey; } });
18
22
  __exportStar(require("./mockUSDCFaucet"), exports);
19
- __exportStar(require("./pythClient"), exports);
23
+ __exportStar(require("./oracles/types"), exports);
24
+ __exportStar(require("./oracles/pythClient"), exports);
25
+ __exportStar(require("./oracles/switchboardClient"), exports);
20
26
  __exportStar(require("./types"), exports);
21
27
  __exportStar(require("./constants/markets"), exports);
22
28
  __exportStar(require("./accounts/webSocketClearingHouseAccountSubscriber"), exports);
@@ -31,6 +37,7 @@ __exportStar(require("./clearingHouseUser"), exports);
31
37
  __exportStar(require("./clearingHouse"), exports);
32
38
  __exportStar(require("./factory/clearingHouse"), exports);
33
39
  __exportStar(require("./factory/clearingHouseUser"), exports);
40
+ __exportStar(require("./factory/oracleClient"), exports);
34
41
  __exportStar(require("./math/conversion"), exports);
35
42
  __exportStar(require("./math/funding"), exports);
36
43
  __exportStar(require("./math/insuranceFund"), exports);
@@ -1,15 +1,15 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@project-serum/anchor';
3
- import { PriceData } from '@pythnetwork/client';
4
3
  import { Market } from '../types';
4
+ import { OraclePriceData } from '../oracles/types';
5
5
  /**
6
6
  *
7
7
  * @param market
8
- * @param pythClient
8
+ * @param oraclePriceData
9
9
  * @param periodAdjustment
10
10
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
11
11
  */
12
- export declare function calculateAllEstimatedFundingRate(market: Market, oraclePriceData: PriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
12
+ export declare function calculateAllEstimatedFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
13
13
  /**
14
14
  *
15
15
  * @param market
@@ -18,7 +18,7 @@ export declare function calculateAllEstimatedFundingRate(market: Market, oracleP
18
18
  * @param estimationMethod
19
19
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
20
20
  */
21
- export declare function calculateEstimatedFundingRate(market: Market, oraclePriceData: PriceData, periodAdjustment: BN, estimationMethod: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
21
+ export declare function calculateEstimatedFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment: BN, estimationMethod: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
22
22
  /**
23
23
  *
24
24
  * @param market
@@ -26,7 +26,7 @@ export declare function calculateEstimatedFundingRate(market: Market, oraclePric
26
26
  * @param periodAdjustment
27
27
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
28
28
  */
29
- export declare function calculateLongShortFundingRate(market: Market, oraclePriceData: PriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
29
+ export declare function calculateLongShortFundingRate(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
30
30
  /**
31
31
  *
32
32
  * @param market
@@ -34,7 +34,7 @@ export declare function calculateLongShortFundingRate(market: Market, oraclePric
34
34
  * @param periodAdjustment
35
35
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
36
36
  */
37
- export declare function calculateLongShortFundingRateAndLiveTwaps(market: Market, oraclePriceData: PriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
37
+ export declare function calculateLongShortFundingRateAndLiveTwaps(market: Market, oraclePriceData: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
38
38
  /**
39
39
  *
40
40
  * @param market
@@ -16,7 +16,7 @@ const market_1 = require("./market");
16
16
  /**
17
17
  *
18
18
  * @param market
19
- * @param pythClient
19
+ * @param oraclePriceData
20
20
  * @param periodAdjustment
21
21
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
22
22
  */
@@ -51,21 +51,9 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
51
51
  const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
52
52
  const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
53
53
  const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, secondsInHour.sub(timeSinceLastOracleTwapUpdate));
54
- // verify pyth input is positive for live update
55
- let oracleStablePriceNum = 0;
56
- let oracleInputCount = 0;
57
- if (oraclePriceData.price >= 0) {
58
- oracleStablePriceNum += oraclePriceData.price;
59
- oracleInputCount += 1;
60
- }
61
- if (oraclePriceData.previousPrice >= 0) {
62
- oracleStablePriceNum += oraclePriceData.previousPrice;
63
- oracleInputCount += 1;
64
- }
65
- oracleStablePriceNum = oracleStablePriceNum / oracleInputCount;
66
- const oraclePriceStableWithMantissa = new anchor_1.BN(oracleStablePriceNum * numericConstants_1.MARK_PRICE_PRECISION.toNumber());
54
+ const oraclePrice = oraclePriceData.price;
67
55
  let oracleTwapWithMantissa = lastOracleTwapWithMantissa;
68
- const oracleLiveVsTwap = oraclePriceStableWithMantissa
56
+ const oracleLiveVsTwap = oraclePrice
69
57
  .sub(lastOracleTwapWithMantissa)
70
58
  .abs()
71
59
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
@@ -75,7 +63,7 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
75
63
  if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
76
64
  oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
77
65
  .mul(lastOracleTwapWithMantissa)
78
- .add(timeSinceLastMarkChange.mul(oraclePriceStableWithMantissa))
66
+ .add(timeSinceLastMarkChange.mul(oraclePrice))
79
67
  .div(timeSinceLastOracleTwapUpdate.add(oracleTwapTimeSinceLastUpdate));
80
68
  }
81
69
  const twapSpread = lastMarkTwapWithMantissa.sub(lastOracleTwapWithMantissa);
@@ -2,3 +2,4 @@ import { ClearingHouseUser } from '../clearingHouseUser';
2
2
  import { Order } from '../types';
3
3
  export declare function isOrderRiskIncreasing(user: ClearingHouseUser, order: Order): boolean;
4
4
  export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouseUser, order: Order): boolean;
5
+ export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
3
+ exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
4
4
  const types_1 = require("../types");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  function isOrderRiskIncreasing(user, order) {
@@ -52,3 +52,21 @@ function isOrderRiskIncreasingInSameDirection(user, order) {
52
52
  return false;
53
53
  }
54
54
  exports.isOrderRiskIncreasingInSameDirection = isOrderRiskIncreasingInSameDirection;
55
+ function isOrderReduceOnly(user, order) {
56
+ if ((0, types_1.isVariant)(order.status, 'init')) {
57
+ return false;
58
+ }
59
+ const position = user.getUserPosition(order.marketIndex) ||
60
+ user.getEmptyPosition(order.marketIndex);
61
+ // if position is long and order is long
62
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(order.direction, 'long')) {
63
+ return false;
64
+ }
65
+ // if position is short and order is short
66
+ if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
67
+ (0, types_1.isVariant)(order.direction, 'short')) {
68
+ return false;
69
+ }
70
+ return order.baseAssetAmount.abs().lte(position.baseAssetAmount.abs());
71
+ }
72
+ exports.isOrderReduceOnly = isOrderReduceOnly;
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="bn.js" />
3
+ import { PriceData } from '@pythnetwork/client';
4
+ import { Connection, PublicKey } from '@solana/web3.js';
5
+ import { OraclePriceData } from './types';
6
+ import { BN } from '@project-serum/anchor';
7
+ export declare class PythClient {
8
+ private connection;
9
+ constructor(connection: Connection);
10
+ getPriceData(pricePublicKey: PublicKey): Promise<PriceData>;
11
+ getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
12
+ getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
13
+ }
14
+ export declare function convertPythPrice(price: number, exponent: number): BN;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.convertPythPrice = exports.PythClient = void 0;
13
+ const client_1 = require("@pythnetwork/client");
14
+ const anchor_1 = require("@project-serum/anchor");
15
+ const numericConstants_1 = require("../constants/numericConstants");
16
+ class PythClient {
17
+ constructor(connection) {
18
+ this.connection = connection;
19
+ }
20
+ getPriceData(pricePublicKey) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const account = yield this.connection.getAccountInfo(pricePublicKey);
23
+ return (0, client_1.parsePriceData)(account.data);
24
+ });
25
+ }
26
+ getOraclePriceData(pricePublicKey) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const accountInfo = yield this.connection.getAccountInfo(pricePublicKey);
29
+ return this.getOraclePriceDataFromBuffer(accountInfo.data);
30
+ });
31
+ }
32
+ getOraclePriceDataFromBuffer(buffer) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const priceData = (0, client_1.parsePriceData)(buffer);
35
+ return {
36
+ price: convertPythPrice(priceData.price, priceData.exponent),
37
+ slot: new anchor_1.BN(priceData.lastSlot.toString()),
38
+ confidence: convertPythPrice(priceData.confidence, priceData.exponent),
39
+ twap: convertPythPrice(priceData.twap.value, priceData.exponent),
40
+ twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent),
41
+ };
42
+ });
43
+ }
44
+ }
45
+ exports.PythClient = PythClient;
46
+ function convertPythPrice(price, exponent) {
47
+ exponent = Math.abs(exponent);
48
+ const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs());
49
+ return new anchor_1.BN(price * Math.pow(10, exponent))
50
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
51
+ .div(pythPrecision);
52
+ }
53
+ exports.convertPythPrice = convertPythPrice;
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ import { Connection, PublicKey } from '@solana/web3.js';
3
+ import { DriftEnv } from '../config';
4
+ import { Program } from '@project-serum/anchor';
5
+ import { OracleClient, OraclePriceData } from './types';
6
+ export declare class SwitchboardClient implements OracleClient {
7
+ connection: Connection;
8
+ env: DriftEnv;
9
+ constructor(connection: Connection, env: DriftEnv);
10
+ getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
11
+ getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
12
+ getProgram(): Promise<Program>;
13
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SwitchboardClient = void 0;
16
+ const switchboard_v2_1 = require("@switchboard-xyz/switchboard-v2");
17
+ const web3_js_1 = require("@solana/web3.js");
18
+ const anchor_1 = require("@project-serum/anchor");
19
+ const numericConstants_1 = require("../constants/numericConstants");
20
+ const wallet_1 = require("../wallet");
21
+ const switchboard_v2_json_1 = __importDefault(require("../idl/switchboard_v2.json"));
22
+ // cache switchboard program for every client object since itll always be the same
23
+ const programMap = new Map();
24
+ class SwitchboardClient {
25
+ constructor(connection, env) {
26
+ this.connection = connection;
27
+ this.env = env;
28
+ }
29
+ getOraclePriceData(pricePublicKey) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ const accountInfo = yield this.connection.getAccountInfo(pricePublicKey);
32
+ return this.getOraclePriceDataFromBuffer(accountInfo.data);
33
+ });
34
+ }
35
+ getOraclePriceDataFromBuffer(buffer) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ const program = yield this.getProgram();
38
+ const aggregatorAccountData = program.account.aggregatorAccountData.coder.accounts.decode('AggregatorAccountData', buffer);
39
+ const price = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.result);
40
+ const confidence = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound
41
+ .stdDeviation);
42
+ const slot = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
43
+ return {
44
+ price,
45
+ slot,
46
+ confidence,
47
+ };
48
+ });
49
+ }
50
+ getProgram() {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ if (programMap.has(this.env)) {
53
+ return programMap.get(this.env);
54
+ }
55
+ const program = yield getSwitchboardProgram(this.env, this.connection);
56
+ programMap.set(this.env, program);
57
+ return program;
58
+ });
59
+ }
60
+ }
61
+ exports.SwitchboardClient = SwitchboardClient;
62
+ function getSwitchboardProgram(env, connection) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ const DEFAULT_KEYPAIR = web3_js_1.Keypair.fromSeed(new Uint8Array(32).fill(1));
65
+ const programId = (0, switchboard_v2_1.getSwitchboardPid)(env);
66
+ const wallet = new wallet_1.Wallet(DEFAULT_KEYPAIR);
67
+ const provider = new anchor_1.Provider(connection, wallet, {});
68
+ return new anchor_1.Program(switchboard_v2_json_1.default, programId, provider);
69
+ });
70
+ }
71
+ function convertSwitchboardDecimal(switchboardDecimal) {
72
+ const switchboardPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(switchboardDecimal.scale));
73
+ return switchboardDecimal.mantissa
74
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
75
+ .div(switchboardPrecision);
76
+ }
@@ -0,0 +1,15 @@
1
+ /// <reference types="bn.js" />
2
+ /// <reference types="node" />
3
+ import { BN } from '@project-serum/anchor';
4
+ import { PublicKey } from '@solana/web3.js';
5
+ export declare type OraclePriceData = {
6
+ price: BN;
7
+ slot: BN;
8
+ confidence: BN;
9
+ twap?: BN;
10
+ twapConfidence?: BN;
11
+ };
12
+ export interface OracleClient {
13
+ getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
14
+ getOraclePriceData(publicKey: PublicKey): Promise<OraclePriceData>;
15
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { OrderParams, OrderTriggerCondition, PositionDirection } from './types';
3
3
  import { BN } from '@project-serum/anchor';
4
- export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
4
+ export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number, postOnly?: boolean): OrderParams;
5
5
  export declare function getTriggerMarketOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
6
6
  export declare function getTriggerLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
7
7
  export declare function getMarketOrderParams(marketIndex: BN, direction: PositionDirection, quoteAssetAmount: BN, baseAssetAmount: BN, reduceOnly: boolean, price?: BN, discountToken?: boolean, referrer?: boolean): OrderParams;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
4
4
  const types_1 = require("./types");
5
5
  const numericConstants_1 = require("./constants/numericConstants");
6
- function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0) {
6
+ function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0, postOnly = false) {
7
7
  return {
8
8
  orderType: types_1.OrderType.LIMIT,
9
9
  userOrderId,
@@ -13,7 +13,7 @@ function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, red
13
13
  baseAssetAmount,
14
14
  price,
15
15
  reduceOnly,
16
- postOnly: false,
16
+ postOnly,
17
17
  immediateOrCancel: false,
18
18
  positionLimit: numericConstants_1.ZERO,
19
19
  padding0: true,
package/lib/orders.js CHANGED
@@ -137,7 +137,7 @@ function isTriggerConditionSatisfied(market, order) {
137
137
  }
138
138
  }
139
139
  function calculateBaseAssetAmountUserCanExecute(market, order, user) {
140
- const maxLeverage = user.getMaxLeverage('Initial');
140
+ const maxLeverage = user.getMaxLeverage(order.marketIndex, 'Initial');
141
141
  const freeCollateral = user.getFreeCollateral();
142
142
  let quoteAssetAmount;
143
143
  if ((0, _1.isOrderRiskIncreasingInSameDirection)(user, order)) {
package/lib/types.d.ts CHANGED
@@ -225,6 +225,7 @@ export declare type OrderRecord = {
225
225
  fee: BN;
226
226
  fillerReward: BN;
227
227
  tradeRecordId: BN;
228
+ quoteAssetAmountSurplus: BN;
228
229
  };
229
230
  export declare type StateAccount = {
230
231
  admin: PublicKey;
@@ -272,7 +273,6 @@ export declare type OrderStateAccount = {
272
273
  minOrderQuoteAssetAmount: BN;
273
274
  };
274
275
  export declare type MarketsAccount = {
275
- accountIndex: BN;
276
276
  markets: Market[];
277
277
  };
278
278
  export declare type Market = {
@@ -282,6 +282,9 @@ export declare type Market = {
282
282
  baseAssetAmountShort: BN;
283
283
  initialized: boolean;
284
284
  openInterest: BN;
285
+ marginRatioInitial: number;
286
+ marginRatioMaintenance: number;
287
+ marginRatioPartial: number;
285
288
  };
286
289
  export declare type AMM = {
287
290
  baseAssetReserve: BN;
@@ -434,3 +437,4 @@ export declare type OrderFillerRewardStructure = {
434
437
  rewardDenominator: BN;
435
438
  timeBasedRewardLowerBound: BN;
436
439
  };
440
+ export declare type MarginCategory = 'Initial' | 'Partial' | 'Maintenance';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.23-master.3",
3
+ "version": "0.1.25-master.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -32,6 +32,7 @@
32
32
  "@pythnetwork/client": "^2.5.1",
33
33
  "@solana/spl-token": "^0.1.6",
34
34
  "@solana/web3.js": "^1.22.0",
35
+ "@switchboard-xyz/switchboard-v2": "^0.0.67",
35
36
  "strict-event-emitter-types": "^2.0.0",
36
37
  "uuid": "^8.3.2"
37
38
  },
@@ -9,6 +9,8 @@ type AccountToLoad = {
9
9
 
10
10
  const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
11
11
 
12
+ const fiveMinutes = 5 * 60 * 1000;
13
+
12
14
  export class BulkAccountLoader {
13
15
  connection: Connection;
14
16
  commitment: Commitment;
@@ -20,6 +22,8 @@ export class BulkAccountLoader {
20
22
  // to handle clients spamming load
21
23
  loadPromise?: Promise<void>;
22
24
  loadPromiseResolver: () => void;
25
+ loggingEnabled = false;
26
+ lastUpdate = Date.now();
23
27
 
24
28
  public constructor(
25
29
  connection: Connection,
@@ -100,6 +104,10 @@ export class BulkAccountLoader {
100
104
  this.loadPromiseResolver = resolver;
101
105
  });
102
106
 
107
+ if (this.loggingEnabled) {
108
+ console.log('Loading accounts');
109
+ }
110
+
103
111
  try {
104
112
  const chunks = this.chunks(
105
113
  Array.from(this.accountsToLoad.values()),
@@ -120,6 +128,20 @@ export class BulkAccountLoader {
120
128
  } finally {
121
129
  this.loadPromiseResolver();
122
130
  this.loadPromise = undefined;
131
+
132
+ const now = Date.now();
133
+ if (now - this.lastUpdate > fiveMinutes) {
134
+ if (this.loggingEnabled) {
135
+ console.log(
136
+ "Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object"
137
+ );
138
+ }
139
+ this.connection = new Connection(
140
+ // @ts-ignore
141
+ this.connection._rpcEndpoint,
142
+ this.connection.commitment
143
+ );
144
+ }
123
145
  }
124
146
  }
125
147
 
@@ -135,19 +157,11 @@ export class BulkAccountLoader {
135
157
  { commitment: this.commitment },
136
158
  ];
137
159
 
138
- let rpcResponse;
139
- try {
140
- // @ts-ignore
141
- rpcResponse = await this.connection._rpcRequest(
142
- 'getMultipleAccounts',
143
- args
144
- );
145
- } catch (e) {
146
- for (const [_, callback] of this.errorCallbacks) {
147
- callback(e);
148
- }
149
- return;
150
- }
160
+ // @ts-ignore
161
+ const rpcResponse = await this.connection._rpcRequest(
162
+ 'getMultipleAccounts',
163
+ args
164
+ );
151
165
 
152
166
  const newSlot = rpcResponse.result.context.slot;
153
167
 
@@ -169,6 +183,7 @@ export class BulkAccountLoader {
169
183
  buffer: newBuffer,
170
184
  });
171
185
  this.handleAccountCallbacks(accountToLoad, newBuffer);
186
+ this.lastUpdate = Date.now();
172
187
  continue;
173
188
  }
174
189
 
@@ -183,6 +198,7 @@ export class BulkAccountLoader {
183
198
  buffer: newBuffer,
184
199
  });
185
200
  this.handleAccountCallbacks(accountToLoad, newBuffer);
201
+ this.lastUpdate = Date.now();
186
202
  }
187
203
  }
188
204
  }
@@ -203,6 +219,10 @@ export class BulkAccountLoader {
203
219
  return;
204
220
  }
205
221
 
222
+ if (this.loggingEnabled) {
223
+ console.log(`startPolling`);
224
+ }
225
+
206
226
  this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
207
227
  }
208
228
 
@@ -210,6 +230,10 @@ export class BulkAccountLoader {
210
230
  if (this.intervalId) {
211
231
  clearInterval(this.intervalId);
212
232
  this.intervalId = undefined;
233
+
234
+ if (this.loggingEnabled) {
235
+ console.log(`stopPolling`);
236
+ }
213
237
  }
214
238
  }
215
239
  }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NotSubscribedError = void 0;
4
+ class NotSubscribedError extends Error {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.name = 'NotSubscribedError';
8
+ }
9
+ }
10
+ exports.NotSubscribedError = NotSubscribedError;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capitalize = void 0;
4
+ function capitalize(value) {
5
+ return value[0].toUpperCase() + value.slice(1);
6
+ }
7
+ exports.capitalize = capitalize;