@drift-labs/sdk 0.1.20 → 0.1.21-master.5

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 (126) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +0 -1
  2. package/lib/accounts/bulkAccountLoader.js +17 -6
  3. package/lib/accounts/bulkUserSubscription.d.ts +0 -1
  4. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +5 -2
  5. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +23 -1
  6. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +0 -1
  7. package/lib/accounts/pollingUserAccountSubscriber.d.ts +3 -2
  8. package/lib/accounts/pollingUserAccountSubscriber.js +13 -0
  9. package/lib/accounts/types.d.ts +8 -3
  10. package/lib/accounts/utils.d.ts +0 -1
  11. package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
  12. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +5 -2
  13. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +25 -0
  14. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +3 -2
  15. package/lib/accounts/webSocketUserAccountSubscriber.js +11 -0
  16. package/lib/addresses.d.ts +4 -1
  17. package/lib/addresses.js +28 -1
  18. package/lib/admin.d.ts +10 -4
  19. package/lib/admin.js +48 -3
  20. package/lib/assert/assert.d.ts +0 -1
  21. package/lib/clearingHouse.d.ts +27 -2
  22. package/lib/clearingHouse.js +307 -7
  23. package/lib/clearingHouseUser.d.ts +16 -3
  24. package/lib/clearingHouseUser.js +79 -9
  25. package/lib/config.d.ts +0 -1
  26. package/lib/constants/markets.d.ts +0 -1
  27. package/lib/constants/markets.js +8 -0
  28. package/lib/constants/numericConstants.d.ts +1 -1
  29. package/lib/constants/numericConstants.js +2 -1
  30. package/lib/examples/makeTradeExample.d.ts +0 -1
  31. package/lib/factory/clearingHouse.d.ts +0 -1
  32. package/lib/factory/clearingHouseUser.d.ts +0 -1
  33. package/lib/idl/clearing_house.json +1077 -50
  34. package/lib/index.d.ts +3 -1
  35. package/lib/index.js +3 -0
  36. package/lib/math/amm.d.ts +3 -1
  37. package/lib/math/amm.js +121 -8
  38. package/lib/math/conversion.d.ts +0 -1
  39. package/lib/math/funding.d.ts +0 -1
  40. package/lib/math/insuranceFund.d.ts +0 -1
  41. package/lib/math/market.d.ts +2 -2
  42. package/lib/math/market.js +11 -1
  43. package/lib/math/orders.d.ts +3 -0
  44. package/lib/math/orders.js +32 -0
  45. package/lib/math/position.d.ts +4 -2
  46. package/lib/math/position.js +18 -4
  47. package/lib/math/trade.d.ts +0 -1
  48. package/lib/math/utils.d.ts +0 -1
  49. package/lib/mockUSDCFaucet.d.ts +0 -1
  50. package/lib/orderParams.d.ts +7 -0
  51. package/lib/orderParams.js +108 -0
  52. package/lib/orders.d.ts +6 -0
  53. package/lib/orders.js +136 -0
  54. package/lib/pythClient.d.ts +0 -1
  55. package/lib/token/index.d.ts +0 -1
  56. package/lib/tx/defaultTxSender.d.ts +0 -1
  57. package/lib/tx/types.d.ts +0 -1
  58. package/lib/tx/utils.d.ts +0 -1
  59. package/lib/types.d.ts +145 -2
  60. package/lib/types.js +36 -1
  61. package/lib/util/computeUnits.d.ts +0 -1
  62. package/lib/util/tps.d.ts +0 -1
  63. package/lib/wallet.d.ts +0 -1
  64. package/package.json +1 -1
  65. package/src/accounts/bulkAccountLoader.ts +21 -13
  66. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +33 -0
  67. package/src/accounts/pollingUserAccountSubscriber.ts +30 -2
  68. package/src/accounts/types.ts +11 -2
  69. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +47 -0
  70. package/src/accounts/webSocketUserAccountSubscriber.ts +29 -2
  71. package/src/addresses.ts +37 -0
  72. package/src/admin.ts +84 -6
  73. package/src/clearingHouse.ts +430 -5
  74. package/src/clearingHouseUser.ts +129 -12
  75. package/src/constants/markets.ts +8 -0
  76. package/src/constants/numericConstants.ts +1 -0
  77. package/src/idl/clearing_house.json +1077 -50
  78. package/src/index.ts +3 -0
  79. package/src/math/amm.ts +169 -14
  80. package/src/math/market.ts +28 -2
  81. package/src/math/orders.ts +44 -0
  82. package/src/math/position.ts +23 -3
  83. package/src/orderParams.ts +151 -0
  84. package/src/orders.ts +236 -0
  85. package/src/types.ts +129 -1
  86. package/tsconfig.json +0 -1
  87. package/lib/accounts/bulkAccountLoader.d.ts.map +0 -1
  88. package/lib/accounts/bulkUserSubscription.d.ts.map +0 -1
  89. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts.map +0 -1
  90. package/lib/accounts/pollingTokenAccountSubscriber.d.ts.map +0 -1
  91. package/lib/accounts/pollingUserAccountSubscriber.d.ts.map +0 -1
  92. package/lib/accounts/types.d.ts.map +0 -1
  93. package/lib/accounts/utils.d.ts.map +0 -1
  94. package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
  95. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts.map +0 -1
  96. package/lib/accounts/webSocketUserAccountSubscriber.d.ts.map +0 -1
  97. package/lib/addresses.d.ts.map +0 -1
  98. package/lib/admin.d.ts.map +0 -1
  99. package/lib/assert/assert.d.ts.map +0 -1
  100. package/lib/clearingHouse.d.ts.map +0 -1
  101. package/lib/clearingHouseUser.d.ts.map +0 -1
  102. package/lib/config.d.ts.map +0 -1
  103. package/lib/constants/markets.d.ts.map +0 -1
  104. package/lib/constants/numericConstants.d.ts.map +0 -1
  105. package/lib/examples/makeTradeExample.d.ts.map +0 -1
  106. package/lib/factory/clearingHouse.d.ts.map +0 -1
  107. package/lib/factory/clearingHouseUser.d.ts.map +0 -1
  108. package/lib/index.d.ts.map +0 -1
  109. package/lib/math/amm.d.ts.map +0 -1
  110. package/lib/math/conversion.d.ts.map +0 -1
  111. package/lib/math/funding.d.ts.map +0 -1
  112. package/lib/math/insuranceFund.d.ts.map +0 -1
  113. package/lib/math/market.d.ts.map +0 -1
  114. package/lib/math/position.d.ts.map +0 -1
  115. package/lib/math/trade.d.ts.map +0 -1
  116. package/lib/math/utils.d.ts.map +0 -1
  117. package/lib/mockUSDCFaucet.d.ts.map +0 -1
  118. package/lib/pythClient.d.ts.map +0 -1
  119. package/lib/token/index.d.ts.map +0 -1
  120. package/lib/tx/defaultTxSender.d.ts.map +0 -1
  121. package/lib/tx/types.d.ts.map +0 -1
  122. package/lib/tx/utils.d.ts.map +0 -1
  123. package/lib/types.d.ts.map +0 -1
  124. package/lib/util/computeUnits.d.ts.map +0 -1
  125. package/lib/util/tps.d.ts.map +0 -1
  126. package/lib/wallet.d.ts.map +0 -1
@@ -2,8 +2,14 @@ import { PublicKey } from '@solana/web3.js';
2
2
  import { EventEmitter } from 'events';
3
3
  import StrictEventEmitter from 'strict-event-emitter-types';
4
4
  import { ClearingHouse } from './clearingHouse';
5
- import { UserAccount, UserPosition, UserPositionsAccount } from './types';
6
- import { calculateEntryPrice } from './math/position';
5
+ import {
6
+ Order,
7
+ UserAccount,
8
+ UserOrdersAccount,
9
+ UserPosition,
10
+ UserPositionsAccount,
11
+ } from './types';
12
+ import { calculateEntryPrice, isEmptyPosition } from './math/position';
7
13
  import {
8
14
  MARK_PRICE_PRECISION,
9
15
  AMM_TO_QUOTE_PRECISION_RATIO,
@@ -23,6 +29,8 @@ import {
23
29
  calculatePositionFundingPNL,
24
30
  calculatePositionPNL,
25
31
  PositionDirection,
32
+ getUserOrdersAccountPublicKey,
33
+ calculateNewStateAfterOrder,
26
34
  calculateTradeSlippage,
27
35
  BN,
28
36
  } from '.';
@@ -37,6 +45,7 @@ export class ClearingHouseUser {
37
45
  authority: PublicKey;
38
46
  accountSubscriber: UserAccountSubscriber;
39
47
  userAccountPublicKey?: PublicKey;
48
+ userOrdersAccountPublicKey?: PublicKey;
40
49
  _isSubscribed = false;
41
50
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
42
51
 
@@ -111,6 +120,10 @@ export class ClearingHouseUser {
111
120
  return this.accountSubscriber.getUserPositionsAccount();
112
121
  }
113
122
 
123
+ public getUserOrdersAccount(): UserOrdersAccount | undefined {
124
+ return this.accountSubscriber.getUserOrdersAccount();
125
+ }
126
+
114
127
  /**
115
128
  * Gets the user's current position for a given market. If the user has no position returns undefined
116
129
  * @param marketIndex
@@ -128,9 +141,30 @@ export class ClearingHouseUser {
128
141
  lastCumulativeFundingRate: ZERO,
129
142
  marketIndex,
130
143
  quoteAssetAmount: ZERO,
144
+ openOrders: ZERO,
131
145
  };
132
146
  }
133
147
 
148
+ /**
149
+ * @param orderId
150
+ * @returns Order
151
+ */
152
+ public getOrder(orderId: BN): Order | undefined {
153
+ return this.getUserOrdersAccount().orders.find((order) =>
154
+ order.orderId.eq(orderId)
155
+ );
156
+ }
157
+
158
+ /**
159
+ * @param userOrderId
160
+ * @returns Order
161
+ */
162
+ public getOrderByUserOrderId(userOrderId: number): Order | undefined {
163
+ return this.getUserOrdersAccount().orders.find(
164
+ (order) => order.userOrderId === userOrderId
165
+ );
166
+ }
167
+
134
168
  public async getUserAccountPublicKey(): Promise<PublicKey> {
135
169
  if (this.userAccountPublicKey) {
136
170
  return this.userAccountPublicKey;
@@ -143,6 +177,18 @@ export class ClearingHouseUser {
143
177
  return this.userAccountPublicKey;
144
178
  }
145
179
 
180
+ public async getUserOrdersAccountPublicKey(): Promise<PublicKey> {
181
+ if (this.userOrdersAccountPublicKey) {
182
+ return this.userOrdersAccountPublicKey;
183
+ }
184
+
185
+ this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
186
+ this.clearingHouse.program.programId,
187
+ await this.getUserAccountPublicKey()
188
+ );
189
+ return this.userOrdersAccountPublicKey;
190
+ }
191
+
146
192
  public async exists(): Promise<boolean> {
147
193
  const userAccountPublicKey = await this.getUserAccountPublicKey();
148
194
  const userAccountRPCResponse =
@@ -438,6 +484,7 @@ export class ClearingHouseUser {
438
484
  ),
439
485
  lastCumulativeFundingRate: new BN(0),
440
486
  quoteAssetAmount: new BN(0),
487
+ openOrders: new BN(0),
441
488
  };
442
489
 
443
490
  const market = this.clearingHouse.getMarket(
@@ -528,14 +575,14 @@ export class ClearingHouseUser {
528
575
  // solves formula for example calc below
529
576
 
530
577
  /* example: assume BTC price is $40k (examine 10% up/down)
531
-
532
- if 10k deposit and levered 10x short BTC => BTC up $400 means:
533
- 1. higher base_asset_value (+$4k)
534
- 2. lower collateral (-$4k)
535
- 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
536
-
537
- for 10x long, BTC down $400:
538
- 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
578
+
579
+ if 10k deposit and levered 10x short BTC => BTC up $400 means:
580
+ 1. higher base_asset_value (+$4k)
581
+ 2. lower collateral (-$4k)
582
+ 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
583
+
584
+ for 10x long, BTC down $400:
585
+ 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
539
586
 
540
587
  const tc = this.getTotalCollateral();
541
588
  const tpv = this.getTotalPositionValue();
@@ -566,6 +613,7 @@ export class ClearingHouseUser {
566
613
  lastCumulativeFundingRate:
567
614
  currentMarketPosition.lastCumulativeFundingRate,
568
615
  quoteAssetAmount: new BN(0),
616
+ openOrders: new BN(0),
569
617
  };
570
618
 
571
619
  const market = this.clearingHouse.getMarket(
@@ -700,7 +748,7 @@ export class ClearingHouseUser {
700
748
  * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
701
749
  * => current position + remaining to get to maxLeverage
702
750
  *
703
- * @param marketIndex
751
+ * @param targetMarketIndex
704
752
  * @param tradeSide
705
753
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
706
754
  * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
@@ -842,7 +890,6 @@ export class ClearingHouseUser {
842
890
  this.getTotalPositionValueExcludingMarket(targetMarketIndex);
843
891
 
844
892
  const totalCollateral = this.getTotalCollateral();
845
-
846
893
  if (totalCollateral.gt(ZERO)) {
847
894
  const newLeverage = currentMarketPositionAfterTrade
848
895
  .add(totalPositionAfterTradeExcludingTargetMarket)
@@ -885,4 +932,74 @@ export class ClearingHouseUser {
885
932
 
886
933
  return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
887
934
  }
935
+
936
+ public canFillOrder(order: Order): boolean {
937
+ const userAccount = this.getUserAccount();
938
+ const userPositionsAccount = this.getUserPositionsAccount();
939
+ const userPosition = this.getUserPosition(order.marketIndex);
940
+ const market = this.clearingHouse.getMarket(order.marketIndex);
941
+
942
+ if (isEmptyPosition(userPosition)) {
943
+ return false;
944
+ }
945
+
946
+ const newState = calculateNewStateAfterOrder(
947
+ userAccount,
948
+ userPosition,
949
+ market,
950
+ order
951
+ );
952
+ if (newState === null) {
953
+ return false;
954
+ }
955
+ const [userAccountAfter, userPositionAfter, marketAfter] = newState;
956
+
957
+ const totalPositionValue = userPositionsAccount.positions.reduce(
958
+ (positionValue, marketPosition) => {
959
+ let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
960
+ if (marketPosition.marketIndex.eq(order.marketIndex)) {
961
+ market = marketAfter;
962
+ marketPosition = userPositionAfter;
963
+ }
964
+
965
+ return positionValue.add(
966
+ calculateBaseAssetValue(market, marketPosition)
967
+ );
968
+ },
969
+ ZERO
970
+ );
971
+
972
+ if (totalPositionValue.eq(ZERO)) {
973
+ return true;
974
+ }
975
+
976
+ const unrealizedPnL = userPositionsAccount.positions.reduce(
977
+ (pnl, marketPosition) => {
978
+ let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
979
+ pnl = pnl.add(
980
+ calculatePositionFundingPNL(market, marketPosition).div(
981
+ PRICE_TO_QUOTE_PRECISION
982
+ )
983
+ );
984
+
985
+ if (marketPosition.marketIndex.eq(order.marketIndex)) {
986
+ market = marketAfter;
987
+ marketPosition = userPositionAfter;
988
+ }
989
+
990
+ // update
991
+ return pnl.add(calculatePositionPNL(market, marketPosition, false));
992
+ },
993
+ ZERO
994
+ );
995
+ const totalCollateral = userAccountAfter.collateral.add(unrealizedPnL);
996
+
997
+ const marginRatioAfter = totalCollateral
998
+ .mul(TEN_THOUSAND)
999
+ .div(totalPositionValue);
1000
+
1001
+ const marginRatioInitial =
1002
+ this.clearingHouse.getStateAccount().marginRatioInitial;
1003
+ return marginRatioAfter.gte(marginRatioInitial);
1004
+ }
888
1005
  }
@@ -106,6 +106,14 @@ export const Markets: Market[] = [
106
106
  mainnetPythOracle: '8JPJJkmDScpcNmBRKGZuPuG2GYAveQgP3t5gFuMymwvF',
107
107
  launchTs: 1644382122000,
108
108
  },
109
+ {
110
+ symbol: 'LTC-PERP',
111
+ baseAssetSymbol: 'LTC',
112
+ marketIndex: new BN(12),
113
+ devnetPythOracle: 'BLArYBCUYhdWiY8PCUTpvFE21iaJq85dvxLk9bYMobcU',
114
+ mainnetPythOracle: '8RMnV1eD55iqUFJLMguPkYBkq8DCtx81XcmAja93LvRR',
115
+ launchTs: 1645027429000,
116
+ },
109
117
  // {
110
118
  // symbol: 'mSOL-PERP',
111
119
  // baseAssetSymbol: 'mSOL',
@@ -2,6 +2,7 @@ import { BN } from '../';
2
2
 
3
3
  export const ZERO = new BN(0);
4
4
  export const ONE = new BN(1);
5
+ export const TWO = new BN(2);
5
6
  export const TEN_THOUSAND = new BN(10000);
6
7
  export const BN_MAX = new BN(Number.MAX_SAFE_INTEGER);
7
8