@drift-labs/sdk 0.1.36-master.5 → 0.2.0-master.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 (197) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +7 -6
  2. package/lib/accounts/bulkAccountLoader.js +83 -93
  3. package/lib/accounts/bulkUserSubscription.js +13 -57
  4. package/lib/accounts/fetch.d.ts +4 -0
  5. package/lib/accounts/fetch.js +18 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
  8. package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
  9. package/lib/accounts/pollingOracleSubscriber.js +37 -49
  10. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  11. package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
  12. package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
  13. package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
  14. package/lib/accounts/types.d.ts +34 -41
  15. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
  16. package/lib/accounts/webSocketAccountSubscriber.js +39 -35
  17. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
  18. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
  19. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
  20. package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
  21. package/lib/addresses/marketAddresses.d.ts +4 -0
  22. package/lib/addresses/marketAddresses.js +15 -0
  23. package/lib/addresses/pda.d.ts +12 -0
  24. package/lib/addresses/pda.js +83 -0
  25. package/lib/admin.d.ts +8 -12
  26. package/lib/admin.js +366 -490
  27. package/lib/clearingHouse.d.ts +84 -103
  28. package/lib/clearingHouse.js +779 -810
  29. package/lib/clearingHouseConfig.d.ts +34 -0
  30. package/lib/clearingHouseConfig.js +2 -0
  31. package/lib/clearingHouseUser.d.ts +19 -18
  32. package/lib/clearingHouseUser.js +157 -115
  33. package/lib/clearingHouseUserConfig.d.ts +14 -0
  34. package/lib/clearingHouseUserConfig.js +2 -0
  35. package/lib/config.d.ts +12 -0
  36. package/lib/config.js +35 -4
  37. package/lib/constants/banks.d.ts +16 -0
  38. package/lib/constants/banks.js +34 -0
  39. package/lib/constants/markets.d.ts +8 -3
  40. package/lib/constants/markets.js +13 -206
  41. package/lib/constants/numericConstants.d.ts +16 -0
  42. package/lib/constants/numericConstants.js +22 -6
  43. package/lib/events/eventList.d.ts +22 -0
  44. package/lib/events/eventList.js +77 -0
  45. package/lib/events/eventSubscriber.d.ts +34 -0
  46. package/lib/events/eventSubscriber.js +126 -0
  47. package/lib/events/fetchLogs.d.ts +13 -0
  48. package/lib/events/fetchLogs.js +39 -0
  49. package/lib/events/pollingLogProvider.d.ts +15 -0
  50. package/lib/events/pollingLogProvider.js +53 -0
  51. package/lib/events/sort.d.ts +2 -0
  52. package/lib/events/sort.js +44 -0
  53. package/lib/events/txEventCache.d.ts +24 -0
  54. package/lib/events/txEventCache.js +71 -0
  55. package/lib/events/types.d.ts +49 -0
  56. package/lib/events/types.js +20 -0
  57. package/lib/events/webSocketLogProvider.d.ts +12 -0
  58. package/lib/events/webSocketLogProvider.js +30 -0
  59. package/lib/examples/makeTradeExample.js +26 -27
  60. package/lib/factory/bigNum.d.ts +112 -0
  61. package/lib/factory/bigNum.js +356 -0
  62. package/lib/factory/oracleClient.d.ts +1 -2
  63. package/lib/factory/oracleClient.js +6 -2
  64. package/lib/idl/clearing_house.json +1739 -2287
  65. package/lib/index.d.ts +13 -4
  66. package/lib/index.js +13 -4
  67. package/lib/math/amm.d.ts +19 -29
  68. package/lib/math/amm.js +129 -179
  69. package/lib/math/auction.d.ts +5 -0
  70. package/lib/math/auction.js +39 -0
  71. package/lib/math/bankBalance.d.ts +9 -0
  72. package/lib/math/bankBalance.js +75 -0
  73. package/lib/math/conversion.d.ts +0 -1
  74. package/lib/math/conversion.js +1 -5
  75. package/lib/math/funding.d.ts +6 -6
  76. package/lib/math/funding.js +158 -175
  77. package/lib/math/market.d.ts +6 -6
  78. package/lib/math/market.js +10 -9
  79. package/lib/math/oracles.d.ts +3 -0
  80. package/lib/math/oracles.js +26 -0
  81. package/lib/math/orders.d.ts +5 -0
  82. package/lib/math/orders.js +31 -1
  83. package/lib/math/position.d.ts +7 -4
  84. package/lib/math/position.js +27 -9
  85. package/lib/math/repeg.d.ts +22 -0
  86. package/lib/math/repeg.js +128 -0
  87. package/lib/math/trade.d.ts +13 -8
  88. package/lib/math/trade.js +85 -22
  89. package/lib/mockUSDCFaucet.js +87 -116
  90. package/lib/oracles/oracleClientCache.d.ts +8 -0
  91. package/lib/oracles/oracleClientCache.js +19 -0
  92. package/lib/oracles/pythClient.d.ts +3 -5
  93. package/lib/oracles/pythClient.js +12 -30
  94. package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
  95. package/lib/oracles/quoteAssetOracleClient.js +21 -0
  96. package/lib/oracles/switchboardClient.d.ts +3 -5
  97. package/lib/oracles/switchboardClient.js +29 -47
  98. package/lib/oracles/types.d.ts +7 -1
  99. package/lib/orders.d.ts +6 -6
  100. package/lib/orders.js +10 -9
  101. package/lib/slot/SlotSubscriber.d.ts +12 -0
  102. package/lib/slot/SlotSubscriber.js +23 -0
  103. package/lib/tx/retryTxSender.d.ts +2 -2
  104. package/lib/tx/retryTxSender.js +108 -123
  105. package/lib/tx/types.d.ts +5 -1
  106. package/lib/tx/utils.d.ts +1 -1
  107. package/lib/tx/utils.js +11 -2
  108. package/lib/types.d.ts +105 -98
  109. package/lib/types.js +13 -1
  110. package/lib/userName.d.ts +4 -0
  111. package/lib/userName.js +20 -0
  112. package/lib/util/computeUnits.js +10 -21
  113. package/lib/util/tps.js +11 -22
  114. package/lib/wallet.js +7 -20
  115. package/package.json +10 -3
  116. package/src/accounts/bulkAccountLoader.ts +26 -15
  117. package/src/accounts/bulkUserSubscription.ts +1 -45
  118. package/src/accounts/fetch.ts +33 -0
  119. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
  120. package/src/accounts/pollingOracleSubscriber.ts +16 -8
  121. package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
  122. package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
  123. package/src/accounts/types.ts +41 -70
  124. package/src/accounts/webSocketAccountSubscriber.ts +33 -16
  125. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
  126. package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
  127. package/src/addresses/marketAddresses.ts +18 -0
  128. package/src/addresses/pda.ts +118 -0
  129. package/src/admin.ts +209 -267
  130. package/src/clearingHouse.ts +921 -829
  131. package/src/clearingHouseConfig.ts +37 -0
  132. package/src/clearingHouseUser.ts +280 -127
  133. package/src/clearingHouseUserConfig.ts +18 -0
  134. package/src/config.ts +54 -1
  135. package/src/constants/banks.ts +43 -0
  136. package/src/constants/markets.ts +16 -207
  137. package/src/constants/numericConstants.ts +33 -5
  138. package/src/events/eventList.ts +94 -0
  139. package/src/events/eventSubscriber.ts +194 -0
  140. package/src/events/fetchLogs.ts +80 -0
  141. package/src/events/pollingLogProvider.ts +79 -0
  142. package/src/events/sort.ts +65 -0
  143. package/src/events/txEventCache.ts +74 -0
  144. package/src/events/types.ts +98 -0
  145. package/src/events/webSocketLogProvider.ts +38 -0
  146. package/src/examples/makeTradeExample.ts +20 -11
  147. package/src/factory/bigNum.ts +507 -0
  148. package/src/factory/oracleClient.ts +7 -4
  149. package/src/idl/clearing_house.json +1739 -2287
  150. package/src/index.ts +13 -4
  151. package/src/math/amm.ts +229 -245
  152. package/src/math/auction.ts +39 -0
  153. package/src/math/bankBalance.ts +112 -0
  154. package/src/math/conversion.ts +1 -11
  155. package/src/math/funding.ts +12 -9
  156. package/src/math/market.ts +37 -30
  157. package/src/math/oracles.ts +36 -0
  158. package/src/math/orders.ts +38 -0
  159. package/src/math/position.ts +48 -13
  160. package/src/math/repeg.ts +175 -0
  161. package/src/math/trade.ts +114 -36
  162. package/src/math/utils.js +27 -0
  163. package/src/math/utils.js.map +1 -0
  164. package/src/oracles/oracleClientCache.ts +20 -0
  165. package/src/oracles/pythClient.ts +5 -11
  166. package/src/oracles/quoteAssetOracleClient.ts +25 -0
  167. package/src/oracles/switchboardClient.ts +16 -24
  168. package/src/oracles/types.ts +8 -1
  169. package/src/orders.ts +35 -20
  170. package/src/slot/SlotSubscriber.ts +32 -0
  171. package/src/tx/retryTxSender.ts +6 -4
  172. package/src/tx/types.ts +6 -1
  173. package/src/tx/utils.ts +22 -3
  174. package/src/types.ts +108 -110
  175. package/src/userName.ts +20 -0
  176. package/src/util/computeUnits.js +17 -0
  177. package/src/util/computeUnits.js.map +1 -0
  178. package/tests/bn/test.ts +255 -0
  179. package/tsconfig.json +12 -12
  180. package/lib/addresses.d.ts +0 -9
  181. package/lib/addresses.js +0 -87
  182. package/lib/constants/accounts.d.ts +0 -15
  183. package/lib/constants/accounts.js +0 -18
  184. package/lib/factory/clearingHouse.d.ts +0 -35
  185. package/lib/factory/clearingHouse.js +0 -81
  186. package/lib/factory/clearingHouseUser.d.ts +0 -19
  187. package/lib/factory/clearingHouseUser.js +0 -34
  188. package/lib/math/insuranceFund.d.ts +0 -15
  189. package/lib/math/insuranceFund.js +0 -33
  190. package/lib/tx/defaultTxSender.d.ts +0 -8
  191. package/lib/tx/defaultTxSender.js +0 -12
  192. package/src/addresses.ts +0 -71
  193. package/src/constants/accounts.ts +0 -26
  194. package/src/factory/clearingHouse.ts +0 -173
  195. package/src/factory/clearingHouseUser.ts +0 -73
  196. package/src/math/insuranceFund.ts +0 -29
  197. package/src/tx/defaultTxSender.ts +0 -24
@@ -1,39 +1,27 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.WebSocketAccountSubscriber = void 0;
13
4
  const utils_1 = require("./utils");
14
5
  class WebSocketAccountSubscriber {
15
- constructor(accountName, program, accountPublicKey) {
6
+ constructor(accountName, program, accountPublicKey, decodeBuffer) {
16
7
  this.accountName = accountName;
17
8
  this.program = program;
18
9
  this.accountPublicKey = accountPublicKey;
10
+ this.decodeBufferFn = decodeBuffer;
19
11
  }
20
- subscribe(onChange) {
21
- return __awaiter(this, void 0, void 0, function* () {
22
- if (this.listenerId) {
23
- return;
24
- }
25
- this.onChange = onChange;
26
- yield this.fetch();
27
- this.listenerId = this.program.provider.connection.onAccountChange(this.accountPublicKey, (accountInfo, context) => {
28
- this.handleRpcResponse(context, accountInfo);
29
- }, this.program.provider.opts.commitment);
30
- });
12
+ async subscribe(onChange) {
13
+ if (this.listenerId) {
14
+ return;
15
+ }
16
+ this.onChange = onChange;
17
+ await this.fetch();
18
+ this.listenerId = this.program.provider.connection.onAccountChange(this.accountPublicKey, (accountInfo, context) => {
19
+ this.handleRpcResponse(context, accountInfo);
20
+ }, this.program.provider.opts.commitment);
31
21
  }
32
- fetch() {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- const rpcResponse = yield this.program.provider.connection.getAccountInfoAndContext(this.accountPublicKey, this.program.provider.opts.commitment);
35
- this.handleRpcResponse(rpcResponse.context, rpcResponse === null || rpcResponse === void 0 ? void 0 : rpcResponse.value);
36
- });
22
+ async fetch() {
23
+ const rpcResponse = await this.program.provider.connection.getAccountInfoAndContext(this.accountPublicKey, this.program.provider.opts.commitment);
24
+ this.handleRpcResponse(rpcResponse.context, rpcResponse === null || rpcResponse === void 0 ? void 0 : rpcResponse.value);
37
25
  }
38
26
  handleRpcResponse(context, accountInfo) {
39
27
  const newSlot = context.slot;
@@ -41,28 +29,44 @@ class WebSocketAccountSubscriber {
41
29
  if (accountInfo) {
42
30
  newBuffer = accountInfo.data;
43
31
  }
44
- if (!this.accountData) {
45
- this.accountData = {
32
+ if (!this.bufferAndSlot) {
33
+ this.bufferAndSlot = {
46
34
  buffer: newBuffer,
47
35
  slot: newSlot,
48
36
  };
49
37
  if (newBuffer) {
50
- this.data = this.program.account[this.accountName].coder.accounts.decode((0, utils_1.capitalize)(this.accountName), newBuffer);
51
- this.onChange(this.data);
38
+ const account = this.decodeBuffer(newBuffer);
39
+ this.dataAndSlot = {
40
+ data: account,
41
+ slot: newSlot,
42
+ };
43
+ this.onChange(account);
52
44
  }
53
45
  return;
54
46
  }
55
- if (newSlot <= this.accountData.slot) {
47
+ if (newSlot <= this.bufferAndSlot.slot) {
56
48
  return;
57
49
  }
58
- const oldBuffer = this.accountData.buffer;
50
+ const oldBuffer = this.bufferAndSlot.buffer;
59
51
  if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
60
- this.accountData = {
52
+ this.bufferAndSlot = {
61
53
  buffer: newBuffer,
62
54
  slot: newSlot,
63
55
  };
64
- this.data = this.program.account[this.accountName].coder.accounts.decode((0, utils_1.capitalize)(this.accountName), newBuffer);
65
- this.onChange(this.data);
56
+ const account = this.decodeBuffer(newBuffer);
57
+ this.dataAndSlot = {
58
+ data: account,
59
+ slot: newSlot,
60
+ };
61
+ this.onChange(account);
62
+ }
63
+ }
64
+ decodeBuffer(buffer) {
65
+ if (this.decodeBufferFn) {
66
+ return this.decodeBufferFn(buffer);
67
+ }
68
+ else {
69
+ return this.program.account[this.accountName].coder.accounts.decode((0, utils_1.capitalize)(this.accountName), buffer);
66
70
  }
67
71
  }
68
72
  unsubscribe() {
@@ -1,44 +1,49 @@
1
+ /// <reference types="bn.js" />
1
2
  /// <reference types="node" />
2
- import { ClearingHouseAccountSubscriber, ClearingHouseAccountEvents, ClearingHouseAccountTypes } from './types';
3
+ import { ClearingHouseAccountSubscriber, ClearingHouseAccountEvents, DataAndSlot } from './types';
3
4
  import { AccountSubscriber } from './types';
4
- import { DepositHistoryAccount, ExtendedCurveHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, LiquidationHistoryAccount, MarketsAccount, OrderHistoryAccount, OrderStateAccount, StateAccount, TradeHistoryAccount } from '../types';
5
- import { Program } from '@project-serum/anchor';
5
+ import { BankAccount, MarketAccount, StateAccount } from '../types';
6
+ import { BN, Program } from '@project-serum/anchor';
6
7
  import StrictEventEmitter from 'strict-event-emitter-types';
7
8
  import { EventEmitter } from 'events';
8
- import { ClearingHouseConfigType } from '../factory/clearingHouse';
9
+ import { PublicKey } from '@solana/web3.js';
10
+ import { OracleInfo, OraclePriceData } from '../oracles/types';
11
+ import { OracleClientCache } from '../oracles/oracleClientCache';
9
12
  export declare class WebSocketClearingHouseAccountSubscriber implements ClearingHouseAccountSubscriber {
10
13
  isSubscribed: boolean;
11
14
  program: Program;
15
+ marketIndexes: BN[];
16
+ bankIndexes: BN[];
17
+ oracleInfos: OracleInfo[];
18
+ oracleClientCache: OracleClientCache;
12
19
  eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
13
20
  stateAccountSubscriber?: AccountSubscriber<StateAccount>;
14
- marketsAccountSubscriber?: AccountSubscriber<MarketsAccount>;
15
- tradeHistoryAccountSubscriber?: AccountSubscriber<TradeHistoryAccount>;
16
- depositHistoryAccountSubscriber?: AccountSubscriber<DepositHistoryAccount>;
17
- fundingPaymentHistoryAccountSubscriber?: AccountSubscriber<FundingPaymentHistoryAccount>;
18
- fundingRateHistoryAccountSubscriber?: AccountSubscriber<FundingRateHistoryAccount>;
19
- curveHistoryAccountSubscriber?: AccountSubscriber<ExtendedCurveHistoryAccount>;
20
- liquidationHistoryAccountSubscriber?: AccountSubscriber<LiquidationHistoryAccount>;
21
- orderStateAccountSubscriber?: AccountSubscriber<OrderStateAccount>;
22
- orderHistoryAccountSubscriber?: AccountSubscriber<OrderHistoryAccount>;
23
- optionalExtraSubscriptions: ClearingHouseAccountTypes[];
24
- type: ClearingHouseConfigType;
21
+ marketAccountSubscribers: Map<number, AccountSubscriber<MarketAccount>>;
22
+ bankAccountSubscribers: Map<number, AccountSubscriber<BankAccount>>;
23
+ oracleSubscribers: Map<string, AccountSubscriber<OraclePriceData>>;
25
24
  private isSubscribing;
26
25
  private subscriptionPromise;
27
26
  private subscriptionPromiseResolver;
28
- constructor(program: Program);
29
- subscribe(optionalSubscriptions?: ClearingHouseAccountTypes[]): Promise<boolean>;
27
+ constructor(program: Program, marketIndexes: BN[], bankIndexes: BN[], oracleInfos: OracleInfo[]);
28
+ subscribe(): Promise<boolean>;
29
+ subscribeToMarketAccounts(): Promise<boolean>;
30
+ subscribeToMarketAccount(marketIndex: BN): Promise<boolean>;
31
+ subscribeToBankAccounts(): Promise<boolean>;
32
+ subscribeToBankAccount(bankIndex: BN): Promise<boolean>;
33
+ subscribeToOracles(): Promise<boolean>;
34
+ subscribeToOracle(oracleInfo: OracleInfo): Promise<boolean>;
35
+ unsubscribeFromMarketAccounts(): Promise<void>;
36
+ unsubscribeFromBankAccounts(): Promise<void>;
37
+ unsubscribeFromOracles(): Promise<void>;
30
38
  fetch(): Promise<void>;
31
39
  unsubscribe(): Promise<void>;
40
+ addBank(bankIndex: BN): Promise<boolean>;
41
+ addMarket(marketIndex: BN): Promise<boolean>;
42
+ addOracle(oracleInfo: OracleInfo): Promise<boolean>;
32
43
  assertIsSubscribed(): void;
33
- assertOptionalIsSubscribed(optionalSubscription: ClearingHouseAccountTypes): void;
34
- getStateAccount(): StateAccount;
35
- getMarketsAccount(): MarketsAccount;
36
- getTradeHistoryAccount(): TradeHistoryAccount;
37
- getDepositHistoryAccount(): DepositHistoryAccount;
38
- getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
39
- getFundingRateHistoryAccount(): FundingRateHistoryAccount;
40
- getCurveHistoryAccount(): ExtendedCurveHistoryAccount;
41
- getLiquidationHistoryAccount(): LiquidationHistoryAccount;
42
- getOrderHistoryAccount(): OrderHistoryAccount;
43
- getOrderStateAccount(): OrderStateAccount;
44
+ getStateAccountAndSlot(): DataAndSlot<StateAccount>;
45
+ getMarketAccountAndSlot(marketIndex: BN): DataAndSlot<MarketAccount> | undefined;
46
+ getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[];
47
+ getBankAccountAndSlot(bankIndex: BN): DataAndSlot<BankAccount> | undefined;
48
+ getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
44
49
  }
@@ -1,226 +1,194 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.WebSocketClearingHouseAccountSubscriber = void 0;
13
4
  const types_1 = require("./types");
14
5
  const events_1 = require("events");
15
- const addresses_1 = require("../addresses");
6
+ const pda_1 = require("../addresses/pda");
16
7
  const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
8
+ const web3_js_1 = require("@solana/web3.js");
9
+ const oracleClientCache_1 = require("../oracles/oracleClientCache");
10
+ const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
17
11
  class WebSocketClearingHouseAccountSubscriber {
18
- constructor(program) {
19
- this.optionalExtraSubscriptions = [];
20
- this.type = 'websocket';
12
+ constructor(program, marketIndexes, bankIndexes, oracleInfos) {
13
+ this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
14
+ this.marketAccountSubscribers = new Map();
15
+ this.bankAccountSubscribers = new Map();
16
+ this.oracleSubscribers = new Map();
21
17
  this.isSubscribing = false;
22
18
  this.isSubscribed = false;
23
19
  this.program = program;
24
20
  this.eventEmitter = new events_1.EventEmitter();
21
+ this.marketIndexes = marketIndexes;
22
+ this.bankIndexes = bankIndexes;
23
+ this.oracleInfos = oracleInfos;
25
24
  }
26
- subscribe(optionalSubscriptions) {
27
- return __awaiter(this, void 0, void 0, function* () {
28
- if (this.isSubscribed) {
29
- return true;
30
- }
31
- if (this.isSubscribing) {
32
- return yield this.subscriptionPromise;
33
- }
34
- this.isSubscribing = true;
35
- this.subscriptionPromise = new Promise((res) => {
36
- this.subscriptionPromiseResolver = res;
37
- });
38
- const statePublicKey = yield (0, addresses_1.getClearingHouseStateAccountPublicKey)(this.program.programId);
39
- // create and activate main state account subscription
40
- this.stateAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('state', this.program, statePublicKey);
41
- yield this.stateAccountSubscriber.subscribe((data) => {
42
- this.eventEmitter.emit('stateAccountUpdate', data);
43
- this.eventEmitter.emit('update');
44
- });
45
- const state = this.stateAccountSubscriber.data;
46
- this.marketsAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('markets', this.program, state.markets);
47
- yield this.marketsAccountSubscriber.subscribe((data) => {
48
- this.eventEmitter.emit('marketsAccountUpdate', data);
49
- this.eventEmitter.emit('update');
50
- });
51
- this.orderStateAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('orderState', this.program, state.orderState);
52
- yield this.orderStateAccountSubscriber.subscribe((data) => {
53
- this.eventEmitter.emit('orderStateAccountUpdate', data);
54
- this.eventEmitter.emit('update');
55
- });
56
- const orderState = this.orderStateAccountSubscriber.data;
57
- // create subscribers for other state accounts
58
- this.tradeHistoryAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('tradeHistory', this.program, state.tradeHistory);
59
- this.depositHistoryAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('depositHistory', this.program, state.depositHistory);
60
- this.fundingPaymentHistoryAccountSubscriber =
61
- new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('fundingPaymentHistory', this.program, state.fundingPaymentHistory);
62
- this.fundingRateHistoryAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('fundingRateHistory', this.program, state.fundingRateHistory);
63
- this.liquidationHistoryAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('liquidationHistory', this.program, state.liquidationHistory);
64
- this.curveHistoryAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('extendedCurveHistory', this.program, state.extendedCurveHistory);
65
- this.orderHistoryAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('orderHistory', this.program, orderState.orderHistory);
66
- const extraSusbcribersToUse = [];
67
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('tradeHistoryAccount'))
68
- extraSusbcribersToUse.push({
69
- subscriber: this.tradeHistoryAccountSubscriber,
70
- eventType: 'tradeHistoryAccountUpdate',
71
- });
72
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('depositHistoryAccount'))
73
- extraSusbcribersToUse.push({
74
- subscriber: this.depositHistoryAccountSubscriber,
75
- eventType: 'depositHistoryAccountUpdate',
76
- });
77
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('fundingPaymentHistoryAccount'))
78
- extraSusbcribersToUse.push({
79
- subscriber: this.fundingPaymentHistoryAccountSubscriber,
80
- eventType: 'fundingPaymentHistoryAccountUpdate',
81
- });
82
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('fundingRateHistoryAccount'))
83
- extraSusbcribersToUse.push({
84
- subscriber: this.fundingRateHistoryAccountSubscriber,
85
- eventType: 'fundingRateHistoryAccountUpdate',
86
- });
87
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('liquidationHistoryAccount'))
88
- extraSusbcribersToUse.push({
89
- subscriber: this.liquidationHistoryAccountSubscriber,
90
- eventType: 'liquidationHistoryAccountUpdate',
91
- });
92
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('curveHistoryAccount'))
93
- extraSusbcribersToUse.push({
94
- subscriber: this.curveHistoryAccountSubscriber,
95
- eventType: 'curveHistoryAccountUpdate',
96
- });
97
- if (optionalSubscriptions === null || optionalSubscriptions === void 0 ? void 0 : optionalSubscriptions.includes('orderHistoryAccount'))
98
- extraSusbcribersToUse.push({
99
- subscriber: this.orderHistoryAccountSubscriber,
100
- eventType: 'orderHistoryAccountUpdate',
101
- });
102
- this.optionalExtraSubscriptions = optionalSubscriptions !== null && optionalSubscriptions !== void 0 ? optionalSubscriptions : [];
103
- // await all subcriptions in parallel to boost performance
104
- //// the state account subscription above can't happen in here, because some of these susbcriptions are dependent on clearing house state being available
105
- yield Promise.all(extraSusbcribersToUse.map(({ subscriber, eventType }) => subscriber.subscribe((data) => {
106
- this.eventEmitter.emit(eventType, data);
107
- this.eventEmitter.emit('update');
108
- })));
109
- this.eventEmitter.emit('update');
110
- this.isSubscribing = false;
111
- this.isSubscribed = true;
112
- this.subscriptionPromiseResolver(true);
25
+ async subscribe() {
26
+ if (this.isSubscribed) {
113
27
  return true;
28
+ }
29
+ if (this.isSubscribing) {
30
+ return await this.subscriptionPromise;
31
+ }
32
+ this.isSubscribing = true;
33
+ this.subscriptionPromise = new Promise((res) => {
34
+ this.subscriptionPromiseResolver = res;
35
+ });
36
+ const statePublicKey = await (0, pda_1.getClearingHouseStateAccountPublicKey)(this.program.programId);
37
+ // create and activate main state account subscription
38
+ this.stateAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('state', this.program, statePublicKey);
39
+ await this.stateAccountSubscriber.subscribe((data) => {
40
+ this.eventEmitter.emit('stateAccountUpdate', data);
41
+ this.eventEmitter.emit('update');
114
42
  });
43
+ // subscribe to market accounts
44
+ await this.subscribeToMarketAccounts();
45
+ // subscribe to bank accounts
46
+ await this.subscribeToBankAccounts();
47
+ // subscribe to oracles
48
+ await this.subscribeToOracles();
49
+ this.eventEmitter.emit('update');
50
+ this.isSubscribing = false;
51
+ this.isSubscribed = true;
52
+ this.subscriptionPromiseResolver(true);
53
+ return true;
115
54
  }
116
- fetch() {
117
- return __awaiter(this, void 0, void 0, function* () {
118
- if (!this.isSubscribed) {
119
- return;
120
- }
121
- const promises = this.optionalExtraSubscriptions
122
- .map((optionalSubscription) => {
123
- const subscriber = `${optionalSubscription}Subscriber`;
124
- return this[subscriber].fetch();
125
- })
126
- .concat([
127
- this.stateAccountSubscriber.fetch(),
128
- this.marketsAccountSubscriber.fetch(),
129
- ]);
130
- yield Promise.all(promises);
55
+ async subscribeToMarketAccounts() {
56
+ for (const marketIndex of this.marketIndexes) {
57
+ await this.subscribeToMarketAccount(marketIndex);
58
+ }
59
+ return true;
60
+ }
61
+ async subscribeToMarketAccount(marketIndex) {
62
+ const marketPublicKey = await (0, pda_1.getMarketPublicKey)(this.program.programId, marketIndex);
63
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('market', this.program, marketPublicKey);
64
+ await accountSubscriber.subscribe((data) => {
65
+ this.eventEmitter.emit('marketAccountUpdate', data);
66
+ this.eventEmitter.emit('update');
131
67
  });
68
+ this.marketAccountSubscribers.set(marketIndex.toNumber(), accountSubscriber);
69
+ return true;
132
70
  }
133
- unsubscribe() {
134
- return __awaiter(this, void 0, void 0, function* () {
135
- if (!this.isSubscribed) {
136
- return;
137
- }
138
- yield this.stateAccountSubscriber.unsubscribe();
139
- yield this.marketsAccountSubscriber.unsubscribe();
140
- yield this.orderStateAccountSubscriber.unsubscribe();
141
- if (this.optionalExtraSubscriptions.includes('tradeHistoryAccount')) {
142
- yield this.tradeHistoryAccountSubscriber.unsubscribe();
143
- }
144
- if (this.optionalExtraSubscriptions.includes('fundingRateHistoryAccount')) {
145
- yield this.fundingRateHistoryAccountSubscriber.unsubscribe();
146
- }
147
- if (this.optionalExtraSubscriptions.includes('fundingPaymentHistoryAccount')) {
148
- yield this.fundingPaymentHistoryAccountSubscriber.unsubscribe();
149
- }
150
- if (this.optionalExtraSubscriptions.includes('depositHistoryAccount')) {
151
- yield this.depositHistoryAccountSubscriber.unsubscribe();
152
- }
153
- if (this.optionalExtraSubscriptions.includes('curveHistoryAccount')) {
154
- yield this.curveHistoryAccountSubscriber.unsubscribe();
155
- }
156
- if (this.optionalExtraSubscriptions.includes('liquidationHistoryAccount')) {
157
- yield this.liquidationHistoryAccountSubscriber.unsubscribe();
158
- }
159
- if (this.optionalExtraSubscriptions.includes('orderHistoryAccount')) {
160
- yield this.orderHistoryAccountSubscriber.unsubscribe();
71
+ async subscribeToBankAccounts() {
72
+ for (const bankIndex of this.bankIndexes) {
73
+ await this.subscribeToBankAccount(bankIndex);
74
+ }
75
+ return true;
76
+ }
77
+ async subscribeToBankAccount(bankIndex) {
78
+ const bankPublicKey = await (0, pda_1.getBankPublicKey)(this.program.programId, bankIndex);
79
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('bank', this.program, bankPublicKey);
80
+ await accountSubscriber.subscribe((data) => {
81
+ this.eventEmitter.emit('bankAccountUpdate', data);
82
+ this.eventEmitter.emit('update');
83
+ });
84
+ this.bankAccountSubscribers.set(bankIndex.toNumber(), accountSubscriber);
85
+ return true;
86
+ }
87
+ async subscribeToOracles() {
88
+ for (const oracleInfo of this.oracleInfos) {
89
+ if (!oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
90
+ await this.subscribeToOracle(oracleInfo);
161
91
  }
162
- this.isSubscribed = false;
92
+ }
93
+ return true;
94
+ }
95
+ async subscribeToOracle(oracleInfo) {
96
+ const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection);
97
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
98
+ return client.getOraclePriceDataFromBuffer(buffer);
163
99
  });
100
+ await accountSubscriber.subscribe((data) => {
101
+ this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
102
+ this.eventEmitter.emit('update');
103
+ });
104
+ this.oracleSubscribers.set(oracleInfo.publicKey.toString(), accountSubscriber);
105
+ return true;
164
106
  }
165
- assertIsSubscribed() {
166
- if (!this.isSubscribed) {
167
- throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
107
+ async unsubscribeFromMarketAccounts() {
108
+ for (const accountSubscriber of this.marketAccountSubscribers.values()) {
109
+ await accountSubscriber.unsubscribe();
168
110
  }
169
111
  }
170
- assertOptionalIsSubscribed(optionalSubscription) {
171
- if (!this.isSubscribed) {
172
- throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
112
+ async unsubscribeFromBankAccounts() {
113
+ for (const accountSubscriber of this.bankAccountSubscribers.values()) {
114
+ await accountSubscriber.unsubscribe();
173
115
  }
174
- if (!this.optionalExtraSubscriptions.includes(optionalSubscription)) {
175
- throw new types_1.NotSubscribedError(`You need to subscribe to the optional Clearing House account "${optionalSubscription}" to use this method`);
116
+ }
117
+ async unsubscribeFromOracles() {
118
+ for (const accountSubscriber of this.oracleSubscribers.values()) {
119
+ await accountSubscriber.unsubscribe();
176
120
  }
177
121
  }
178
- getStateAccount() {
179
- this.assertIsSubscribed();
180
- return this.stateAccountSubscriber.data;
122
+ async fetch() {
123
+ if (!this.isSubscribed) {
124
+ return;
125
+ }
126
+ const promises = [this.stateAccountSubscriber.fetch()]
127
+ .concat(Array.from(this.marketAccountSubscribers.values()).map((subscriber) => subscriber.fetch()))
128
+ .concat(Array.from(this.bankAccountSubscribers.values()).map((subscriber) => subscriber.fetch()));
129
+ await Promise.all(promises);
181
130
  }
182
- getMarketsAccount() {
183
- this.assertIsSubscribed();
184
- return this.marketsAccountSubscriber.data;
131
+ async unsubscribe() {
132
+ if (!this.isSubscribed) {
133
+ return;
134
+ }
135
+ await this.stateAccountSubscriber.unsubscribe();
136
+ await this.unsubscribeFromMarketAccounts();
137
+ await this.unsubscribeFromBankAccounts();
138
+ await this.unsubscribeFromOracles();
139
+ this.isSubscribed = false;
185
140
  }
186
- getTradeHistoryAccount() {
187
- this.assertIsSubscribed();
188
- this.assertOptionalIsSubscribed('tradeHistoryAccount');
189
- return this.tradeHistoryAccountSubscriber.data;
141
+ async addBank(bankIndex) {
142
+ if (this.bankAccountSubscribers.has(bankIndex.toNumber())) {
143
+ return true;
144
+ }
145
+ return this.subscribeToBankAccount(bankIndex);
190
146
  }
191
- getDepositHistoryAccount() {
192
- this.assertIsSubscribed();
193
- this.assertOptionalIsSubscribed('depositHistoryAccount');
194
- return this.depositHistoryAccountSubscriber.data;
147
+ async addMarket(marketIndex) {
148
+ if (this.marketAccountSubscribers.has(marketIndex.toNumber())) {
149
+ return true;
150
+ }
151
+ return this.subscribeToMarketAccount(marketIndex);
195
152
  }
196
- getFundingPaymentHistoryAccount() {
197
- this.assertIsSubscribed();
198
- this.assertOptionalIsSubscribed('fundingPaymentHistoryAccount');
199
- return this.fundingPaymentHistoryAccountSubscriber.data;
153
+ async addOracle(oracleInfo) {
154
+ if (this.oracleSubscribers.has(oracleInfo.publicKey.toString())) {
155
+ return true;
156
+ }
157
+ if (oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
158
+ return true;
159
+ }
160
+ return this.subscribeToOracle(oracleInfo);
200
161
  }
201
- getFundingRateHistoryAccount() {
202
- this.assertIsSubscribed();
203
- this.assertOptionalIsSubscribed('fundingRateHistoryAccount');
204
- return this.fundingRateHistoryAccountSubscriber.data;
162
+ assertIsSubscribed() {
163
+ if (!this.isSubscribed) {
164
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
165
+ }
205
166
  }
206
- getCurveHistoryAccount() {
167
+ getStateAccountAndSlot() {
207
168
  this.assertIsSubscribed();
208
- this.assertOptionalIsSubscribed('curveHistoryAccount');
209
- return this.curveHistoryAccountSubscriber.data;
169
+ return this.stateAccountSubscriber.dataAndSlot;
210
170
  }
211
- getLiquidationHistoryAccount() {
171
+ getMarketAccountAndSlot(marketIndex) {
212
172
  this.assertIsSubscribed();
213
- this.assertOptionalIsSubscribed('liquidationHistoryAccount');
214
- return this.liquidationHistoryAccountSubscriber.data;
173
+ return this.marketAccountSubscribers.get(marketIndex.toNumber())
174
+ .dataAndSlot;
175
+ }
176
+ getMarketAccountsAndSlots() {
177
+ return Array.from(this.marketAccountSubscribers.values()).map((subscriber) => subscriber.dataAndSlot);
215
178
  }
216
- getOrderHistoryAccount() {
179
+ getBankAccountAndSlot(bankIndex) {
217
180
  this.assertIsSubscribed();
218
- this.assertOptionalIsSubscribed('orderHistoryAccount');
219
- return this.orderHistoryAccountSubscriber.data;
181
+ return this.bankAccountSubscribers.get(bankIndex.toNumber()).dataAndSlot;
220
182
  }
221
- getOrderStateAccount() {
183
+ getOraclePriceDataAndSlot(oraclePublicKey) {
222
184
  this.assertIsSubscribed();
223
- return this.orderStateAccountSubscriber.data;
185
+ if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
186
+ return {
187
+ data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
188
+ slot: 0,
189
+ };
190
+ }
191
+ return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
224
192
  }
225
193
  }
226
194
  exports.WebSocketClearingHouseAccountSubscriber = WebSocketClearingHouseAccountSubscriber;
@@ -1,26 +1,20 @@
1
1
  /// <reference types="node" />
2
- import { AccountSubscriber, UserAccountEvents, UserAccountSubscriber } from './types';
2
+ import { DataAndSlot, AccountSubscriber, UserAccountEvents, UserAccountSubscriber } from './types';
3
3
  import { Program } from '@project-serum/anchor';
4
4
  import StrictEventEmitter from 'strict-event-emitter-types';
5
5
  import { EventEmitter } from 'events';
6
6
  import { PublicKey } from '@solana/web3.js';
7
- import { UserAccount, UserOrdersAccount, UserPositionsAccount } from '../types';
8
- import { ClearingHouseConfigType } from '../factory/clearingHouse';
7
+ import { UserAccount } from '../types';
9
8
  export declare class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
10
9
  isSubscribed: boolean;
11
10
  program: Program;
12
11
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
13
- authority: PublicKey;
12
+ userAccountPublicKey: PublicKey;
14
13
  userDataAccountSubscriber: AccountSubscriber<UserAccount>;
15
- userPositionsAccountSubscriber: AccountSubscriber<UserPositionsAccount>;
16
- userOrdersAccountSubscriber: AccountSubscriber<UserOrdersAccount>;
17
- type: ClearingHouseConfigType;
18
- constructor(program: Program, authority: PublicKey);
14
+ constructor(program: Program, userAccountPublicKey: PublicKey);
19
15
  subscribe(): Promise<boolean>;
20
16
  fetch(): Promise<void>;
21
17
  unsubscribe(): Promise<void>;
22
18
  assertIsSubscribed(): void;
23
- getUserAccount(): UserAccount;
24
- getUserPositionsAccount(): UserPositionsAccount;
25
- getUserOrdersAccount(): UserOrdersAccount;
19
+ getUserAccountAndSlot(): DataAndSlot<UserAccount>;
26
20
  }