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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +2 -2
  2. package/lib/accounts/bulkAccountLoader.js +21 -24
  3. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +15 -0
  4. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +50 -23
  5. package/lib/clearingHouse.d.ts +0 -1
  6. package/lib/clearingHouse.js +0 -14
  7. package/lib/constants/accounts.d.ts +15 -0
  8. package/lib/constants/accounts.js +18 -0
  9. package/lib/constants/markets.js +11 -8
  10. package/lib/factory/clearingHouse.d.ts +14 -4
  11. package/lib/factory/clearingHouse.js +23 -6
  12. package/lib/idl/clearing_house.json +2 -33
  13. package/lib/index.d.ts +0 -1
  14. package/lib/index.js +0 -1
  15. package/lib/math/amm.d.ts +20 -0
  16. package/lib/math/amm.js +151 -1
  17. package/lib/util/promiseTimeout.d.ts +1 -0
  18. package/lib/util/promiseTimeout.js +14 -0
  19. package/package.json +1 -1
  20. package/src/accounts/bulkAccountLoader.ts +22 -32
  21. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +73 -30
  22. package/src/clearingHouse.ts +0 -13
  23. package/src/constants/accounts.ts +26 -0
  24. package/src/constants/markets.ts +11 -8
  25. package/src/factory/clearingHouse.ts +47 -7
  26. package/src/idl/clearing_house.json +2 -33
  27. package/src/index.ts +0 -1
  28. package/src/math/amm.ts +212 -1
  29. package/src/util/promiseTimeout.ts +14 -0
  30. package/lib/math/repeg.d.ts +0 -32
  31. package/lib/math/repeg.js +0 -178
  32. package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -210
  33. package/src/accounts/pollingClearingHouseAccountSubscriber.js.map +0 -1
  34. package/src/accounts/pollingOracleSubscriber.js +0 -65
  35. package/src/accounts/pollingOracleSubscriber.js.map +0 -1
  36. package/src/accounts/pollingTokenAccountSubscriber.js +0 -65
  37. package/src/accounts/pollingTokenAccountSubscriber.js.map +0 -1
  38. package/src/accounts/utils.js +0 -8
  39. package/src/accounts/utils.js.map +0 -1
  40. package/src/accounts/webSocketAccountSubscriber.js +0 -64
  41. package/src/accounts/webSocketAccountSubscriber.js.map +0 -1
  42. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -212
  43. package/src/accounts/webSocketClearingHouseAccountSubscriber.js.map +0 -1
  44. package/src/assert/assert.js +0 -10
  45. package/src/assert/assert.js.map +0 -1
  46. package/src/constants/markets.js +0 -167
  47. package/src/constants/markets.js.map +0 -1
  48. package/src/constants/numericConstants.js +0 -22
  49. package/src/constants/numericConstants.js.map +0 -1
  50. package/src/math/conversion.js +0 -16
  51. package/src/math/conversion.js.map +0 -1
  52. package/src/math/funding.js +0 -223
  53. package/src/math/funding.js.map +0 -1
  54. package/src/math/insuranceFund.js +0 -23
  55. package/src/math/insuranceFund.js.map +0 -1
  56. package/src/math/market.js +0 -30
  57. package/src/math/market.js.map +0 -1
  58. package/src/math/orders.js +0 -73
  59. package/src/math/orders.js.map +0 -1
  60. package/src/math/position.js +0 -121
  61. package/src/math/position.js.map +0 -1
  62. package/src/math/repeg.ts +0 -253
  63. package/src/math/trade.js +0 -182
  64. package/src/math/trade.js.map +0 -1
  65. package/src/math/utils.js +0 -27
  66. package/src/math/utils.js.map +0 -1
  67. package/src/oracles/switchboardClient.js +0 -60
  68. package/src/oracles/switchboardClient.js.map +0 -1
  69. package/src/oracles/types.js +0 -3
  70. package/src/oracles/types.js.map +0 -1
  71. package/src/token/index.js +0 -39
  72. package/src/token/index.js.map +0 -1
  73. package/src/tx/defaultTxSender.js +0 -13
  74. package/src/tx/defaultTxSender.js.map +0 -1
  75. package/src/tx/types.js +0 -3
  76. package/src/tx/types.js.map +0 -1
  77. package/src/tx/utils.js +0 -9
  78. package/src/tx/utils.js.map +0 -1
  79. package/src/util/computeUnits.js +0 -17
  80. package/src/util/computeUnits.js.map +0 -1
  81. package/src/util/tps.js +0 -17
  82. package/src/util/tps.js.map +0 -1
package/lib/math/amm.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
3
+ exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.calculateRepegCost = exports.calculateAdjustKCost = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
4
4
  const anchor_1 = require("@project-serum/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ const position_1 = require("./position");
6
7
  const types_1 = require("../types");
7
8
  const assert_1 = require("../assert/assert");
8
9
  const __1 = require("..");
@@ -87,6 +88,92 @@ function getSwapDirection(inputAssetType, positionDirection) {
87
88
  return types_1.SwapDirection.ADD;
88
89
  }
89
90
  exports.getSwapDirection = getSwapDirection;
91
+ /**
92
+ * Helper function calculating adjust k cost
93
+ * @param market
94
+ * @param marketIndex
95
+ * @param numerator
96
+ * @param denomenator
97
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
98
+ */
99
+ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
100
+ const netUserPosition = {
101
+ baseAssetAmount: market.baseAssetAmount,
102
+ lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
103
+ marketIndex: new anchor_1.BN(marketIndex),
104
+ quoteAssetAmount: new anchor_1.BN(0),
105
+ openOrders: new anchor_1.BN(0),
106
+ };
107
+ const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
108
+ const marketNewK = Object.assign({}, market);
109
+ marketNewK.amm = Object.assign({}, market.amm);
110
+ marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
111
+ .mul(numerator)
112
+ .div(denomenator);
113
+ marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
114
+ .mul(numerator)
115
+ .div(denomenator);
116
+ marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
117
+ netUserPosition.quoteAssetAmount = currentValue;
118
+ const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
119
+ const p = numericConstants_1.PEG_PRECISION.mul(numerator).div(denomenator);
120
+ const x = market.amm.baseAssetReserve;
121
+ const y = market.amm.quoteAssetReserve;
122
+ const delta = market.baseAssetAmount;
123
+ const k = market.amm.sqrtK.mul(market.amm.sqrtK);
124
+ const numer1 = numericConstants_1.PEG_PRECISION.sub(p).mul(y).div(numericConstants_1.PEG_PRECISION);
125
+ const numer20 = k
126
+ .mul(p)
127
+ .mul(p)
128
+ .div(numericConstants_1.PEG_PRECISION)
129
+ .div(numericConstants_1.PEG_PRECISION)
130
+ .div(x.mul(p).div(numericConstants_1.PEG_PRECISION).add(delta));
131
+ const numer21 = k.div(x.add(delta));
132
+ const formulaCost = numer21
133
+ .sub(numer20)
134
+ .sub(numer1)
135
+ .mul(market.amm.pegMultiplier)
136
+ .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
137
+ console.log((0, __1.convertToNumber)(formulaCost, numericConstants_1.QUOTE_PRECISION));
138
+ // p.div(p.mul(x).add(delta)).sub()
139
+ return cost;
140
+ }
141
+ exports.calculateAdjustKCost = calculateAdjustKCost;
142
+ /**
143
+ * Helper function calculating adjust pegMultiplier (repeg) cost
144
+ *
145
+ * @param market
146
+ * @param marketIndex
147
+ * @param newPeg
148
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
149
+ */
150
+ function calculateRepegCost(market, marketIndex, newPeg) {
151
+ const netUserPosition = {
152
+ baseAssetAmount: market.baseAssetAmount,
153
+ lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
154
+ marketIndex: new anchor_1.BN(marketIndex),
155
+ quoteAssetAmount: new anchor_1.BN(0),
156
+ openOrders: new anchor_1.BN(0),
157
+ };
158
+ const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
159
+ netUserPosition.quoteAssetAmount = currentValue;
160
+ const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
161
+ const marketNewPeg = Object.assign({}, market);
162
+ marketNewPeg.amm = Object.assign({}, market.amm);
163
+ // const marketNewPeg = JSON.parse(JSON.stringify(market));
164
+ marketNewPeg.amm.pegMultiplier = newPeg;
165
+ console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
166
+ const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
167
+ const k = market.amm.sqrtK.mul(market.amm.sqrtK);
168
+ const newQuoteAssetReserve = k.div(market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount));
169
+ const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(market.amm.quoteAssetReserve);
170
+ const cost2 = deltaQuoteAssetReserves
171
+ .mul(market.amm.pegMultiplier.sub(newPeg))
172
+ .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
173
+ console.log((0, __1.convertToNumber)(cost2, numericConstants_1.QUOTE_PRECISION));
174
+ return cost;
175
+ }
176
+ exports.calculateRepegCost = calculateRepegCost;
90
177
  /**
91
178
  * Helper function calculating terminal price of amm
92
179
  *
@@ -132,3 +219,66 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
132
219
  }
133
220
  }
134
221
  exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
222
+ function calculateBudgetedK(market, cost) {
223
+ // wolframalpha.com
224
+ // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
225
+ // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
226
+ // todo: assumes k = x * y
227
+ // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
228
+ // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
229
+ const x = market.amm.baseAssetReserve;
230
+ const y = market.amm.quoteAssetReserve;
231
+ const d = market.baseAssetAmount;
232
+ const Q = market.amm.pegMultiplier;
233
+ const C = cost.mul(new anchor_1.BN(-1));
234
+ const numer1 = y.mul(d).mul(Q).div(numericConstants_1.AMM_RESERVE_PRECISION).div(numericConstants_1.PEG_PRECISION);
235
+ const numer2 = C.mul(x.add(d)).div(numericConstants_1.QUOTE_PRECISION);
236
+ const denom1 = C.mul(x)
237
+ .mul(x.add(d))
238
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
239
+ .div(numericConstants_1.QUOTE_PRECISION);
240
+ const denom2 = y
241
+ .mul(d)
242
+ .mul(d)
243
+ .mul(Q)
244
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
245
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
246
+ .div(numericConstants_1.PEG_PRECISION);
247
+ const numerator = d
248
+ .mul(numer1.add(numer2))
249
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
250
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
251
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
252
+ const denominator = denom1
253
+ .add(denom2)
254
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
255
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
256
+ console.log(numerator, denominator);
257
+ // const p = (numerator).div(denominator);
258
+ // const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
259
+ // console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
260
+ return [numerator, denominator];
261
+ }
262
+ exports.calculateBudgetedK = calculateBudgetedK;
263
+ function calculateBudgetedPeg(market, cost) {
264
+ // wolframalpha.com
265
+ // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
266
+ // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
267
+ // todo: assumes k = x * y
268
+ // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
269
+ const k = market.amm.sqrtK.mul(market.amm.sqrtK);
270
+ const x = market.amm.baseAssetReserve;
271
+ const y = market.amm.quoteAssetReserve;
272
+ const d = market.baseAssetAmount;
273
+ const Q = market.amm.pegMultiplier;
274
+ const C = cost.mul(new anchor_1.BN(-1));
275
+ const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
276
+ const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION)
277
+ .div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO))
278
+ .mul(numericConstants_1.PEG_PRECISION)
279
+ .div(numericConstants_1.QUOTE_PRECISION);
280
+ console.log(Q.toNumber(), 'change by', deltaPegMultiplier.toNumber() / numericConstants_1.MARK_PRICE_PRECISION.toNumber());
281
+ const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
282
+ return newPeg;
283
+ }
284
+ exports.calculateBudgetedPeg = calculateBudgetedPeg;
@@ -0,0 +1 @@
1
+ export declare function promiseTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T | null>;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promiseTimeout = void 0;
4
+ function promiseTimeout(promise, timeoutMs) {
5
+ let timeoutId;
6
+ const timeoutPromise = new Promise((resolve) => {
7
+ timeoutId = setTimeout(() => resolve(null), timeoutMs);
8
+ });
9
+ return Promise.race([promise, timeoutPromise]).then((result) => {
10
+ clearTimeout(timeoutId);
11
+ return result;
12
+ });
13
+ }
14
+ exports.promiseTimeout = promiseTimeout;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.30-master.0",
3
+ "version": "0.1.30-master.3",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -1,6 +1,7 @@
1
1
  import { Commitment, Connection, PublicKey } from '@solana/web3.js';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
3
  import { AccountData } from './types';
4
+ import { promiseTimeout } from '../util/promiseTimeout';
4
5
 
5
6
  type AccountToLoad = {
6
7
  publicKey: PublicKey;
@@ -10,7 +11,6 @@ type AccountToLoad = {
10
11
  const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
11
12
 
12
13
  const oneMinute = 60 * 1000;
13
- const fiveMinutes = 5 * 60 * 1000;
14
14
 
15
15
  export class BulkAccountLoader {
16
16
  connection: Connection;
@@ -24,7 +24,7 @@ export class BulkAccountLoader {
24
24
  loadPromise?: Promise<void>;
25
25
  loadPromiseResolver: () => void;
26
26
  loggingEnabled = false;
27
- lastUpdate = Date.now();
27
+ lastTimeLoadingPromiseCleared = Date.now();
28
28
 
29
29
  public constructor(
30
30
  connection: Connection,
@@ -107,12 +107,20 @@ export class BulkAccountLoader {
107
107
 
108
108
  public async load(): Promise<void> {
109
109
  if (this.loadPromise) {
110
- this.log(`Load promise exists. Returning early`);
111
- return this.loadPromise;
110
+ const now = Date.now();
111
+ if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
112
+ this.log(`Load promise hasnt been clearing for one minute. Clearing.`);
113
+ this.loadPromise = undefined;
114
+ } else {
115
+ this.log(`Load promise exists. Returning early`);
116
+ return this.loadPromise;
117
+ }
112
118
  }
119
+
113
120
  this.loadPromise = new Promise((resolver) => {
114
121
  this.loadPromiseResolver = resolver;
115
122
  });
123
+ this.lastTimeLoadingPromiseCleared = Date.now();
116
124
 
117
125
  this.log(`Loading`);
118
126
 
@@ -139,18 +147,6 @@ export class BulkAccountLoader {
139
147
  this.log(`resetting load promise`);
140
148
  this.loadPromiseResolver();
141
149
  this.loadPromise = undefined;
142
-
143
- const now = Date.now();
144
- if (now - this.lastUpdate > fiveMinutes) {
145
- this.log(
146
- "Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object"
147
- );
148
- this.connection = new Connection(
149
- // @ts-ignore
150
- this.connection._rpcEndpoint,
151
- this.connection.commitment
152
- );
153
- }
154
150
  }
155
151
  }
156
152
 
@@ -167,15 +163,15 @@ export class BulkAccountLoader {
167
163
  { commitment: this.commitment },
168
164
  ];
169
165
 
170
- // @ts-ignore
171
- const rpcResponse = await this.connection._rpcRequest(
172
- 'getMultipleAccounts',
173
- args
166
+ const rpcResponse: any | null = await promiseTimeout(
167
+ // @ts-ignore
168
+ this.connection._rpcRequest('getMultipleAccounts', args),
169
+ 10 * 1000 // 30 second timeout
174
170
  );
175
171
 
176
- const oneMinuteSinceLastUpdate = Date.now() - this.lastUpdate > oneMinute;
177
- if (oneMinuteSinceLastUpdate) {
178
- this.log('rpcResponse ' + JSON.stringify(rpcResponse));
172
+ if (rpcResponse === null) {
173
+ this.log('request to rpc timed out', true);
174
+ return;
179
175
  }
180
176
 
181
177
  const newSlot = rpcResponse.result.context.slot;
@@ -192,10 +188,6 @@ export class BulkAccountLoader {
192
188
  newBuffer = Buffer.from(raw, dataType);
193
189
  }
194
190
 
195
- if (oneMinuteSinceLastUpdate) {
196
- this.log('oldRPCResponse' + oldRPCResponse);
197
- }
198
-
199
191
  if (!oldRPCResponse) {
200
192
  this.log('No old rpc response, updating account data');
201
193
  this.accountData.set(key, {
@@ -203,7 +195,6 @@ export class BulkAccountLoader {
203
195
  buffer: newBuffer,
204
196
  });
205
197
  this.handleAccountCallbacks(accountToLoad, newBuffer);
206
- this.lastUpdate = Date.now();
207
198
  continue;
208
199
  }
209
200
 
@@ -220,12 +211,11 @@ export class BulkAccountLoader {
220
211
  buffer: newBuffer,
221
212
  });
222
213
  this.handleAccountCallbacks(accountToLoad, newBuffer);
223
- this.lastUpdate = Date.now();
224
214
  } else {
225
215
  this.log('unable to update account for newest slot');
226
216
  this.log('oldBuffer ' + oldBuffer);
227
217
  this.log('newBuffer ' + newBuffer);
228
- this.log('buffers equal ' + newBuffer.equals(oldBuffer));
218
+ this.log('buffers equal ' + newBuffer?.equals(oldBuffer));
229
219
  }
230
220
  }
231
221
  }
@@ -262,8 +252,8 @@ export class BulkAccountLoader {
262
252
  }
263
253
  }
264
254
 
265
- public log(msg: string): void {
266
- if (this.loggingEnabled) {
255
+ public log(msg: string, force = false): void {
256
+ if (this.loggingEnabled || force) {
267
257
  console.log(msg);
268
258
  }
269
259
  }
@@ -24,6 +24,8 @@ import { getClearingHouseStateAccountPublicKey } from '../addresses';
24
24
  import { BulkAccountLoader } from './bulkAccountLoader';
25
25
  import { capitalize } from './utils';
26
26
  import { ClearingHouseConfigType } from '../factory/clearingHouse';
27
+ import { PublicKey } from '@solana/web3.js';
28
+ import { CLEARING_HOUSE_STATE_ACCOUNTS } from '../constants/accounts';
27
29
 
28
30
  export class PollingClearingHouseAccountSubscriber
29
31
  implements ClearingHouseAccountSubscriber
@@ -98,44 +100,38 @@ export class PollingClearingHouseAccountSubscriber
98
100
  return;
99
101
  }
100
102
 
101
- const statePublicKey = await getClearingHouseStateAccountPublicKey(
102
- this.program.programId
103
- );
104
-
105
- const state = (await this.program.account.state.fetch(
106
- statePublicKey
107
- )) as StateAccount;
103
+ const accounts = await this.getClearingHouseAccounts();
108
104
 
109
- this.accountsToPoll.set(statePublicKey.toString(), {
105
+ this.accountsToPoll.set(accounts.state.toString(), {
110
106
  key: 'state',
111
- publicKey: statePublicKey,
107
+ publicKey: accounts.state,
112
108
  eventType: 'stateAccountUpdate',
113
109
  });
114
110
 
115
- this.accountsToPoll.set(state.markets.toString(), {
111
+ this.accountsToPoll.set(accounts.markets.toString(), {
116
112
  key: 'markets',
117
- publicKey: state.markets,
113
+ publicKey: accounts.markets,
118
114
  eventType: 'marketsAccountUpdate',
119
115
  });
120
116
 
121
- this.accountsToPoll.set(state.orderState.toString(), {
117
+ this.accountsToPoll.set(accounts.orderState.toString(), {
122
118
  key: 'orderState',
123
- publicKey: state.orderState,
119
+ publicKey: accounts.orderState,
124
120
  eventType: 'orderStateAccountUpdate',
125
121
  });
126
122
 
127
123
  if (this.optionalExtraSubscriptions?.includes('tradeHistoryAccount')) {
128
- this.accountsToPoll.set(state.tradeHistory.toString(), {
124
+ this.accountsToPoll.set(accounts.tradeHistory.toString(), {
129
125
  key: 'tradeHistory',
130
- publicKey: state.tradeHistory,
126
+ publicKey: accounts.tradeHistory,
131
127
  eventType: 'tradeHistoryAccountUpdate',
132
128
  });
133
129
  }
134
130
 
135
131
  if (this.optionalExtraSubscriptions?.includes('depositHistoryAccount')) {
136
- this.accountsToPoll.set(state.depositHistory.toString(), {
132
+ this.accountsToPoll.set(accounts.depositHistory.toString(), {
137
133
  key: 'depositHistory',
138
- publicKey: state.depositHistory,
134
+ publicKey: accounts.depositHistory,
139
135
  eventType: 'depositHistoryAccountUpdate',
140
136
  });
141
137
  }
@@ -143,9 +139,9 @@ export class PollingClearingHouseAccountSubscriber
143
139
  if (
144
140
  this.optionalExtraSubscriptions?.includes('fundingPaymentHistoryAccount')
145
141
  ) {
146
- this.accountsToPoll.set(state.fundingPaymentHistory.toString(), {
142
+ this.accountsToPoll.set(accounts.fundingPaymentHistory.toString(), {
147
143
  key: 'fundingPaymentHistory',
148
- publicKey: state.fundingPaymentHistory,
144
+ publicKey: accounts.fundingPaymentHistory,
149
145
  eventType: 'fundingPaymentHistoryAccountUpdate',
150
146
  });
151
147
  }
@@ -153,17 +149,17 @@ export class PollingClearingHouseAccountSubscriber
153
149
  if (
154
150
  this.optionalExtraSubscriptions?.includes('fundingRateHistoryAccount')
155
151
  ) {
156
- this.accountsToPoll.set(state.fundingRateHistory.toString(), {
152
+ this.accountsToPoll.set(accounts.fundingRateHistory.toString(), {
157
153
  key: 'fundingRateHistory',
158
- publicKey: state.fundingRateHistory,
154
+ publicKey: accounts.fundingRateHistory,
159
155
  eventType: 'fundingRateHistoryAccountUpdate',
160
156
  });
161
157
  }
162
158
 
163
159
  if (this.optionalExtraSubscriptions?.includes('curveHistoryAccount')) {
164
- this.accountsToPoll.set(state.extendedCurveHistory.toString(), {
160
+ this.accountsToPoll.set(accounts.extendedCurveHistory.toString(), {
165
161
  key: 'extendedCurveHistory',
166
- publicKey: state.extendedCurveHistory,
162
+ publicKey: accounts.extendedCurveHistory,
167
163
  eventType: 'curveHistoryAccountUpdate',
168
164
  });
169
165
  }
@@ -171,24 +167,58 @@ export class PollingClearingHouseAccountSubscriber
171
167
  if (
172
168
  this.optionalExtraSubscriptions?.includes('liquidationHistoryAccount')
173
169
  ) {
174
- this.accountsToPoll.set(state.liquidationHistory.toString(), {
170
+ this.accountsToPoll.set(accounts.liquidationHistory.toString(), {
175
171
  key: 'liquidationHistory',
176
- publicKey: state.liquidationHistory,
172
+ publicKey: accounts.liquidationHistory,
177
173
  eventType: 'liquidationHistoryAccountUpdate',
178
174
  });
179
175
  }
180
176
 
177
+ if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
178
+ this.accountsToPoll.set(accounts.orderHistory.toString(), {
179
+ key: 'orderHistory',
180
+ publicKey: accounts.orderHistory,
181
+ eventType: 'orderHistoryAccountUpdate',
182
+ });
183
+ }
184
+ }
185
+
186
+ async getClearingHouseAccounts(): Promise<ClearingHouseAccounts> {
187
+ // Skip extra calls to rpc if we already know all the accounts
188
+ if (CLEARING_HOUSE_STATE_ACCOUNTS[this.program.programId.toString()]) {
189
+ return CLEARING_HOUSE_STATE_ACCOUNTS[this.program.programId.toString()];
190
+ }
191
+
192
+ const statePublicKey = await getClearingHouseStateAccountPublicKey(
193
+ this.program.programId
194
+ );
195
+
196
+ const state = (await this.program.account.state.fetch(
197
+ statePublicKey
198
+ )) as StateAccount;
199
+
200
+ const accounts = {
201
+ state: statePublicKey,
202
+ markets: state.markets,
203
+ orderState: state.orderState,
204
+ tradeHistory: state.tradeHistory,
205
+ depositHistory: state.depositHistory,
206
+ fundingPaymentHistory: state.fundingPaymentHistory,
207
+ fundingRateHistory: state.fundingRateHistory,
208
+ extendedCurveHistory: state.extendedCurveHistory,
209
+ liquidationHistory: state.liquidationHistory,
210
+ orderHistory: undefined,
211
+ };
212
+
181
213
  if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
182
214
  const orderState = (await this.program.account.orderState.fetch(
183
215
  state.orderState
184
216
  )) as OrderStateAccount;
185
217
 
186
- this.accountsToPoll.set(orderState.orderHistory.toString(), {
187
- key: 'orderHistory',
188
- publicKey: orderState.orderHistory,
189
- eventType: 'orderHistoryAccountUpdate',
190
- });
218
+ accounts.orderHistory = orderState.orderHistory;
191
219
  }
220
+
221
+ return accounts;
192
222
  }
193
223
 
194
224
  async addToAccountLoader(): Promise<void> {
@@ -324,3 +354,16 @@ export class PollingClearingHouseAccountSubscriber
324
354
  return this.orderHistory;
325
355
  }
326
356
  }
357
+
358
+ type ClearingHouseAccounts = {
359
+ state: PublicKey;
360
+ markets: PublicKey;
361
+ orderState: PublicKey;
362
+ tradeHistory?: PublicKey;
363
+ depositHistory?: PublicKey;
364
+ fundingPaymentHistory?: PublicKey;
365
+ fundingRateHistory?: PublicKey;
366
+ extendedCurveHistory?: PublicKey;
367
+ liquidationHistory?: PublicKey;
368
+ orderHistory?: PublicKey;
369
+ };
@@ -543,19 +543,6 @@ export class ClearingHouse {
543
543
  return [txSig, userAccountPublicKey];
544
544
  }
545
545
 
546
- public async deleteUser(): Promise<TransactionSignature> {
547
- const userAccountPublicKey = await this.getUserAccountPublicKey();
548
- const user = await this.program.account.user.fetch(userAccountPublicKey);
549
- const deleteUserTx = await this.program.transaction.deleteUser({
550
- accounts: {
551
- user: userAccountPublicKey,
552
- userPositions: user.positions,
553
- authority: this.wallet.publicKey,
554
- },
555
- });
556
- return this.txSender.send(deleteUserTx, [], this.opts);
557
- }
558
-
559
546
  public async withdrawCollateral(
560
547
  amount: BN,
561
548
  collateralAccountPublicKey: PublicKey
@@ -0,0 +1,26 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+
3
+ export const CLEARING_HOUSE_STATE_ACCOUNTS = {
4
+ dammHkt7jmytvbS3nHTxQNEcP59aE57nxwV21YdqEDN: {
5
+ state: new PublicKey('FExhvPycCCwYnZGeDsVtLhpEQ3yEkVY2k1HuPyfLj91L'),
6
+ markets: new PublicKey('773hq3SbGPKVj93TXi5qV5CREuhxobywfALjS3XVHhLH'),
7
+ orderState: new PublicKey('4cC34bWwTPGncBaX2S6v5mH3Lj4Nb3byPMrxQSDcY985'),
8
+ tradeHistory: new PublicKey('FCuCXEoQppoaCYdttA7rK3HNQfYkTNEGpwuBESzYcENp'),
9
+ depositHistory: new PublicKey(
10
+ 'C7rF2Qy2rnDGQLRijBRRArJyaeuQcFi81BXDrUCQ45ya'
11
+ ),
12
+ fundingPaymentHistory: new PublicKey(
13
+ '895iPhzwT2tBufLnRpYtBG3gif1HDDUfpH2AqbS5joo4'
14
+ ),
15
+ fundingRateHistory: new PublicKey(
16
+ 'BWiJLMbmrwfqHVpcPJa8715XamNyNYamDDKQVQMnduEC'
17
+ ),
18
+ extendedCurveHistory: new PublicKey(
19
+ '7vBbqvMdtZLQdTVdzt5y63pZdAFE5W42kP3avngSJKCk'
20
+ ),
21
+ liquidationHistory: new PublicKey(
22
+ 'CSFaaf8yVoTx6NcXUKtNPYAewv76CH2jATqSVRBvUWKM'
23
+ ),
24
+ orderHistory: new PublicKey('DZ7XfUqyHoRKnJLRApxmJ943xHJ7NDBUTqpbooviEtbU'),
25
+ },
26
+ };
@@ -198,12 +198,15 @@ export const Markets: MarketConfig[] = [
198
198
  launchTs: 1649105516000,
199
199
  oracleSource: OracleSource.PYTH,
200
200
  },
201
- // {
202
- // symbol: 'mSOL-PERP',
203
- // baseAssetSymbol: 'mSOL',
204
- // marketIndex: new BN(11), //todo
205
- // devnetPythOracle: '9a6RNx3tCu1TSs6TBSfV2XRXEPEZXQ6WB7jRojZRvyeZ',
206
- // mainnetPythOracle: 'E4v1BBgoso9s64TQvmyownAVJbhbEPGyzA3qn4n46qj9',
207
- // launchTs: 1643346125000,
208
- // },
201
+ {
202
+ fullName: 'Serum',
203
+ category: ['DEX'],
204
+ symbol: 'SRM-PERP',
205
+ baseAssetSymbol: 'SRM',
206
+ marketIndex: new BN(17),
207
+ devnetPublicKey: '992moaMQKs32GKZ9dxi8keyM2bUmbrwBZpK4p2K6X5Vs',
208
+ mainnetPublicKey: '3NBReDRTLKMQEKiLD5tGcx4kXbTf88b7f2xLS9UuGjym',
209
+ launchTs: 1649877367000,
210
+ oracleSource: OracleSource.PYTH,
211
+ },
209
212
  ];