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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +2 -1
  2. package/lib/accounts/bulkAccountLoader.d.ts +32 -0
  3. package/lib/accounts/bulkAccountLoader.js +156 -0
  4. package/lib/accounts/bulkUserSubscription.d.ts +7 -0
  5. package/lib/accounts/bulkUserSubscription.js +28 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +49 -0
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +228 -0
  8. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +25 -0
  9. package/lib/accounts/pollingTokenAccountSubscriber.js +79 -0
  10. package/lib/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  11. package/lib/accounts/pollingUserAccountSubscriber.js +133 -0
  12. package/lib/accounts/types.d.ts +30 -25
  13. package/lib/accounts/utils.d.ts +1 -0
  14. package/lib/accounts/utils.js +7 -0
  15. package/lib/accounts/{defaultClearingHouseAccountSubscriber.d.ts → webSocketClearingHouseAccountSubscriber.d.ts} +6 -4
  16. package/lib/accounts/{defaultClearingHouseAccountSubscriber.js → webSocketClearingHouseAccountSubscriber.js} +5 -4
  17. package/lib/accounts/{defaultUserAccountSubscriber.d.ts → webSocketUserAccountSubscriber.d.ts} +3 -1
  18. package/lib/accounts/{defaultUserAccountSubscriber.js → webSocketUserAccountSubscriber.js} +10 -7
  19. package/lib/addresses.d.ts +2 -2
  20. package/lib/addresses.js +4 -4
  21. package/lib/admin.d.ts +3 -0
  22. package/lib/admin.js +61 -13
  23. package/lib/clearingHouse.d.ts +16 -4
  24. package/lib/clearingHouse.js +50 -10
  25. package/lib/clearingHouseUser.d.ts +9 -1
  26. package/lib/clearingHouseUser.js +19 -5
  27. package/lib/config.js +1 -1
  28. package/lib/constants/markets.js +16 -0
  29. package/lib/factory/clearingHouse.d.ts +25 -0
  30. package/lib/factory/clearingHouse.js +64 -0
  31. package/lib/factory/clearingHouseUser.d.ts +19 -0
  32. package/lib/factory/clearingHouseUser.js +34 -0
  33. package/lib/idl/clearing_house.json +360 -15
  34. package/lib/index.d.ts +9 -4
  35. package/lib/index.js +14 -5
  36. package/lib/math/funding.js +4 -1
  37. package/lib/math/utils.d.ts +2 -2
  38. package/lib/math/utils.js +6 -3
  39. package/lib/orderParams.d.ts +3 -3
  40. package/lib/orderParams.js +23 -3
  41. package/lib/token/index.d.ts +3 -0
  42. package/lib/token/index.js +38 -0
  43. package/lib/types.d.ts +13 -3
  44. package/package.json +3 -3
  45. package/src/accounts/bulkAccountLoader.ts +195 -0
  46. package/src/accounts/bulkUserSubscription.ts +28 -0
  47. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +326 -0
  48. package/src/accounts/pollingTokenAccountSubscriber.ts +99 -0
  49. package/src/accounts/pollingUserAccountSubscriber.ts +186 -0
  50. package/src/accounts/types.ts +35 -30
  51. package/src/accounts/utils.ts +3 -0
  52. package/src/accounts/{defaultClearingHouseAccountSubscriber.ts → webSocketClearingHouseAccountSubscriber.ts} +9 -6
  53. package/src/accounts/{defaultUserAccountSubscriber.ts → webSocketUserAccountSubscriber.ts} +10 -5
  54. package/src/addresses.ts +6 -4
  55. package/src/admin.ts +73 -20
  56. package/src/clearingHouse.ts +69 -25
  57. package/src/clearingHouseUser.ts +26 -6
  58. package/src/config.ts +1 -1
  59. package/src/constants/markets.ts +16 -0
  60. package/src/factory/clearingHouse.ts +125 -0
  61. package/src/factory/clearingHouseUser.ts +73 -0
  62. package/src/idl/clearing_house.json +360 -15
  63. package/src/index.ts +9 -4
  64. package/src/math/funding.ts +5 -1
  65. package/src/math/utils.ts +1 -1
  66. package/src/orderParams.ts +26 -3
  67. package/src/token/index.ts +37 -0
  68. package/src/types.ts +13 -3
  69. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -28
  70. package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
  71. package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -176
@@ -1,6 +1,6 @@
1
1
  import {
2
- CurveHistoryAccount,
3
2
  DepositHistoryAccount,
3
+ ExtendedCurveHistoryAccount,
4
4
  FundingPaymentHistoryAccount,
5
5
  FundingRateHistoryAccount,
6
6
  LiquidationHistoryAccount,
@@ -15,12 +15,15 @@ import {
15
15
  } from '../types';
16
16
  import StrictEventEmitter from 'strict-event-emitter-types';
17
17
  import { EventEmitter } from 'events';
18
+ import { PublicKey } from '@solana/web3.js';
19
+ import { AccountInfo } from '@solana/spl-token';
20
+ import { ClearingHouseConfigType, ClearingHouseUserConfigType } from '..';
18
21
 
19
22
  export interface AccountSubscriber<T> {
20
23
  data?: T;
21
24
  subscribe(onChange: (data: T) => void): Promise<void>;
22
25
  fetch(): Promise<void>;
23
- unsubscribe(): void;
26
+ unsubscribe(): Promise<void>;
24
27
  }
25
28
 
26
29
  export class NotSubscribedError extends Error {
@@ -37,10 +40,11 @@ export interface ClearingHouseAccountEvents {
37
40
  tradeHistoryAccountUpdate: (payload: TradeHistoryAccount) => void;
38
41
  liquidationHistoryAccountUpdate: (payload: LiquidationHistoryAccount) => void;
39
42
  depositHistoryAccountUpdate: (payload: DepositHistoryAccount) => void;
40
- curveHistoryAccountUpdate: (payload: CurveHistoryAccount) => void;
43
+ curveHistoryAccountUpdate: (payload: ExtendedCurveHistoryAccount) => void;
41
44
  orderHistoryAccountUpdate: (payload: OrderHistoryAccount) => void;
42
45
  orderStateAccountUpdate: (payload: OrderStateAccount) => void;
43
46
  update: void;
47
+ error: (e: Error) => void;
44
48
  }
45
49
 
46
50
  export type ClearingHouseAccountTypes =
@@ -70,37 +74,12 @@ export interface ClearingHouseAccountSubscriber {
70
74
  getDepositHistoryAccount(): DepositHistoryAccount;
71
75
  getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
72
76
  getFundingRateHistoryAccount(): FundingRateHistoryAccount;
73
- getCurveHistoryAccount(): CurveHistoryAccount;
77
+ getCurveHistoryAccount(): ExtendedCurveHistoryAccount;
74
78
  getLiquidationHistoryAccount(): LiquidationHistoryAccount;
75
79
  getOrderStateAccount(): OrderStateAccount;
76
80
  getOrderHistoryAccount(): OrderHistoryAccount;
77
- }
78
-
79
- export interface HistoryAccountEvents {
80
- fundingPaymentHistoryAccountUpdate: (
81
- payload: FundingPaymentHistoryAccount
82
- ) => void;
83
- fundingRateHistoryAccountUpdate: (payload: FundingRateHistoryAccount) => void;
84
- tradeHistoryAccountUpdate: (payload: TradeHistoryAccount) => void;
85
- liquidationHistoryAccountUpdate: (payload: LiquidationHistoryAccount) => void;
86
- depositHistoryAccountUpdate: (payload: DepositHistoryAccount) => void;
87
- curveHistoryAccountUpdate: (payload: CurveHistoryAccount) => void;
88
- update: void;
89
- }
90
-
91
- export interface HistoryAccountSubscriber {
92
- eventEmitter: StrictEventEmitter<EventEmitter, HistoryAccountEvents>;
93
- isSubscribed: boolean;
94
-
95
- subscribe(): Promise<boolean>;
96
- unsubscribe(): Promise<void>;
97
81
 
98
- getTradeHistoryAccount(): TradeHistoryAccount;
99
- getDepositHistoryAccount(): DepositHistoryAccount;
100
- getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
101
- getFundingRateHistoryAccount(): FundingRateHistoryAccount;
102
- getCurveHistoryAccount(): CurveHistoryAccount;
103
- getLiquidationHistoryAccount(): LiquidationHistoryAccount;
82
+ type: ClearingHouseConfigType;
104
83
  }
105
84
 
106
85
  export interface UserAccountEvents {
@@ -108,6 +87,7 @@ export interface UserAccountEvents {
108
87
  userPositionsData: (payload: UserPositionsAccount) => void;
109
88
  userOrdersData: (payload: UserOrdersAccount) => void;
110
89
  update: void;
90
+ error: (e: Error) => void;
111
91
  }
112
92
 
113
93
  export interface UserAccountSubscriber {
@@ -121,4 +101,29 @@ export interface UserAccountSubscriber {
121
101
  getUserAccount(): UserAccount;
122
102
  getUserPositionsAccount(): UserPositionsAccount;
123
103
  getUserOrdersAccount(): UserOrdersAccount;
104
+ type: ClearingHouseUserConfigType;
124
105
  }
106
+
107
+ export interface TokenAccountEvents {
108
+ tokenAccountUpdate: (payload: AccountInfo) => void;
109
+ update: void;
110
+ error: (e: Error) => void;
111
+ }
112
+
113
+ export interface TokenAccountSubscriber {
114
+ eventEmitter: StrictEventEmitter<EventEmitter, TokenAccountEvents>;
115
+ isSubscribed: boolean;
116
+
117
+ subscribe(): Promise<boolean>;
118
+ fetch(): Promise<void>;
119
+ unsubscribe(): Promise<void>;
120
+
121
+ getTokenAccount(): AccountInfo;
122
+ }
123
+
124
+ export type AccountToPoll = {
125
+ key: string;
126
+ publicKey: PublicKey;
127
+ eventType: string;
128
+ callbackId?: string;
129
+ };
@@ -0,0 +1,3 @@
1
+ export function capitalize(value: string): string {
2
+ return value[0].toUpperCase() + value.slice(1);
3
+ }
@@ -5,8 +5,8 @@ import {
5
5
  } from './types';
6
6
  import { AccountSubscriber, NotSubscribedError } from './types';
7
7
  import {
8
- CurveHistoryAccount,
9
8
  DepositHistoryAccount,
9
+ ExtendedCurveHistoryAccount,
10
10
  FundingPaymentHistoryAccount,
11
11
  FundingRateHistoryAccount,
12
12
  LiquidationHistoryAccount,
@@ -21,8 +21,9 @@ import StrictEventEmitter from 'strict-event-emitter-types';
21
21
  import { EventEmitter } from 'events';
22
22
  import { getClearingHouseStateAccountPublicKey } from '../addresses';
23
23
  import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
24
+ import { ClearingHouseConfigType } from '../factory/clearingHouse';
24
25
 
25
- export class DefaultClearingHouseAccountSubscriber
26
+ export class WebSocketClearingHouseAccountSubscriber
26
27
  implements ClearingHouseAccountSubscriber
27
28
  {
28
29
  isSubscribed: boolean;
@@ -34,13 +35,15 @@ export class DefaultClearingHouseAccountSubscriber
34
35
  depositHistoryAccountSubscriber?: AccountSubscriber<DepositHistoryAccount>;
35
36
  fundingPaymentHistoryAccountSubscriber?: AccountSubscriber<FundingPaymentHistoryAccount>;
36
37
  fundingRateHistoryAccountSubscriber?: AccountSubscriber<FundingRateHistoryAccount>;
37
- curveHistoryAccountSubscriber?: AccountSubscriber<CurveHistoryAccount>;
38
+ curveHistoryAccountSubscriber?: AccountSubscriber<ExtendedCurveHistoryAccount>;
38
39
  liquidationHistoryAccountSubscriber?: AccountSubscriber<LiquidationHistoryAccount>;
39
40
  orderStateAccountSubscriber?: AccountSubscriber<OrderStateAccount>;
40
41
  orderHistoryAccountSubscriber?: AccountSubscriber<OrderHistoryAccount>;
41
42
 
42
43
  optionalExtraSubscriptions: ClearingHouseAccountTypes[] = [];
43
44
 
45
+ type: ClearingHouseConfigType = 'websocket';
46
+
44
47
  private isSubscribing = false;
45
48
  private subscriptionPromise: Promise<boolean>;
46
49
  private subscriptionPromiseResolver: (val: boolean) => void;
@@ -145,9 +148,9 @@ export class DefaultClearingHouseAccountSubscriber
145
148
  );
146
149
 
147
150
  this.curveHistoryAccountSubscriber = new WebSocketAccountSubscriber(
148
- 'curveHistory',
151
+ 'extendedCurveHistory',
149
152
  this.program,
150
- state.curveHistory
153
+ state.extendedCurveHistory
151
154
  );
152
155
 
153
156
  this.orderHistoryAccountSubscriber = new WebSocketAccountSubscriber(
@@ -343,7 +346,7 @@ export class DefaultClearingHouseAccountSubscriber
343
346
  return this.fundingRateHistoryAccountSubscriber.data;
344
347
  }
345
348
 
346
- public getCurveHistoryAccount(): CurveHistoryAccount {
349
+ public getCurveHistoryAccount(): ExtendedCurveHistoryAccount {
347
350
  this.assertIsSubscribed();
348
351
  this.assertOptionalIsSubscribed('curveHistoryAccount');
349
352
  return this.curveHistoryAccountSubscriber.data;
@@ -14,8 +14,9 @@ import {
14
14
  } from '../addresses';
15
15
  import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
16
16
  import { UserAccount, UserOrdersAccount, UserPositionsAccount } from '../types';
17
+ import { ClearingHouseConfigType } from '../factory/clearingHouse';
17
18
 
18
- export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
19
+ export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
19
20
  isSubscribed: boolean;
20
21
  program: Program;
21
22
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
@@ -25,6 +26,8 @@ export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
25
26
  userPositionsAccountSubscriber: AccountSubscriber<UserPositionsAccount>;
26
27
  userOrdersAccountSubscriber: AccountSubscriber<UserOrdersAccount>;
27
28
 
29
+ type: ClearingHouseConfigType = 'websocket';
30
+
28
31
  public constructor(program: Program, authority: PublicKey) {
29
32
  this.isSubscribed = false;
30
33
  this.program = program;
@@ -67,7 +70,7 @@ export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
67
70
 
68
71
  const userOrdersPublicKey = await getUserOrdersAccountPublicKey(
69
72
  this.program.programId,
70
- this.authority
73
+ userPublicKey
71
74
  );
72
75
 
73
76
  this.userOrdersAccountSubscriber = new WebSocketAccountSubscriber(
@@ -100,9 +103,11 @@ export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
100
103
  return;
101
104
  }
102
105
 
103
- this.userDataAccountSubscriber.unsubscribe();
104
- this.userPositionsAccountSubscriber.unsubscribe();
105
- this.userOrdersAccountSubscriber.unsubscribe();
106
+ await Promise.all([
107
+ this.userDataAccountSubscriber.unsubscribe(),
108
+ this.userPositionsAccountSubscriber.unsubscribe(),
109
+ await this.userOrdersAccountSubscriber.unsubscribe(),
110
+ ]);
106
111
 
107
112
  this.isSubscribed = false;
108
113
  }
package/src/addresses.ts CHANGED
@@ -50,12 +50,12 @@ export async function getUserAccountPublicKey(
50
50
 
51
51
  export async function getUserOrdersAccountPublicKeyAndNonce(
52
52
  programId: PublicKey,
53
- authority: PublicKey
53
+ userAccount: PublicKey
54
54
  ): Promise<[PublicKey, number]> {
55
55
  return anchor.web3.PublicKey.findProgramAddress(
56
56
  [
57
57
  Buffer.from(anchor.utils.bytes.utf8.encode('user_orders')),
58
- authority.toBuffer(),
58
+ userAccount.toBuffer(),
59
59
  ],
60
60
  programId
61
61
  );
@@ -63,7 +63,9 @@ export async function getUserOrdersAccountPublicKeyAndNonce(
63
63
 
64
64
  export async function getUserOrdersAccountPublicKey(
65
65
  programId: PublicKey,
66
- authority: PublicKey
66
+ userAccount: PublicKey
67
67
  ): Promise<PublicKey> {
68
- return (await getUserOrdersAccountPublicKeyAndNonce(programId, authority))[0];
68
+ return (
69
+ await getUserOrdersAccountPublicKeyAndNonce(programId, userAccount)
70
+ )[0];
69
71
  }
package/src/admin.ts CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  OracleSource,
13
13
  OrderFillerRewardStructure,
14
14
  } from './types';
15
- import { BN, Idl, Program, Provider } from '@project-serum/anchor';
15
+ import { BN, Provider } from '@project-serum/anchor';
16
16
  import * as anchor from '@project-serum/anchor';
17
17
  import {
18
18
  getClearingHouseStateAccountPublicKey,
@@ -22,11 +22,12 @@ import {
22
22
  import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
23
23
  import { ClearingHouse } from './clearingHouse';
24
24
  import { PEG_PRECISION } from './constants/numericConstants';
25
- import clearingHouseIDL from './idl/clearing_house.json';
26
- import { DefaultClearingHouseAccountSubscriber } from './accounts/defaultClearingHouseAccountSubscriber';
27
- import { DefaultTxSender } from './tx/defaultTxSender';
28
25
  import { calculateTargetPriceTrade } from './math/trade';
29
26
  import { calculateAmmReservesAfterSwap, getSwapDirection } from './math/amm';
27
+ import {
28
+ getAdmin,
29
+ getWebSocketClearingHouseConfig,
30
+ } from './factory/clearingHouse';
30
31
 
31
32
  export class Admin extends ClearingHouse {
32
33
  public static from(
@@ -35,24 +36,13 @@ export class Admin extends ClearingHouse {
35
36
  clearingHouseProgramId: PublicKey,
36
37
  opts: ConfirmOptions = Provider.defaultOptions()
37
38
  ): Admin {
38
- const provider = new Provider(connection, wallet, opts);
39
- const program = new Program(
40
- clearingHouseIDL as Idl,
41
- clearingHouseProgramId,
42
- provider
43
- );
44
- const accountSubscriber = new DefaultClearingHouseAccountSubscriber(
45
- program
46
- );
47
- const txSender = new DefaultTxSender(provider);
48
- return new Admin(
39
+ const config = getWebSocketClearingHouseConfig(
49
40
  connection,
50
41
  wallet,
51
- program,
52
- accountSubscriber,
53
- txSender,
42
+ clearingHouseProgramId,
54
43
  opts
55
44
  );
45
+ return getAdmin(config);
56
46
  }
57
47
 
58
48
  public async initialize(
@@ -165,7 +155,7 @@ export class Admin extends ClearingHouse {
165
155
  await this.program.account.depositHistory.createInstruction(
166
156
  depositHistory
167
157
  ),
168
- await this.program.account.curveHistory.createInstruction(
158
+ await this.program.account.extendedCurveHistory.createInstruction(
169
159
  curveHistory
170
160
  ),
171
161
  ],
@@ -275,13 +265,38 @@ export class Admin extends ClearingHouse {
275
265
  marketIndex: BN
276
266
  ): Promise<TransactionSignature> {
277
267
  const state = this.getStateAccount();
268
+ const markets = this.getMarketsAccount();
269
+ const marketData = markets.markets[marketIndex.toNumber()];
270
+ const ammData = marketData.amm;
271
+
278
272
  return await this.program.rpc.updateK(sqrtK, marketIndex, {
279
273
  accounts: {
280
274
  state: await this.getStatePublicKey(),
281
275
  admin: this.wallet.publicKey,
282
276
  markets: state.markets,
277
+ curveHistory: state.extendedCurveHistory,
278
+ oracle: ammData.oracle,
279
+ },
280
+ });
281
+ }
282
+
283
+ public async updateCurveHistory(): Promise<TransactionSignature> {
284
+ const extendedCurveHistory = anchor.web3.Keypair.generate();
285
+
286
+ const state = this.getStateAccount();
287
+ return await this.program.rpc.updateCurveHistory({
288
+ accounts: {
289
+ state: await this.getStatePublicKey(),
290
+ admin: this.wallet.publicKey,
283
291
  curveHistory: state.curveHistory,
292
+ extendedCurveHistory: extendedCurveHistory.publicKey,
284
293
  },
294
+ instructions: [
295
+ await this.program.account.extendedCurveHistory.createInstruction(
296
+ extendedCurveHistory
297
+ ),
298
+ ],
299
+ signers: [extendedCurveHistory],
285
300
  });
286
301
  }
287
302
 
@@ -334,7 +349,45 @@ export class Admin extends ClearingHouse {
334
349
  admin: this.wallet.publicKey,
335
350
  oracle: ammData.oracle,
336
351
  markets: state.markets,
337
- curveHistory: state.curveHistory,
352
+ curveHistory: state.extendedCurveHistory,
353
+ },
354
+ });
355
+ }
356
+
357
+ public async updateAmmOracleTwap(
358
+ marketIndex: BN
359
+ ): Promise<TransactionSignature> {
360
+ const state = this.getStateAccount();
361
+ const markets = this.getMarketsAccount();
362
+ const marketData = markets.markets[marketIndex.toNumber()];
363
+ const ammData = marketData.amm;
364
+
365
+ return await this.program.rpc.updateAmmOracleTwap(marketIndex, {
366
+ accounts: {
367
+ state: await this.getStatePublicKey(),
368
+ admin: this.wallet.publicKey,
369
+ oracle: ammData.oracle,
370
+ markets: state.markets,
371
+ curveHistory: state.extendedCurveHistory,
372
+ },
373
+ });
374
+ }
375
+
376
+ public async resetAmmOracleTwap(
377
+ marketIndex: BN
378
+ ): Promise<TransactionSignature> {
379
+ const state = this.getStateAccount();
380
+ const markets = this.getMarketsAccount();
381
+ const marketData = markets.markets[marketIndex.toNumber()];
382
+ const ammData = marketData.amm;
383
+
384
+ return await this.program.rpc.resetAmmOracleTwap(marketIndex, {
385
+ accounts: {
386
+ state: await this.getStatePublicKey(),
387
+ admin: this.wallet.publicKey,
388
+ oracle: ammData.oracle,
389
+ markets: state.markets,
390
+ curveHistory: state.extendedCurveHistory,
338
391
  },
339
392
  });
340
393
  }
@@ -7,7 +7,6 @@ import {
7
7
  import {
8
8
  MarketsAccount,
9
9
  StateAccount,
10
- CurveHistoryAccount,
11
10
  DepositHistoryAccount,
12
11
  FundingPaymentHistoryAccount,
13
12
  FundingRateHistoryAccount,
@@ -21,6 +20,7 @@ import {
21
20
  OrderStateAccount,
22
21
  OrderParams,
23
22
  Order,
23
+ ExtendedCurveHistoryAccount,
24
24
  } from './types';
25
25
  import * as anchor from '@project-serum/anchor';
26
26
  import clearingHouseIDL from './idl/clearing_house.json';
@@ -51,16 +51,19 @@ import {
51
51
  ClearingHouseAccountEvents,
52
52
  ClearingHouseAccountTypes,
53
53
  } from './accounts/types';
54
- import { DefaultClearingHouseAccountSubscriber } from './accounts/defaultClearingHouseAccountSubscriber';
55
54
  import { TxSender } from './tx/types';
56
55
  import { DefaultTxSender } from './tx/defaultTxSender';
57
56
  import { wrapInTx } from './tx/utils';
57
+ import {
58
+ getClearingHouse,
59
+ getWebSocketClearingHouseConfig,
60
+ } from './factory/clearingHouse';
58
61
 
59
62
  /**
60
63
  * # ClearingHouse
61
64
  * This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
62
65
  *
63
- * The default way to construct a ClearingHouse instance is using the {@link from} method. This will create an instance using the static {@link DefaultClearingHouseAccountSubscriber}, which will use a websocket for each state account subscription.
66
+ * The default way to construct a ClearingHouse instance is using the {@link from} method. This will create an instance using the static {@link WebSocketClearingHouseAccountSubscriber}, which will use a websocket for each state account subscription.
64
67
  * Alternatively, if you want to implement your own method of subscribing to the state accounts on the blockchain, you can implement a {@link ClearingHouseAccountSubscriber} and use it in the {@link ClearingHouse.constructor}
65
68
  */
66
69
  export class ClearingHouse {
@@ -71,33 +74,38 @@ export class ClearingHouse {
71
74
  opts?: ConfirmOptions;
72
75
  accountSubscriber: ClearingHouseAccountSubscriber;
73
76
  eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
74
- isSubscribed = false;
77
+ _isSubscribed = false;
75
78
  txSender: TxSender;
76
79
 
80
+ public get isSubscribed() {
81
+ return this._isSubscribed && this.accountSubscriber.isSubscribed;
82
+ }
83
+
84
+ public set isSubscribed(val: boolean) {
85
+ this._isSubscribed = val;
86
+ }
87
+
88
+ /**
89
+ * @deprecated You should use the getClearingHouse factory method instead
90
+ * @param connection
91
+ * @param wallet
92
+ * @param clearingHouseProgramId
93
+ * @param opts
94
+ * @returns
95
+ */
77
96
  public static from(
78
97
  connection: Connection,
79
98
  wallet: IWallet,
80
99
  clearingHouseProgramId: PublicKey,
81
100
  opts: ConfirmOptions = Provider.defaultOptions()
82
101
  ): ClearingHouse {
83
- const provider = new Provider(connection, wallet, opts);
84
- const program = new Program(
85
- clearingHouseIDL as Idl,
86
- clearingHouseProgramId,
87
- provider
88
- );
89
- const accountSubscriber = new DefaultClearingHouseAccountSubscriber(
90
- program
91
- );
92
- const txSender = new DefaultTxSender(provider);
93
- return new ClearingHouse(
102
+ const config = getWebSocketClearingHouseConfig(
94
103
  connection,
95
104
  wallet,
96
- program,
97
- accountSubscriber,
98
- txSender,
105
+ clearingHouseProgramId,
99
106
  opts
100
107
  );
108
+ return getClearingHouse(config);
101
109
  }
102
110
 
103
111
  public constructor(
@@ -208,7 +216,7 @@ export class ClearingHouse {
208
216
  return this.accountSubscriber.getDepositHistoryAccount();
209
217
  }
210
218
 
211
- public getCurveHistoryAccount(): CurveHistoryAccount {
219
+ public getCurveHistoryAccount(): ExtendedCurveHistoryAccount {
212
220
  return this.accountSubscriber.getCurveHistoryAccount();
213
221
  }
214
222
 
@@ -335,16 +343,16 @@ export class ClearingHouse {
335
343
  async getInitializeUserOrdersInstruction(
336
344
  userAccountPublicKey?: PublicKey
337
345
  ): Promise<TransactionInstruction> {
346
+ if (!userAccountPublicKey) {
347
+ userAccountPublicKey = await this.getUserAccountPublicKey();
348
+ }
349
+
338
350
  const [userOrdersAccountPublicKey, userOrdersAccountNonce] =
339
351
  await getUserOrdersAccountPublicKeyAndNonce(
340
352
  this.program.programId,
341
- this.wallet.publicKey
353
+ userAccountPublicKey
342
354
  );
343
355
 
344
- if (!userAccountPublicKey) {
345
- userAccountPublicKey = await this.getUserAccountPublicKey();
346
- }
347
-
348
356
  return await this.program.instruction.initializeUserOrders(
349
357
  userOrdersAccountNonce,
350
358
  {
@@ -401,7 +409,7 @@ export class ClearingHouse {
401
409
 
402
410
  this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
403
411
  this.program.programId,
404
- this.wallet.publicKey
412
+ await this.getUserAccountPublicKey()
405
413
  );
406
414
  return this.userOrdersAccountPublicKey;
407
415
  }
@@ -765,6 +773,40 @@ export class ClearingHouse {
765
773
  });
766
774
  }
767
775
 
776
+ public async cancelOrderByUserId(
777
+ userOrderId: number
778
+ ): Promise<TransactionSignature> {
779
+ return await this.txSender.send(
780
+ wrapInTx(await this.getCancelOrderByUserIdIx(userOrderId)),
781
+ [],
782
+ this.opts
783
+ );
784
+ }
785
+
786
+ public async getCancelOrderByUserIdIx(
787
+ userOrderId: number
788
+ ): Promise<TransactionInstruction> {
789
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
790
+ const userAccount = await this.getUserAccount();
791
+
792
+ const state = this.getStateAccount();
793
+ const orderState = this.getOrderStateAccount();
794
+ return await this.program.instruction.cancelOrderByUserId(userOrderId, {
795
+ accounts: {
796
+ state: await this.getStatePublicKey(),
797
+ user: userAccountPublicKey,
798
+ authority: this.wallet.publicKey,
799
+ markets: state.markets,
800
+ userOrders: await this.getUserOrdersAccountPublicKey(),
801
+ userPositions: userAccount.positions,
802
+ fundingPaymentHistory: state.fundingPaymentHistory,
803
+ fundingRateHistory: state.fundingRateHistory,
804
+ orderState: await this.getOrderStatePublicKey(),
805
+ orderHistory: orderState.orderHistory,
806
+ },
807
+ });
808
+ }
809
+
768
810
  public async fillOrder(
769
811
  userAccountPublicKey: PublicKey,
770
812
  userOrdersAccountPublicKey: PublicKey,
@@ -823,6 +865,7 @@ export class ClearingHouse {
823
865
  fundingRateHistory: state.fundingRateHistory,
824
866
  orderState: await this.getOrderStatePublicKey(),
825
867
  orderHistory: orderState.orderHistory,
868
+ extendedCurveHistory: state.extendedCurveHistory,
826
869
  oracle: oracle,
827
870
  },
828
871
  remainingAccounts,
@@ -899,6 +942,7 @@ export class ClearingHouse {
899
942
  fundingRateHistory: state.fundingRateHistory,
900
943
  orderState: await this.getOrderStatePublicKey(),
901
944
  orderHistory: orderState.orderHistory,
945
+ extendedCurveHistory: state.extendedCurveHistory,
902
946
  oracle: priceOracle,
903
947
  },
904
948
  remainingAccounts,
@@ -24,7 +24,6 @@ import {
24
24
  PRICE_TO_QUOTE_PRECISION,
25
25
  } from './constants/numericConstants';
26
26
  import { UserAccountSubscriber, UserAccountEvents } from './accounts/types';
27
- import { DefaultUserAccountSubscriber } from './accounts/defaultUserAccountSubscriber';
28
27
  import {
29
28
  calculateMarkPrice,
30
29
  calculateBaseAssetValue,
@@ -36,6 +35,10 @@ import {
36
35
  calculateTradeSlippage,
37
36
  } from '.';
38
37
  import { getUserAccountPublicKey } from './addresses';
38
+ import {
39
+ getClearingHouseUser,
40
+ getWebSocketClearingHouseUserConfig,
41
+ } from './factory/clearingHouseUser';
39
42
 
40
43
  export class ClearingHouseUser {
41
44
  clearingHouse: ClearingHouse;
@@ -43,18 +46,35 @@ export class ClearingHouseUser {
43
46
  accountSubscriber: UserAccountSubscriber;
44
47
  userAccountPublicKey?: PublicKey;
45
48
  userOrdersAccountPublicKey?: PublicKey;
46
- isSubscribed = false;
49
+ _isSubscribed = false;
47
50
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
48
51
 
52
+ public get isSubscribed() {
53
+ return this._isSubscribed && this.accountSubscriber.isSubscribed;
54
+ }
55
+
56
+ public set isSubscribed(val: boolean) {
57
+ this._isSubscribed = val;
58
+ }
59
+
60
+ /**
61
+ * @deprecated You should use getClearingHouseUser factory method instead
62
+ * @param clearingHouse
63
+ * @param authority
64
+ * @returns
65
+ */
49
66
  public static from(
50
67
  clearingHouse: ClearingHouse,
51
68
  authority: PublicKey
52
69
  ): ClearingHouseUser {
53
- const accountSubscriber = new DefaultUserAccountSubscriber(
54
- clearingHouse.program,
70
+ if (clearingHouse.accountSubscriber.type !== 'websocket')
71
+ throw 'This method only works for clearing houses with a websocket account listener. Try using the getClearingHouseUser factory method to initialize a ClearingHouseUser instead';
72
+
73
+ const config = getWebSocketClearingHouseUserConfig(
74
+ clearingHouse,
55
75
  authority
56
76
  );
57
- return new ClearingHouseUser(clearingHouse, authority, accountSubscriber);
77
+ return getClearingHouseUser(config);
58
78
  }
59
79
 
60
80
  public constructor(
@@ -154,7 +174,7 @@ export class ClearingHouseUser {
154
174
 
155
175
  this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
156
176
  this.clearingHouse.program.programId,
157
- this.authority
177
+ await this.getUserAccountPublicKey()
158
178
  );
159
179
  return this.userOrdersAccountPublicKey;
160
180
  }
package/src/config.ts CHANGED
@@ -11,7 +11,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
11
11
  devnet: {
12
12
  ENV: 'devnet',
13
13
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
14
- CLEARING_HOUSE_PROGRAM_ID: 'HiZ8CnfEE9LrBZTfc8hBneWrPg1Cbsn8Wdy6SPLfae9V',
14
+ CLEARING_HOUSE_PROGRAM_ID: '8mKouB1uzsoMAhAu4qAXCiu8KAfwH7nonpuYfTM21Xg2',
15
15
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
16
16
  },
17
17
  'mainnet-beta': {
@@ -90,4 +90,20 @@ export const Markets: Market[] = [
90
90
  mainnetPythOracle: '3pyn4svBbxJ9Wnn3RVeafyLWfzie6yC5eTig2S62v9SC',
91
91
  launchTs: 1643084413000,
92
92
  },
93
+ {
94
+ symbol: 'ALGO-PERP',
95
+ baseAssetSymbol: 'ALGO',
96
+ marketIndex: new BN(10),
97
+ devnetPythOracle: 'c1A946dY5NHuVda77C8XXtXytyR3wK1SCP3eA9VRfC3',
98
+ mainnetPythOracle: 'HqFyq1wh1xKvL7KDqqT7NJeSPdAqsDqnmBisUC2XdXAX',
99
+ launchTs: 1643686767000,
100
+ },
101
+ // {
102
+ // symbol: 'mSOL-PERP',
103
+ // baseAssetSymbol: 'mSOL',
104
+ // marketIndex: new BN(11), //todo
105
+ // devnetPythOracle: '9a6RNx3tCu1TSs6TBSfV2XRXEPEZXQ6WB7jRojZRvyeZ',
106
+ // mainnetPythOracle: 'E4v1BBgoso9s64TQvmyownAVJbhbEPGyzA3qn4n46qj9',
107
+ // launchTs: 1643346125000,
108
+ // },
93
109
  ];