@drift-labs/sdk 0.1.21-master.0 → 0.1.21-master.3

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 +4 -2
  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 +15 -17
  24. package/lib/clearingHouseUser.js +105 -84
  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 +1066 -39
  34. package/lib/index.d.ts +3 -1
  35. package/lib/index.js +3 -0
  36. package/lib/math/amm.d.ts +1 -1
  37. package/lib/math/amm.js +31 -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 +3 -3
  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 +164 -102
  75. package/src/constants/markets.ts +8 -0
  76. package/src/constants/numericConstants.ts +1 -0
  77. package/src/idl/clearing_house.json +1066 -39
  78. package/src/index.ts +3 -0
  79. package/src/math/amm.ts +47 -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
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, 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';
@@ -38,7 +48,9 @@ export class Admin extends ClearingHouse {
38
48
  public async initialize(
39
49
  usdcMint: PublicKey,
40
50
  adminControlsPrices: boolean
41
- ): Promise<[TransactionSignature, TransactionSignature]> {
51
+ ): Promise<
52
+ [TransactionSignature, TransactionSignature, TransactionSignature]
53
+ > {
42
54
  const stateAccountRPCResponse = await this.connection.getParsedAccountInfo(
43
55
  await this.getStatePublicKey()
44
56
  );
@@ -162,7 +174,40 @@ export class Admin extends ClearingHouse {
162
174
  this.opts
163
175
  );
164
176
 
165
- return [initializeTxSig, initializeHistoryTxSig];
177
+ const initializeOrderStateTxSig = await this.initializeOrderState();
178
+
179
+ return [initializeTxSig, initializeHistoryTxSig, initializeOrderStateTxSig];
180
+ }
181
+
182
+ public async initializeOrderState(): Promise<TransactionSignature> {
183
+ const orderHistory = anchor.web3.Keypair.generate();
184
+ const [orderStatePublicKey, orderStateNonce] =
185
+ await getOrderStateAccountPublicKeyAndNonce(this.program.programId);
186
+ const clearingHouseStatePublicKey =
187
+ await getClearingHouseStateAccountPublicKey(this.program.programId);
188
+
189
+ const initializeOrderStateTx =
190
+ await this.program.transaction.initializeOrderState(orderStateNonce, {
191
+ accounts: {
192
+ admin: this.wallet.publicKey,
193
+ state: clearingHouseStatePublicKey,
194
+ orderHistory: orderHistory.publicKey,
195
+ orderState: orderStatePublicKey,
196
+ rent: SYSVAR_RENT_PUBKEY,
197
+ systemProgram: anchor.web3.SystemProgram.programId,
198
+ },
199
+ instructions: [
200
+ await this.program.account.orderHistory.createInstruction(
201
+ orderHistory
202
+ ),
203
+ ],
204
+ });
205
+
206
+ return await this.txSender.send(
207
+ initializeOrderStateTx,
208
+ [orderHistory],
209
+ this.opts
210
+ );
166
211
  }
167
212
 
168
213
  public async initializeMarket(
@@ -508,6 +553,21 @@ export class Admin extends ClearingHouse {
508
553
  );
509
554
  }
510
555
 
556
+ public async updateOrderFillerRewardStructure(
557
+ orderFillerRewardStructure: OrderFillerRewardStructure
558
+ ): Promise<TransactionSignature> {
559
+ return await this.program.rpc.updateOrderFillerRewardStructure(
560
+ orderFillerRewardStructure,
561
+ {
562
+ accounts: {
563
+ admin: this.wallet.publicKey,
564
+ state: await this.getStatePublicKey(),
565
+ orderState: await this.getOrderStatePublicKey(),
566
+ },
567
+ }
568
+ );
569
+ }
570
+
511
571
  public async updateFee(fees: FeeStructure): Promise<TransactionSignature> {
512
572
  return await this.program.rpc.updateFee(fees, {
513
573
  accounts: {
@@ -548,12 +608,30 @@ export class Admin extends ClearingHouse {
548
608
  );
549
609
  }
550
610
 
551
- public async updateMarketMinimumTradeSize(
611
+ public async updateMarketMinimumQuoteAssetTradeSize(
612
+ marketIndex: BN,
613
+ minimumTradeSize: BN
614
+ ): Promise<TransactionSignature> {
615
+ const state = this.getStateAccount();
616
+ return await this.program.rpc.updateMarketMinimumQuoteAssetTradeSize(
617
+ marketIndex,
618
+ minimumTradeSize,
619
+ {
620
+ accounts: {
621
+ admin: this.wallet.publicKey,
622
+ state: await this.getStatePublicKey(),
623
+ markets: state.markets,
624
+ },
625
+ }
626
+ );
627
+ }
628
+
629
+ public async updateMarketMinimumBaseAssetTradeSize(
552
630
  marketIndex: BN,
553
631
  minimumTradeSize: BN
554
632
  ): Promise<TransactionSignature> {
555
633
  const state = this.getStateAccount();
556
- return await this.program.rpc.updateMarketMinimumTradeSize(
634
+ return await this.program.rpc.updateMarketMinimumBaseAssetTradeSize(
557
635
  marketIndex,
558
636
  minimumTradeSize,
559
637
  {
@@ -16,6 +16,10 @@ import {
16
16
  TradeHistoryAccount,
17
17
  UserAccount,
18
18
  Market,
19
+ OrderHistoryAccount,
20
+ OrderStateAccount,
21
+ OrderParams,
22
+ Order,
19
23
  ExtendedCurveHistoryAccount,
20
24
  } from './types';
21
25
  import * as anchor from '@project-serum/anchor';
@@ -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,
@@ -144,6 +151,7 @@ export class ClearingHouse {
144
151
  'fundingRateHistoryAccount',
145
152
  'liquidationHistoryAccount',
146
153
  'tradeHistoryAccount',
154
+ 'orderHistoryAccount',
147
155
  ]);
148
156
  }
149
157
 
@@ -212,6 +220,25 @@ export class ClearingHouse {
212
220
  return this.accountSubscriber.getCurveHistoryAccount();
213
221
  }
214
222
 
223
+ public getOrderHistoryAccount(): OrderHistoryAccount {
224
+ return this.accountSubscriber.getOrderHistoryAccount();
225
+ }
226
+
227
+ orderStatePublicKey?: PublicKey;
228
+ public async getOrderStatePublicKey(): Promise<PublicKey> {
229
+ if (this.orderStatePublicKey) {
230
+ return this.orderStatePublicKey;
231
+ }
232
+ this.orderStatePublicKey = await getOrderStateAccountPublicKey(
233
+ this.program.programId
234
+ );
235
+ return this.orderStatePublicKey;
236
+ }
237
+
238
+ public getOrderStateAccount(): OrderStateAccount {
239
+ return this.accountSubscriber.getOrderStateAccount();
240
+ }
241
+
215
242
  /**
216
243
  * Update the wallet to use for clearing house transactions and linked user account
217
244
  * @param newWallet
@@ -240,9 +267,12 @@ export class ClearingHouse {
240
267
  userPositionsAccount,
241
268
  userAccountPublicKey,
242
269
  initializeUserAccountIx,
270
+ initializeUserOrdersAccountIx,
243
271
  ] = await this.getInitializeUserInstructions();
244
272
 
245
- const tx = new Transaction().add(initializeUserAccountIx);
273
+ const tx = new Transaction()
274
+ .add(initializeUserAccountIx)
275
+ .add(initializeUserOrdersAccountIx);
246
276
  const txSig = await this.txSender.send(
247
277
  tx,
248
278
  [userPositionsAccount],
@@ -252,9 +282,9 @@ export class ClearingHouse {
252
282
  }
253
283
 
254
284
  async getInitializeUserInstructions(): Promise<
255
- [Keypair, PublicKey, TransactionInstruction]
285
+ [Keypair, PublicKey, TransactionInstruction, TransactionInstruction]
256
286
  > {
257
- const [userPublicKey, userAccountNonce] =
287
+ const [userAccountPublicKey, userAccountNonce] =
258
288
  await getUserAccountPublicKeyAndNonce(
259
289
  this.program.programId,
260
290
  this.wallet.publicKey
@@ -288,7 +318,7 @@ export class ClearingHouse {
288
318
  optionalAccounts,
289
319
  {
290
320
  accounts: {
291
- user: userPublicKey,
321
+ user: userAccountPublicKey,
292
322
  authority: this.wallet.publicKey,
293
323
  rent: anchor.web3.SYSVAR_RENT_PUBKEY,
294
324
  systemProgram: anchor.web3.SystemProgram.programId,
@@ -298,7 +328,44 @@ export class ClearingHouse {
298
328
  remainingAccounts: remainingAccounts,
299
329
  }
300
330
  );
301
- return [userPositions, userPublicKey, initializeUserAccountIx];
331
+
332
+ const initializeUserOrdersAccountIx =
333
+ await this.getInitializeUserOrdersInstruction(userAccountPublicKey);
334
+
335
+ return [
336
+ userPositions,
337
+ userAccountPublicKey,
338
+ initializeUserAccountIx,
339
+ initializeUserOrdersAccountIx,
340
+ ];
341
+ }
342
+
343
+ async getInitializeUserOrdersInstruction(
344
+ userAccountPublicKey?: PublicKey
345
+ ): Promise<TransactionInstruction> {
346
+ if (!userAccountPublicKey) {
347
+ userAccountPublicKey = await this.getUserAccountPublicKey();
348
+ }
349
+
350
+ const [userOrdersAccountPublicKey, userOrdersAccountNonce] =
351
+ await getUserOrdersAccountPublicKeyAndNonce(
352
+ this.program.programId,
353
+ userAccountPublicKey
354
+ );
355
+
356
+ return await this.program.instruction.initializeUserOrders(
357
+ userOrdersAccountNonce,
358
+ {
359
+ accounts: {
360
+ user: userAccountPublicKey,
361
+ authority: this.wallet.publicKey,
362
+ rent: anchor.web3.SYSVAR_RENT_PUBKEY,
363
+ systemProgram: anchor.web3.SystemProgram.programId,
364
+ userOrders: userOrdersAccountPublicKey,
365
+ state: await this.getStatePublicKey(),
366
+ },
367
+ }
368
+ );
302
369
  }
303
370
 
304
371
  userAccountPublicKey?: PublicKey;
@@ -330,6 +397,37 @@ export class ClearingHouse {
330
397
  return this.userAccount;
331
398
  }
332
399
 
400
+ userOrdersAccountPublicKey?: PublicKey;
401
+ /**
402
+ * Get the address for the Clearing House User Order's account. NOT the user's wallet address.
403
+ * @returns
404
+ */
405
+ public async getUserOrdersAccountPublicKey(): Promise<PublicKey> {
406
+ if (this.userOrdersAccountPublicKey) {
407
+ return this.userOrdersAccountPublicKey;
408
+ }
409
+
410
+ this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
411
+ this.program.programId,
412
+ await this.getUserAccountPublicKey()
413
+ );
414
+ return this.userOrdersAccountPublicKey;
415
+ }
416
+
417
+ userOrdersExist?: boolean;
418
+ async userOrdersAccountExists(): Promise<boolean> {
419
+ if (this.userOrdersExist) {
420
+ return this.userOrdersExist;
421
+ }
422
+ const userOrdersAccountRPCResponse =
423
+ await this.connection.getParsedAccountInfo(
424
+ await this.getUserOrdersAccountPublicKey()
425
+ );
426
+
427
+ this.userOrdersExist = userOrdersAccountRPCResponse.value !== null;
428
+ return this.userOrdersExist;
429
+ }
430
+
333
431
  public async depositCollateral(
334
432
  amount: BN,
335
433
  collateralAccountPublicKey: PublicKey,
@@ -387,6 +485,7 @@ export class ClearingHouse {
387
485
  userPositionsAccount,
388
486
  userAccountPublicKey,
389
487
  initializeUserAccountIx,
488
+ initializeUserOrdersAccountIx,
390
489
  ] = await this.getInitializeUserInstructions();
391
490
 
392
491
  const depositCollateralIx = await this.getDepositCollateralInstruction(
@@ -397,6 +496,7 @@ export class ClearingHouse {
397
496
 
398
497
  const tx = new Transaction()
399
498
  .add(initializeUserAccountIx)
499
+ .add(initializeUserOrdersAccountIx)
400
500
  .add(depositCollateralIx);
401
501
 
402
502
  const txSig = await this.program.provider.send(tx, [userPositionsAccount]);
@@ -418,6 +518,7 @@ export class ClearingHouse {
418
518
  userPositionsAccount,
419
519
  userAccountPublicKey,
420
520
  initializeUserAccountIx,
521
+ initializeUserOrdersAccountIx,
421
522
  ] = await this.getInitializeUserInstructions();
422
523
 
423
524
  const depositCollateralIx = await this.getDepositCollateralInstruction(
@@ -430,6 +531,7 @@ export class ClearingHouse {
430
531
  .add(createAssociatedAccountIx)
431
532
  .add(mintToIx)
432
533
  .add(initializeUserAccountIx)
534
+ .add(initializeUserOrdersAccountIx)
433
535
  .add(depositCollateralIx);
434
536
 
435
537
  const txSig = await this.program.provider.send(tx, [userPositionsAccount]);
@@ -580,6 +682,329 @@ export class ClearingHouse {
580
682
  );
581
683
  }
582
684
 
685
+ public async initializeUserOrdersThenPlaceOrder(
686
+ orderParams: OrderParams,
687
+ discountToken?: PublicKey,
688
+ referrer?: PublicKey
689
+ ): Promise<TransactionSignature> {
690
+ const instructions: anchor.web3.TransactionInstruction[] = [];
691
+ const userOrdersAccountExists = await this.userOrdersAccountExists();
692
+ if (!userOrdersAccountExists) {
693
+ instructions.push(await this.getInitializeUserOrdersInstruction());
694
+ }
695
+ instructions.push(
696
+ await this.getPlaceOrderIx(orderParams, discountToken, referrer)
697
+ );
698
+ const tx = new Transaction();
699
+ for (const instruction of instructions) {
700
+ tx.add(instruction);
701
+ }
702
+
703
+ return await this.txSender.send(tx, [], this.opts);
704
+ }
705
+
706
+ public async placeOrder(
707
+ orderParams: OrderParams,
708
+ discountToken?: PublicKey,
709
+ referrer?: PublicKey
710
+ ): Promise<TransactionSignature> {
711
+ return await this.txSender.send(
712
+ wrapInTx(
713
+ await this.getPlaceOrderIx(orderParams, discountToken, referrer)
714
+ ),
715
+ [],
716
+ this.opts
717
+ );
718
+ }
719
+
720
+ public async getPlaceOrderIx(
721
+ orderParams: OrderParams,
722
+ discountToken?: PublicKey,
723
+ referrer?: PublicKey
724
+ ): Promise<TransactionInstruction> {
725
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
726
+ const userAccount = await this.getUserAccount();
727
+
728
+ const priceOracle =
729
+ this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
730
+ .oracle;
731
+
732
+ const remainingAccounts = [];
733
+ if (orderParams.optionalAccounts.discountToken) {
734
+ if (!discountToken) {
735
+ throw Error(
736
+ 'Optional accounts specified discount token but no discount token present'
737
+ );
738
+ }
739
+
740
+ remainingAccounts.push({
741
+ pubkey: discountToken,
742
+ isWritable: false,
743
+ isSigner: false,
744
+ });
745
+ }
746
+
747
+ if (orderParams.optionalAccounts.referrer) {
748
+ if (!referrer) {
749
+ throw Error(
750
+ 'Optional accounts specified referrer but no referrer present'
751
+ );
752
+ }
753
+
754
+ remainingAccounts.push({
755
+ pubkey: referrer,
756
+ isWritable: false,
757
+ isSigner: false,
758
+ });
759
+ }
760
+
761
+ const state = this.getStateAccount();
762
+ const orderState = this.getOrderStateAccount();
763
+ return await this.program.instruction.placeOrder(orderParams, {
764
+ accounts: {
765
+ state: await this.getStatePublicKey(),
766
+ user: userAccountPublicKey,
767
+ authority: this.wallet.publicKey,
768
+ markets: state.markets,
769
+ userOrders: await this.getUserOrdersAccountPublicKey(),
770
+ userPositions: userAccount.positions,
771
+ fundingPaymentHistory: state.fundingPaymentHistory,
772
+ fundingRateHistory: state.fundingRateHistory,
773
+ orderState: await this.getOrderStatePublicKey(),
774
+ orderHistory: orderState.orderHistory,
775
+ oracle: priceOracle,
776
+ },
777
+ remainingAccounts,
778
+ });
779
+ }
780
+
781
+ public async cancelOrder(orderId: BN): Promise<TransactionSignature> {
782
+ return await this.txSender.send(
783
+ wrapInTx(await this.getCancelOrderIx(orderId)),
784
+ [],
785
+ this.opts
786
+ );
787
+ }
788
+
789
+ public async getCancelOrderIx(orderId: BN): Promise<TransactionInstruction> {
790
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
791
+ const userAccount = await this.getUserAccount();
792
+
793
+ const state = this.getStateAccount();
794
+ const orderState = this.getOrderStateAccount();
795
+ return await this.program.instruction.cancelOrder(orderId, {
796
+ accounts: {
797
+ state: await this.getStatePublicKey(),
798
+ user: userAccountPublicKey,
799
+ authority: this.wallet.publicKey,
800
+ markets: state.markets,
801
+ userOrders: await this.getUserOrdersAccountPublicKey(),
802
+ userPositions: userAccount.positions,
803
+ fundingPaymentHistory: state.fundingPaymentHistory,
804
+ fundingRateHistory: state.fundingRateHistory,
805
+ orderState: await this.getOrderStatePublicKey(),
806
+ orderHistory: orderState.orderHistory,
807
+ },
808
+ });
809
+ }
810
+
811
+ public async cancelOrderByUserId(
812
+ userOrderId: number
813
+ ): Promise<TransactionSignature> {
814
+ return await this.txSender.send(
815
+ wrapInTx(await this.getCancelOrderByUserIdIx(userOrderId)),
816
+ [],
817
+ this.opts
818
+ );
819
+ }
820
+
821
+ public async getCancelOrderByUserIdIx(
822
+ userOrderId: number
823
+ ): Promise<TransactionInstruction> {
824
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
825
+ const userAccount = await this.getUserAccount();
826
+
827
+ const state = this.getStateAccount();
828
+ const orderState = this.getOrderStateAccount();
829
+ return await this.program.instruction.cancelOrderByUserId(userOrderId, {
830
+ accounts: {
831
+ state: await this.getStatePublicKey(),
832
+ user: userAccountPublicKey,
833
+ authority: this.wallet.publicKey,
834
+ markets: state.markets,
835
+ userOrders: await this.getUserOrdersAccountPublicKey(),
836
+ userPositions: userAccount.positions,
837
+ fundingPaymentHistory: state.fundingPaymentHistory,
838
+ fundingRateHistory: state.fundingRateHistory,
839
+ orderState: await this.getOrderStatePublicKey(),
840
+ orderHistory: orderState.orderHistory,
841
+ },
842
+ });
843
+ }
844
+
845
+ public async fillOrder(
846
+ userAccountPublicKey: PublicKey,
847
+ userOrdersAccountPublicKey: PublicKey,
848
+ order: Order
849
+ ): Promise<TransactionSignature> {
850
+ return await this.txSender.send(
851
+ wrapInTx(
852
+ await this.getFillOrderIx(
853
+ userAccountPublicKey,
854
+ userOrdersAccountPublicKey,
855
+ order
856
+ )
857
+ ),
858
+ [],
859
+ this.opts
860
+ );
861
+ }
862
+
863
+ public async getFillOrderIx(
864
+ userAccountPublicKey: PublicKey,
865
+ userOrdersAccountPublicKey: PublicKey,
866
+ order: Order
867
+ ): Promise<TransactionInstruction> {
868
+ const fillerPublicKey = await this.getUserAccountPublicKey();
869
+ const userAccount: any = await this.program.account.user.fetch(
870
+ userAccountPublicKey
871
+ );
872
+
873
+ const marketIndex = order.marketIndex;
874
+ const oracle = this.getMarket(marketIndex).amm.oracle;
875
+
876
+ const state = this.getStateAccount();
877
+ const orderState = this.getOrderStateAccount();
878
+
879
+ const remainingAccounts = [];
880
+ if (!order.referrer.equals(PublicKey.default)) {
881
+ remainingAccounts.push({
882
+ pubkey: order.referrer,
883
+ isWritable: true,
884
+ isSigner: false,
885
+ });
886
+ }
887
+
888
+ const orderId = order.orderId;
889
+ return await this.program.instruction.fillOrder(orderId, {
890
+ accounts: {
891
+ state: await this.getStatePublicKey(),
892
+ filler: fillerPublicKey,
893
+ user: userAccountPublicKey,
894
+ authority: this.wallet.publicKey,
895
+ markets: state.markets,
896
+ userPositions: userAccount.positions,
897
+ userOrders: userOrdersAccountPublicKey,
898
+ tradeHistory: state.tradeHistory,
899
+ fundingPaymentHistory: state.fundingPaymentHistory,
900
+ fundingRateHistory: state.fundingRateHistory,
901
+ orderState: await this.getOrderStatePublicKey(),
902
+ orderHistory: orderState.orderHistory,
903
+ extendedCurveHistory: state.extendedCurveHistory,
904
+ oracle: oracle,
905
+ },
906
+ remainingAccounts,
907
+ });
908
+ }
909
+
910
+ public async initializeUserOrdersThenPlaceAndFillOrder(
911
+ orderParams: OrderParams,
912
+ discountToken?: PublicKey,
913
+ referrer?: PublicKey
914
+ ): Promise<TransactionSignature> {
915
+ const instructions: anchor.web3.TransactionInstruction[] = [];
916
+ const userOrdersAccountExists = await this.userOrdersAccountExists();
917
+ if (!userOrdersAccountExists) {
918
+ instructions.push(await this.getInitializeUserOrdersInstruction());
919
+ }
920
+ instructions.push(
921
+ await this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)
922
+ );
923
+ const tx = new Transaction();
924
+ for (const instruction of instructions) {
925
+ tx.add(instruction);
926
+ }
927
+
928
+ return await this.txSender.send(tx, [], this.opts);
929
+ }
930
+
931
+ public async placeAndFillOrder(
932
+ orderParams: OrderParams,
933
+ discountToken?: PublicKey,
934
+ referrer?: PublicKey
935
+ ): Promise<TransactionSignature> {
936
+ return await this.txSender.send(
937
+ wrapInTx(
938
+ await this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)
939
+ ),
940
+ [],
941
+ this.opts
942
+ );
943
+ }
944
+
945
+ public async getPlaceAndFillOrderIx(
946
+ orderParams: OrderParams,
947
+ discountToken?: PublicKey,
948
+ referrer?: PublicKey
949
+ ): Promise<TransactionInstruction> {
950
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
951
+ const userAccount = await this.getUserAccount();
952
+
953
+ const priceOracle =
954
+ this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
955
+ .oracle;
956
+
957
+ const remainingAccounts = [];
958
+ if (orderParams.optionalAccounts.discountToken) {
959
+ if (!discountToken) {
960
+ throw Error(
961
+ 'Optional accounts specified discount token but no discount token present'
962
+ );
963
+ }
964
+
965
+ remainingAccounts.push({
966
+ pubkey: discountToken,
967
+ isWritable: false,
968
+ isSigner: false,
969
+ });
970
+ }
971
+
972
+ if (orderParams.optionalAccounts.referrer) {
973
+ if (!referrer) {
974
+ throw Error(
975
+ 'Optional accounts specified referrer but no referrer present'
976
+ );
977
+ }
978
+
979
+ remainingAccounts.push({
980
+ pubkey: referrer,
981
+ isWritable: true,
982
+ isSigner: false,
983
+ });
984
+ }
985
+
986
+ const state = this.getStateAccount();
987
+ const orderState = this.getOrderStateAccount();
988
+ return await this.program.instruction.placeAndFillOrder(orderParams, {
989
+ accounts: {
990
+ state: await this.getStatePublicKey(),
991
+ user: userAccountPublicKey,
992
+ authority: this.wallet.publicKey,
993
+ markets: state.markets,
994
+ userOrders: await this.getUserOrdersAccountPublicKey(),
995
+ userPositions: userAccount.positions,
996
+ tradeHistory: state.tradeHistory,
997
+ fundingPaymentHistory: state.fundingPaymentHistory,
998
+ fundingRateHistory: state.fundingRateHistory,
999
+ orderState: await this.getOrderStatePublicKey(),
1000
+ orderHistory: orderState.orderHistory,
1001
+ extendedCurveHistory: state.extendedCurveHistory,
1002
+ oracle: priceOracle,
1003
+ },
1004
+ remainingAccounts,
1005
+ });
1006
+ }
1007
+
583
1008
  /**
584
1009
  * Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
585
1010
  * @param marketIndex