@drift-labs/sdk 0.1.17 → 0.1.18-orders.0

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 (103) hide show
  1. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts +5 -2
  2. package/lib/accounts/defaultClearingHouseAccountSubscriber.js +25 -0
  3. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +28 -0
  4. package/lib/accounts/defaultHistoryAccountSubscriber.js +110 -0
  5. package/lib/accounts/defaultUserAccountSubscriber.d.ts +3 -2
  6. package/lib/accounts/defaultUserAccountSubscriber.js +11 -0
  7. package/lib/accounts/types.d.ts +29 -3
  8. package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
  9. package/lib/addresses.d.ts +4 -1
  10. package/lib/addresses.js +28 -1
  11. package/lib/admin.d.ts +10 -4
  12. package/lib/admin.js +48 -3
  13. package/lib/assert/assert.d.ts +0 -1
  14. package/lib/clearingHouse.d.ts +21 -2
  15. package/lib/clearingHouse.js +238 -7
  16. package/lib/clearingHouseUser.d.ts +10 -17
  17. package/lib/clearingHouseUser.js +98 -84
  18. package/lib/config.d.ts +0 -1
  19. package/lib/config.js +1 -1
  20. package/lib/constants/markets.d.ts +0 -1
  21. package/lib/constants/numericConstants.d.ts +0 -1
  22. package/lib/examples/makeTradeExample.d.ts +0 -1
  23. package/lib/idl/clearing_house.json +956 -59
  24. package/lib/index.d.ts +3 -1
  25. package/lib/index.js +3 -0
  26. package/lib/math/amm.d.ts +1 -1
  27. package/lib/math/amm.js +31 -8
  28. package/lib/math/conversion.d.ts +0 -1
  29. package/lib/math/funding.d.ts +0 -1
  30. package/lib/math/insuranceFund.d.ts +0 -1
  31. package/lib/math/market.d.ts +2 -2
  32. package/lib/math/market.js +11 -1
  33. package/lib/math/orders.d.ts +3 -0
  34. package/lib/math/orders.js +30 -0
  35. package/lib/math/position.d.ts +4 -2
  36. package/lib/math/position.js +18 -4
  37. package/lib/math/trade.d.ts +0 -1
  38. package/lib/math/utils.d.ts +0 -1
  39. package/lib/mockUSDCFaucet.d.ts +0 -1
  40. package/lib/orderParams.d.ts +7 -0
  41. package/lib/orderParams.js +88 -0
  42. package/lib/orders.d.ts +5 -0
  43. package/lib/orders.js +136 -0
  44. package/lib/pythClient.d.ts +0 -1
  45. package/lib/tx/defaultTxSender.d.ts +0 -1
  46. package/lib/tx/types.d.ts +0 -1
  47. package/lib/tx/utils.d.ts +0 -1
  48. package/lib/types.d.ts +137 -2
  49. package/lib/types.js +36 -1
  50. package/lib/util/computeUnits.d.ts +0 -1
  51. package/lib/util/tps.d.ts +0 -1
  52. package/lib/wallet.d.ts +0 -1
  53. package/package.json +1 -1
  54. package/src/accounts/defaultClearingHouseAccountSubscriber.ts +47 -0
  55. package/src/accounts/defaultHistoryAccountSubscriber.ts +176 -0
  56. package/src/accounts/defaultUserAccountSubscriber.ts +29 -2
  57. package/src/accounts/types.ts +38 -1
  58. package/src/addresses.ts +35 -0
  59. package/src/admin.ts +84 -6
  60. package/src/clearingHouse.ts +338 -5
  61. package/src/clearingHouseUser.ts +154 -102
  62. package/src/config.ts +1 -1
  63. package/src/idl/clearing_house.json +956 -59
  64. package/src/index.ts +3 -0
  65. package/src/math/amm.ts +47 -14
  66. package/src/math/market.ts +28 -2
  67. package/src/math/orders.ts +39 -0
  68. package/src/math/position.ts +23 -3
  69. package/src/orderParams.ts +128 -0
  70. package/src/orders.ts +230 -0
  71. package/src/types.ts +121 -1
  72. package/tsconfig.json +0 -1
  73. package/lib/accounts/defaultClearingHouseAccountSubscriber.d.ts.map +0 -1
  74. package/lib/accounts/defaultUserAccountSubscriber.d.ts.map +0 -1
  75. package/lib/accounts/types.d.ts.map +0 -1
  76. package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
  77. package/lib/addresses.d.ts.map +0 -1
  78. package/lib/admin.d.ts.map +0 -1
  79. package/lib/assert/assert.d.ts.map +0 -1
  80. package/lib/clearingHouse.d.ts.map +0 -1
  81. package/lib/clearingHouseUser.d.ts.map +0 -1
  82. package/lib/config.d.ts.map +0 -1
  83. package/lib/constants/markets.d.ts.map +0 -1
  84. package/lib/constants/numericConstants.d.ts.map +0 -1
  85. package/lib/examples/makeTradeExample.d.ts.map +0 -1
  86. package/lib/index.d.ts.map +0 -1
  87. package/lib/math/amm.d.ts.map +0 -1
  88. package/lib/math/conversion.d.ts.map +0 -1
  89. package/lib/math/funding.d.ts.map +0 -1
  90. package/lib/math/insuranceFund.d.ts.map +0 -1
  91. package/lib/math/market.d.ts.map +0 -1
  92. package/lib/math/position.d.ts.map +0 -1
  93. package/lib/math/trade.d.ts.map +0 -1
  94. package/lib/math/utils.d.ts.map +0 -1
  95. package/lib/mockUSDCFaucet.d.ts.map +0 -1
  96. package/lib/pythClient.d.ts.map +0 -1
  97. package/lib/tx/defaultTxSender.d.ts.map +0 -1
  98. package/lib/tx/types.d.ts.map +0 -1
  99. package/lib/tx/utils.d.ts.map +0 -1
  100. package/lib/types.d.ts.map +0 -1
  101. package/lib/util/computeUnits.d.ts.map +0 -1
  102. package/lib/util/tps.d.ts.map +0 -1
  103. package/lib/wallet.d.ts.map +0 -1
package/src/addresses.ts CHANGED
@@ -10,6 +10,21 @@ export async function getClearingHouseStateAccountPublicKeyAndNonce(
10
10
  );
11
11
  }
12
12
 
13
+ export async function getOrderStateAccountPublicKey(
14
+ programId: PublicKey
15
+ ): Promise<PublicKey> {
16
+ return (await getOrderStateAccountPublicKeyAndNonce(programId))[0];
17
+ }
18
+
19
+ export async function getOrderStateAccountPublicKeyAndNonce(
20
+ programId: PublicKey
21
+ ): Promise<[PublicKey, number]> {
22
+ return anchor.web3.PublicKey.findProgramAddress(
23
+ [Buffer.from(anchor.utils.bytes.utf8.encode('order_state'))],
24
+ programId
25
+ );
26
+ }
27
+
13
28
  export async function getClearingHouseStateAccountPublicKey(
14
29
  programId: PublicKey
15
30
  ): Promise<PublicKey> {
@@ -32,3 +47,23 @@ export async function getUserAccountPublicKey(
32
47
  ): Promise<PublicKey> {
33
48
  return (await getUserAccountPublicKeyAndNonce(programId, authority))[0];
34
49
  }
50
+
51
+ export async function getUserOrdersAccountPublicKeyAndNonce(
52
+ programId: PublicKey,
53
+ authority: PublicKey
54
+ ): Promise<[PublicKey, number]> {
55
+ return anchor.web3.PublicKey.findProgramAddress(
56
+ [
57
+ Buffer.from(anchor.utils.bytes.utf8.encode('user_orders')),
58
+ authority.toBuffer(),
59
+ ],
60
+ programId
61
+ );
62
+ }
63
+
64
+ export async function getUserOrdersAccountPublicKey(
65
+ programId: PublicKey,
66
+ authority: PublicKey
67
+ ): Promise<PublicKey> {
68
+ return (await getUserOrdersAccountPublicKeyAndNonce(programId, authority))[0];
69
+ }
package/src/admin.ts CHANGED
@@ -5,10 +5,20 @@ import {
5
5
  SYSVAR_RENT_PUBKEY,
6
6
  TransactionSignature,
7
7
  } from '@solana/web3.js';
8
- import { FeeStructure, IWallet, OracleGuardRails, OracleSource } from './types';
8
+ import {
9
+ FeeStructure,
10
+ IWallet,
11
+ OracleGuardRails,
12
+ OracleSource,
13
+ OrderFillerRewardStructure,
14
+ } from './types';
9
15
  import { BN, Idl, Program, Provider } from '@project-serum/anchor';
10
16
  import * as anchor from '@project-serum/anchor';
11
- import { getClearingHouseStateAccountPublicKeyAndNonce } from './addresses';
17
+ import {
18
+ getClearingHouseStateAccountPublicKey,
19
+ getClearingHouseStateAccountPublicKeyAndNonce,
20
+ getOrderStateAccountPublicKeyAndNonce,
21
+ } from './addresses';
12
22
  import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
13
23
  import { ClearingHouse } from './clearingHouse';
14
24
  import { PEG_PRECISION } from './constants/numericConstants';
@@ -48,7 +58,9 @@ export class Admin extends ClearingHouse {
48
58
  public async initialize(
49
59
  usdcMint: PublicKey,
50
60
  adminControlsPrices: boolean
51
- ): Promise<[TransactionSignature, TransactionSignature]> {
61
+ ): Promise<
62
+ [TransactionSignature, TransactionSignature, TransactionSignature]
63
+ > {
52
64
  const stateAccountRPCResponse = await this.connection.getParsedAccountInfo(
53
65
  await this.getStatePublicKey()
54
66
  );
@@ -172,7 +184,40 @@ export class Admin extends ClearingHouse {
172
184
  this.opts
173
185
  );
174
186
 
175
- return [initializeTxSig, initializeHistoryTxSig];
187
+ const initializeOrderStateTxSig = await this.initializeOrderState();
188
+
189
+ return [initializeTxSig, initializeHistoryTxSig, initializeOrderStateTxSig];
190
+ }
191
+
192
+ public async initializeOrderState(): Promise<TransactionSignature> {
193
+ const orderHistory = anchor.web3.Keypair.generate();
194
+ const [orderStatePublicKey, orderStateNonce] =
195
+ await getOrderStateAccountPublicKeyAndNonce(this.program.programId);
196
+ const clearingHouseStatePublicKey =
197
+ await getClearingHouseStateAccountPublicKey(this.program.programId);
198
+
199
+ const initializeOrderStateTx =
200
+ await this.program.transaction.initializeOrderState(orderStateNonce, {
201
+ accounts: {
202
+ admin: this.wallet.publicKey,
203
+ state: clearingHouseStatePublicKey,
204
+ orderHistory: orderHistory.publicKey,
205
+ orderState: orderStatePublicKey,
206
+ rent: SYSVAR_RENT_PUBKEY,
207
+ systemProgram: anchor.web3.SystemProgram.programId,
208
+ },
209
+ instructions: [
210
+ await this.program.account.orderHistory.createInstruction(
211
+ orderHistory
212
+ ),
213
+ ],
214
+ });
215
+
216
+ return await this.txSender.send(
217
+ initializeOrderStateTx,
218
+ [orderHistory],
219
+ this.opts
220
+ );
176
221
  }
177
222
 
178
223
  public async initializeMarket(
@@ -455,6 +500,21 @@ export class Admin extends ClearingHouse {
455
500
  );
456
501
  }
457
502
 
503
+ public async updateOrderFillerRewardStructure(
504
+ orderFillerRewardStructure: OrderFillerRewardStructure
505
+ ): Promise<TransactionSignature> {
506
+ return await this.program.rpc.updateOrderFillerRewardStructure(
507
+ orderFillerRewardStructure,
508
+ {
509
+ accounts: {
510
+ admin: this.wallet.publicKey,
511
+ state: await this.getStatePublicKey(),
512
+ orderState: await this.getOrderStatePublicKey(),
513
+ },
514
+ }
515
+ );
516
+ }
517
+
458
518
  public async updateFee(fees: FeeStructure): Promise<TransactionSignature> {
459
519
  return await this.program.rpc.updateFee(fees, {
460
520
  accounts: {
@@ -495,12 +555,30 @@ export class Admin extends ClearingHouse {
495
555
  );
496
556
  }
497
557
 
498
- public async updateMarketMinimumTradeSize(
558
+ public async updateMarketMinimumQuoteAssetTradeSize(
559
+ marketIndex: BN,
560
+ minimumTradeSize: BN
561
+ ): Promise<TransactionSignature> {
562
+ const state = this.getStateAccount();
563
+ return await this.program.rpc.updateMarketMinimumQuoteAssetTradeSize(
564
+ marketIndex,
565
+ minimumTradeSize,
566
+ {
567
+ accounts: {
568
+ admin: this.wallet.publicKey,
569
+ state: await this.getStatePublicKey(),
570
+ markets: state.markets,
571
+ },
572
+ }
573
+ );
574
+ }
575
+
576
+ public async updateMarketMinimumBaseAssetTradeSize(
499
577
  marketIndex: BN,
500
578
  minimumTradeSize: BN
501
579
  ): Promise<TransactionSignature> {
502
580
  const state = this.getStateAccount();
503
- return await this.program.rpc.updateMarketMinimumTradeSize(
581
+ return await this.program.rpc.updateMarketMinimumBaseAssetTradeSize(
504
582
  marketIndex,
505
583
  minimumTradeSize,
506
584
  {
@@ -17,6 +17,10 @@ import {
17
17
  TradeHistoryAccount,
18
18
  UserAccount,
19
19
  Market,
20
+ OrderHistoryAccount,
21
+ OrderStateAccount,
22
+ OrderParams,
23
+ Order,
20
24
  } from './types';
21
25
  import * as anchor from '@project-serum/anchor';
22
26
  import clearingHouseIDL from './idl/clearing_house.json';
@@ -36,8 +40,11 @@ import { EventEmitter } from 'events';
36
40
  import StrictEventEmitter from 'strict-event-emitter-types';
37
41
  import {
38
42
  getClearingHouseStateAccountPublicKey,
43
+ getOrderStateAccountPublicKey,
39
44
  getUserAccountPublicKey,
40
45
  getUserAccountPublicKeyAndNonce,
46
+ getUserOrdersAccountPublicKey,
47
+ getUserOrdersAccountPublicKeyAndNonce,
41
48
  } from './addresses';
42
49
  import {
43
50
  ClearingHouseAccountSubscriber,
@@ -136,6 +143,7 @@ export class ClearingHouse {
136
143
  'fundingRateHistoryAccount',
137
144
  'liquidationHistoryAccount',
138
145
  'tradeHistoryAccount',
146
+ 'orderHistoryAccount',
139
147
  ]);
140
148
  }
141
149
 
@@ -204,6 +212,25 @@ export class ClearingHouse {
204
212
  return this.accountSubscriber.getCurveHistoryAccount();
205
213
  }
206
214
 
215
+ public getOrderHistoryAccount(): OrderHistoryAccount {
216
+ return this.accountSubscriber.getOrderHistoryAccount();
217
+ }
218
+
219
+ orderStatePublicKey?: PublicKey;
220
+ public async getOrderStatePublicKey(): Promise<PublicKey> {
221
+ if (this.orderStatePublicKey) {
222
+ return this.orderStatePublicKey;
223
+ }
224
+ this.orderStatePublicKey = await getOrderStateAccountPublicKey(
225
+ this.program.programId
226
+ );
227
+ return this.orderStatePublicKey;
228
+ }
229
+
230
+ public getOrderStateAccount(): OrderStateAccount {
231
+ return this.accountSubscriber.getOrderStateAccount();
232
+ }
233
+
207
234
  /**
208
235
  * Update the wallet to use for clearing house transactions and linked user account
209
236
  * @param newWallet
@@ -232,9 +259,12 @@ export class ClearingHouse {
232
259
  userPositionsAccount,
233
260
  userAccountPublicKey,
234
261
  initializeUserAccountIx,
262
+ initializeUserOrdersAccountIx,
235
263
  ] = await this.getInitializeUserInstructions();
236
264
 
237
- const tx = new Transaction().add(initializeUserAccountIx);
265
+ const tx = new Transaction()
266
+ .add(initializeUserAccountIx)
267
+ .add(initializeUserOrdersAccountIx);
238
268
  const txSig = await this.txSender.send(
239
269
  tx,
240
270
  [userPositionsAccount],
@@ -244,9 +274,9 @@ export class ClearingHouse {
244
274
  }
245
275
 
246
276
  async getInitializeUserInstructions(): Promise<
247
- [Keypair, PublicKey, TransactionInstruction]
277
+ [Keypair, PublicKey, TransactionInstruction, TransactionInstruction]
248
278
  > {
249
- const [userPublicKey, userAccountNonce] =
279
+ const [userAccountPublicKey, userAccountNonce] =
250
280
  await getUserAccountPublicKeyAndNonce(
251
281
  this.program.programId,
252
282
  this.wallet.publicKey
@@ -280,7 +310,7 @@ export class ClearingHouse {
280
310
  optionalAccounts,
281
311
  {
282
312
  accounts: {
283
- user: userPublicKey,
313
+ user: userAccountPublicKey,
284
314
  authority: this.wallet.publicKey,
285
315
  rent: anchor.web3.SYSVAR_RENT_PUBKEY,
286
316
  systemProgram: anchor.web3.SystemProgram.programId,
@@ -290,7 +320,44 @@ export class ClearingHouse {
290
320
  remainingAccounts: remainingAccounts,
291
321
  }
292
322
  );
293
- return [userPositions, userPublicKey, initializeUserAccountIx];
323
+
324
+ const initializeUserOrdersAccountIx =
325
+ await this.getInitializeUserOrdersInstruction(userAccountPublicKey);
326
+
327
+ return [
328
+ userPositions,
329
+ userAccountPublicKey,
330
+ initializeUserAccountIx,
331
+ initializeUserOrdersAccountIx,
332
+ ];
333
+ }
334
+
335
+ async getInitializeUserOrdersInstruction(
336
+ userAccountPublicKey?: PublicKey
337
+ ): Promise<TransactionInstruction> {
338
+ const [userOrdersAccountPublicKey, userOrdersAccountNonce] =
339
+ await getUserOrdersAccountPublicKeyAndNonce(
340
+ this.program.programId,
341
+ this.wallet.publicKey
342
+ );
343
+
344
+ if (!userAccountPublicKey) {
345
+ userAccountPublicKey = await this.getUserAccountPublicKey();
346
+ }
347
+
348
+ return await this.program.instruction.initializeUserOrders(
349
+ userOrdersAccountNonce,
350
+ {
351
+ accounts: {
352
+ user: userAccountPublicKey,
353
+ authority: this.wallet.publicKey,
354
+ rent: anchor.web3.SYSVAR_RENT_PUBKEY,
355
+ systemProgram: anchor.web3.SystemProgram.programId,
356
+ userOrders: userOrdersAccountPublicKey,
357
+ state: await this.getStatePublicKey(),
358
+ },
359
+ }
360
+ );
294
361
  }
295
362
 
296
363
  userAccountPublicKey?: PublicKey;
@@ -322,6 +389,23 @@ export class ClearingHouse {
322
389
  return this.userAccount;
323
390
  }
324
391
 
392
+ userOrdersAccountPublicKey?: PublicKey;
393
+ /**
394
+ * Get the address for the Clearing House User Order's account. NOT the user's wallet address.
395
+ * @returns
396
+ */
397
+ public async getUserOrdersAccountPublicKey(): Promise<PublicKey> {
398
+ if (this.userOrdersAccountPublicKey) {
399
+ return this.userOrdersAccountPublicKey;
400
+ }
401
+
402
+ this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
403
+ this.program.programId,
404
+ this.wallet.publicKey
405
+ );
406
+ return this.userOrdersAccountPublicKey;
407
+ }
408
+
325
409
  public async depositCollateral(
326
410
  amount: BN,
327
411
  collateralAccountPublicKey: PublicKey,
@@ -379,6 +463,7 @@ export class ClearingHouse {
379
463
  userPositionsAccount,
380
464
  userAccountPublicKey,
381
465
  initializeUserAccountIx,
466
+ initializeUserOrdersAccountIx,
382
467
  ] = await this.getInitializeUserInstructions();
383
468
 
384
469
  const depositCollateralIx = await this.getDepositCollateralInstruction(
@@ -389,6 +474,7 @@ export class ClearingHouse {
389
474
 
390
475
  const tx = new Transaction()
391
476
  .add(initializeUserAccountIx)
477
+ .add(initializeUserOrdersAccountIx)
392
478
  .add(depositCollateralIx);
393
479
 
394
480
  const txSig = await this.program.provider.send(tx, [userPositionsAccount]);
@@ -410,6 +496,7 @@ export class ClearingHouse {
410
496
  userPositionsAccount,
411
497
  userAccountPublicKey,
412
498
  initializeUserAccountIx,
499
+ initializeUserOrdersAccountIx,
413
500
  ] = await this.getInitializeUserInstructions();
414
501
 
415
502
  const depositCollateralIx = await this.getDepositCollateralInstruction(
@@ -422,6 +509,7 @@ export class ClearingHouse {
422
509
  .add(createAssociatedAccountIx)
423
510
  .add(mintToIx)
424
511
  .add(initializeUserAccountIx)
512
+ .add(initializeUserOrdersAccountIx)
425
513
  .add(depositCollateralIx);
426
514
 
427
515
  const txSig = await this.program.provider.send(tx, [userPositionsAccount]);
@@ -572,6 +660,251 @@ export class ClearingHouse {
572
660
  );
573
661
  }
574
662
 
663
+ public async placeOrder(
664
+ orderParams: OrderParams,
665
+ discountToken?: PublicKey,
666
+ referrer?: PublicKey
667
+ ): Promise<TransactionSignature> {
668
+ return await this.txSender.send(
669
+ wrapInTx(
670
+ await this.getPlaceOrderIx(orderParams, discountToken, referrer)
671
+ ),
672
+ [],
673
+ this.opts
674
+ );
675
+ }
676
+
677
+ public async getPlaceOrderIx(
678
+ orderParams: OrderParams,
679
+ discountToken?: PublicKey,
680
+ referrer?: PublicKey
681
+ ): Promise<TransactionInstruction> {
682
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
683
+ const userAccount = await this.getUserAccount();
684
+
685
+ const priceOracle =
686
+ this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
687
+ .oracle;
688
+
689
+ const remainingAccounts = [];
690
+ if (orderParams.optionalAccounts.discountToken) {
691
+ if (!discountToken) {
692
+ throw Error(
693
+ 'Optional accounts specified discount token but no discount token present'
694
+ );
695
+ }
696
+
697
+ remainingAccounts.push({
698
+ pubkey: discountToken,
699
+ isWritable: false,
700
+ isSigner: false,
701
+ });
702
+ }
703
+
704
+ if (orderParams.optionalAccounts.referrer) {
705
+ if (!referrer) {
706
+ throw Error(
707
+ 'Optional accounts specified referrer but no referrer present'
708
+ );
709
+ }
710
+
711
+ remainingAccounts.push({
712
+ pubkey: referrer,
713
+ isWritable: false,
714
+ isSigner: false,
715
+ });
716
+ }
717
+
718
+ const state = this.getStateAccount();
719
+ const orderState = this.getOrderStateAccount();
720
+ return await this.program.instruction.placeOrder(orderParams, {
721
+ accounts: {
722
+ state: await this.getStatePublicKey(),
723
+ user: userAccountPublicKey,
724
+ authority: this.wallet.publicKey,
725
+ markets: state.markets,
726
+ userOrders: await this.getUserOrdersAccountPublicKey(),
727
+ userPositions: userAccount.positions,
728
+ fundingPaymentHistory: state.fundingPaymentHistory,
729
+ fundingRateHistory: state.fundingRateHistory,
730
+ orderState: await this.getOrderStatePublicKey(),
731
+ orderHistory: orderState.orderHistory,
732
+ oracle: priceOracle,
733
+ },
734
+ remainingAccounts,
735
+ });
736
+ }
737
+
738
+ public async cancelOrder(orderId: BN): Promise<TransactionSignature> {
739
+ return await this.txSender.send(
740
+ wrapInTx(await this.getCancelOrderIx(orderId)),
741
+ [],
742
+ this.opts
743
+ );
744
+ }
745
+
746
+ public async getCancelOrderIx(orderId: BN): Promise<TransactionInstruction> {
747
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
748
+ const userAccount = await this.getUserAccount();
749
+
750
+ const state = this.getStateAccount();
751
+ const orderState = this.getOrderStateAccount();
752
+ return await this.program.instruction.cancelOrder(orderId, {
753
+ accounts: {
754
+ state: await this.getStatePublicKey(),
755
+ user: userAccountPublicKey,
756
+ authority: this.wallet.publicKey,
757
+ markets: state.markets,
758
+ userOrders: await this.getUserOrdersAccountPublicKey(),
759
+ userPositions: userAccount.positions,
760
+ fundingPaymentHistory: state.fundingPaymentHistory,
761
+ fundingRateHistory: state.fundingRateHistory,
762
+ orderState: await this.getOrderStatePublicKey(),
763
+ orderHistory: orderState.orderHistory,
764
+ },
765
+ });
766
+ }
767
+
768
+ public async fillOrder(
769
+ userAccountPublicKey: PublicKey,
770
+ userOrdersAccountPublicKey: PublicKey,
771
+ order: Order
772
+ ): Promise<TransactionSignature> {
773
+ return await this.txSender.send(
774
+ wrapInTx(
775
+ await this.getFillOrderIx(
776
+ userAccountPublicKey,
777
+ userOrdersAccountPublicKey,
778
+ order
779
+ )
780
+ ),
781
+ [],
782
+ this.opts
783
+ );
784
+ }
785
+
786
+ public async getFillOrderIx(
787
+ userAccountPublicKey: PublicKey,
788
+ userOrdersAccountPublicKey: PublicKey,
789
+ order: Order
790
+ ): Promise<TransactionInstruction> {
791
+ const fillerPublicKey = await this.getUserAccountPublicKey();
792
+ const userAccount: any = await this.program.account.user.fetch(
793
+ userAccountPublicKey
794
+ );
795
+
796
+ const marketIndex = order.marketIndex;
797
+ const oracle = this.getMarket(marketIndex).amm.oracle;
798
+
799
+ const state = this.getStateAccount();
800
+ const orderState = this.getOrderStateAccount();
801
+
802
+ const remainingAccounts = [];
803
+ if (!order.referrer.equals(PublicKey.default)) {
804
+ remainingAccounts.push({
805
+ pubkey: order.referrer,
806
+ isWritable: true,
807
+ isSigner: false,
808
+ });
809
+ }
810
+
811
+ const orderId = order.orderId;
812
+ return await this.program.instruction.fillOrder(orderId, {
813
+ accounts: {
814
+ state: await this.getStatePublicKey(),
815
+ filler: fillerPublicKey,
816
+ user: userAccountPublicKey,
817
+ authority: this.wallet.publicKey,
818
+ markets: state.markets,
819
+ userPositions: userAccount.positions,
820
+ userOrders: userOrdersAccountPublicKey,
821
+ tradeHistory: state.tradeHistory,
822
+ fundingPaymentHistory: state.fundingPaymentHistory,
823
+ fundingRateHistory: state.fundingRateHistory,
824
+ orderState: await this.getOrderStatePublicKey(),
825
+ orderHistory: orderState.orderHistory,
826
+ oracle: oracle,
827
+ },
828
+ remainingAccounts,
829
+ });
830
+ }
831
+
832
+ public async placeAndFillOrder(
833
+ orderParams: OrderParams,
834
+ discountToken?: PublicKey,
835
+ referrer?: PublicKey
836
+ ): Promise<TransactionSignature> {
837
+ return await this.txSender.send(
838
+ wrapInTx(
839
+ await this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)
840
+ ),
841
+ [],
842
+ this.opts
843
+ );
844
+ }
845
+
846
+ public async getPlaceAndFillOrderIx(
847
+ orderParams: OrderParams,
848
+ discountToken?: PublicKey,
849
+ referrer?: PublicKey
850
+ ): Promise<TransactionInstruction> {
851
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
852
+ const userAccount = await this.getUserAccount();
853
+
854
+ const priceOracle =
855
+ this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
856
+ .oracle;
857
+
858
+ const remainingAccounts = [];
859
+ if (orderParams.optionalAccounts.discountToken) {
860
+ if (!discountToken) {
861
+ throw Error(
862
+ 'Optional accounts specified discount token but no discount token present'
863
+ );
864
+ }
865
+
866
+ remainingAccounts.push({
867
+ pubkey: discountToken,
868
+ isWritable: false,
869
+ isSigner: false,
870
+ });
871
+ }
872
+
873
+ if (orderParams.optionalAccounts.referrer) {
874
+ if (!referrer) {
875
+ throw Error(
876
+ 'Optional accounts specified referrer but no referrer present'
877
+ );
878
+ }
879
+
880
+ remainingAccounts.push({
881
+ pubkey: referrer,
882
+ isWritable: true,
883
+ isSigner: false,
884
+ });
885
+ }
886
+
887
+ const state = this.getStateAccount();
888
+ const orderState = this.getOrderStateAccount();
889
+ return await this.program.instruction.placeAndFillOrder(orderParams, {
890
+ accounts: {
891
+ state: await this.getStatePublicKey(),
892
+ user: userAccountPublicKey,
893
+ authority: this.wallet.publicKey,
894
+ markets: state.markets,
895
+ userOrders: await this.getUserOrdersAccountPublicKey(),
896
+ userPositions: userAccount.positions,
897
+ tradeHistory: state.tradeHistory,
898
+ fundingPaymentHistory: state.fundingPaymentHistory,
899
+ fundingRateHistory: state.fundingRateHistory,
900
+ orderState: await this.getOrderStatePublicKey(),
901
+ orderHistory: orderState.orderHistory,
902
+ oracle: priceOracle,
903
+ },
904
+ remainingAccounts,
905
+ });
906
+ }
907
+
575
908
  /**
576
909
  * Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
577
910
  * @param marketIndex