@drift-labs/sdk 0.1.18-master.7 → 0.1.18-orders.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 (136) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +32 -0
  2. package/lib/accounts/bulkAccountLoader.js +156 -0
  3. package/lib/accounts/bulkUserSubscription.d.ts +7 -0
  4. package/lib/accounts/bulkUserSubscription.js +28 -0
  5. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +49 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +228 -0
  7. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +25 -0
  8. package/lib/accounts/pollingTokenAccountSubscriber.js +79 -0
  9. package/lib/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  10. package/lib/accounts/pollingUserAccountSubscriber.js +133 -0
  11. package/lib/accounts/types.d.ts +34 -3
  12. package/lib/accounts/utils.d.ts +1 -0
  13. package/lib/accounts/utils.js +7 -0
  14. package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
  15. package/lib/accounts/{defaultClearingHouseAccountSubscriber.d.ts → webSocketClearingHouseAccountSubscriber.d.ts} +8 -3
  16. package/lib/accounts/{defaultClearingHouseAccountSubscriber.js → webSocketClearingHouseAccountSubscriber.js} +30 -4
  17. package/lib/accounts/{defaultUserAccountSubscriber.d.ts → webSocketUserAccountSubscriber.d.ts} +6 -3
  18. package/lib/accounts/{defaultUserAccountSubscriber.js → webSocketUserAccountSubscriber.js} +16 -4
  19. package/lib/addresses.d.ts +4 -1
  20. package/lib/addresses.js +28 -1
  21. package/lib/admin.d.ts +11 -4
  22. package/lib/admin.js +71 -17
  23. package/lib/assert/assert.d.ts +0 -1
  24. package/lib/clearingHouse.d.ts +35 -4
  25. package/lib/clearingHouse.js +294 -23
  26. package/lib/clearingHouseUser.d.ts +19 -18
  27. package/lib/clearingHouseUser.js +129 -101
  28. package/lib/config.d.ts +0 -1
  29. package/lib/config.js +1 -1
  30. package/lib/constants/markets.d.ts +0 -1
  31. package/lib/constants/markets.js +13 -5
  32. package/lib/constants/numericConstants.d.ts +0 -1
  33. package/lib/examples/makeTradeExample.d.ts +0 -1
  34. package/lib/examples/makeTradeExample.js +6 -6
  35. package/lib/factory/clearingHouse.d.ts +25 -0
  36. package/lib/factory/clearingHouse.js +64 -0
  37. package/lib/factory/clearingHouseUser.d.ts +19 -0
  38. package/lib/factory/clearingHouseUser.js +34 -0
  39. package/lib/idl/clearing_house.json +1077 -54
  40. package/lib/index.d.ts +12 -4
  41. package/lib/index.js +17 -4
  42. package/lib/math/amm.d.ts +1 -1
  43. package/lib/math/amm.js +38 -15
  44. package/lib/math/conversion.d.ts +0 -1
  45. package/lib/math/conversion.js +1 -1
  46. package/lib/math/funding.d.ts +0 -1
  47. package/lib/math/funding.js +1 -1
  48. package/lib/math/insuranceFund.d.ts +0 -1
  49. package/lib/math/market.d.ts +2 -2
  50. package/lib/math/market.js +12 -2
  51. package/lib/math/orders.d.ts +3 -0
  52. package/lib/math/orders.js +30 -0
  53. package/lib/math/position.d.ts +4 -2
  54. package/lib/math/position.js +19 -5
  55. package/lib/math/trade.d.ts +0 -1
  56. package/lib/math/trade.js +16 -16
  57. package/lib/math/utils.d.ts +2 -3
  58. package/lib/math/utils.js +6 -3
  59. package/lib/mockUSDCFaucet.d.ts +0 -1
  60. package/lib/orderParams.d.ts +7 -0
  61. package/lib/orderParams.js +108 -0
  62. package/lib/orders.d.ts +5 -0
  63. package/lib/orders.js +136 -0
  64. package/lib/pythClient.d.ts +0 -1
  65. package/lib/pythClient.js +1 -1
  66. package/lib/token/index.d.ts +3 -0
  67. package/lib/token/index.js +38 -0
  68. package/lib/tx/defaultTxSender.d.ts +0 -1
  69. package/lib/tx/types.d.ts +0 -1
  70. package/lib/tx/utils.d.ts +0 -1
  71. package/lib/types.d.ts +144 -2
  72. package/lib/types.js +36 -1
  73. package/lib/util/computeUnits.d.ts +0 -1
  74. package/lib/util/tps.d.ts +0 -1
  75. package/lib/wallet.d.ts +0 -1
  76. package/package.json +3 -3
  77. package/src/accounts/bulkAccountLoader.ts +195 -0
  78. package/src/accounts/bulkUserSubscription.ts +28 -0
  79. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +326 -0
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +99 -0
  81. package/src/accounts/pollingUserAccountSubscriber.ts +186 -0
  82. package/src/accounts/types.ts +43 -1
  83. package/src/accounts/utils.ts +3 -0
  84. package/src/accounts/{defaultClearingHouseAccountSubscriber.ts → webSocketClearingHouseAccountSubscriber.ts} +51 -1
  85. package/src/accounts/{defaultUserAccountSubscriber.ts → webSocketUserAccountSubscriber.ts} +33 -3
  86. package/src/addresses.ts +37 -0
  87. package/src/admin.ts +111 -24
  88. package/src/clearingHouse.ts +399 -22
  89. package/src/clearingHouseUser.ts +179 -107
  90. package/src/config.ts +1 -1
  91. package/src/constants/markets.ts +13 -5
  92. package/src/factory/clearingHouse.ts +125 -0
  93. package/src/factory/clearingHouseUser.ts +73 -0
  94. package/src/idl/clearing_house.json +1077 -54
  95. package/src/index.ts +12 -3
  96. package/src/math/amm.ts +47 -14
  97. package/src/math/market.ts +28 -2
  98. package/src/math/orders.ts +39 -0
  99. package/src/math/position.ts +23 -3
  100. package/src/math/utils.ts +1 -1
  101. package/src/orderParams.ts +151 -0
  102. package/src/orders.ts +230 -0
  103. package/src/token/index.ts +37 -0
  104. package/src/types.ts +128 -1
  105. package/tsconfig.json +0 -1
  106. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +0 -1
  107. package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +0 -1
  108. package/lib/accounts/types.d.ts.map +0 -1
  109. package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
  110. package/lib/addresses.d.ts.map +0 -1
  111. package/lib/admin.d.ts.map +0 -1
  112. package/lib/assert/assert.d.ts.map +0 -1
  113. package/lib/clearingHouse.d.ts.map +0 -1
  114. package/lib/clearingHouseUser.d.ts.map +0 -1
  115. package/lib/config.d.ts.map +0 -1
  116. package/lib/constants/markets.d.ts.map +0 -1
  117. package/lib/constants/numericConstants.d.ts.map +0 -1
  118. package/lib/examples/makeTradeExample.d.ts.map +0 -1
  119. package/lib/index.d.ts.map +0 -1
  120. package/lib/math/amm.d.ts.map +0 -1
  121. package/lib/math/conversion.d.ts.map +0 -1
  122. package/lib/math/funding.d.ts.map +0 -1
  123. package/lib/math/insuranceFund.d.ts.map +0 -1
  124. package/lib/math/market.d.ts.map +0 -1
  125. package/lib/math/position.d.ts.map +0 -1
  126. package/lib/math/trade.d.ts.map +0 -1
  127. package/lib/math/utils.d.ts.map +0 -1
  128. package/lib/mockUSDCFaucet.d.ts.map +0 -1
  129. package/lib/pythClient.d.ts.map +0 -1
  130. package/lib/tx/defaultTxSender.d.ts.map +0 -1
  131. package/lib/tx/types.d.ts.map +0 -1
  132. package/lib/tx/utils.d.ts.map +0 -1
  133. package/lib/types.d.ts.map +0 -1
  134. package/lib/util/computeUnits.d.ts.map +0 -1
  135. package/lib/util/tps.d.ts.map +0 -1
  136. package/lib/wallet.d.ts.map +0 -1
package/lib/orders.js ADDED
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateAmountToTradeForStopLimit = exports.calculateAmountToTradeForLimit = exports.calculateNewStateAfterOrder = void 0;
4
+ const types_1 = require("./types");
5
+ const market_1 = require("./math/market");
6
+ const numericConstants_1 = require("./constants/numericConstants");
7
+ const amm_1 = require("./math/amm");
8
+ const position_1 = require("./math/position");
9
+ function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
10
+ if (types_1.isVariant(order.status, 'init')) {
11
+ return null;
12
+ }
13
+ const baseAssetAmountToTrade = calculateAmountToTrade(market, order);
14
+ if (baseAssetAmountToTrade.lt(market.amm.minimumBaseAssetTradeSize)) {
15
+ return null;
16
+ }
17
+ const userAccountAfter = Object.assign({}, userAccount);
18
+ const userPositionAfter = Object.assign({}, userPosition);
19
+ const currentPositionDirection = position_1.positionCurrentDirection(userPosition);
20
+ const increasePosition = userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) ||
21
+ isSameDirection(order.direction, currentPositionDirection);
22
+ if (increasePosition) {
23
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
24
+ const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(market, marketAfter);
25
+ userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
26
+ userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(quoteAssetAmountSwapped);
27
+ return [userAccountAfter, userPositionAfter, marketAfter];
28
+ }
29
+ else {
30
+ const reversePosition = baseAssetAmountToTrade.gt(userPosition.baseAssetAmount.abs());
31
+ if (reversePosition) {
32
+ const intermediateMarket = market_1.calculateNewMarketAfterTrade(userPosition.baseAssetAmount, position_1.findDirectionToClose(userPosition), market);
33
+ const { quoteAssetAmountSwapped: baseAssetValue } = calculateAmountSwapped(market, intermediateMarket);
34
+ let pnl;
35
+ if (types_1.isVariant(currentPositionDirection, 'long')) {
36
+ pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
37
+ }
38
+ else {
39
+ pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
40
+ }
41
+ userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
42
+ const baseAssetAmountLeft = baseAssetAmountToTrade.sub(userPosition.baseAssetAmount.abs());
43
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountLeft, order.direction, intermediateMarket);
44
+ const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(intermediateMarket, marketAfter);
45
+ userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
46
+ userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
47
+ return [userAccountAfter, userPositionAfter, marketAfter];
48
+ }
49
+ else {
50
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
51
+ const { quoteAssetAmountSwapped: baseAssetValue, baseAssetAmountSwapped, } = calculateAmountSwapped(market, marketAfter);
52
+ const costBasisRealized = userPosition.quoteAssetAmount
53
+ .mul(baseAssetAmountSwapped.abs())
54
+ .div(userPosition.baseAssetAmount.abs());
55
+ let pnl;
56
+ if (types_1.isVariant(currentPositionDirection, 'long')) {
57
+ pnl = baseAssetValue.sub(costBasisRealized);
58
+ }
59
+ else {
60
+ pnl = costBasisRealized.sub(baseAssetValue);
61
+ }
62
+ userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
63
+ userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
64
+ userPositionAfter.quoteAssetAmount =
65
+ userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
66
+ return [userAccountAfter, userPositionAfter, marketAfter];
67
+ }
68
+ }
69
+ }
70
+ exports.calculateNewStateAfterOrder = calculateNewStateAfterOrder;
71
+ function calculateAmountSwapped(marketBefore, marketAfter) {
72
+ return {
73
+ quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
74
+ .sub(marketAfter.amm.quoteAssetReserve)
75
+ .abs()
76
+ .mul(marketBefore.amm.pegMultiplier)
77
+ .div(numericConstants_1.PEG_PRECISION)
78
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO),
79
+ baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
80
+ };
81
+ }
82
+ function calculateAmountToTrade(market, order) {
83
+ if (types_1.isVariant(order.orderType, 'limit')) {
84
+ return calculateAmountToTradeForLimit(market, order);
85
+ }
86
+ else if (types_1.isVariant(order.orderType, 'stopLimit')) {
87
+ return calculateAmountToTradeForStopLimit(market, order);
88
+ }
89
+ else if (types_1.isVariant(order.orderType, 'market')) {
90
+ // should never be a market order queued
91
+ return numericConstants_1.ZERO;
92
+ }
93
+ else {
94
+ return calculateAmountToTradeForStop(market, order);
95
+ }
96
+ }
97
+ function calculateAmountToTradeForLimit(market, order) {
98
+ const [maxAmountToTrade, direction] = amm_1.calculateMaxBaseAssetAmountToTrade(market.amm, order.price);
99
+ // Check that directions are the same
100
+ const sameDirection = isSameDirection(direction, order.direction);
101
+ if (!sameDirection) {
102
+ return numericConstants_1.ZERO;
103
+ }
104
+ return maxAmountToTrade.gt(order.baseAssetAmount)
105
+ ? order.baseAssetAmount
106
+ : maxAmountToTrade;
107
+ }
108
+ exports.calculateAmountToTradeForLimit = calculateAmountToTradeForLimit;
109
+ function calculateAmountToTradeForStopLimit(market, order) {
110
+ if (order.baseAssetAmountFilled.eq(numericConstants_1.ZERO)) {
111
+ const baseAssetAmount = calculateAmountToTradeForStop(market, order);
112
+ if (baseAssetAmount.eq(numericConstants_1.ZERO)) {
113
+ return numericConstants_1.ZERO;
114
+ }
115
+ }
116
+ return calculateAmountToTradeForLimit(market, order);
117
+ }
118
+ exports.calculateAmountToTradeForStopLimit = calculateAmountToTradeForStopLimit;
119
+ function isSameDirection(firstDirection, secondDirection) {
120
+ return ((types_1.isVariant(firstDirection, 'long') && types_1.isVariant(secondDirection, 'long')) ||
121
+ (types_1.isVariant(firstDirection, 'short') && types_1.isVariant(secondDirection, 'short')));
122
+ }
123
+ function calculateAmountToTradeForStop(market, order) {
124
+ return isTriggerConditionSatisfied(market, order)
125
+ ? order.baseAssetAmount
126
+ : numericConstants_1.ZERO;
127
+ }
128
+ function isTriggerConditionSatisfied(market, order) {
129
+ const markPrice = market_1.calculateMarkPrice(market);
130
+ if (types_1.isVariant(order.triggerCondition, 'above')) {
131
+ return markPrice.gt(order.triggerPrice);
132
+ }
133
+ else {
134
+ return markPrice.lt(order.triggerPrice);
135
+ }
136
+ }
@@ -5,4 +5,3 @@ export declare class PythClient {
5
5
  constructor(connection: Connection);
6
6
  getPriceData(pricePublicKey: PublicKey): Promise<PriceData>;
7
7
  }
8
- //# sourceMappingURL=pythClient.d.ts.map
package/lib/pythClient.js CHANGED
@@ -18,7 +18,7 @@ class PythClient {
18
18
  getPriceData(pricePublicKey) {
19
19
  return __awaiter(this, void 0, void 0, function* () {
20
20
  const account = yield this.connection.getAccountInfo(pricePublicKey);
21
- return (0, client_1.parsePriceData)(account.data);
21
+ return client_1.parsePriceData(account.data);
22
22
  });
23
23
  }
24
24
  }
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import { AccountInfo } from '@solana/spl-token';
3
+ export declare function parseTokenAccount(data: Buffer): AccountInfo;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTokenAccount = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ function parseTokenAccount(data) {
7
+ const accountInfo = spl_token_1.AccountLayout.decode(data);
8
+ accountInfo.mint = new web3_js_1.PublicKey(accountInfo.mint);
9
+ accountInfo.owner = new web3_js_1.PublicKey(accountInfo.owner);
10
+ accountInfo.amount = spl_token_1.u64.fromBuffer(accountInfo.amount);
11
+ if (accountInfo.delegateOption === 0) {
12
+ accountInfo.delegate = null;
13
+ // eslint-disable-next-line new-cap
14
+ accountInfo.delegatedAmount = new spl_token_1.u64(0);
15
+ }
16
+ else {
17
+ accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate);
18
+ accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(accountInfo.delegatedAmount);
19
+ }
20
+ accountInfo.isInitialized = accountInfo.state !== 0;
21
+ accountInfo.isFrozen = accountInfo.state === 2;
22
+ if (accountInfo.isNativeOption === 1) {
23
+ accountInfo.rentExemptReserve = spl_token_1.u64.fromBuffer(accountInfo.isNative);
24
+ accountInfo.isNative = true;
25
+ }
26
+ else {
27
+ accountInfo.rentExemptReserve = null;
28
+ accountInfo.isNative = false;
29
+ }
30
+ if (accountInfo.closeAuthorityOption === 0) {
31
+ accountInfo.closeAuthority = null;
32
+ }
33
+ else {
34
+ accountInfo.closeAuthority = new web3_js_1.PublicKey(accountInfo.closeAuthority);
35
+ }
36
+ return accountInfo;
37
+ }
38
+ exports.parseTokenAccount = parseTokenAccount;
@@ -6,4 +6,3 @@ export declare class DefaultTxSender implements TxSender {
6
6
  constructor(provider: Provider);
7
7
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TransactionSignature>;
8
8
  }
9
- //# sourceMappingURL=defaultTxSender.d.ts.map
package/lib/tx/types.d.ts CHANGED
@@ -2,4 +2,3 @@ import { ConfirmOptions, Signer, Transaction, TransactionSignature } from '@sola
2
2
  export interface TxSender {
3
3
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TransactionSignature>;
4
4
  }
5
- //# sourceMappingURL=types.d.ts.map
package/lib/tx/utils.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import { Transaction, TransactionInstruction } from '@solana/web3.js';
2
2
  export declare function wrapInTx(instruction: TransactionInstruction): Transaction;
3
- //# sourceMappingURL=utils.d.ts.map
package/lib/types.d.ts CHANGED
@@ -24,6 +24,65 @@ export declare class OracleSource {
24
24
  switchboard: {};
25
25
  };
26
26
  }
27
+ export declare class OrderType {
28
+ static readonly LIMIT: {
29
+ limit: {};
30
+ };
31
+ static readonly STOP: {
32
+ stop: {};
33
+ };
34
+ static readonly STOP_LIMIT: {
35
+ stopLimit: {};
36
+ };
37
+ static readonly MARKET: {
38
+ market: {};
39
+ };
40
+ }
41
+ export declare class OrderStatus {
42
+ static readonly INIT: {
43
+ init: {};
44
+ };
45
+ static readonly OPEN: {
46
+ open: {};
47
+ };
48
+ }
49
+ export declare class OrderDiscountTier {
50
+ static readonly NONE: {
51
+ none: {};
52
+ };
53
+ static readonly FIRST: {
54
+ first: {};
55
+ };
56
+ static readonly SECOND: {
57
+ second: {};
58
+ };
59
+ static readonly THIRD: {
60
+ third: {};
61
+ };
62
+ static readonly FOURTH: {
63
+ fourth: {};
64
+ };
65
+ }
66
+ export declare class OrderAction {
67
+ static readonly PLACE: {
68
+ place: {};
69
+ };
70
+ static readonly CANCEL: {
71
+ cancel: {};
72
+ };
73
+ static readonly FILL: {
74
+ fill: {};
75
+ };
76
+ }
77
+ export declare class OrderTriggerCondition {
78
+ static readonly ABOVE: {
79
+ above: {};
80
+ };
81
+ static readonly BELOW: {
82
+ below: {};
83
+ };
84
+ }
85
+ export declare function isVariant(object: unknown, type: string): boolean;
27
86
  export declare enum TradeSide {
28
87
  None = 0,
29
88
  Buy = 1,
@@ -54,6 +113,11 @@ export declare type LiquidationHistoryAccount = {
54
113
  head: BN;
55
114
  liquidationRecords: LiquidationRecord[];
56
115
  };
116
+ export declare type OrderHistoryAccount = {
117
+ head: BN;
118
+ lastOrderId: BN;
119
+ orderRecords: OrderRecord[];
120
+ };
57
121
  export declare type DepositRecord = {
58
122
  ts: BN;
59
123
  recordId: BN;
@@ -147,6 +211,20 @@ export declare type LiquidationRecord = {
147
211
  unrealizedPnl: BN;
148
212
  marginRatio: BN;
149
213
  };
214
+ export declare type OrderRecord = {
215
+ ts: BN;
216
+ recordId: BN;
217
+ order: Order;
218
+ user: PublicKey;
219
+ authority: PublicKey;
220
+ action: OrderAction;
221
+ filler: PublicKey;
222
+ baseAssetAmountFilled: BN;
223
+ quoteAssetAmountFilled: BN;
224
+ fee: BN;
225
+ fillerReward: BN;
226
+ tradeRecordId: BN;
227
+ };
150
228
  export declare type StateAccount = {
151
229
  admin: PublicKey;
152
230
  fundingPaused: boolean;
@@ -184,8 +262,14 @@ export declare type StateAccount = {
184
262
  discountMint: PublicKey;
185
263
  oracleGuardRails: OracleGuardRails;
186
264
  maxDeposit: BN;
265
+ orderState: PublicKey;
187
266
  extendedCurveHistory: PublicKey;
188
267
  };
268
+ export declare type OrderStateAccount = {
269
+ orderHistory: PublicKey;
270
+ orderFillerRewardStructure: OrderFillerRewardStructure;
271
+ minOrderQuoteAssetAmount: BN;
272
+ };
189
273
  export declare type MarketsAccount = {
190
274
  accountIndex: BN;
191
275
  markets: Market[];
@@ -220,13 +304,16 @@ export declare type AMM = {
220
304
  totalFeeMinusDistributions: BN;
221
305
  totalFeeWithdrawn: BN;
222
306
  totalFee: BN;
223
- minimumTradeSize: BN;
307
+ minimumQuoteAssetTradeSize: BN;
308
+ minimumBaseAssetTradeSize: BN;
309
+ lastOraclePrice: BN;
224
310
  };
225
311
  export declare type UserPosition = {
226
312
  baseAssetAmount: BN;
227
313
  lastCumulativeFundingRate: BN;
228
314
  marketIndex: BN;
229
315
  quoteAssetAmount: BN;
316
+ openOrders: BN;
230
317
  };
231
318
  export declare type UserPositionsAccount = {
232
319
  positions: UserPosition[];
@@ -238,6 +325,57 @@ export declare type UserAccount = {
238
325
  cumulativeDeposits: BN;
239
326
  positions: PublicKey;
240
327
  totalFeePaid: BN;
328
+ totalTokenDiscount: BN;
329
+ totalReferralReward: BN;
330
+ totalRefereeDiscount: BN;
331
+ };
332
+ export declare type UserOrdersAccount = {
333
+ orders: Order[];
334
+ user: PublicKey;
335
+ };
336
+ export declare type Order = {
337
+ status: OrderStatus;
338
+ orderType: OrderType;
339
+ ts: BN;
340
+ orderId: BN;
341
+ userOrderId: number;
342
+ marketIndex: BN;
343
+ price: BN;
344
+ baseAssetAmount: BN;
345
+ baseAssetAmountFilled: BN;
346
+ quoteAssetAmount: BN;
347
+ quoteAssetAmountFilled: BN;
348
+ fee: BN;
349
+ direction: PositionDirection;
350
+ reduceOnly: boolean;
351
+ triggerPrice: BN;
352
+ triggerCondition: OrderTriggerCondition;
353
+ discountTier: OrderDiscountTier;
354
+ referrer: PublicKey;
355
+ postOnly: boolean;
356
+ immediateOrCancel: boolean;
357
+ };
358
+ export declare type OrderParams = {
359
+ orderType: OrderType;
360
+ userOrderId: number;
361
+ direction: PositionDirection;
362
+ quoteAssetAmount: BN;
363
+ baseAssetAmount: BN;
364
+ price: BN;
365
+ marketIndex: BN;
366
+ reduceOnly: boolean;
367
+ postOnly: boolean;
368
+ immediateOrCancel: boolean;
369
+ triggerPrice: BN;
370
+ triggerCondition: OrderTriggerCondition;
371
+ positionLimit: BN;
372
+ oraclePriceOffset: BN;
373
+ padding0: boolean;
374
+ padding1: BN;
375
+ optionalAccounts: {
376
+ discountToken: boolean;
377
+ referrer: boolean;
378
+ };
241
379
  };
242
380
  export interface IWallet {
243
381
  signTransaction(tx: Transaction): Promise<Transaction>;
@@ -288,4 +426,8 @@ export declare type OracleGuardRails = {
288
426
  };
289
427
  useForLiquidations: boolean;
290
428
  };
291
- //# sourceMappingURL=types.d.ts.map
429
+ export declare type OrderFillerRewardStructure = {
430
+ rewardNumerator: BN;
431
+ rewardDenominator: BN;
432
+ timeBasedRewardLowerBound: BN;
433
+ };
package/lib/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TradeSide = exports.OracleSource = exports.PositionDirection = exports.SwapDirection = void 0;
3
+ exports.TradeSide = exports.isVariant = exports.OrderTriggerCondition = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.PositionDirection = exports.SwapDirection = void 0;
4
4
  // # Utility Types / Enums / Constants
5
5
  class SwapDirection {
6
6
  }
@@ -17,6 +17,41 @@ class OracleSource {
17
17
  exports.OracleSource = OracleSource;
18
18
  OracleSource.PYTH = { pyth: {} };
19
19
  OracleSource.SWITCHBOARD = { switchboard: {} };
20
+ class OrderType {
21
+ }
22
+ exports.OrderType = OrderType;
23
+ OrderType.LIMIT = { limit: {} };
24
+ OrderType.STOP = { stop: {} };
25
+ OrderType.STOP_LIMIT = { stopLimit: {} };
26
+ OrderType.MARKET = { market: {} };
27
+ class OrderStatus {
28
+ }
29
+ exports.OrderStatus = OrderStatus;
30
+ OrderStatus.INIT = { init: {} };
31
+ OrderStatus.OPEN = { open: {} };
32
+ class OrderDiscountTier {
33
+ }
34
+ exports.OrderDiscountTier = OrderDiscountTier;
35
+ OrderDiscountTier.NONE = { none: {} };
36
+ OrderDiscountTier.FIRST = { first: {} };
37
+ OrderDiscountTier.SECOND = { second: {} };
38
+ OrderDiscountTier.THIRD = { third: {} };
39
+ OrderDiscountTier.FOURTH = { fourth: {} };
40
+ class OrderAction {
41
+ }
42
+ exports.OrderAction = OrderAction;
43
+ OrderAction.PLACE = { place: {} };
44
+ OrderAction.CANCEL = { cancel: {} };
45
+ OrderAction.FILL = { fill: {} };
46
+ class OrderTriggerCondition {
47
+ }
48
+ exports.OrderTriggerCondition = OrderTriggerCondition;
49
+ OrderTriggerCondition.ABOVE = { above: {} };
50
+ OrderTriggerCondition.BELOW = { below: {} };
51
+ function isVariant(object, type) {
52
+ return object.hasOwnProperty(type);
53
+ }
54
+ exports.isVariant = isVariant;
20
55
  var TradeSide;
21
56
  (function (TradeSide) {
22
57
  TradeSide[TradeSide["None"] = 0] = "None";
@@ -1,3 +1,2 @@
1
1
  import { Connection, Finality, PublicKey } from '@solana/web3.js';
2
2
  export declare function findComputeUnitConsumption(programId: PublicKey, connection: Connection, txSignature: string, commitment?: Finality): Promise<number[]>;
3
- //# sourceMappingURL=computeUnits.d.ts.map
package/lib/util/tps.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import { Connection, PublicKey } from '@solana/web3.js';
2
2
  export declare function estimateTps(programId: PublicKey, connection: Connection, failed: boolean): Promise<number>;
3
- //# sourceMappingURL=tps.d.ts.map
package/lib/wallet.d.ts CHANGED
@@ -7,4 +7,3 @@ export declare class Wallet implements IWallet {
7
7
  signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
8
8
  get publicKey(): PublicKey;
9
9
  }
10
- //# sourceMappingURL=wallet.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.18-master.7",
3
+ "version": "0.1.18-orders.2",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -31,8 +31,8 @@
31
31
  "@pythnetwork/client": "^2.5.1",
32
32
  "@solana/spl-token": "^0.1.6",
33
33
  "@solana/web3.js": "^1.22.0",
34
- "@types/bn.js": "^5.1.0",
35
- "strict-event-emitter-types": "^2.0.0"
34
+ "strict-event-emitter-types": "^2.0.0",
35
+ "uuid": "^8.3.2"
36
36
  },
37
37
  "description": "SDK for Drift Protocol v1",
38
38
  "engines": {
@@ -0,0 +1,195 @@
1
+ import { Commitment, Connection, PublicKey } from '@solana/web3.js';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+
4
+ type AccountToLoad = {
5
+ publicKey: PublicKey;
6
+ callbacks: Map<string, (buffer: Buffer) => void>;
7
+ };
8
+
9
+ type AccountData = {
10
+ slot: number;
11
+ buffer: Buffer | undefined;
12
+ };
13
+
14
+ const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
15
+
16
+ export class BulkAccountLoader {
17
+ connection: Connection;
18
+ commitment: Commitment;
19
+ pollingFrequency: number;
20
+ accountsToLoad = new Map<string, AccountToLoad>();
21
+ accountData = new Map<string, AccountData>();
22
+ errorCallbacks = new Map<string, (e) => void>();
23
+ intervalId?: NodeJS.Timer;
24
+
25
+ public constructor(
26
+ connection: Connection,
27
+ commitment: Commitment,
28
+ pollingFrequency: number
29
+ ) {
30
+ this.connection = connection;
31
+ this.commitment = commitment;
32
+ this.pollingFrequency = pollingFrequency;
33
+ }
34
+
35
+ public addAccount(
36
+ publicKey: PublicKey,
37
+ callback: (buffer: Buffer) => void
38
+ ): string {
39
+ const existingSize = this.accountsToLoad.size;
40
+
41
+ const callbackId = uuidv4();
42
+ const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
43
+ if (existingAccountToLoad) {
44
+ existingAccountToLoad.callbacks.set(callbackId, callback);
45
+ } else {
46
+ const callbacks = new Map<string, (buffer: Buffer) => void>();
47
+ callbacks.set(callbackId, callback);
48
+ const newAccountToLoad = {
49
+ publicKey,
50
+ callbacks,
51
+ };
52
+ this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
53
+ }
54
+
55
+ if (existingSize === 0) {
56
+ this.startPolling();
57
+ }
58
+
59
+ return callbackId;
60
+ }
61
+
62
+ public removeAccount(publicKey: PublicKey, callbackId: string): void {
63
+ const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
64
+ if (existingAccountToLoad) {
65
+ existingAccountToLoad.callbacks.delete(callbackId);
66
+ if (existingAccountToLoad.callbacks.size === 0) {
67
+ this.accountsToLoad.delete(existingAccountToLoad.publicKey.toString());
68
+ }
69
+ }
70
+
71
+ if (this.accountsToLoad.size === 0) {
72
+ this.stopPolling();
73
+ }
74
+ }
75
+
76
+ public addErrorCallbacks(callback: (error: Error) => void): string {
77
+ const callbackId = uuidv4();
78
+ this.errorCallbacks.set(callbackId, callback);
79
+ return callbackId;
80
+ }
81
+
82
+ public removeErrorCallbacks(callbackId: string): void {
83
+ this.errorCallbacks.delete(callbackId);
84
+ }
85
+
86
+ chunks<T>(array: readonly T[], size: number): T[][] {
87
+ return new Array(Math.ceil(array.length / size))
88
+ .fill(null)
89
+ .map((_, index) => index * size)
90
+ .map((begin) => array.slice(begin, begin + size));
91
+ }
92
+
93
+ public async load(): Promise<void> {
94
+ const chunks = this.chunks(
95
+ Array.from(this.accountsToLoad.values()),
96
+ GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
97
+ );
98
+
99
+ await Promise.all(
100
+ chunks.map((chunk) => {
101
+ return this.loadChunk(chunk);
102
+ })
103
+ );
104
+ }
105
+
106
+ async loadChunk(accountsToLoad: AccountToLoad[]): Promise<void> {
107
+ if (accountsToLoad.length === 0) {
108
+ return;
109
+ }
110
+
111
+ const args = [
112
+ accountsToLoad.map((accountToLoad) => {
113
+ return accountToLoad.publicKey.toBase58();
114
+ }),
115
+ { commitment: this.commitment },
116
+ ];
117
+
118
+ let rpcResponse;
119
+ try {
120
+ // @ts-ignore
121
+ rpcResponse = await this.connection._rpcRequest(
122
+ 'getMultipleAccounts',
123
+ args
124
+ );
125
+ } catch (e) {
126
+ for (const [_, callback] of this.errorCallbacks) {
127
+ callback(e);
128
+ }
129
+ return;
130
+ }
131
+
132
+ const newSlot = rpcResponse.result.context.slot;
133
+
134
+ for (const i in accountsToLoad) {
135
+ const accountToLoad = accountsToLoad[i];
136
+ const key = accountToLoad.publicKey.toString();
137
+ const oldRPCResponse = this.accountData.get(key);
138
+
139
+ let newBuffer: Buffer | undefined = undefined;
140
+ if (rpcResponse.result.value[i]) {
141
+ const raw: string = rpcResponse.result.value[i].data[0];
142
+ const dataType = rpcResponse.result.value[i].data[1];
143
+ newBuffer = Buffer.from(raw, dataType);
144
+ }
145
+
146
+ if (!oldRPCResponse) {
147
+ this.accountData.set(key, {
148
+ slot: newSlot,
149
+ buffer: newBuffer,
150
+ });
151
+ this.handleAccountCallbacks(accountToLoad, newBuffer);
152
+ continue;
153
+ }
154
+
155
+ if (newSlot <= oldRPCResponse.slot) {
156
+ continue;
157
+ }
158
+
159
+ const oldBuffer = oldRPCResponse.buffer;
160
+ if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
161
+ this.accountData.set(key, {
162
+ slot: newSlot,
163
+ buffer: newBuffer,
164
+ });
165
+ this.handleAccountCallbacks(accountToLoad, newBuffer);
166
+ }
167
+ }
168
+ }
169
+
170
+ handleAccountCallbacks(accountToLoad: AccountToLoad, buffer: Buffer): void {
171
+ for (const [_, callback] of accountToLoad.callbacks) {
172
+ callback(buffer);
173
+ }
174
+ }
175
+
176
+ public getAccountData(publicKey: PublicKey): Buffer | undefined {
177
+ const accountData = this.accountData.get(publicKey.toString());
178
+ return accountData?.buffer;
179
+ }
180
+
181
+ public startPolling(): void {
182
+ if (this.intervalId) {
183
+ return;
184
+ }
185
+
186
+ this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
187
+ }
188
+
189
+ public stopPolling(): void {
190
+ if (this.intervalId) {
191
+ clearInterval(this.intervalId);
192
+ this.intervalId = undefined;
193
+ }
194
+ }
195
+ }