@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
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="bn.js" />
3
3
  import { BN, Program, Provider } from '@project-serum/anchor';
4
- import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, ExtendedCurveHistoryAccount } from './types';
4
+ import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount } from './types';
5
5
  import { Connection, PublicKey, TransactionSignature, Keypair, ConfirmOptions, TransactionInstruction } from '@solana/web3.js';
6
6
  import { MockUSDCFaucet } from './mockUSDCFaucet';
7
7
  import { EventEmitter } from 'events';
@@ -67,6 +67,10 @@ export declare class ClearingHouse {
67
67
  getLiquidationHistoryAccount(): LiquidationHistoryAccount;
68
68
  getDepositHistoryAccount(): DepositHistoryAccount;
69
69
  getCurveHistoryAccount(): ExtendedCurveHistoryAccount;
70
+ getOrderHistoryAccount(): OrderHistoryAccount;
71
+ orderStatePublicKey?: PublicKey;
72
+ getOrderStatePublicKey(): Promise<PublicKey>;
73
+ getOrderStateAccount(): OrderStateAccount;
70
74
  /**
71
75
  * Update the wallet to use for clearing house transactions and linked user account
72
76
  * @param newWallet
@@ -79,8 +83,10 @@ export declare class ClearingHouse {
79
83
  getInitializeUserInstructions(): Promise<[
80
84
  Keypair,
81
85
  PublicKey,
86
+ TransactionInstruction,
82
87
  TransactionInstruction
83
88
  ]>;
89
+ getInitializeUserOrdersInstruction(userAccountPublicKey?: PublicKey): Promise<TransactionInstruction>;
84
90
  userAccountPublicKey?: PublicKey;
85
91
  /**
86
92
  * Get the address for the Clearing House User's account. NOT the user's wallet address.
@@ -89,6 +95,14 @@ export declare class ClearingHouse {
89
95
  getUserAccountPublicKey(): Promise<PublicKey>;
90
96
  userAccount?: UserAccount;
91
97
  getUserAccount(): Promise<UserAccount>;
98
+ userOrdersAccountPublicKey?: PublicKey;
99
+ /**
100
+ * Get the address for the Clearing House User Order's account. NOT the user's wallet address.
101
+ * @returns
102
+ */
103
+ getUserOrdersAccountPublicKey(): Promise<PublicKey>;
104
+ userOrdersExist?: boolean;
105
+ userOrdersAccountExists(): Promise<boolean>;
92
106
  depositCollateral(amount: BN, collateralAccountPublicKey: PublicKey, userPositionsAccountPublicKey?: PublicKey): Promise<TransactionSignature>;
93
107
  getDepositCollateralInstruction(amount: BN, collateralAccountPublicKey: PublicKey, userPositionsAccountPublicKey?: PublicKey): Promise<TransactionInstruction>;
94
108
  /**
@@ -104,6 +118,18 @@ export declare class ClearingHouse {
104
118
  getWithdrawCollateralIx(amount: BN, collateralAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
105
119
  openPosition(direction: PositionDirection, amount: BN, marketIndex: BN, limitPrice?: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
106
120
  getOpenPositionIx(direction: PositionDirection, amount: BN, marketIndex: BN, limitPrice?: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
121
+ initializeUserOrdersThenPlaceOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
122
+ placeOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
123
+ getPlaceOrderIx(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
124
+ cancelOrder(orderId: BN): Promise<TransactionSignature>;
125
+ getCancelOrderIx(orderId: BN): Promise<TransactionInstruction>;
126
+ cancelOrderByUserId(userOrderId: number): Promise<TransactionSignature>;
127
+ getCancelOrderByUserIdIx(userOrderId: number): Promise<TransactionInstruction>;
128
+ fillOrder(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionSignature>;
129
+ getFillOrderIx(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionInstruction>;
130
+ initializeUserOrdersThenPlaceAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
131
+ placeAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
132
+ getPlaceAndFillOrderIx(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
107
133
  /**
108
134
  * Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
109
135
  * @param marketIndex
@@ -121,4 +147,3 @@ export declare class ClearingHouse {
121
147
  getSettleFundingPaymentIx(userAccount: PublicKey, userPositionsAccount: PublicKey): Promise<TransactionInstruction>;
122
148
  triggerEvent(eventName: keyof ClearingHouseAccountEvents, data?: any): void;
123
149
  }
124
- //# sourceMappingURL=clearingHouse.d.ts.map
@@ -101,6 +101,7 @@ class ClearingHouse {
101
101
  'fundingRateHistoryAccount',
102
102
  'liquidationHistoryAccount',
103
103
  'tradeHistoryAccount',
104
+ 'orderHistoryAccount',
104
105
  ]);
105
106
  });
106
107
  }
@@ -160,6 +161,21 @@ class ClearingHouse {
160
161
  getCurveHistoryAccount() {
161
162
  return this.accountSubscriber.getCurveHistoryAccount();
162
163
  }
164
+ getOrderHistoryAccount() {
165
+ return this.accountSubscriber.getOrderHistoryAccount();
166
+ }
167
+ getOrderStatePublicKey() {
168
+ return __awaiter(this, void 0, void 0, function* () {
169
+ if (this.orderStatePublicKey) {
170
+ return this.orderStatePublicKey;
171
+ }
172
+ this.orderStatePublicKey = yield addresses_1.getOrderStateAccountPublicKey(this.program.programId);
173
+ return this.orderStatePublicKey;
174
+ });
175
+ }
176
+ getOrderStateAccount() {
177
+ return this.accountSubscriber.getOrderStateAccount();
178
+ }
163
179
  /**
164
180
  * Update the wallet to use for clearing house transactions and linked user account
165
181
  * @param newWallet
@@ -177,15 +193,17 @@ class ClearingHouse {
177
193
  }
178
194
  initializeUserAccount() {
179
195
  return __awaiter(this, void 0, void 0, function* () {
180
- const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx,] = yield this.getInitializeUserInstructions();
181
- const tx = new web3_js_1.Transaction().add(initializeUserAccountIx);
196
+ const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx, initializeUserOrdersAccountIx,] = yield this.getInitializeUserInstructions();
197
+ const tx = new web3_js_1.Transaction()
198
+ .add(initializeUserAccountIx)
199
+ .add(initializeUserOrdersAccountIx);
182
200
  const txSig = yield this.txSender.send(tx, [userPositionsAccount], this.opts);
183
201
  return [txSig, userAccountPublicKey];
184
202
  });
185
203
  }
186
204
  getInitializeUserInstructions() {
187
205
  return __awaiter(this, void 0, void 0, function* () {
188
- const [userPublicKey, userAccountNonce] = yield addresses_1.getUserAccountPublicKeyAndNonce(this.program.programId, this.wallet.publicKey);
206
+ const [userAccountPublicKey, userAccountNonce] = yield addresses_1.getUserAccountPublicKeyAndNonce(this.program.programId, this.wallet.publicKey);
189
207
  const remainingAccounts = [];
190
208
  const optionalAccounts = {
191
209
  whitelistToken: false,
@@ -203,7 +221,7 @@ class ClearingHouse {
203
221
  const userPositions = new web3_js_1.Keypair();
204
222
  const initializeUserAccountIx = yield this.program.instruction.initializeUser(userAccountNonce, optionalAccounts, {
205
223
  accounts: {
206
- user: userPublicKey,
224
+ user: userAccountPublicKey,
207
225
  authority: this.wallet.publicKey,
208
226
  rent: anchor.web3.SYSVAR_RENT_PUBKEY,
209
227
  systemProgram: anchor.web3.SystemProgram.programId,
@@ -212,7 +230,31 @@ class ClearingHouse {
212
230
  },
213
231
  remainingAccounts: remainingAccounts,
214
232
  });
215
- return [userPositions, userPublicKey, initializeUserAccountIx];
233
+ const initializeUserOrdersAccountIx = yield this.getInitializeUserOrdersInstruction(userAccountPublicKey);
234
+ return [
235
+ userPositions,
236
+ userAccountPublicKey,
237
+ initializeUserAccountIx,
238
+ initializeUserOrdersAccountIx,
239
+ ];
240
+ });
241
+ }
242
+ getInitializeUserOrdersInstruction(userAccountPublicKey) {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ if (!userAccountPublicKey) {
245
+ userAccountPublicKey = yield this.getUserAccountPublicKey();
246
+ }
247
+ const [userOrdersAccountPublicKey, userOrdersAccountNonce] = yield addresses_1.getUserOrdersAccountPublicKeyAndNonce(this.program.programId, userAccountPublicKey);
248
+ return yield this.program.instruction.initializeUserOrders(userOrdersAccountNonce, {
249
+ accounts: {
250
+ user: userAccountPublicKey,
251
+ authority: this.wallet.publicKey,
252
+ rent: anchor.web3.SYSVAR_RENT_PUBKEY,
253
+ systemProgram: anchor.web3.SystemProgram.programId,
254
+ userOrders: userOrdersAccountPublicKey,
255
+ state: yield this.getStatePublicKey(),
256
+ },
257
+ });
216
258
  });
217
259
  }
218
260
  /**
@@ -237,6 +279,29 @@ class ClearingHouse {
237
279
  return this.userAccount;
238
280
  });
239
281
  }
282
+ /**
283
+ * Get the address for the Clearing House User Order's account. NOT the user's wallet address.
284
+ * @returns
285
+ */
286
+ getUserOrdersAccountPublicKey() {
287
+ return __awaiter(this, void 0, void 0, function* () {
288
+ if (this.userOrdersAccountPublicKey) {
289
+ return this.userOrdersAccountPublicKey;
290
+ }
291
+ this.userOrdersAccountPublicKey = yield addresses_1.getUserOrdersAccountPublicKey(this.program.programId, yield this.getUserAccountPublicKey());
292
+ return this.userOrdersAccountPublicKey;
293
+ });
294
+ }
295
+ userOrdersAccountExists() {
296
+ return __awaiter(this, void 0, void 0, function* () {
297
+ if (this.userOrdersExist) {
298
+ return this.userOrdersExist;
299
+ }
300
+ const userOrdersAccountRPCResponse = yield this.connection.getParsedAccountInfo(yield this.getUserOrdersAccountPublicKey());
301
+ this.userOrdersExist = userOrdersAccountRPCResponse.value !== null;
302
+ return this.userOrdersExist;
303
+ });
304
+ }
240
305
  depositCollateral(amount, collateralAccountPublicKey, userPositionsAccountPublicKey) {
241
306
  return __awaiter(this, void 0, void 0, function* () {
242
307
  const depositCollateralIx = yield this.getDepositCollateralInstruction(amount, collateralAccountPublicKey, userPositionsAccountPublicKey);
@@ -275,10 +340,11 @@ class ClearingHouse {
275
340
  */
276
341
  initializeUserAccountAndDepositCollateral(amount, collateralAccountPublicKey) {
277
342
  return __awaiter(this, void 0, void 0, function* () {
278
- const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx,] = yield this.getInitializeUserInstructions();
343
+ const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx, initializeUserOrdersAccountIx,] = yield this.getInitializeUserInstructions();
279
344
  const depositCollateralIx = yield this.getDepositCollateralInstruction(amount, collateralAccountPublicKey, userPositionsAccount.publicKey);
280
345
  const tx = new web3_js_1.Transaction()
281
346
  .add(initializeUserAccountIx)
347
+ .add(initializeUserOrdersAccountIx)
282
348
  .add(depositCollateralIx);
283
349
  const txSig = yield this.program.provider.send(tx, [userPositionsAccount]);
284
350
  return [txSig, userAccountPublicKey];
@@ -287,12 +353,13 @@ class ClearingHouse {
287
353
  initializeUserAccountForDevnet(mockUSDCFaucet, amount) {
288
354
  return __awaiter(this, void 0, void 0, function* () {
289
355
  const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = yield mockUSDCFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
290
- const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx,] = yield this.getInitializeUserInstructions();
356
+ const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx, initializeUserOrdersAccountIx,] = yield this.getInitializeUserInstructions();
291
357
  const depositCollateralIx = yield this.getDepositCollateralInstruction(amount, associateTokenPublicKey, userPositionsAccount.publicKey);
292
358
  const tx = new web3_js_1.Transaction()
293
359
  .add(createAssociatedAccountIx)
294
360
  .add(mintToIx)
295
361
  .add(initializeUserAccountIx)
362
+ .add(initializeUserOrdersAccountIx)
296
363
  .add(depositCollateralIx);
297
364
  const txSig = yield this.program.provider.send(tx, [userPositionsAccount]);
298
365
  return [txSig, userAccountPublicKey];
@@ -392,6 +459,239 @@ class ClearingHouse {
392
459
  });
393
460
  });
394
461
  }
462
+ initializeUserOrdersThenPlaceOrder(orderParams, discountToken, referrer) {
463
+ return __awaiter(this, void 0, void 0, function* () {
464
+ const instructions = [];
465
+ const userOrdersAccountExists = yield this.userOrdersAccountExists();
466
+ if (!userOrdersAccountExists) {
467
+ instructions.push(yield this.getInitializeUserOrdersInstruction());
468
+ }
469
+ instructions.push(yield this.getPlaceOrderIx(orderParams, discountToken, referrer));
470
+ const tx = new web3_js_1.Transaction();
471
+ for (const instruction of instructions) {
472
+ tx.add(instruction);
473
+ }
474
+ return yield this.txSender.send(tx, [], this.opts);
475
+ });
476
+ }
477
+ placeOrder(orderParams, discountToken, referrer) {
478
+ return __awaiter(this, void 0, void 0, function* () {
479
+ return yield this.txSender.send(utils_1.wrapInTx(yield this.getPlaceOrderIx(orderParams, discountToken, referrer)), [], this.opts);
480
+ });
481
+ }
482
+ getPlaceOrderIx(orderParams, discountToken, referrer) {
483
+ return __awaiter(this, void 0, void 0, function* () {
484
+ const userAccountPublicKey = yield this.getUserAccountPublicKey();
485
+ const userAccount = yield this.getUserAccount();
486
+ const priceOracle = this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
487
+ .oracle;
488
+ const remainingAccounts = [];
489
+ if (orderParams.optionalAccounts.discountToken) {
490
+ if (!discountToken) {
491
+ throw Error('Optional accounts specified discount token but no discount token present');
492
+ }
493
+ remainingAccounts.push({
494
+ pubkey: discountToken,
495
+ isWritable: false,
496
+ isSigner: false,
497
+ });
498
+ }
499
+ if (orderParams.optionalAccounts.referrer) {
500
+ if (!referrer) {
501
+ throw Error('Optional accounts specified referrer but no referrer present');
502
+ }
503
+ remainingAccounts.push({
504
+ pubkey: referrer,
505
+ isWritable: false,
506
+ isSigner: false,
507
+ });
508
+ }
509
+ const state = this.getStateAccount();
510
+ const orderState = this.getOrderStateAccount();
511
+ return yield this.program.instruction.placeOrder(orderParams, {
512
+ accounts: {
513
+ state: yield this.getStatePublicKey(),
514
+ user: userAccountPublicKey,
515
+ authority: this.wallet.publicKey,
516
+ markets: state.markets,
517
+ userOrders: yield this.getUserOrdersAccountPublicKey(),
518
+ userPositions: userAccount.positions,
519
+ fundingPaymentHistory: state.fundingPaymentHistory,
520
+ fundingRateHistory: state.fundingRateHistory,
521
+ orderState: yield this.getOrderStatePublicKey(),
522
+ orderHistory: orderState.orderHistory,
523
+ oracle: priceOracle,
524
+ },
525
+ remainingAccounts,
526
+ });
527
+ });
528
+ }
529
+ cancelOrder(orderId) {
530
+ return __awaiter(this, void 0, void 0, function* () {
531
+ return yield this.txSender.send(utils_1.wrapInTx(yield this.getCancelOrderIx(orderId)), [], this.opts);
532
+ });
533
+ }
534
+ getCancelOrderIx(orderId) {
535
+ return __awaiter(this, void 0, void 0, function* () {
536
+ const userAccountPublicKey = yield this.getUserAccountPublicKey();
537
+ const userAccount = yield this.getUserAccount();
538
+ const state = this.getStateAccount();
539
+ const orderState = this.getOrderStateAccount();
540
+ return yield this.program.instruction.cancelOrder(orderId, {
541
+ accounts: {
542
+ state: yield this.getStatePublicKey(),
543
+ user: userAccountPublicKey,
544
+ authority: this.wallet.publicKey,
545
+ markets: state.markets,
546
+ userOrders: yield this.getUserOrdersAccountPublicKey(),
547
+ userPositions: userAccount.positions,
548
+ fundingPaymentHistory: state.fundingPaymentHistory,
549
+ fundingRateHistory: state.fundingRateHistory,
550
+ orderState: yield this.getOrderStatePublicKey(),
551
+ orderHistory: orderState.orderHistory,
552
+ },
553
+ });
554
+ });
555
+ }
556
+ cancelOrderByUserId(userOrderId) {
557
+ return __awaiter(this, void 0, void 0, function* () {
558
+ return yield this.txSender.send(utils_1.wrapInTx(yield this.getCancelOrderByUserIdIx(userOrderId)), [], this.opts);
559
+ });
560
+ }
561
+ getCancelOrderByUserIdIx(userOrderId) {
562
+ return __awaiter(this, void 0, void 0, function* () {
563
+ const userAccountPublicKey = yield this.getUserAccountPublicKey();
564
+ const userAccount = yield this.getUserAccount();
565
+ const state = this.getStateAccount();
566
+ const orderState = this.getOrderStateAccount();
567
+ return yield this.program.instruction.cancelOrderByUserId(userOrderId, {
568
+ accounts: {
569
+ state: yield this.getStatePublicKey(),
570
+ user: userAccountPublicKey,
571
+ authority: this.wallet.publicKey,
572
+ markets: state.markets,
573
+ userOrders: yield this.getUserOrdersAccountPublicKey(),
574
+ userPositions: userAccount.positions,
575
+ fundingPaymentHistory: state.fundingPaymentHistory,
576
+ fundingRateHistory: state.fundingRateHistory,
577
+ orderState: yield this.getOrderStatePublicKey(),
578
+ orderHistory: orderState.orderHistory,
579
+ },
580
+ });
581
+ });
582
+ }
583
+ fillOrder(userAccountPublicKey, userOrdersAccountPublicKey, order) {
584
+ return __awaiter(this, void 0, void 0, function* () {
585
+ return yield this.txSender.send(utils_1.wrapInTx(yield this.getFillOrderIx(userAccountPublicKey, userOrdersAccountPublicKey, order)), [], this.opts);
586
+ });
587
+ }
588
+ getFillOrderIx(userAccountPublicKey, userOrdersAccountPublicKey, order) {
589
+ return __awaiter(this, void 0, void 0, function* () {
590
+ const fillerPublicKey = yield this.getUserAccountPublicKey();
591
+ const userAccount = yield this.program.account.user.fetch(userAccountPublicKey);
592
+ const marketIndex = order.marketIndex;
593
+ const oracle = this.getMarket(marketIndex).amm.oracle;
594
+ const state = this.getStateAccount();
595
+ const orderState = this.getOrderStateAccount();
596
+ const remainingAccounts = [];
597
+ if (!order.referrer.equals(web3_js_1.PublicKey.default)) {
598
+ remainingAccounts.push({
599
+ pubkey: order.referrer,
600
+ isWritable: true,
601
+ isSigner: false,
602
+ });
603
+ }
604
+ const orderId = order.orderId;
605
+ return yield this.program.instruction.fillOrder(orderId, {
606
+ accounts: {
607
+ state: yield this.getStatePublicKey(),
608
+ filler: fillerPublicKey,
609
+ user: userAccountPublicKey,
610
+ authority: this.wallet.publicKey,
611
+ markets: state.markets,
612
+ userPositions: userAccount.positions,
613
+ userOrders: userOrdersAccountPublicKey,
614
+ tradeHistory: state.tradeHistory,
615
+ fundingPaymentHistory: state.fundingPaymentHistory,
616
+ fundingRateHistory: state.fundingRateHistory,
617
+ orderState: yield this.getOrderStatePublicKey(),
618
+ orderHistory: orderState.orderHistory,
619
+ extendedCurveHistory: state.extendedCurveHistory,
620
+ oracle: oracle,
621
+ },
622
+ remainingAccounts,
623
+ });
624
+ });
625
+ }
626
+ initializeUserOrdersThenPlaceAndFillOrder(orderParams, discountToken, referrer) {
627
+ return __awaiter(this, void 0, void 0, function* () {
628
+ const instructions = [];
629
+ const userOrdersAccountExists = yield this.userOrdersAccountExists();
630
+ if (!userOrdersAccountExists) {
631
+ instructions.push(yield this.getInitializeUserOrdersInstruction());
632
+ }
633
+ instructions.push(yield this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer));
634
+ const tx = new web3_js_1.Transaction();
635
+ for (const instruction of instructions) {
636
+ tx.add(instruction);
637
+ }
638
+ return yield this.txSender.send(tx, [], this.opts);
639
+ });
640
+ }
641
+ placeAndFillOrder(orderParams, discountToken, referrer) {
642
+ return __awaiter(this, void 0, void 0, function* () {
643
+ return yield this.txSender.send(utils_1.wrapInTx(yield this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)), [], this.opts);
644
+ });
645
+ }
646
+ getPlaceAndFillOrderIx(orderParams, discountToken, referrer) {
647
+ return __awaiter(this, void 0, void 0, function* () {
648
+ const userAccountPublicKey = yield this.getUserAccountPublicKey();
649
+ const userAccount = yield this.getUserAccount();
650
+ const priceOracle = this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
651
+ .oracle;
652
+ const remainingAccounts = [];
653
+ if (orderParams.optionalAccounts.discountToken) {
654
+ if (!discountToken) {
655
+ throw Error('Optional accounts specified discount token but no discount token present');
656
+ }
657
+ remainingAccounts.push({
658
+ pubkey: discountToken,
659
+ isWritable: false,
660
+ isSigner: false,
661
+ });
662
+ }
663
+ if (orderParams.optionalAccounts.referrer) {
664
+ if (!referrer) {
665
+ throw Error('Optional accounts specified referrer but no referrer present');
666
+ }
667
+ remainingAccounts.push({
668
+ pubkey: referrer,
669
+ isWritable: true,
670
+ isSigner: false,
671
+ });
672
+ }
673
+ const state = this.getStateAccount();
674
+ const orderState = this.getOrderStateAccount();
675
+ return yield this.program.instruction.placeAndFillOrder(orderParams, {
676
+ accounts: {
677
+ state: yield this.getStatePublicKey(),
678
+ user: userAccountPublicKey,
679
+ authority: this.wallet.publicKey,
680
+ markets: state.markets,
681
+ userOrders: yield this.getUserOrdersAccountPublicKey(),
682
+ userPositions: userAccount.positions,
683
+ tradeHistory: state.tradeHistory,
684
+ fundingPaymentHistory: state.fundingPaymentHistory,
685
+ fundingRateHistory: state.fundingRateHistory,
686
+ orderState: yield this.getOrderStatePublicKey(),
687
+ orderHistory: orderState.orderHistory,
688
+ extendedCurveHistory: state.extendedCurveHistory,
689
+ oracle: priceOracle,
690
+ },
691
+ remainingAccounts,
692
+ });
693
+ });
694
+ }
395
695
  /**
396
696
  * Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
397
697
  * @param marketIndex
@@ -4,7 +4,7 @@ import { PublicKey } from '@solana/web3.js';
4
4
  import { EventEmitter } from 'events';
5
5
  import StrictEventEmitter from 'strict-event-emitter-types';
6
6
  import { ClearingHouse } from './clearingHouse';
7
- import { UserAccount, UserPosition, UserPositionsAccount } from './types';
7
+ import { Order, UserAccount, UserOrdersAccount, UserPosition, UserPositionsAccount } from './types';
8
8
  import { UserAccountSubscriber, UserAccountEvents } from './accounts/types';
9
9
  import { PositionDirection, BN } from '.';
10
10
  export declare class ClearingHouseUser {
@@ -12,6 +12,7 @@ export declare class ClearingHouseUser {
12
12
  authority: PublicKey;
13
13
  accountSubscriber: UserAccountSubscriber;
14
14
  userAccountPublicKey?: PublicKey;
15
+ userOrdersAccountPublicKey?: PublicKey;
15
16
  _isSubscribed: boolean;
16
17
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
17
18
  get isSubscribed(): boolean;
@@ -36,6 +37,7 @@ export declare class ClearingHouseUser {
36
37
  unsubscribe(): Promise<void>;
37
38
  getUserAccount(): UserAccount;
38
39
  getUserPositionsAccount(): UserPositionsAccount;
40
+ getUserOrdersAccount(): UserOrdersAccount | undefined;
39
41
  /**
40
42
  * Gets the user's current position for a given market. If the user has no position returns undefined
41
43
  * @param marketIndex
@@ -43,7 +45,18 @@ export declare class ClearingHouseUser {
43
45
  */
44
46
  getUserPosition(marketIndex: BN): UserPosition | undefined;
45
47
  getEmptyPosition(marketIndex: BN): UserPosition;
48
+ /**
49
+ * @param orderId
50
+ * @returns Order
51
+ */
52
+ getOrder(orderId: BN): Order | undefined;
53
+ /**
54
+ * @param userOrderId
55
+ * @returns Order
56
+ */
57
+ getOrderByUserOrderId(userOrderId: number): Order | undefined;
46
58
  getUserAccountPublicKey(): Promise<PublicKey>;
59
+ getUserOrdersAccountPublicKey(): Promise<PublicKey>;
47
60
  exists(): Promise<boolean>;
48
61
  /**
49
62
  * calculates Buying Power = FC * MAX_LEVERAGE
@@ -148,7 +161,7 @@ export declare class ClearingHouseUser {
148
161
  * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
149
162
  * => current position + remaining to get to maxLeverage
150
163
  *
151
- * @param marketIndex
164
+ * @param targetMarketIndex
152
165
  * @param tradeSide
153
166
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
154
167
  * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
@@ -174,5 +187,5 @@ export declare class ClearingHouseUser {
174
187
  * @returns positionValue : Precision QUOTE_PRECISION
175
188
  */
176
189
  private getTotalPositionValueExcludingMarket;
190
+ canFillOrder(order: Order): boolean;
177
191
  }
178
- //# sourceMappingURL=clearingHouseUser.d.ts.map
@@ -73,6 +73,9 @@ class ClearingHouseUser {
73
73
  getUserPositionsAccount() {
74
74
  return this.accountSubscriber.getUserPositionsAccount();
75
75
  }
76
+ getUserOrdersAccount() {
77
+ return this.accountSubscriber.getUserOrdersAccount();
78
+ }
76
79
  /**
77
80
  * Gets the user's current position for a given market. If the user has no position returns undefined
78
81
  * @param marketIndex
@@ -87,8 +90,23 @@ class ClearingHouseUser {
87
90
  lastCumulativeFundingRate: numericConstants_1.ZERO,
88
91
  marketIndex,
89
92
  quoteAssetAmount: numericConstants_1.ZERO,
93
+ openOrders: numericConstants_1.ZERO,
90
94
  };
91
95
  }
96
+ /**
97
+ * @param orderId
98
+ * @returns Order
99
+ */
100
+ getOrder(orderId) {
101
+ return this.getUserOrdersAccount().orders.find((order) => order.orderId.eq(orderId));
102
+ }
103
+ /**
104
+ * @param userOrderId
105
+ * @returns Order
106
+ */
107
+ getOrderByUserOrderId(userOrderId) {
108
+ return this.getUserOrdersAccount().orders.find((order) => order.userOrderId === userOrderId);
109
+ }
92
110
  getUserAccountPublicKey() {
93
111
  return __awaiter(this, void 0, void 0, function* () {
94
112
  if (this.userAccountPublicKey) {
@@ -98,6 +116,15 @@ class ClearingHouseUser {
98
116
  return this.userAccountPublicKey;
99
117
  });
100
118
  }
119
+ getUserOrdersAccountPublicKey() {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ if (this.userOrdersAccountPublicKey) {
122
+ return this.userOrdersAccountPublicKey;
123
+ }
124
+ this.userOrdersAccountPublicKey = yield _1.getUserOrdersAccountPublicKey(this.clearingHouse.program.programId, yield this.getUserAccountPublicKey());
125
+ return this.userOrdersAccountPublicKey;
126
+ });
127
+ }
101
128
  exists() {
102
129
  return __awaiter(this, void 0, void 0, function* () {
103
130
  const userAccountPublicKey = yield this.getUserAccountPublicKey();
@@ -323,6 +350,7 @@ class ClearingHouseUser {
323
350
  baseAssetAmount: currentMarketPositionBaseSize.add(positionBaseSizeChange),
324
351
  lastCumulativeFundingRate: new _1.BN(0),
325
352
  quoteAssetAmount: new _1.BN(0),
353
+ openOrders: new _1.BN(0),
326
354
  };
327
355
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
328
356
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
@@ -383,14 +411,14 @@ class ClearingHouseUser {
383
411
  liquidationPrice(targetMarket, positionBaseSizeChange = numericConstants_1.ZERO, partial = false) {
384
412
  // solves formula for example calc below
385
413
  /* example: assume BTC price is $40k (examine 10% up/down)
386
-
387
- if 10k deposit and levered 10x short BTC => BTC up $400 means:
388
- 1. higher base_asset_value (+$4k)
389
- 2. lower collateral (-$4k)
390
- 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
391
-
392
- for 10x long, BTC down $400:
393
- 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
414
+
415
+ if 10k deposit and levered 10x short BTC => BTC up $400 means:
416
+ 1. higher base_asset_value (+$4k)
417
+ 2. lower collateral (-$4k)
418
+ 3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
419
+
420
+ for 10x long, BTC down $400:
421
+ 3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
394
422
  const tc = this.getTotalCollateral();
395
423
  const tpv = this.getTotalPositionValue();
396
424
  const partialLev = 16;
@@ -408,6 +436,7 @@ class ClearingHouseUser {
408
436
  baseAssetAmount: proposedBaseAssetAmount,
409
437
  lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
410
438
  quoteAssetAmount: new _1.BN(0),
439
+ openOrders: new _1.BN(0),
411
440
  };
412
441
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
413
442
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
@@ -499,7 +528,7 @@ class ClearingHouseUser {
499
528
  * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
500
529
  * => current position + remaining to get to maxLeverage
501
530
  *
502
- * @param marketIndex
531
+ * @param targetMarketIndex
503
532
  * @param tradeSide
504
533
  * @param userMaxLeverageSetting - leverage : Precision TEN_THOUSAND
505
534
  * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
@@ -630,5 +659,46 @@ class ClearingHouseUser {
630
659
  }
631
660
  return this.getTotalPositionValue().sub(currentMarketPositionValueUSDC);
632
661
  }
662
+ canFillOrder(order) {
663
+ const userAccount = this.getUserAccount();
664
+ const userPositionsAccount = this.getUserPositionsAccount();
665
+ const userPosition = this.getUserPosition(order.marketIndex);
666
+ const market = this.clearingHouse.getMarket(order.marketIndex);
667
+ if (position_1.isEmptyPosition(userPosition)) {
668
+ return false;
669
+ }
670
+ const newState = _1.calculateNewStateAfterOrder(userAccount, userPosition, market, order);
671
+ if (newState === null) {
672
+ return false;
673
+ }
674
+ const [userAccountAfter, userPositionAfter, marketAfter] = newState;
675
+ const totalPositionValue = userPositionsAccount.positions.reduce((positionValue, marketPosition) => {
676
+ let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
677
+ if (marketPosition.marketIndex.eq(order.marketIndex)) {
678
+ market = marketAfter;
679
+ marketPosition = userPositionAfter;
680
+ }
681
+ return positionValue.add(_1.calculateBaseAssetValue(market, marketPosition));
682
+ }, numericConstants_1.ZERO);
683
+ if (totalPositionValue.eq(numericConstants_1.ZERO)) {
684
+ return true;
685
+ }
686
+ const unrealizedPnL = userPositionsAccount.positions.reduce((pnl, marketPosition) => {
687
+ let market = this.clearingHouse.getMarket(marketPosition.marketIndex);
688
+ pnl = pnl.add(_1.calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION));
689
+ if (marketPosition.marketIndex.eq(order.marketIndex)) {
690
+ market = marketAfter;
691
+ marketPosition = userPositionAfter;
692
+ }
693
+ // update
694
+ return pnl.add(_1.calculatePositionPNL(market, marketPosition, false));
695
+ }, numericConstants_1.ZERO);
696
+ const totalCollateral = userAccountAfter.collateral.add(unrealizedPnL);
697
+ const marginRatioAfter = totalCollateral
698
+ .mul(numericConstants_1.TEN_THOUSAND)
699
+ .div(totalPositionValue);
700
+ const marginRatioInitial = this.clearingHouse.getStateAccount().marginRatioInitial;
701
+ return marginRatioAfter.gte(marginRatioInitial);
702
+ }
633
703
  }
634
704
  exports.ClearingHouseUser = ClearingHouseUser;
package/lib/config.d.ts CHANGED
@@ -21,4 +21,3 @@ export declare const initialize: (props: {
21
21
  overrideEnv?: Partial<DriftConfig>;
22
22
  }) => DriftConfig;
23
23
  export {};
24
- //# sourceMappingURL=config.d.ts.map
@@ -10,4 +10,3 @@ declare type Market = {
10
10
  };
11
11
  export declare const Markets: Market[];
12
12
  export {};
13
- //# sourceMappingURL=markets.d.ts.map