@drift-labs/sdk 0.1.18-orders.2 → 0.1.18-orders.6

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 (56) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +3 -4
  2. package/lib/accounts/bulkAccountLoader.js +23 -4
  3. package/lib/accounts/pollingUserAccountSubscriber.js +8 -5
  4. package/lib/accounts/types.d.ts +4 -0
  5. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -2
  6. package/lib/accounts/webSocketAccountSubscriber.js +43 -12
  7. package/lib/clearingHouse.d.ts +4 -0
  8. package/lib/clearingHouse.js +40 -0
  9. package/lib/clearingHouseUser.d.ts +8 -3
  10. package/lib/clearingHouseUser.js +23 -20
  11. package/lib/config.js +1 -1
  12. package/lib/constants/markets.d.ts +2 -1
  13. package/lib/constants/markets.js +20 -15
  14. package/lib/constants/numericConstants.d.ts +4 -1
  15. package/lib/constants/numericConstants.js +16 -17
  16. package/lib/examples/makeTradeExample.js +1 -1
  17. package/lib/idl/clearing_house.json +8 -4
  18. package/lib/index.d.ts +1 -1
  19. package/lib/index.js +2 -5
  20. package/lib/math/conversion.d.ts +1 -1
  21. package/lib/math/insuranceFund.d.ts +2 -1
  22. package/lib/math/insuranceFund.js +3 -6
  23. package/lib/math/orders.js +2 -1
  24. package/lib/math/position.d.ts +2 -1
  25. package/lib/math/position.js +2 -5
  26. package/lib/math/utils.d.ts +2 -1
  27. package/lib/math/utils.js +3 -6
  28. package/lib/mockUSDCFaucet.d.ts +2 -1
  29. package/lib/orderParams.d.ts +2 -2
  30. package/lib/orderParams.js +7 -7
  31. package/lib/orders.d.ts +3 -2
  32. package/lib/orders.js +8 -8
  33. package/lib/types.d.ts +8 -5
  34. package/lib/types.js +2 -2
  35. package/package.json +9 -1
  36. package/src/accounts/bulkAccountLoader.ts +35 -15
  37. package/src/accounts/pollingUserAccountSubscriber.ts +13 -5
  38. package/src/accounts/types.ts +5 -0
  39. package/src/accounts/webSocketAccountSubscriber.ts +67 -17
  40. package/src/clearingHouse.ts +56 -0
  41. package/src/clearingHouseUser.ts +12 -2
  42. package/src/config.ts +1 -1
  43. package/src/constants/markets.ts +9 -1
  44. package/src/constants/numericConstants.ts +3 -1
  45. package/src/examples/makeTradeExample.ts +4 -1
  46. package/src/idl/clearing_house.json +8 -4
  47. package/src/index.ts +1 -1
  48. package/src/math/conversion.ts +1 -1
  49. package/src/math/insuranceFund.ts +1 -1
  50. package/src/math/orders.ts +4 -2
  51. package/src/math/position.ts +1 -1
  52. package/src/math/utils.ts +1 -1
  53. package/src/mockUSDCFaucet.ts +1 -1
  54. package/src/orderParams.ts +4 -4
  55. package/src/orders.ts +13 -7
  56. package/src/types.ts +5 -3
@@ -414,6 +414,20 @@ export class ClearingHouse {
414
414
  return this.userOrdersAccountPublicKey;
415
415
  }
416
416
 
417
+ userOrdersExist?: boolean;
418
+ async userOrdersAccountExists(): Promise<boolean> {
419
+ if (this.userOrdersExist) {
420
+ return this.userOrdersExist;
421
+ }
422
+ const userOrdersAccountRPCResponse =
423
+ await this.connection.getParsedAccountInfo(
424
+ await this.getUserOrdersAccountPublicKey()
425
+ );
426
+
427
+ this.userOrdersExist = userOrdersAccountRPCResponse.value !== null;
428
+ return this.userOrdersExist;
429
+ }
430
+
417
431
  public async depositCollateral(
418
432
  amount: BN,
419
433
  collateralAccountPublicKey: PublicKey,
@@ -668,6 +682,27 @@ export class ClearingHouse {
668
682
  );
669
683
  }
670
684
 
685
+ public async initializeUserOrdersThenPlaceOrder(
686
+ orderParams: OrderParams,
687
+ discountToken?: PublicKey,
688
+ referrer?: PublicKey
689
+ ): Promise<TransactionSignature> {
690
+ const instructions: anchor.web3.TransactionInstruction[] = [];
691
+ const userOrdersAccountExists = await this.userOrdersAccountExists();
692
+ if (!userOrdersAccountExists) {
693
+ instructions.push(await this.getInitializeUserOrdersInstruction());
694
+ }
695
+ instructions.push(
696
+ await this.getPlaceOrderIx(orderParams, discountToken, referrer)
697
+ );
698
+ const tx = new Transaction();
699
+ for (const instruction of instructions) {
700
+ tx.add(instruction);
701
+ }
702
+
703
+ return await this.txSender.send(tx, [], this.opts);
704
+ }
705
+
671
706
  public async placeOrder(
672
707
  orderParams: OrderParams,
673
708
  discountToken?: PublicKey,
@@ -872,6 +907,27 @@ export class ClearingHouse {
872
907
  });
873
908
  }
874
909
 
910
+ public async initializeUserOrdersThenPlaceAndFillOrder(
911
+ orderParams: OrderParams,
912
+ discountToken?: PublicKey,
913
+ referrer?: PublicKey
914
+ ): Promise<TransactionSignature> {
915
+ const instructions: anchor.web3.TransactionInstruction[] = [];
916
+ const userOrdersAccountExists = await this.userOrdersAccountExists();
917
+ if (!userOrdersAccountExists) {
918
+ instructions.push(await this.getInitializeUserOrdersInstruction());
919
+ }
920
+ instructions.push(
921
+ await this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)
922
+ );
923
+ const tx = new Transaction();
924
+ for (const instruction of instructions) {
925
+ tx.add(instruction);
926
+ }
927
+
928
+ return await this.txSender.send(tx, [], this.opts);
929
+ }
930
+
875
931
  public async placeAndFillOrder(
876
932
  orderParams: OrderParams,
877
933
  discountToken?: PublicKey,
@@ -1,5 +1,4 @@
1
1
  import { PublicKey } from '@solana/web3.js';
2
- import BN from 'bn.js';
3
2
  import { EventEmitter } from 'events';
4
3
  import StrictEventEmitter from 'strict-event-emitter-types';
5
4
  import { ClearingHouse } from './clearingHouse';
@@ -33,6 +32,7 @@ import {
33
32
  getUserOrdersAccountPublicKey,
34
33
  calculateNewStateAfterOrder,
35
34
  calculateTradeSlippage,
35
+ BN,
36
36
  } from '.';
37
37
  import { getUserAccountPublicKey } from './addresses';
38
38
  import {
@@ -120,7 +120,7 @@ export class ClearingHouseUser {
120
120
  return this.accountSubscriber.getUserPositionsAccount();
121
121
  }
122
122
 
123
- public getUserOrdersAccount(): UserOrdersAccount {
123
+ public getUserOrdersAccount(): UserOrdersAccount | undefined {
124
124
  return this.accountSubscriber.getUserOrdersAccount();
125
125
  }
126
126
 
@@ -155,6 +155,16 @@ export class ClearingHouseUser {
155
155
  );
156
156
  }
157
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
+
158
168
  public async getUserAccountPublicKey(): Promise<PublicKey> {
159
169
  if (this.userAccountPublicKey) {
160
170
  return this.userAccountPublicKey;
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: '8mKouB1uzsoMAhAu4qAXCiu8KAfwH7nonpuYfTM21Xg2',
14
+ CLEARING_HOUSE_PROGRAM_ID: '3PfbDmWxR6e2rJ2brhSv7KJyUrHbSCu63d3FHqdLhxUJ',
15
15
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
16
16
  },
17
17
  'mainnet-beta': {
@@ -1,4 +1,4 @@
1
- import BN from 'bn.js';
1
+ import { BN } from '../';
2
2
 
3
3
  type Market = {
4
4
  symbol: string;
@@ -98,6 +98,14 @@ export const Markets: Market[] = [
98
98
  mainnetPythOracle: 'HqFyq1wh1xKvL7KDqqT7NJeSPdAqsDqnmBisUC2XdXAX',
99
99
  launchTs: 1643686767000,
100
100
  },
101
+ {
102
+ symbol: 'FTT-PERP',
103
+ baseAssetSymbol: 'FTT',
104
+ marketIndex: new BN(11),
105
+ devnetPythOracle: '6vivTRs5ZPeeXbjo7dfburfaYDWoXjBtdtuYgQRuGfu',
106
+ mainnetPythOracle: '8JPJJkmDScpcNmBRKGZuPuG2GYAveQgP3t5gFuMymwvF',
107
+ launchTs: 1644382122000,
108
+ },
101
109
  // {
102
110
  // symbol: 'mSOL-PERP',
103
111
  // baseAssetSymbol: 'mSOL',
@@ -1,7 +1,8 @@
1
- import BN from 'bn.js';
1
+ 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
 
@@ -15,6 +16,7 @@ export const FUNDING_PAYMENT_PRECISION = new BN(10000);
15
16
  export const PEG_PRECISION = new BN(1000);
16
17
 
17
18
  export const AMM_RESERVE_PRECISION = new BN(10 ** 13);
19
+ export const BASE_PRECISION = AMM_RESERVE_PRECISION;
18
20
  export const AMM_TO_QUOTE_PRECISION_RATIO =
19
21
  AMM_RESERVE_PRECISION.div(QUOTE_PRECISION); // 10^7
20
22
  export const PRICE_TO_QUOTE_PRECISION =
@@ -95,7 +95,10 @@ const main = async () => {
95
95
  clearingHouse.getMarket(solMarketInfo.marketIndex)
96
96
  );
97
97
 
98
- const formattedPrice = convertToNumber(currentMarketPrice, QUOTE_PRECISION);
98
+ const formattedPrice = convertToNumber(
99
+ currentMarketPrice,
100
+ MARK_PRICE_PRECISION
101
+ );
99
102
 
100
103
  console.log(`Current Market Price is $${formattedPrice}`);
101
104
 
@@ -572,7 +572,7 @@
572
572
  },
573
573
  {
574
574
  "name": "markets",
575
- "isMut": true,
575
+ "isMut": false,
576
576
  "isSigner": false
577
577
  },
578
578
  {
@@ -628,7 +628,7 @@
628
628
  },
629
629
  {
630
630
  "name": "markets",
631
- "isMut": true,
631
+ "isMut": false,
632
632
  "isSigner": false
633
633
  },
634
634
  {
@@ -3547,6 +3547,10 @@
3547
3547
  "name": "price",
3548
3548
  "type": "u128"
3549
3549
  },
3550
+ {
3551
+ "name": "userBaseAssetAmount",
3552
+ "type": "i128"
3553
+ },
3550
3554
  {
3551
3555
  "name": "quoteAssetAmount",
3552
3556
  "type": "u128"
@@ -3734,10 +3738,10 @@
3734
3738
  "name": "Limit"
3735
3739
  },
3736
3740
  {
3737
- "name": "Stop"
3741
+ "name": "TriggerMarket"
3738
3742
  },
3739
3743
  {
3740
- "name": "StopLimit"
3744
+ "name": "TriggerLimit"
3741
3745
  }
3742
3746
  ]
3743
3747
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import BN from 'bn.js';
1
+ import { BN } from '@project-serum/anchor';
2
2
  import { PublicKey } from '@solana/web3.js';
3
3
 
4
4
  export * from './mockUSDCFaucet';
@@ -1,4 +1,4 @@
1
- import BN from 'bn.js';
1
+ import { BN } from '../';
2
2
  import {
3
3
  MARK_PRICE_PRECISION,
4
4
  PEG_PRECISION,
@@ -1,5 +1,5 @@
1
1
  import { MarketsAccount, StateAccount } from '../types';
2
- import BN from 'bn.js';
2
+ import { BN } from '../';
3
3
  import { Connection } from '@solana/web3.js';
4
4
 
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import { ClearingHouseUser } from '../clearingHouseUser';
2
2
  import { isVariant, Order } from '../types';
3
- import { ZERO } from '../constants/numericConstants';
3
+ import { ZERO, TWO } from '../constants/numericConstants';
4
4
 
5
5
  export function isOrderRiskIncreasing(
6
6
  user: ClearingHouseUser,
@@ -33,7 +33,9 @@ export function isOrderRiskIncreasing(
33
33
  }
34
34
 
35
35
  // if order will flip position
36
- if (position.baseAssetAmount.abs().gt(order.baseAssetAmountFilled)) {
36
+ if (order.baseAssetAmountFilled.gt(position.baseAssetAmount.abs().mul(TWO))) {
37
37
  return true;
38
38
  }
39
+
40
+ return false;
39
41
  }
@@ -1,4 +1,4 @@
1
- import BN from 'bn.js';
1
+ import { BN } from '../';
2
2
  import {
3
3
  AMM_RESERVE_PRECISION,
4
4
  AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO,
package/src/math/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import BN from 'bn.js';
1
+ import { BN } from '../';
2
2
 
3
3
  export const squareRootBN = (n, closeness = new BN(1)) => {
4
4
  // Assuming the sqrt of n as n only
@@ -17,7 +17,7 @@ import {
17
17
  TransactionInstruction,
18
18
  TransactionSignature,
19
19
  } from '@solana/web3.js';
20
- import BN from 'bn.js';
20
+ import { BN } from '.';
21
21
  import mockUSDCFaucetIDL from './idl/mock_usdc_faucet.json';
22
22
  import { IWallet } from './types';
23
23
 
@@ -41,7 +41,7 @@ export function getLimitOrderParams(
41
41
  };
42
42
  }
43
43
 
44
- export function getStopOrderParams(
44
+ export function getTriggerMarketOrderParams(
45
45
  marketIndex: BN,
46
46
  direction: PositionDirection,
47
47
  baseAssetAmount: BN,
@@ -53,7 +53,7 @@ export function getStopOrderParams(
53
53
  userOrderId = 0
54
54
  ): OrderParams {
55
55
  return {
56
- orderType: OrderType.STOP,
56
+ orderType: OrderType.TRIGGER_MARKET,
57
57
  userOrderId,
58
58
  marketIndex,
59
59
  direction,
@@ -76,7 +76,7 @@ export function getStopOrderParams(
76
76
  };
77
77
  }
78
78
 
79
- export function getStopLimitOrderParams(
79
+ export function getTriggerLimitOrderParams(
80
80
  marketIndex: BN,
81
81
  direction: PositionDirection,
82
82
  baseAssetAmount: BN,
@@ -89,7 +89,7 @@ export function getStopLimitOrderParams(
89
89
  userOrderId = 0
90
90
  ): OrderParams {
91
91
  return {
92
- orderType: OrderType.STOP_LIMIT,
92
+ orderType: OrderType.TRIGGER_LIMIT,
93
93
  userOrderId,
94
94
  marketIndex,
95
95
  direction,
package/src/orders.ts CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  UserAccount,
7
7
  UserPosition,
8
8
  } from './types';
9
- import BN from 'bn.js';
9
+ import { BN } from '.';
10
10
  import {
11
11
  calculateMarkPrice,
12
12
  calculateNewMarketAfterTrade,
@@ -160,13 +160,13 @@ function calculateAmountSwapped(
160
160
  function calculateAmountToTrade(market: Market, order: Order): BN {
161
161
  if (isVariant(order.orderType, 'limit')) {
162
162
  return calculateAmountToTradeForLimit(market, order);
163
- } else if (isVariant(order.orderType, 'stopLimit')) {
164
- return calculateAmountToTradeForStopLimit(market, order);
163
+ } else if (isVariant(order.orderType, 'triggerLimit')) {
164
+ return calculateAmountToTradeForTriggerLimit(market, order);
165
165
  } else if (isVariant(order.orderType, 'market')) {
166
166
  // should never be a market order queued
167
167
  return ZERO;
168
168
  } else {
169
- return calculateAmountToTradeForStop(market, order);
169
+ return calculateAmountToTradeForTriggerMarket(market, order);
170
170
  }
171
171
  }
172
172
 
@@ -190,12 +190,15 @@ export function calculateAmountToTradeForLimit(
190
190
  : maxAmountToTrade;
191
191
  }
192
192
 
193
- export function calculateAmountToTradeForStopLimit(
193
+ export function calculateAmountToTradeForTriggerLimit(
194
194
  market: Market,
195
195
  order: Order
196
196
  ): BN {
197
197
  if (order.baseAssetAmountFilled.eq(ZERO)) {
198
- const baseAssetAmount = calculateAmountToTradeForStop(market, order);
198
+ const baseAssetAmount = calculateAmountToTradeForTriggerMarket(
199
+ market,
200
+ order
201
+ );
199
202
  if (baseAssetAmount.eq(ZERO)) {
200
203
  return ZERO;
201
204
  }
@@ -214,7 +217,10 @@ function isSameDirection(
214
217
  );
215
218
  }
216
219
 
217
- function calculateAmountToTradeForStop(market: Market, order: Order): BN {
220
+ function calculateAmountToTradeForTriggerMarket(
221
+ market: Market,
222
+ order: Order
223
+ ): BN {
218
224
  return isTriggerConditionSatisfied(market, order)
219
225
  ? order.baseAssetAmount
220
226
  : ZERO;
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PublicKey, Transaction } from '@solana/web3.js';
2
- import BN from 'bn.js';
2
+ import { BN } from '.';
3
3
 
4
4
  // # Utility Types / Enums / Constants
5
5
  export class SwapDirection {
@@ -19,8 +19,8 @@ export class OracleSource {
19
19
 
20
20
  export class OrderType {
21
21
  static readonly LIMIT = { limit: {} };
22
- static readonly STOP = { stop: {} };
23
- static readonly STOP_LIMIT = { stopLimit: {} };
22
+ static readonly TRIGGER_MARKET = { triggerMarket: {} };
23
+ static readonly TRIGGER_LIMIT = { triggerLimit: {} };
24
24
  static readonly MARKET = { market: {} };
25
25
  }
26
26
 
@@ -345,6 +345,7 @@ export type Order = {
345
345
  userOrderId: number;
346
346
  marketIndex: BN;
347
347
  price: BN;
348
+ userBaseAssetAmount: BN;
348
349
  baseAssetAmount: BN;
349
350
  baseAssetAmountFilled: BN;
350
351
  quoteAssetAmount: BN;
@@ -358,6 +359,7 @@ export type Order = {
358
359
  referrer: PublicKey;
359
360
  postOnly: boolean;
360
361
  immediateOrCancel: boolean;
362
+ oraclePriceOffset: BN;
361
363
  };
362
364
 
363
365
  export type OrderParams = {