@drift-labs/sdk 0.1.18-orders.1 → 0.1.19-master.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.
Files changed (112) hide show
  1. package/README.md +2 -1
  2. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts +4 -7
  3. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +1 -0
  4. package/lib/accounts/defaultClearingHouseAccountSubscriber.js +2 -27
  5. package/lib/accounts/defaultUserAccountSubscriber.d.ts +2 -3
  6. package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +1 -0
  7. package/lib/accounts/defaultUserAccountSubscriber.js +5 -14
  8. package/lib/accounts/types.d.ts +6 -32
  9. package/lib/accounts/types.d.ts.map +1 -0
  10. package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -0
  11. package/lib/accounts/webSocketAccountSubscriber.d.ts.map +1 -0
  12. package/lib/addresses.d.ts +1 -4
  13. package/lib/addresses.d.ts.map +1 -0
  14. package/lib/addresses.js +1 -28
  15. package/lib/admin.d.ts +7 -10
  16. package/lib/admin.d.ts.map +1 -0
  17. package/lib/admin.js +64 -53
  18. package/lib/assert/assert.d.ts +1 -0
  19. package/lib/assert/assert.d.ts.map +1 -0
  20. package/lib/clearingHouse.d.ts +3 -22
  21. package/lib/clearingHouse.d.ts.map +1 -0
  22. package/lib/clearingHouse.js +15 -246
  23. package/lib/clearingHouseUser.d.ts +17 -10
  24. package/lib/clearingHouseUser.d.ts.map +1 -0
  25. package/lib/clearingHouseUser.js +97 -111
  26. package/lib/config.d.ts +1 -0
  27. package/lib/config.d.ts.map +1 -0
  28. package/lib/config.js +1 -1
  29. package/lib/constants/markets.d.ts +1 -0
  30. package/lib/constants/markets.d.ts.map +1 -0
  31. package/lib/constants/markets.js +16 -0
  32. package/lib/constants/numericConstants.d.ts +1 -0
  33. package/lib/constants/numericConstants.d.ts.map +1 -0
  34. package/lib/examples/makeTradeExample.d.ts +1 -0
  35. package/lib/examples/makeTradeExample.d.ts.map +1 -0
  36. package/lib/examples/makeTradeExample.js +6 -6
  37. package/lib/idl/clearing_house.json +233 -911
  38. package/lib/index.d.ts +1 -4
  39. package/lib/index.d.ts.map +1 -0
  40. package/lib/index.js +0 -4
  41. package/lib/math/amm.d.ts +1 -1
  42. package/lib/math/amm.d.ts.map +1 -0
  43. package/lib/math/amm.js +15 -38
  44. package/lib/math/conversion.d.ts +1 -0
  45. package/lib/math/conversion.d.ts.map +1 -0
  46. package/lib/math/conversion.js +1 -1
  47. package/lib/math/funding.d.ts +1 -0
  48. package/lib/math/funding.d.ts.map +1 -0
  49. package/lib/math/funding.js +5 -2
  50. package/lib/math/insuranceFund.d.ts +1 -0
  51. package/lib/math/insuranceFund.d.ts.map +1 -0
  52. package/lib/math/market.d.ts +2 -2
  53. package/lib/math/market.d.ts.map +1 -0
  54. package/lib/math/market.js +2 -12
  55. package/lib/math/position.d.ts +2 -4
  56. package/lib/math/position.d.ts.map +1 -0
  57. package/lib/math/position.js +5 -19
  58. package/lib/math/trade.d.ts +1 -0
  59. package/lib/math/trade.d.ts.map +1 -0
  60. package/lib/math/trade.js +16 -16
  61. package/lib/math/utils.d.ts +1 -0
  62. package/lib/math/utils.d.ts.map +1 -0
  63. package/lib/mockUSDCFaucet.d.ts +1 -0
  64. package/lib/mockUSDCFaucet.d.ts.map +1 -0
  65. package/lib/pythClient.d.ts +1 -0
  66. package/lib/pythClient.d.ts.map +1 -0
  67. package/lib/pythClient.js +1 -1
  68. package/lib/tx/defaultTxSender.d.ts +1 -0
  69. package/lib/tx/defaultTxSender.d.ts.map +1 -0
  70. package/lib/tx/types.d.ts +1 -0
  71. package/lib/tx/types.d.ts.map +1 -0
  72. package/lib/tx/utils.d.ts +1 -0
  73. package/lib/tx/utils.d.ts.map +1 -0
  74. package/lib/types.d.ts +9 -140
  75. package/lib/types.d.ts.map +1 -0
  76. package/lib/types.js +1 -36
  77. package/lib/util/computeUnits.d.ts +1 -0
  78. package/lib/util/computeUnits.d.ts.map +1 -0
  79. package/lib/util/tps.d.ts +1 -0
  80. package/lib/util/tps.d.ts.map +1 -0
  81. package/lib/wallet.d.ts +1 -0
  82. package/lib/wallet.d.ts.map +1 -0
  83. package/package.json +1 -1
  84. package/src/accounts/defaultClearingHouseAccountSubscriber.ts +5 -52
  85. package/src/accounts/defaultUserAccountSubscriber.ts +6 -31
  86. package/src/accounts/types.ts +5 -42
  87. package/src/addresses.ts +0 -35
  88. package/src/admin.ts +71 -86
  89. package/src/clearingHouse.ts +7 -340
  90. package/src/clearingHouseUser.ts +102 -154
  91. package/src/config.ts +1 -1
  92. package/src/constants/markets.ts +16 -0
  93. package/src/idl/clearing_house.json +233 -911
  94. package/src/index.ts +0 -4
  95. package/src/math/amm.ts +14 -47
  96. package/src/math/funding.ts +5 -1
  97. package/src/math/market.ts +2 -28
  98. package/src/math/position.ts +3 -23
  99. package/src/types.ts +8 -124
  100. package/tsconfig.json +1 -0
  101. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -28
  102. package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
  103. package/lib/math/orders.d.ts +0 -3
  104. package/lib/math/orders.js +0 -30
  105. package/lib/orderParams.d.ts +0 -7
  106. package/lib/orderParams.js +0 -88
  107. package/lib/orders.d.ts +0 -5
  108. package/lib/orders.js +0 -136
  109. package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -176
  110. package/src/math/orders.ts +0 -39
  111. package/src/orderParams.ts +0 -128
  112. package/src/orders.ts +0 -230
@@ -3,14 +3,8 @@ import BN from 'bn.js';
3
3
  import { EventEmitter } from 'events';
4
4
  import StrictEventEmitter from 'strict-event-emitter-types';
5
5
  import { ClearingHouse } from './clearingHouse';
6
- import {
7
- Order,
8
- UserAccount,
9
- UserOrdersAccount,
10
- UserPosition,
11
- UserPositionsAccount,
12
- } from './types';
13
- import { calculateEntryPrice, isEmptyPosition } from './math/position';
6
+ import { UserAccount, UserPosition, UserPositionsAccount } from './types';
7
+ import { calculateEntryPrice } from './math/position';
14
8
  import {
15
9
  MARK_PRICE_PRECISION,
16
10
  AMM_TO_QUOTE_PRECISION_RATIO,
@@ -31,8 +25,6 @@ import {
31
25
  calculatePositionFundingPNL,
32
26
  calculatePositionPNL,
33
27
  PositionDirection,
34
- getUserOrdersAccountPublicKey,
35
- calculateNewStateAfterOrder,
36
28
  calculateTradeSlippage,
37
29
  } from '.';
38
30
  import { getUserAccountPublicKey } from './addresses';
@@ -42,7 +34,6 @@ export class ClearingHouseUser {
42
34
  authority: PublicKey;
43
35
  accountSubscriber: UserAccountSubscriber;
44
36
  userAccountPublicKey?: PublicKey;
45
- userOrdersAccountPublicKey?: PublicKey;
46
37
  isSubscribed = false;
47
38
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
48
39
 
@@ -100,10 +91,6 @@ export class ClearingHouseUser {
100
91
  return this.accountSubscriber.getUserPositionsAccount();
101
92
  }
102
93
 
103
- public getUserOrdersAccount(): UserOrdersAccount {
104
- return this.accountSubscriber.getUserOrdersAccount();
105
- }
106
-
107
94
  /**
108
95
  * Gets the user's current position for a given market. If the user has no position returns undefined
109
96
  * @param marketIndex
@@ -121,20 +108,9 @@ export class ClearingHouseUser {
121
108
  lastCumulativeFundingRate: ZERO,
122
109
  marketIndex,
123
110
  quoteAssetAmount: ZERO,
124
- openOrders: ZERO,
125
111
  };
126
112
  }
127
113
 
128
- /**
129
- * @param orderId
130
- * @returns Order
131
- */
132
- public getOrder(orderId: BN): Order | undefined {
133
- return this.getUserOrdersAccount().orders.find((order) =>
134
- order.orderId.eq(orderId)
135
- );
136
- }
137
-
138
114
  public async getUserAccountPublicKey(): Promise<PublicKey> {
139
115
  if (this.userAccountPublicKey) {
140
116
  return this.userAccountPublicKey;
@@ -147,18 +123,6 @@ export class ClearingHouseUser {
147
123
  return this.userAccountPublicKey;
148
124
  }
149
125
 
150
- public async getUserOrdersAccountPublicKey(): Promise<PublicKey> {
151
- if (this.userOrdersAccountPublicKey) {
152
- return this.userOrdersAccountPublicKey;
153
- }
154
-
155
- this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
156
- this.clearingHouse.program.programId,
157
- this.authority
158
- );
159
- return this.userOrdersAccountPublicKey;
160
- }
161
-
162
126
  public async exists(): Promise<boolean> {
163
127
  const userAccountPublicKey = await this.getUserAccountPublicKey();
164
128
  const userAccountRPCResponse =
@@ -454,7 +418,6 @@ export class ClearingHouseUser {
454
418
  ),
455
419
  lastCumulativeFundingRate: new BN(0),
456
420
  quoteAssetAmount: new BN(0),
457
- openOrders: new BN(0),
458
421
  };
459
422
 
460
423
  const market = this.clearingHouse.getMarket(
@@ -545,14 +508,14 @@ export class ClearingHouseUser {
545
508
  // solves formula for example calc below
546
509
 
547
510
  /* example: assume BTC price is $40k (examine 10% up/down)
548
-
549
- if 10k deposit and levered 10x short BTC => BTC up $400 means:
550
- 1. higher base_asset_value (+$4k)
551
- 2. lower collateral (-$4k)
552
- 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
553
-
554
- for 10x long, BTC down $400:
555
- 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
511
+
512
+ if 10k deposit and levered 10x short BTC => BTC up $400 means:
513
+ 1. higher base_asset_value (+$4k)
514
+ 2. lower collateral (-$4k)
515
+ 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
516
+
517
+ for 10x long, BTC down $400:
518
+ 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
556
519
 
557
520
  const tc = this.getTotalCollateral();
558
521
  const tpv = this.getTotalPositionValue();
@@ -583,7 +546,6 @@ export class ClearingHouseUser {
583
546
  lastCumulativeFundingRate:
584
547
  currentMarketPosition.lastCumulativeFundingRate,
585
548
  quoteAssetAmount: new BN(0),
586
- openOrders: new BN(0),
587
549
  };
588
550
 
589
551
  const market = this.clearingHouse.getMarket(
@@ -703,6 +665,21 @@ export class ClearingHouseUser {
703
665
 
704
666
  /**
705
667
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
668
+ *
669
+ * To Calculate Max Quote Available:
670
+ *
671
+ * Case 1: SameSide
672
+ * => Remaining quote to get to maxLeverage
673
+ *
674
+ * Case 2: NOT SameSide && currentLeverage <= maxLeverage
675
+ * => Current opposite position x2 + remaining to get to maxLeverage
676
+ *
677
+ * Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
678
+ * => strictly reduce current position size
679
+ *
680
+ * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
681
+ * => current position + remaining to get to maxLeverage
682
+ *
706
683
  * @param marketIndex
707
684
  * @param tradeSide
708
685
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
@@ -713,34 +690,28 @@ export class ClearingHouseUser {
713
690
  tradeSide: PositionDirection,
714
691
  userMaxLeverageSetting: BN
715
692
  ): BN {
716
- // inline function which get's the current position size on the opposite side of the target trade
717
- const getOppositePositionValueUSDC = () => {
718
- if (!currentPosition) return ZERO;
693
+ const currentPosition =
694
+ this.getUserPosition(targetMarketIndex) ||
695
+ this.getEmptyPosition(targetMarketIndex);
719
696
 
720
- const side = tradeSide === PositionDirection.SHORT ? 'short' : 'long';
697
+ const targetSide = tradeSide === PositionDirection.SHORT ? 'short' : 'long';
721
698
 
722
- if (side === 'long' && currentPosition?.baseAssetAmount.isNeg()) {
723
- return this.getPositionValue(targetMarketIndex);
724
- } else if (
725
- side === 'short' &&
726
- !currentPosition?.baseAssetAmount.isNeg()
727
- ) {
728
- return this.getPositionValue(targetMarketIndex);
729
- }
699
+ const currentPositionSide = currentPosition?.baseAssetAmount.isNeg()
700
+ ? 'short'
701
+ : 'long';
730
702
 
731
- return ZERO;
732
- };
703
+ const targettingSameSide = !currentPosition
704
+ ? true
705
+ : targetSide === currentPositionSide;
733
706
 
734
- const currentPosition =
735
- this.getUserPosition(targetMarketIndex) ||
736
- this.getEmptyPosition(targetMarketIndex);
707
+ // add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
708
+ const oppositeSizeValueUSDC = targettingSameSide
709
+ ? ZERO
710
+ : this.getPositionValue(targetMarketIndex);
737
711
 
738
712
  // get current leverage
739
713
  const currentLeverage = this.getLeverage();
740
714
 
741
- // remaining leverage
742
- // let remainingLeverage = userMaxLeverageSetting;
743
-
744
715
  const remainingLeverage = BN.max(
745
716
  userMaxLeverageSetting.sub(currentLeverage),
746
717
  ZERO
@@ -754,10 +725,57 @@ export class ClearingHouseUser {
754
725
  .mul(totalCollateral)
755
726
  .div(TEN_THOUSAND);
756
727
 
757
- // add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
758
- const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
728
+ if (userMaxLeverageSetting.sub(currentLeverage).gte(ZERO)) {
729
+ if (oppositeSizeValueUSDC.eq(ZERO)) {
730
+ // case 1 : Regular trade where current total position less than max, and no opposite position to account for
731
+ // do nothing
732
+ } else {
733
+ // case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
734
+ maxPositionSize = maxPositionSize.add(
735
+ oppositeSizeValueUSDC.mul(new BN(2))
736
+ );
737
+ }
738
+ } else {
739
+ // current leverage is greater than max leverage - can only reduce position size
740
+
741
+ if (!targettingSameSide) {
742
+ const currentPositionQuoteSize =
743
+ this.getPositionValue(targetMarketIndex);
744
+
745
+ const currentTotalQuoteSize = currentLeverage
746
+ .mul(totalCollateral)
747
+ .div(TEN_THOUSAND);
748
+
749
+ const otherPositionsTotalQuoteSize = currentTotalQuoteSize.sub(
750
+ currentPositionQuoteSize
751
+ );
759
752
 
760
- maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new BN(2)));
753
+ const quoteValueOfMaxLeverage = userMaxLeverageSetting
754
+ .mul(totalCollateral)
755
+ .div(TEN_THOUSAND);
756
+
757
+ if (
758
+ otherPositionsTotalQuoteSize
759
+ .sub(currentPositionQuoteSize)
760
+ .gte(quoteValueOfMaxLeverage)
761
+ ) {
762
+ // case 3: Can only reduce the current position because it will still be greater than max leverage
763
+
764
+ maxPositionSize = currentPositionQuoteSize;
765
+ } else {
766
+ // case 4: Can reduce the position, and then take extra remaining quote to get to max leverage
767
+
768
+ const allowedQuoteSizeAfterClosingCurrentPosition =
769
+ quoteValueOfMaxLeverage.sub(otherPositionsTotalQuoteSize);
770
+
771
+ maxPositionSize = currentPositionQuoteSize.add(
772
+ allowedQuoteSizeAfterClosingCurrentPosition
773
+ );
774
+ }
775
+ } else {
776
+ // do nothing if targetting same side
777
+ }
778
+ }
761
779
 
762
780
  // subtract oneMillionth of maxPositionSize
763
781
  // => to avoid rounding errors when taking max leverage
@@ -802,13 +820,19 @@ export class ClearingHouseUser {
802
820
 
803
821
  const totalPositionAfterTradeExcludingTargetMarket =
804
822
  this.getTotalPositionValueExcludingMarket(targetMarketIndex);
805
- const newLeverage = currentMarketPositionAfterTrade
806
- .add(totalPositionAfterTradeExcludingTargetMarket)
807
- .abs()
808
- .mul(TEN_THOUSAND)
809
- .div(this.getTotalCollateral());
810
823
 
811
- return newLeverage;
824
+ const totalCollateral = this.getTotalCollateral();
825
+
826
+ if (totalCollateral.gt(ZERO)) {
827
+ const newLeverage = currentMarketPositionAfterTrade
828
+ .add(totalPositionAfterTradeExcludingTargetMarket)
829
+ .abs()
830
+ .mul(TEN_THOUSAND)
831
+ .div(totalCollateral);
832
+ return newLeverage;
833
+ } else {
834
+ return new BN(0);
835
+ }
812
836
  }
813
837
 
814
838
  /**
@@ -836,85 +860,9 @@ export class ClearingHouseUser {
836
860
 
837
861
  let currentMarketPositionValueUSDC = ZERO;
838
862
  if (currentMarketPosition) {
839
- const market = this.clearingHouse.getMarket(
840
- currentMarketPosition.marketIndex
841
- );
842
- currentMarketPositionValueUSDC = calculateBaseAssetValue(
843
- market,
844
- currentMarketPosition
845
- );
863
+ currentMarketPositionValueUSDC = this.getPositionValue(marketToIgnore);
846
864
  }
847
865
 
848
866
  return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
849
867
  }
850
-
851
- public canFillOrder(order: Order): boolean {
852
- const userAccount = this.getUserAccount();
853
- const userPositionsAccount = this.getUserPositionsAccount();
854
- const userPosition = this.getUserPosition(order.marketIndex);
855
- const market = this.clearingHouse.getMarket(order.marketIndex);
856
-
857
- if (isEmptyPosition(userPosition)) {
858
- return false;
859
- }
860
-
861
- const newState = calculateNewStateAfterOrder(
862
- userAccount,
863
- userPosition,
864
- market,
865
- order
866
- );
867
- if (newState === null) {
868
- return false;
869
- }
870
- const [userAccountAfter, userPositionAfter, marketAfter] = newState;
871
-
872
- const totalPositionValue = userPositionsAccount.positions.reduce(
873
- (positionValue, marketPosition) => {
874
- let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
875
- if (marketPosition.marketIndex.eq(order.marketIndex)) {
876
- market = marketAfter;
877
- marketPosition = userPositionAfter;
878
- }
879
-
880
- return positionValue.add(
881
- calculateBaseAssetValue(market, marketPosition)
882
- );
883
- },
884
- ZERO
885
- );
886
-
887
- if (totalPositionValue.eq(ZERO)) {
888
- return true;
889
- }
890
-
891
- const unrealizedPnL = userPositionsAccount.positions.reduce(
892
- (pnl, marketPosition) => {
893
- let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
894
- pnl = pnl.add(
895
- calculatePositionFundingPNL(market, marketPosition).div(
896
- PRICE_TO_QUOTE_PRECISION
897
- )
898
- );
899
-
900
- if (marketPosition.marketIndex.eq(order.marketIndex)) {
901
- market = marketAfter;
902
- marketPosition = userPositionAfter;
903
- }
904
-
905
- // update
906
- return pnl.add(calculatePositionPNL(market, marketPosition, false));
907
- },
908
- ZERO
909
- );
910
- const totalCollateral = userAccountAfter.collateral.add(unrealizedPnL);
911
-
912
- const marginRatioAfter = totalCollateral
913
- .mul(TEN_THOUSAND)
914
- .div(totalPositionValue);
915
-
916
- const marginRatioInitial =
917
- this.clearingHouse.getStateAccount().marginRatioInitial;
918
- return marginRatioAfter.gte(marginRatioInitial);
919
- }
920
868
  }
package/src/config.ts CHANGED
@@ -11,7 +11,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
11
11
  devnet: {
12
12
  ENV: 'devnet',
13
13
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
14
- CLEARING_HOUSE_PROGRAM_ID: 'HiZ8CnfEE9LrBZTfc8hBneWrPg1Cbsn8Wdy6SPLfae9V',
14
+ CLEARING_HOUSE_PROGRAM_ID: 'AsW7LnXB9UA1uec9wi9MctYTgTz7YH9snhxd16GsFaGX',
15
15
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
16
16
  },
17
17
  'mainnet-beta': {
@@ -90,4 +90,20 @@ export const Markets: Market[] = [
90
90
  mainnetPythOracle: '3pyn4svBbxJ9Wnn3RVeafyLWfzie6yC5eTig2S62v9SC',
91
91
  launchTs: 1643084413000,
92
92
  },
93
+ {
94
+ symbol: 'ALGO-PERP',
95
+ baseAssetSymbol: 'ALGO',
96
+ marketIndex: new BN(10),
97
+ devnetPythOracle: 'c1A946dY5NHuVda77C8XXtXytyR3wK1SCP3eA9VRfC3',
98
+ mainnetPythOracle: 'HqFyq1wh1xKvL7KDqqT7NJeSPdAqsDqnmBisUC2XdXAX',
99
+ launchTs: 1643686767000,
100
+ },
101
+ // {
102
+ // symbol: 'mSOL-PERP',
103
+ // baseAssetSymbol: 'mSOL',
104
+ // marketIndex: new BN(11), //todo
105
+ // devnetPythOracle: '9a6RNx3tCu1TSs6TBSfV2XRXEPEZXQ6WB7jRojZRvyeZ',
106
+ // mainnetPythOracle: 'E4v1BBgoso9s64TQvmyownAVJbhbEPGyzA3qn4n46qj9',
107
+ // launchTs: 1643346125000,
108
+ // },
93
109
  ];