@drift-labs/sdk 0.2.0-master.25 → 0.2.0-master.27

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 (124) hide show
  1. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +14 -13
  2. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +30 -27
  3. package/lib/accounts/types.d.ts +9 -9
  4. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +15 -14
  5. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +38 -34
  6. package/lib/addresses/pda.d.ts +7 -6
  7. package/lib/addresses/pda.js +31 -27
  8. package/lib/admin.d.ts +13 -7
  9. package/lib/admin.js +111 -44
  10. package/lib/clearingHouse.d.ts +71 -42
  11. package/lib/clearingHouse.js +767 -278
  12. package/lib/clearingHouseConfig.d.ts +2 -2
  13. package/lib/clearingHouseUser.d.ts +24 -22
  14. package/lib/clearingHouseUser.js +273 -177
  15. package/lib/config.d.ts +7 -7
  16. package/lib/config.js +21 -21
  17. package/lib/constants/numericConstants.d.ts +12 -12
  18. package/lib/constants/numericConstants.js +13 -13
  19. package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
  20. package/lib/constants/{markets.js → perpMarkets.js} +4 -4
  21. package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
  22. package/lib/constants/{banks.js → spotMarkets.js} +16 -16
  23. package/lib/dlob/DLOB.d.ts +73 -0
  24. package/lib/dlob/DLOB.js +557 -0
  25. package/lib/dlob/DLOBNode.d.ts +52 -0
  26. package/lib/dlob/DLOBNode.js +82 -0
  27. package/lib/dlob/NodeList.d.ts +26 -0
  28. package/lib/dlob/NodeList.js +138 -0
  29. package/lib/events/types.d.ts +2 -1
  30. package/lib/events/types.js +1 -0
  31. package/lib/examples/makeTradeExample.js +7 -7
  32. package/lib/idl/clearing_house.json +1152 -503
  33. package/lib/index.d.ts +10 -3
  34. package/lib/index.js +10 -3
  35. package/lib/math/amm.d.ts +2 -2
  36. package/lib/math/amm.js +1 -1
  37. package/lib/math/funding.d.ts +6 -6
  38. package/lib/math/funding.js +2 -1
  39. package/lib/math/margin.d.ts +4 -4
  40. package/lib/math/margin.js +18 -11
  41. package/lib/math/market.d.ts +11 -10
  42. package/lib/math/market.js +30 -7
  43. package/lib/math/oracles.d.ts +2 -1
  44. package/lib/math/oracles.js +11 -1
  45. package/lib/math/orders.d.ts +6 -6
  46. package/lib/math/orders.js +31 -16
  47. package/lib/math/position.d.ts +13 -13
  48. package/lib/math/position.js +19 -19
  49. package/lib/math/spotBalance.d.ts +22 -0
  50. package/lib/math/spotBalance.js +193 -0
  51. package/lib/math/spotMarket.d.ts +4 -0
  52. package/lib/math/spotMarket.js +8 -0
  53. package/lib/math/spotPosition.d.ts +6 -0
  54. package/lib/math/spotPosition.js +23 -0
  55. package/lib/math/state.js +2 -2
  56. package/lib/math/trade.d.ts +4 -4
  57. package/lib/orderParams.d.ts +4 -4
  58. package/lib/orderParams.js +12 -4
  59. package/lib/serum/serumSubscriber.d.ts +23 -0
  60. package/lib/serum/serumSubscriber.js +41 -0
  61. package/lib/serum/types.d.ts +11 -0
  62. package/lib/serum/types.js +2 -0
  63. package/lib/tx/retryTxSender.d.ts +1 -1
  64. package/lib/tx/retryTxSender.js +4 -2
  65. package/lib/tx/types.d.ts +1 -1
  66. package/lib/types.d.ts +148 -57
  67. package/lib/types.js +39 -11
  68. package/lib/userMap/userMap.d.ts +25 -0
  69. package/lib/userMap/userMap.js +73 -0
  70. package/lib/userMap/userStatsMap.d.ts +19 -0
  71. package/lib/userMap/userStatsMap.js +68 -0
  72. package/package.json +6 -3
  73. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +42 -38
  74. package/src/accounts/types.ts +12 -9
  75. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +65 -52
  76. package/src/addresses/pda.ts +49 -44
  77. package/src/admin.ts +190 -55
  78. package/src/clearingHouse.ts +1092 -365
  79. package/src/clearingHouseConfig.ts +2 -2
  80. package/src/clearingHouseUser.ts +518 -255
  81. package/src/config.ts +30 -30
  82. package/src/constants/numericConstants.ts +17 -15
  83. package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
  84. package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
  85. package/src/dlob/DLOB.ts +884 -0
  86. package/src/dlob/DLOBNode.ts +163 -0
  87. package/src/dlob/NodeList.ts +185 -0
  88. package/src/events/types.ts +3 -0
  89. package/src/examples/makeTradeExample.js +152 -75
  90. package/src/examples/makeTradeExample.ts +10 -8
  91. package/src/idl/clearing_house.json +1152 -503
  92. package/src/index.ts +10 -3
  93. package/src/math/amm.ts +6 -3
  94. package/src/math/funding.ts +7 -7
  95. package/src/math/margin.ts +34 -23
  96. package/src/math/market.ts +72 -20
  97. package/src/math/oracles.ts +18 -1
  98. package/src/math/orders.ts +33 -25
  99. package/src/math/position.ts +31 -31
  100. package/src/math/spotBalance.ts +316 -0
  101. package/src/math/spotMarket.ts +9 -0
  102. package/src/math/spotPosition.ts +47 -0
  103. package/src/math/state.ts +2 -2
  104. package/src/math/trade.ts +4 -4
  105. package/src/orderParams.ts +16 -8
  106. package/src/serum/serumSubscriber.ts +80 -0
  107. package/src/serum/types.ts +13 -0
  108. package/src/tx/retryTxSender.ts +5 -2
  109. package/src/tx/types.ts +2 -1
  110. package/src/types.ts +135 -56
  111. package/src/userMap/userMap.ts +100 -0
  112. package/src/userMap/userStatsMap.ts +110 -0
  113. package/tests/bn/test.ts +2 -3
  114. package/tests/dlob/helpers.ts +322 -0
  115. package/tests/dlob/test.ts +2865 -0
  116. package/lib/math/bankBalance.d.ts +0 -15
  117. package/lib/math/bankBalance.js +0 -150
  118. package/src/constants/numericConstants.js +0 -41
  119. package/src/math/bankBalance.ts +0 -258
  120. package/src/math/oracles.js +0 -26
  121. package/src/math/state.js +0 -15
  122. package/src/orderParams.js +0 -20
  123. package/src/slot/SlotSubscriber.js +0 -39
  124. package/src/tokenFaucet.js +0 -189
@@ -0,0 +1,80 @@
1
+ import { Connection, PublicKey } from '@solana/web3.js';
2
+ import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
3
+ import { Market, Orderbook } from '@project-serum/serum';
4
+ import { SerumMarketSubscriberConfig } from './types';
5
+
6
+ export class SerumSubscriber {
7
+ connection: Connection;
8
+ programId: PublicKey;
9
+ marketAddress: PublicKey;
10
+ accountLoader: BulkAccountLoader;
11
+ market: Market;
12
+
13
+ subscribed: boolean;
14
+
15
+ asksAddress: PublicKey;
16
+ asks: Orderbook;
17
+ asksCallbackId: string;
18
+ lastAsksSlot: number;
19
+
20
+ bidsAddress: PublicKey;
21
+ bids: Orderbook;
22
+ bidsCallbackId: string;
23
+ lastBidsSlot: number;
24
+
25
+ public constructor(config: SerumMarketSubscriberConfig) {
26
+ this.connection = config.connection;
27
+ this.programId = config.programId;
28
+ this.marketAddress = config.marketAddress;
29
+ this.accountLoader = config.accountSubscription.accountLoader;
30
+ }
31
+
32
+ public async subscribe(): Promise<void> {
33
+ if (this.subscribed) {
34
+ return;
35
+ }
36
+
37
+ this.market = await Market.load(
38
+ this.connection,
39
+ this.marketAddress,
40
+ undefined,
41
+ this.programId
42
+ );
43
+
44
+ this.asksAddress = this.market.asksAddress;
45
+ this.asks = await this.market.loadAsks(this.connection);
46
+
47
+ this.asksCallbackId = this.accountLoader.addAccount(
48
+ this.asksAddress,
49
+ (buffer, slot) => {
50
+ this.lastAsksSlot = slot;
51
+ this.asks = Orderbook.decode(this.market, buffer);
52
+ console.log(this.asks.getL2(3));
53
+ }
54
+ );
55
+
56
+ this.bidsAddress = this.market.bidsAddress;
57
+ this.bids = await this.market.loadBids(this.connection);
58
+
59
+ this.bidsCallbackId = this.accountLoader.addAccount(
60
+ this.bidsAddress,
61
+ (buffer, slot) => {
62
+ this.lastBidsSlot = slot;
63
+ this.bids = Orderbook.decode(this.market, buffer);
64
+ }
65
+ );
66
+
67
+ this.subscribed = true;
68
+ }
69
+
70
+ public async unsubscribe(): Promise<void> {
71
+ if (!this.subscribed) {
72
+ return;
73
+ }
74
+
75
+ this.accountLoader.removeAccount(this.asksAddress, this.asksCallbackId);
76
+ this.accountLoader.removeAccount(this.bidsAddress, this.bidsCallbackId);
77
+
78
+ this.subscribed = false;
79
+ }
80
+ }
@@ -0,0 +1,13 @@
1
+ import { Connection, PublicKey } from '@solana/web3.js';
2
+ import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
3
+
4
+ export type SerumMarketSubscriberConfig = {
5
+ connection: Connection;
6
+ programId: PublicKey;
7
+ marketAddress: PublicKey;
8
+ accountSubscription: {
9
+ // enables use to add web sockets in the future
10
+ type: 'polling';
11
+ accountLoader: BulkAccountLoader;
12
+ };
13
+ };
@@ -42,7 +42,8 @@ export class RetryTxSender implements TxSender {
42
42
  async send(
43
43
  tx: Transaction,
44
44
  additionalSigners?: Array<Signer>,
45
- opts?: ConfirmOptions
45
+ opts?: ConfirmOptions,
46
+ preSigned?: boolean
46
47
  ): Promise<TxSigAndSlot> {
47
48
  if (additionalSigners === undefined) {
48
49
  additionalSigners = [];
@@ -51,7 +52,9 @@ export class RetryTxSender implements TxSender {
51
52
  opts = this.provider.opts;
52
53
  }
53
54
 
54
- await this.prepareTx(tx, additionalSigners, opts);
55
+ if (!preSigned) {
56
+ await this.prepareTx(tx, additionalSigners, opts);
57
+ }
55
58
 
56
59
  const rawTransaction = tx.serialize();
57
60
  const startTime = this.getTimestamp();
package/src/tx/types.ts CHANGED
@@ -17,6 +17,7 @@ export interface TxSender {
17
17
  send(
18
18
  tx: Transaction,
19
19
  additionalSigners?: Array<Signer>,
20
- opts?: ConfirmOptions
20
+ opts?: ConfirmOptions,
21
+ preSigned?: boolean
21
22
  ): Promise<TxSigAndSlot>;
22
23
  }
package/src/types.ts CHANGED
@@ -2,12 +2,25 @@ import { PublicKey, Transaction } from '@solana/web3.js';
2
2
  import { BN, ZERO } from '.';
3
3
 
4
4
  // # Utility Types / Enums / Constants
5
+
6
+ export class MarketStatus {
7
+ static readonly INITIALIZED = { initialized: {} };
8
+ static readonly REDUCEONLY = { reduceonly: {} };
9
+ static readonly SETTLEMENT = { settlement: {} };
10
+ static readonly DELISTED = { delisted: {} };
11
+ }
12
+
13
+ export class ContractType {
14
+ static readonly PERPETUAL = { perpetual: {} };
15
+ static readonly FUTURE = { future: {} };
16
+ }
17
+
5
18
  export class SwapDirection {
6
19
  static readonly ADD = { add: {} };
7
20
  static readonly REMOVE = { remove: {} };
8
21
  }
9
22
 
10
- export class BankBalanceType {
23
+ export class SpotBalanceType {
11
24
  static readonly DEPOSIT = { deposit: {} };
12
25
  static readonly BORROW = { borrow: {} };
13
26
  }
@@ -35,6 +48,12 @@ export class OrderType {
35
48
  static readonly MARKET = { market: {} };
36
49
  }
37
50
 
51
+ export declare type MarketTypeStr = 'perp' | 'spot';
52
+ export class MarketType {
53
+ static readonly SPOT = { spot: {} };
54
+ static readonly PERP = { perp: {} };
55
+ }
56
+
38
57
  export class OrderStatus {
39
58
  static readonly INIT = { init: {} };
40
59
  static readonly OPEN = { open: {} };
@@ -77,6 +96,15 @@ export class OrderTriggerCondition {
77
96
  static readonly BELOW = { below: {} };
78
97
  }
79
98
 
99
+ export class SpotFulfillmentType {
100
+ static readonly SERUM_v3 = { serumV3: {} };
101
+ }
102
+
103
+ export class SpotFulfillmentStatus {
104
+ static readonly ENABLED = { enabled: {} };
105
+ static readonly DISABLED = { disabled: {} };
106
+ }
107
+
80
108
  export function isVariant(object: unknown, type: string) {
81
109
  return object.hasOwnProperty(type);
82
110
  }
@@ -87,6 +115,10 @@ export function isOneOfVariant(object: unknown, types: string[]) {
87
115
  }, false);
88
116
  }
89
117
 
118
+ export function getVariant(object: unknown): string {
119
+ return Object.keys(object)[0];
120
+ }
121
+
90
122
  export enum TradeSide {
91
123
  None = 0,
92
124
  Buy = 1,
@@ -120,7 +152,7 @@ export type DepositRecord = {
120
152
  deposit?: any;
121
153
  withdraw?: any;
122
154
  };
123
- bankIndex: BN;
155
+ marketIndex: BN;
124
156
  amount: BN;
125
157
  oraclePrice: BN;
126
158
  referrer: PublicKey;
@@ -148,6 +180,19 @@ export type CurveRecord = {
148
180
  tradeId: BN;
149
181
  };
150
182
 
183
+ export declare type InsuranceFundRecord = {
184
+ ts: BN;
185
+ bankIndex: BN;
186
+ marketIndex: BN;
187
+ userIfFactor: BN;
188
+ totalIfFactor: BN;
189
+ vaultAmountBefore: BN;
190
+ insuranceVaultAmountBefore: BN;
191
+ amount: BN;
192
+ totalIfSharesBefore: BN;
193
+ totalIfSharesAfter: BN;
194
+ };
195
+
151
196
  export type LPRecord = {
152
197
  ts: BN;
153
198
  user: PublicKey;
@@ -202,6 +247,7 @@ export type LiquidationRecord = {
202
247
  marginRequirement: BN;
203
248
  totalCollateral: BN;
204
249
  liquidationId: number;
250
+ canceledOrderIds: BN[];
205
251
  liquidatePerp: LiquidatePerpRecord;
206
252
  liquidateBorrow: LiquidateBorrowRecord;
207
253
  liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
@@ -229,42 +275,42 @@ export class LiquidationType {
229
275
 
230
276
  export type LiquidatePerpRecord = {
231
277
  marketIndex: BN;
232
- orderIds: BN[];
233
278
  oraclePrice: BN;
234
279
  baseAssetAmount: BN;
235
280
  quoteAssetAmount: BN;
236
281
  lpShares: BN;
237
282
  userPnl: BN;
238
283
  liquidatorPnl: BN;
239
- canceledOrdersFee: BN;
240
284
  userOrderId: BN;
241
285
  liquidatorOrderId: BN;
242
286
  fillRecordId: BN;
287
+ ifFee: BN;
243
288
  };
244
289
 
245
290
  export type LiquidateBorrowRecord = {
246
- assetBankIndex: BN;
291
+ assetMarketIndex: BN;
247
292
  assetPrice: BN;
248
293
  assetTransfer: BN;
249
- liabilityBankIndex: BN;
294
+ liabilityMarketIndex: BN;
250
295
  liabilityPrice: BN;
251
296
  liabilityTransfer: BN;
297
+ ifFee: BN;
252
298
  };
253
299
 
254
300
  export type LiquidateBorrowForPerpPnlRecord = {
255
- marketIndex: BN;
301
+ perpMarketIndex: BN;
256
302
  marketOraclePrice: BN;
257
303
  pnlTransfer: BN;
258
- liabilityBankIndex: BN;
304
+ liabilityMarketIndex: BN;
259
305
  liabilityPrice: BN;
260
306
  liabilityTransfer: BN;
261
307
  };
262
308
 
263
309
  export type LiquidatePerpPnlForDepositRecord = {
264
- marketIndex: BN;
310
+ perpMarketIndex: BN;
265
311
  marketOraclePrice: BN;
266
312
  pnlTransfer: BN;
267
- assetBankIndex: BN;
313
+ assetMarketIndex: BN;
268
314
  assetPrice: BN;
269
315
  assetTransfer: BN;
270
316
  };
@@ -276,7 +322,7 @@ export type PerpBankruptcyRecord = {
276
322
  };
277
323
 
278
324
  export type BorrowBankruptcyRecord = {
279
- bankIndex: BN;
325
+ marketIndex: BN;
280
326
  borrowAmount: BN;
281
327
  cumulativeDepositInterestDelta: BN;
282
328
  };
@@ -288,7 +334,7 @@ export type SettlePnlRecord = {
288
334
  pnl: BN;
289
335
  baseAssetAmount: BN;
290
336
  quoteAssetAmountAfter: BN;
291
- quoteEntryamount: BN;
337
+ quoteEntryAmount: BN;
292
338
  settlePrice: BN;
293
339
  };
294
340
 
@@ -318,12 +364,14 @@ export type OrderActionRecord = {
318
364
  quoteAssetAmountSurplus: BN | null;
319
365
  taker: PublicKey | null;
320
366
  takerOrderId: BN | null;
367
+ takerOrderDirection: PositionDirection | null;
321
368
  takerOrderBaseAssetAmount: BN | null;
322
369
  takerOrderBaseAssetAmountFilled: BN | null;
323
370
  takerOrderQuoteAssetAmountFilled: BN | null;
324
371
  takerOrderFee: BN | null;
325
372
  maker: PublicKey | null;
326
373
  makerOrderId: BN | null;
374
+ makerOrderDirection: PositionDirection | null;
327
375
  makerOrderBaseAssetAmount: BN | null;
328
376
  makerOrderBaseAssetAmountFilled: BN | null;
329
377
  makerOrderQuoteAssetAmountFilled: BN | null;
@@ -337,18 +385,8 @@ export type StateAccount = {
337
385
  exchangePaused: boolean;
338
386
  adminControlsPrices: boolean;
339
387
  insuranceVault: PublicKey;
340
- marginRatioInitial: BN;
341
- marginRatioMaintenance: BN;
342
- marginRatioPartial: BN;
343
- partialLiquidationClosePercentageNumerator: BN;
344
- partialLiquidationClosePercentageDenominator: BN;
345
- partialLiquidationPenaltyPercentageNumerator: BN;
346
- partialLiquidationPenaltyPercentageDenominator: BN;
347
- fullLiquidationPenaltyPercentageNumerator: BN;
348
- fullLiquidationPenaltyPercentageDenominator: BN;
349
- partialLiquidationLiquidatorShareDenominator: BN;
350
- fullLiquidationLiquidatorShareDenominator: BN;
351
- feeStructure: FeeStructure;
388
+ perpFeeStructure: FeeStructure;
389
+ spotFeeStructure: FeeStructure;
352
390
  totalFee: BN;
353
391
  totalFeeWithdrawn: BN;
354
392
  whitelistMint: PublicKey;
@@ -356,16 +394,21 @@ export type StateAccount = {
356
394
  oracleGuardRails: OracleGuardRails;
357
395
  maxDeposit: BN;
358
396
  numberOfMarkets: BN;
359
- numberOfBanks: BN;
397
+ numberOfSpotMarkets: BN;
360
398
  minOrderQuoteAssetAmount: BN;
361
399
  signer: PublicKey;
362
400
  signerNonce: number;
363
- maxAuctionDuration: number;
364
- minAuctionDuration: number;
401
+ defaultMarketOrderTimeInForce: number;
402
+ minPerpAuctionDuration: number;
403
+ defaultSpotAuctionDuration: number;
404
+ liquidationMarginBufferRatio: number;
365
405
  };
366
406
 
367
- export type MarketAccount = {
368
- initialized: boolean;
407
+ export type PerpMarketAccount = {
408
+ status: MarketStatus;
409
+ contractType: ContractType;
410
+ expiryTs: BN;
411
+ settlementPrice: BN;
369
412
  marketIndex: BN;
370
413
  pubkey: PublicKey;
371
414
  amm: AMM;
@@ -377,15 +420,22 @@ export type MarketAccount = {
377
420
  marginRatioMaintenance: number;
378
421
  nextFillRecordId: BN;
379
422
  pnlPool: PoolBalance;
380
- liquidationFee: BN;
423
+ liquidatorFee: BN;
424
+ ifLiquidationFee: BN;
381
425
  imfFactor: BN;
382
426
  unrealizedImfFactor: BN;
427
+ unrealizedMaxImbalance: BN;
383
428
  unrealizedInitialAssetWeight: number;
384
429
  unrealizedMaintenanceAssetWeight: number;
430
+ revenueWithdrawSinceLastSettle: BN;
431
+ maxRevenueWithdrawPerPeriod: BN;
432
+ lastRevenueWithdrawTs: BN;
433
+ quoteSettledInsurance: BN;
434
+ quoteMaxInsurance: BN;
385
435
  };
386
436
 
387
- export type BankAccount = {
388
- bankIndex: BN;
437
+ export type SpotMarketAccount = {
438
+ marketIndex: BN;
389
439
  pubkey: PublicKey;
390
440
  mint: PublicKey;
391
441
  vault: PublicKey;
@@ -399,7 +449,7 @@ export type BankAccount = {
399
449
 
400
450
  userIfFactor: BN;
401
451
  totalIfFactor: BN;
402
- liquidationIfFactor: BN;
452
+ ifLiquidationFee: BN;
403
453
 
404
454
  decimals: number;
405
455
  optimalUtilization: BN;
@@ -416,13 +466,20 @@ export type BankAccount = {
416
466
  maintenanceAssetWeight: BN;
417
467
  initialLiabilityWeight: BN;
418
468
  maintenanceLiabilityWeight: BN;
419
- liquidationFee: BN;
469
+ liquidatorFee: BN;
420
470
  imfFactor: BN;
421
471
 
422
472
  withdrawGuardThreshold: BN;
423
473
  depositTokenTwap: BN;
424
474
  borrowTokenTwap: BN;
425
475
  utilizationTwap: BN;
476
+
477
+ orderStepSize: BN;
478
+ nextFillRecordId: BN;
479
+ spotFeePool: {
480
+ balance: BN;
481
+ };
482
+ totalSpotFee: BN;
426
483
  };
427
484
 
428
485
  export type PoolBalance = {
@@ -477,21 +534,24 @@ export type AMM = {
477
534
  totalMmFee: BN;
478
535
  netRevenueSinceLastFunding: BN;
479
536
  lastUpdateSlot: BN;
537
+ lastOracleValid: boolean;
480
538
  lastBidPriceTwap: BN;
481
539
  lastAskPriceTwap: BN;
482
540
  longSpread: BN;
483
541
  shortSpread: BN;
484
542
  maxSpread: number;
485
- marketPosition: UserPosition;
486
- marketPositionPerLp: UserPosition;
543
+ marketPosition: PerpPosition;
544
+ marketPositionPerLp: PerpPosition;
487
545
  ammJitIntensity: number;
488
546
  maxBaseAssetReserve: BN;
489
547
  minBaseAssetReserve: BN;
548
+ cumulativeSocialLoss: BN;
490
549
  };
491
550
 
492
551
  // # User Account Types
493
- export type UserPosition = {
552
+ export type PerpPosition = {
494
553
  baseAssetAmount: BN;
554
+ remainderBaseAssetAmount: BN;
495
555
  lastCumulativeFundingRate: BN;
496
556
  marketIndex: BN;
497
557
  quoteAssetAmount: BN;
@@ -531,24 +591,29 @@ export type UserAccount = {
531
591
  authority: PublicKey;
532
592
  name: number[];
533
593
  userId: number;
534
- bankBalances: UserBankBalance[];
535
- positions: UserPosition[];
594
+ spotPositions: SpotPosition[];
595
+ perpPositions: PerpPosition[];
536
596
  orders: Order[];
537
597
  beingLiquidated: boolean;
538
598
  bankrupt: boolean;
539
599
  nextLiquidationId: number;
540
600
  nextOrderId: BN;
601
+ customMarginRatio: number;
541
602
  };
542
603
 
543
- export type UserBankBalance = {
544
- bankIndex: BN;
545
- balanceType: BankBalanceType;
604
+ export type SpotPosition = {
605
+ marketIndex: BN;
606
+ balanceType: SpotBalanceType;
546
607
  balance: BN;
608
+ openOrders: number;
609
+ openBids: BN;
610
+ openAsks: BN;
547
611
  };
548
612
 
549
613
  export type Order = {
550
614
  status: OrderStatus;
551
615
  orderType: OrderType;
616
+ marketType: MarketType;
552
617
  ts: BN;
553
618
  slot: BN;
554
619
  orderId: BN;
@@ -572,10 +637,12 @@ export type Order = {
572
637
  auctionDuration: number;
573
638
  auctionStartPrice: BN;
574
639
  auctionEndPrice: BN;
640
+ timeInForce: number;
575
641
  };
576
642
 
577
643
  export type OrderParams = {
578
644
  orderType: OrderType;
645
+ marketType: MarketType;
579
646
  userOrderId: number;
580
647
  direction: PositionDirection;
581
648
  baseAssetAmount: BN;
@@ -588,12 +655,9 @@ export type OrderParams = {
588
655
  triggerCondition: OrderTriggerCondition;
589
656
  positionLimit: BN;
590
657
  oraclePriceOffset: BN;
591
- padding0: boolean;
592
- padding1: BN;
593
- optionalAccounts: {
594
- discountToken: boolean;
595
- referrer: boolean;
596
- };
658
+ auctionDuration: number | null;
659
+ timeInForce: number | null;
660
+ auctionStartPrice: BN | null;
597
661
  };
598
662
 
599
663
  export type NecessaryOrderParams = {
@@ -609,6 +673,7 @@ export type OptionalOrderParams = {
609
673
 
610
674
  export const DefaultOrderParams = {
611
675
  orderType: OrderType.MARKET,
676
+ marketType: MarketType.PERP,
612
677
  userOrderId: 0,
613
678
  direction: PositionDirection.LONG,
614
679
  baseAssetAmount: ZERO,
@@ -621,12 +686,9 @@ export const DefaultOrderParams = {
621
686
  triggerCondition: OrderTriggerCondition.ABOVE,
622
687
  positionLimit: ZERO,
623
688
  oraclePriceOffset: ZERO,
624
- padding0: ZERO,
625
- padding1: ZERO,
626
- optionalAccounts: {
627
- discountToken: false,
628
- referrer: false,
629
- },
689
+ auctionDuration: null,
690
+ timeInForce: null,
691
+ auctionStartPrice: null,
630
692
  };
631
693
 
632
694
  export type MakerInfo = {
@@ -688,7 +750,7 @@ export type FeeStructure = {
688
750
  makerRebateNumerator: BN;
689
751
  makerRebateDenominator: BN;
690
752
  fillerRewardStructure: OrderFillerRewardStructure;
691
- cancelOrderFee: BN;
753
+ flatFillerFee: BN;
692
754
  };
693
755
 
694
756
  export type OracleGuardRails = {
@@ -713,7 +775,7 @@ export type OrderFillerRewardStructure = {
713
775
  export type MarginCategory = 'Initial' | 'Maintenance';
714
776
 
715
777
  export type InsuranceFundStake = {
716
- bankIndex: BN;
778
+ marketIndex: BN;
717
779
  authority: PublicKey;
718
780
 
719
781
  ifShares: BN;
@@ -723,3 +785,20 @@ export type InsuranceFundStake = {
723
785
  lastWithdrawRequestValue: BN;
724
786
  lastWithdrawRequestTs: BN;
725
787
  };
788
+
789
+ export type SerumV3FulfillmentConfigAccount = {
790
+ fulfillmentType: SpotFulfillmentType;
791
+ status: SpotFulfillmentStatus;
792
+ pubkey: PublicKey;
793
+ marketIndex: BN;
794
+ serumProgramId: PublicKey;
795
+ serumMarket: PublicKey;
796
+ serumRequestQueue: PublicKey;
797
+ serumEventQueue: PublicKey;
798
+ serumBids: PublicKey;
799
+ serumAsks: PublicKey;
800
+ serumBaseVault: PublicKey;
801
+ serumQuoteVault: PublicKey;
802
+ serumOpenOrders: PublicKey;
803
+ serumSignerNonce: BN;
804
+ };
@@ -0,0 +1,100 @@
1
+ import {
2
+ ClearingHouseUser,
3
+ ClearingHouse,
4
+ UserAccount,
5
+ bulkPollingUserSubscribe,
6
+ OrderRecord,
7
+ ClearingHouseUserAccountSubscriptionConfig,
8
+ } from '..';
9
+ import { ProgramAccount } from '@project-serum/anchor';
10
+
11
+ import { PublicKey } from '@solana/web3.js';
12
+
13
+ export class UserMap {
14
+ private userMap = new Map<string, ClearingHouseUser>();
15
+ private clearingHouse: ClearingHouse;
16
+ private accountSubscription: ClearingHouseUserAccountSubscriptionConfig;
17
+
18
+ constructor(
19
+ clearingHouse: ClearingHouse,
20
+ accountSubscription: ClearingHouseUserAccountSubscriptionConfig
21
+ ) {
22
+ this.clearingHouse = clearingHouse;
23
+ this.accountSubscription = accountSubscription;
24
+ }
25
+
26
+ public async fetchAllUsers() {
27
+ const userArray: ClearingHouseUser[] = [];
28
+
29
+ const programUserAccounts =
30
+ (await this.clearingHouse.program.account.user.all()) as ProgramAccount<UserAccount>[];
31
+ for (const programUserAccount of programUserAccounts) {
32
+ if (this.userMap.has(programUserAccount.publicKey.toString())) {
33
+ continue;
34
+ }
35
+
36
+ const user = new ClearingHouseUser({
37
+ clearingHouse: this.clearingHouse,
38
+ userAccountPublicKey: programUserAccount.publicKey,
39
+ accountSubscription: this.accountSubscription,
40
+ });
41
+ userArray.push(user);
42
+ }
43
+
44
+ if (this.accountSubscription.type === 'polling') {
45
+ await bulkPollingUserSubscribe(
46
+ userArray,
47
+ this.accountSubscription.accountLoader
48
+ );
49
+ }
50
+
51
+ for (const user of userArray) {
52
+ this.userMap.set(user.getUserAccountPublicKey().toString(), user);
53
+ }
54
+ }
55
+
56
+ public async addPubkey(userAccountPublicKey: PublicKey) {
57
+ const user = new ClearingHouseUser({
58
+ clearingHouse: this.clearingHouse,
59
+ userAccountPublicKey,
60
+ accountSubscription: this.accountSubscription,
61
+ });
62
+ await user.subscribe();
63
+ this.userMap.set(userAccountPublicKey.toString(), user);
64
+ }
65
+
66
+ public has(key: string): boolean {
67
+ return this.userMap.has(key);
68
+ }
69
+
70
+ /**
71
+ * gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, undefined is returned
72
+ * @param key userAccountPublicKey to get ClearngHouseUserFor
73
+ * @returns user ClearingHouseUser | undefined
74
+ */
75
+ public get(key: string): ClearingHouseUser | undefined {
76
+ return this.userMap.get(key);
77
+ }
78
+
79
+ /**
80
+ * gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, new one is created
81
+ * @param key userAccountPublicKey to get ClearngHouseUserFor
82
+ * @returns ClearingHouseUser
83
+ */
84
+ public async mustGet(key: string): Promise<ClearingHouseUser> {
85
+ if (!this.has(key)) {
86
+ await this.addPubkey(new PublicKey(key));
87
+ }
88
+ const user = this.userMap.get(key);
89
+ await user.fetchAccounts();
90
+ return user;
91
+ }
92
+
93
+ public async updateWithOrderRecord(record: OrderRecord) {
94
+ await this.addPubkey(record.user);
95
+ }
96
+
97
+ public values(): IterableIterator<ClearingHouseUser> {
98
+ return this.userMap.values();
99
+ }
100
+ }