@drift-labs/sdk 0.1.18-orders.3 → 0.1.18-orders.7

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 (53) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +3 -4
  2. package/lib/accounts/bulkAccountLoader.js +23 -4
  3. package/lib/accounts/pollingUserAccountSubscriber.js +8 -5
  4. package/lib/accounts/types.d.ts +4 -0
  5. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -2
  6. package/lib/accounts/webSocketAccountSubscriber.js +43 -12
  7. package/lib/clearingHouse.d.ts +4 -0
  8. package/lib/clearingHouse.js +40 -0
  9. package/lib/clearingHouseUser.d.ts +8 -3
  10. package/lib/clearingHouseUser.js +23 -20
  11. package/lib/config.js +1 -1
  12. package/lib/constants/markets.d.ts +2 -1
  13. package/lib/constants/markets.js +20 -15
  14. package/lib/constants/numericConstants.d.ts +4 -1
  15. package/lib/constants/numericConstants.js +16 -17
  16. package/lib/examples/makeTradeExample.js +1 -1
  17. package/lib/idl/clearing_house.json +8 -4
  18. package/lib/math/conversion.d.ts +1 -1
  19. package/lib/math/insuranceFund.d.ts +2 -1
  20. package/lib/math/insuranceFund.js +3 -6
  21. package/lib/math/orders.js +3 -1
  22. package/lib/math/position.d.ts +2 -1
  23. package/lib/math/position.js +2 -5
  24. package/lib/math/utils.d.ts +2 -1
  25. package/lib/math/utils.js +3 -6
  26. package/lib/mockUSDCFaucet.d.ts +2 -1
  27. package/lib/orderParams.d.ts +2 -2
  28. package/lib/orderParams.js +7 -7
  29. package/lib/orders.d.ts +3 -2
  30. package/lib/orders.js +8 -8
  31. package/lib/types.d.ts +8 -5
  32. package/lib/types.js +2 -2
  33. package/package.json +9 -1
  34. package/src/accounts/bulkAccountLoader.ts +35 -15
  35. package/src/accounts/pollingUserAccountSubscriber.ts +13 -5
  36. package/src/accounts/types.ts +5 -0
  37. package/src/accounts/webSocketAccountSubscriber.ts +67 -17
  38. package/src/clearingHouse.ts +56 -0
  39. package/src/clearingHouseUser.ts +12 -2
  40. package/src/config.ts +1 -1
  41. package/src/constants/markets.ts +9 -1
  42. package/src/constants/numericConstants.ts +3 -1
  43. package/src/examples/makeTradeExample.ts +4 -1
  44. package/src/idl/clearing_house.json +8 -4
  45. package/src/math/conversion.ts +1 -1
  46. package/src/math/insuranceFund.ts +1 -1
  47. package/src/math/orders.ts +7 -2
  48. package/src/math/position.ts +1 -1
  49. package/src/math/utils.ts +1 -1
  50. package/src/mockUSDCFaucet.ts +1 -1
  51. package/src/orderParams.ts +4 -4
  52. package/src/orders.ts +13 -7
  53. package/src/types.ts +5 -3
@@ -1,13 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  import { Commitment, Connection, PublicKey } from '@solana/web3.js';
3
+ import { AccountData } from './types';
3
4
  declare type AccountToLoad = {
4
5
  publicKey: PublicKey;
5
6
  callbacks: Map<string, (buffer: Buffer) => void>;
6
7
  };
7
- declare type AccountData = {
8
- slot: number;
9
- buffer: Buffer | undefined;
10
- };
11
8
  export declare class BulkAccountLoader {
12
9
  connection: Connection;
13
10
  commitment: Commitment;
@@ -16,6 +13,8 @@ export declare class BulkAccountLoader {
16
13
  accountData: Map<string, AccountData>;
17
14
  errorCallbacks: Map<string, (e: any) => void>;
18
15
  intervalId?: NodeJS.Timer;
16
+ loadPromise?: Promise<void>;
17
+ loadPromiseResolver: () => void;
19
18
  constructor(connection: Connection, commitment: Commitment, pollingFrequency: number);
20
19
  addAccount(publicKey: PublicKey, callback: (buffer: Buffer) => void): string;
21
20
  removeAccount(publicKey: PublicKey, callbackId: string): void;
@@ -40,6 +40,8 @@ class BulkAccountLoader {
40
40
  if (existingSize === 0) {
41
41
  this.startPolling();
42
42
  }
43
+ // if a new account needs to be polled, remove the cached loadPromise in case client calls load immediately after
44
+ this.loadPromise = undefined;
43
45
  return callbackId;
44
46
  }
45
47
  removeAccount(publicKey, callbackId) {
@@ -70,10 +72,27 @@ class BulkAccountLoader {
70
72
  }
71
73
  load() {
72
74
  return __awaiter(this, void 0, void 0, function* () {
73
- const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
74
- yield Promise.all(chunks.map((chunk) => {
75
- return this.loadChunk(chunk);
76
- }));
75
+ if (this.loadPromise) {
76
+ return this.loadPromise;
77
+ }
78
+ this.loadPromise = new Promise((resolver) => {
79
+ this.loadPromiseResolver = resolver;
80
+ });
81
+ try {
82
+ const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
83
+ yield Promise.all(chunks.map((chunk) => {
84
+ return this.loadChunk(chunk);
85
+ }));
86
+ }
87
+ catch (e) {
88
+ console.error(`Error in bulkAccountLoader.load()`);
89
+ console.error(e);
90
+ for (const [_, callback] of this.errorCallbacks) {
91
+ callback(e);
92
+ }
93
+ }
94
+ this.loadPromiseResolver();
95
+ this.loadPromise = undefined;
77
96
  });
78
97
  }
79
98
  loadChunk(accountsToLoad) {
@@ -54,11 +54,14 @@ class PollingUserAccountSubscriber {
54
54
  eventType: 'userPositionsData',
55
55
  });
56
56
  const userOrdersPublicKey = yield addresses_1.getUserOrdersAccountPublicKey(this.program.programId, userPublicKey);
57
- this.accountsToPoll.set(userOrdersPublicKey.toString(), {
58
- key: 'userOrders',
59
- publicKey: userOrdersPublicKey,
60
- eventType: 'userOrdersData',
61
- });
57
+ const userOrdersExist = (yield this.program.provider.connection.getParsedAccountInfo(userOrdersPublicKey)).value !== null;
58
+ if (userOrdersExist) {
59
+ this.accountsToPoll.set(userOrdersPublicKey.toString(), {
60
+ key: 'userOrders',
61
+ publicKey: userOrdersPublicKey,
62
+ eventType: 'userOrdersData',
63
+ });
64
+ }
62
65
  for (const [_, accountToPoll] of this.accountsToPoll) {
63
66
  accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer) => {
64
67
  const account = this.program.account[accountToPoll.key].coder.accounts.decode(utils_1.capitalize(accountToPoll.key), buffer);
@@ -85,3 +85,7 @@ export declare type AccountToPoll = {
85
85
  eventType: string;
86
86
  callbackId?: string;
87
87
  };
88
+ export declare type AccountData = {
89
+ slot: number;
90
+ buffer: Buffer | undefined;
91
+ };
@@ -1,14 +1,18 @@
1
- import { AccountSubscriber } from './types';
1
+ /// <reference types="node" />
2
+ import { AccountData, AccountSubscriber } from './types';
2
3
  import { Program } from '@project-serum/anchor';
3
- import { PublicKey } from '@solana/web3.js';
4
+ import { AccountInfo, Context, PublicKey } from '@solana/web3.js';
4
5
  export declare class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
5
6
  data?: T;
7
+ accountData?: AccountData;
6
8
  accountName: string;
7
9
  program: Program;
8
10
  accountPublicKey: PublicKey;
9
11
  onChange: (data: T) => void;
12
+ listenerId?: number;
10
13
  constructor(accountName: string, program: Program, accountPublicKey: PublicKey);
11
14
  subscribe(onChange: (data: T) => void): Promise<void>;
12
15
  fetch(): Promise<void>;
16
+ handleRpcResponse(context: Context, accountInfo?: AccountInfo<Buffer>): void;
13
17
  unsubscribe(): Promise<void>;
14
18
  }
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.WebSocketAccountSubscriber = void 0;
13
+ const utils_1 = require("./utils");
13
14
  class WebSocketAccountSubscriber {
14
15
  constructor(accountName, program, accountPublicKey) {
15
16
  this.accountName = accountName;
@@ -18,28 +19,58 @@ class WebSocketAccountSubscriber {
18
19
  }
19
20
  subscribe(onChange) {
20
21
  return __awaiter(this, void 0, void 0, function* () {
22
+ if (this.listenerId) {
23
+ return;
24
+ }
21
25
  this.onChange = onChange;
22
26
  yield this.fetch();
23
- this.program.account[this.accountName]
24
- .subscribe(this.accountPublicKey, this.program.provider.opts.commitment)
25
- .on('change', (data) => __awaiter(this, void 0, void 0, function* () {
26
- this.data = data;
27
- this.onChange(data);
28
- }));
27
+ this.listenerId = this.program.provider.connection.onAccountChange(this.accountPublicKey, (accountInfo, context) => {
28
+ this.handleRpcResponse(context, accountInfo);
29
+ }, this.program.provider.opts.commitment);
29
30
  });
30
31
  }
31
32
  fetch() {
32
33
  return __awaiter(this, void 0, void 0, function* () {
33
- const newData = (yield this.program.account[this.accountName].fetch(this.accountPublicKey));
34
- // if data has changed trigger update
35
- if (JSON.stringify(newData) !== JSON.stringify(this.data)) {
36
- this.data = newData;
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
+ });
37
+ }
38
+ handleRpcResponse(context, accountInfo) {
39
+ const newSlot = context.slot;
40
+ let newBuffer = undefined;
41
+ if (accountInfo) {
42
+ newBuffer = accountInfo.data;
43
+ }
44
+ if (!this.accountData) {
45
+ this.accountData = {
46
+ buffer: newBuffer,
47
+ slot: newSlot,
48
+ };
49
+ if (newBuffer) {
50
+ this.data = this.program.account[this.accountName].coder.accounts.decode(utils_1.capitalize(this.accountName), newBuffer);
37
51
  this.onChange(this.data);
38
52
  }
39
- });
53
+ return;
54
+ }
55
+ if (newSlot <= this.accountData.slot) {
56
+ return;
57
+ }
58
+ const oldBuffer = this.accountData.buffer;
59
+ if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
60
+ this.accountData = {
61
+ buffer: newBuffer,
62
+ slot: newSlot,
63
+ };
64
+ this.data = this.program.account[this.accountName].coder.accounts.decode(utils_1.capitalize(this.accountName), newBuffer);
65
+ this.onChange(this.data);
66
+ }
40
67
  }
41
68
  unsubscribe() {
42
- return this.program.account[this.accountName].unsubscribe(this.accountPublicKey);
69
+ if (this.listenerId) {
70
+ const promise = this.program.provider.connection.removeAccountChangeListener(this.listenerId);
71
+ this.listenerId = undefined;
72
+ return promise;
73
+ }
43
74
  }
44
75
  }
45
76
  exports.WebSocketAccountSubscriber = WebSocketAccountSubscriber;
@@ -101,6 +101,8 @@ export declare class ClearingHouse {
101
101
  * @returns
102
102
  */
103
103
  getUserOrdersAccountPublicKey(): Promise<PublicKey>;
104
+ userOrdersExist?: boolean;
105
+ userOrdersAccountExists(): Promise<boolean>;
104
106
  depositCollateral(amount: BN, collateralAccountPublicKey: PublicKey, userPositionsAccountPublicKey?: PublicKey): Promise<TransactionSignature>;
105
107
  getDepositCollateralInstruction(amount: BN, collateralAccountPublicKey: PublicKey, userPositionsAccountPublicKey?: PublicKey): Promise<TransactionInstruction>;
106
108
  /**
@@ -116,6 +118,7 @@ export declare class ClearingHouse {
116
118
  getWithdrawCollateralIx(amount: BN, collateralAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
117
119
  openPosition(direction: PositionDirection, amount: BN, marketIndex: BN, limitPrice?: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
118
120
  getOpenPositionIx(direction: PositionDirection, amount: BN, marketIndex: BN, limitPrice?: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
121
+ initializeUserOrdersThenPlaceOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
119
122
  placeOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
120
123
  getPlaceOrderIx(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
121
124
  cancelOrder(orderId: BN): Promise<TransactionSignature>;
@@ -124,6 +127,7 @@ export declare class ClearingHouse {
124
127
  getCancelOrderByUserIdIx(userOrderId: number): Promise<TransactionInstruction>;
125
128
  fillOrder(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionSignature>;
126
129
  getFillOrderIx(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionInstruction>;
130
+ initializeUserOrdersThenPlaceAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
127
131
  placeAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
128
132
  getPlaceAndFillOrderIx(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
129
133
  /**
@@ -292,6 +292,16 @@ class ClearingHouse {
292
292
  return this.userOrdersAccountPublicKey;
293
293
  });
294
294
  }
295
+ userOrdersAccountExists() {
296
+ return __awaiter(this, void 0, void 0, function* () {
297
+ if (this.userOrdersExist) {
298
+ return this.userOrdersExist;
299
+ }
300
+ const userOrdersAccountRPCResponse = yield this.connection.getParsedAccountInfo(yield this.getUserOrdersAccountPublicKey());
301
+ this.userOrdersExist = userOrdersAccountRPCResponse.value !== null;
302
+ return this.userOrdersExist;
303
+ });
304
+ }
295
305
  depositCollateral(amount, collateralAccountPublicKey, userPositionsAccountPublicKey) {
296
306
  return __awaiter(this, void 0, void 0, function* () {
297
307
  const depositCollateralIx = yield this.getDepositCollateralInstruction(amount, collateralAccountPublicKey, userPositionsAccountPublicKey);
@@ -449,6 +459,21 @@ class ClearingHouse {
449
459
  });
450
460
  });
451
461
  }
462
+ initializeUserOrdersThenPlaceOrder(orderParams, discountToken, referrer) {
463
+ return __awaiter(this, void 0, void 0, function* () {
464
+ const instructions = [];
465
+ const userOrdersAccountExists = yield this.userOrdersAccountExists();
466
+ if (!userOrdersAccountExists) {
467
+ instructions.push(yield this.getInitializeUserOrdersInstruction());
468
+ }
469
+ instructions.push(yield this.getPlaceOrderIx(orderParams, discountToken, referrer));
470
+ const tx = new web3_js_1.Transaction();
471
+ for (const instruction of instructions) {
472
+ tx.add(instruction);
473
+ }
474
+ return yield this.txSender.send(tx, [], this.opts);
475
+ });
476
+ }
452
477
  placeOrder(orderParams, discountToken, referrer) {
453
478
  return __awaiter(this, void 0, void 0, function* () {
454
479
  return yield this.txSender.send(utils_1.wrapInTx(yield this.getPlaceOrderIx(orderParams, discountToken, referrer)), [], this.opts);
@@ -598,6 +623,21 @@ class ClearingHouse {
598
623
  });
599
624
  });
600
625
  }
626
+ initializeUserOrdersThenPlaceAndFillOrder(orderParams, discountToken, referrer) {
627
+ return __awaiter(this, void 0, void 0, function* () {
628
+ const instructions = [];
629
+ const userOrdersAccountExists = yield this.userOrdersAccountExists();
630
+ if (!userOrdersAccountExists) {
631
+ instructions.push(yield this.getInitializeUserOrdersInstruction());
632
+ }
633
+ instructions.push(yield this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer));
634
+ const tx = new web3_js_1.Transaction();
635
+ for (const instruction of instructions) {
636
+ tx.add(instruction);
637
+ }
638
+ return yield this.txSender.send(tx, [], this.opts);
639
+ });
640
+ }
601
641
  placeAndFillOrder(orderParams, discountToken, referrer) {
602
642
  return __awaiter(this, void 0, void 0, function* () {
603
643
  return yield this.txSender.send(utils_1.wrapInTx(yield this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)), [], this.opts);
@@ -1,12 +1,12 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="bn.js" />
2
3
  import { PublicKey } from '@solana/web3.js';
3
- import BN from 'bn.js';
4
4
  import { EventEmitter } from 'events';
5
5
  import StrictEventEmitter from 'strict-event-emitter-types';
6
6
  import { ClearingHouse } from './clearingHouse';
7
7
  import { Order, UserAccount, UserOrdersAccount, UserPosition, UserPositionsAccount } from './types';
8
8
  import { UserAccountSubscriber, UserAccountEvents } from './accounts/types';
9
- import { PositionDirection } from '.';
9
+ import { PositionDirection, BN } from '.';
10
10
  export declare class ClearingHouseUser {
11
11
  clearingHouse: ClearingHouse;
12
12
  authority: PublicKey;
@@ -37,7 +37,7 @@ export declare class ClearingHouseUser {
37
37
  unsubscribe(): Promise<void>;
38
38
  getUserAccount(): UserAccount;
39
39
  getUserPositionsAccount(): UserPositionsAccount;
40
- getUserOrdersAccount(): UserOrdersAccount;
40
+ getUserOrdersAccount(): UserOrdersAccount | undefined;
41
41
  /**
42
42
  * Gets the user's current position for a given market. If the user has no position returns undefined
43
43
  * @param marketIndex
@@ -50,6 +50,11 @@ export declare class ClearingHouseUser {
50
50
  * @returns Order
51
51
  */
52
52
  getOrder(orderId: BN): Order | undefined;
53
+ /**
54
+ * @param userOrderId
55
+ * @returns Order
56
+ */
57
+ getOrderByUserOrderId(userOrderId: number): Order | undefined;
53
58
  getUserAccountPublicKey(): Promise<PublicKey>;
54
59
  getUserOrdersAccountPublicKey(): Promise<PublicKey>;
55
60
  exists(): Promise<boolean>;
@@ -8,12 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.ClearingHouseUser = void 0;
16
- const bn_js_1 = __importDefault(require("bn.js"));
17
13
  const position_1 = require("./math/position");
18
14
  const numericConstants_1 = require("./constants/numericConstants");
19
15
  const _1 = require(".");
@@ -104,6 +100,13 @@ class ClearingHouseUser {
104
100
  getOrder(orderId) {
105
101
  return this.getUserOrdersAccount().orders.find((order) => order.orderId.eq(orderId));
106
102
  }
103
+ /**
104
+ * @param userOrderId
105
+ * @returns Order
106
+ */
107
+ getOrderByUserOrderId(userOrderId) {
108
+ return this.getUserOrdersAccount().orders.find((order) => order.userOrderId === userOrderId);
109
+ }
107
110
  getUserAccountPublicKey() {
108
111
  return __awaiter(this, void 0, void 0, function* () {
109
112
  if (this.userAccountPublicKey) {
@@ -177,7 +180,7 @@ class ClearingHouseUser {
177
180
  */
178
181
  getTotalCollateral() {
179
182
  var _a;
180
- return ((_a = this.getUserAccount().collateral.add(this.getUnrealizedPNL(true))) !== null && _a !== void 0 ? _a : new bn_js_1.default(0));
183
+ return ((_a = this.getUserAccount().collateral.add(this.getUnrealizedPNL(true))) !== null && _a !== void 0 ? _a : new _1.BN(0));
181
184
  }
182
185
  /**
183
186
  * calculates sum of position value across all positions
@@ -345,9 +348,9 @@ class ClearingHouseUser {
345
348
  const proposedMarketPosition = {
346
349
  marketIndex: targetMarket.marketIndex,
347
350
  baseAssetAmount: currentMarketPositionBaseSize.add(positionBaseSizeChange),
348
- lastCumulativeFundingRate: new bn_js_1.default(0),
349
- quoteAssetAmount: new bn_js_1.default(0),
350
- openOrders: new bn_js_1.default(0),
351
+ lastCumulativeFundingRate: new _1.BN(0),
352
+ quoteAssetAmount: new _1.BN(0),
353
+ openOrders: new _1.BN(0),
351
354
  };
352
355
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
353
356
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
@@ -364,7 +367,7 @@ class ClearingHouseUser {
364
367
  // if the position value after the trade is less than total collateral, there is no liq price
365
368
  if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
366
369
  proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
367
- return new bn_js_1.default(-1);
370
+ return new _1.BN(-1);
368
371
  }
369
372
  // get current margin ratio based on current collateral and proposed total position value
370
373
  let marginRatio;
@@ -391,7 +394,7 @@ class ClearingHouseUser {
391
394
  if (numericConstants_1.TEN_THOUSAND.lte(pctChange)) {
392
395
  // no liquidation price, position is a fully/over collateralized long
393
396
  // handle as NaN on UI
394
- return new bn_js_1.default(-1);
397
+ return new _1.BN(-1);
395
398
  }
396
399
  pctChange = numericConstants_1.TEN_THOUSAND.sub(pctChange);
397
400
  }
@@ -420,7 +423,7 @@ class ClearingHouseUser {
420
423
  const tpv = this.getTotalPositionValue();
421
424
  const partialLev = 16;
422
425
  const maintLev = 20;
423
- const thisLev = partial ? new bn_js_1.default(partialLev) : new bn_js_1.default(maintLev);
426
+ const thisLev = partial ? new _1.BN(partialLev) : new _1.BN(maintLev);
424
427
  // calculate the total position value ignoring any value from the target market of the trade
425
428
  const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
426
429
  const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
@@ -432,8 +435,8 @@ class ClearingHouseUser {
432
435
  marketIndex: targetMarket.marketIndex,
433
436
  baseAssetAmount: proposedBaseAssetAmount,
434
437
  lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
435
- quoteAssetAmount: new bn_js_1.default(0),
436
- openOrders: new bn_js_1.default(0),
438
+ quoteAssetAmount: new _1.BN(0),
439
+ openOrders: new _1.BN(0),
437
440
  };
438
441
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
439
442
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
@@ -453,14 +456,14 @@ class ClearingHouseUser {
453
456
  .mul(thisLev)
454
457
  .sub(tpv)
455
458
  .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
456
- .div(thisLev.add(new bn_js_1.default(1)));
459
+ .div(thisLev.add(new _1.BN(1)));
457
460
  }
458
461
  else {
459
462
  priceDelt = tc
460
463
  .mul(thisLev)
461
464
  .sub(tpv)
462
465
  .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
463
- .div(thisLev.sub(new bn_js_1.default(1)));
466
+ .div(thisLev.sub(new _1.BN(1)));
464
467
  }
465
468
  let currentPrice;
466
469
  if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
@@ -475,15 +478,15 @@ class ClearingHouseUser {
475
478
  // if the position value after the trade is less than total collateral, there is no liq price
476
479
  if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
477
480
  proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
478
- return new bn_js_1.default(-1);
481
+ return new _1.BN(-1);
479
482
  }
480
483
  if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
481
- return new bn_js_1.default(-1);
484
+ return new _1.BN(-1);
482
485
  const eatMargin2 = priceDelt
483
486
  .mul(numericConstants_1.AMM_RESERVE_PRECISION)
484
487
  .div(proposedBaseAssetAmount);
485
488
  if (eatMargin2.gt(currentPrice)) {
486
- return new bn_js_1.default(-1);
489
+ return new _1.BN(-1);
487
490
  }
488
491
  const liqPrice = currentPrice.sub(eatMargin2);
489
492
  return liqPrice;
@@ -536,7 +539,7 @@ class ClearingHouseUser {
536
539
  const currentLeverage = this.getLeverage();
537
540
  // remaining leverage
538
541
  // let remainingLeverage = userMaxLeverageSetting;
539
- const remainingLeverage = bn_js_1.default.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
542
+ const remainingLeverage = _1.BN.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
540
543
  // get total collateral
541
544
  const totalCollateral = this.getTotalCollateral();
542
545
  // position side allowed based purely on current leverage
@@ -545,7 +548,7 @@ class ClearingHouseUser {
545
548
  .div(numericConstants_1.TEN_THOUSAND);
546
549
  // add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
547
550
  const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
548
- maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
551
+ maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new _1.BN(2)));
549
552
  // subtract oneMillionth of maxPositionSize
550
553
  // => to avoid rounding errors when taking max leverage
551
554
  const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
package/lib/config.js CHANGED
@@ -5,7 +5,7 @@ exports.configs = {
5
5
  devnet: {
6
6
  ENV: 'devnet',
7
7
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
8
- CLEARING_HOUSE_PROGRAM_ID: '8mKouB1uzsoMAhAu4qAXCiu8KAfwH7nonpuYfTM21Xg2',
8
+ CLEARING_HOUSE_PROGRAM_ID: '3PfbDmWxR6e2rJ2brhSv7KJyUrHbSCu63d3FHqdLhxUJ',
9
9
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
10
10
  },
11
11
  'mainnet-beta': {
@@ -1,4 +1,5 @@
1
- import BN from 'bn.js';
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '../';
2
3
  declare type Market = {
3
4
  symbol: string;
4
5
  baseAssetSymbol: string;
@@ -1,15 +1,12 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Markets = void 0;
7
- const bn_js_1 = __importDefault(require("bn.js"));
4
+ const __1 = require("../");
8
5
  exports.Markets = [
9
6
  {
10
7
  symbol: 'SOL-PERP',
11
8
  baseAssetSymbol: 'SOL',
12
- marketIndex: new bn_js_1.default(0),
9
+ marketIndex: new __1.BN(0),
13
10
  devnetPythOracle: 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix',
14
11
  mainnetPythOracle: 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG',
15
12
  launchTs: 1635209696886,
@@ -17,7 +14,7 @@ exports.Markets = [
17
14
  {
18
15
  symbol: 'BTC-PERP',
19
16
  baseAssetSymbol: 'BTC',
20
- marketIndex: new bn_js_1.default(1),
17
+ marketIndex: new __1.BN(1),
21
18
  devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
22
19
  mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
23
20
  launchTs: 1637691088868,
@@ -25,7 +22,7 @@ exports.Markets = [
25
22
  {
26
23
  symbol: 'ETH-PERP',
27
24
  baseAssetSymbol: 'ETH',
28
- marketIndex: new bn_js_1.default(2),
25
+ marketIndex: new __1.BN(2),
29
26
  devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
30
27
  mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
31
28
  launchTs: 1637691133472,
@@ -33,7 +30,7 @@ exports.Markets = [
33
30
  {
34
31
  symbol: 'LUNA-PERP',
35
32
  baseAssetSymbol: 'LUNA',
36
- marketIndex: new bn_js_1.default(3),
33
+ marketIndex: new __1.BN(3),
37
34
  devnetPythOracle: '8PugCXTAHLM9kfLSQWe2njE5pzAgUdpPk3Nx5zSm7BD3',
38
35
  mainnetPythOracle: '5bmWuR1dgP4avtGYMNKLuxumZTVKGgoN2BCMXWDNL9nY',
39
36
  launchTs: 1638821738525,
@@ -41,7 +38,7 @@ exports.Markets = [
41
38
  {
42
39
  symbol: 'AVAX-PERP',
43
40
  baseAssetSymbol: 'AVAX',
44
- marketIndex: new bn_js_1.default(4),
41
+ marketIndex: new __1.BN(4),
45
42
  devnetPythOracle: 'FVb5h1VmHPfVb1RfqZckchq18GxRv4iKt8T4eVTQAqdz',
46
43
  mainnetPythOracle: 'Ax9ujW5B9oqcv59N8m6f1BpTBq2rGeGaBcpKjC5UYsXU',
47
44
  launchTs: 1639092501080,
@@ -49,7 +46,7 @@ exports.Markets = [
49
46
  {
50
47
  symbol: 'BNB-PERP',
51
48
  baseAssetSymbol: 'BNB',
52
- marketIndex: new bn_js_1.default(5),
49
+ marketIndex: new __1.BN(5),
53
50
  devnetPythOracle: 'GwzBgrXb4PG59zjce24SF2b9JXbLEjJJTBkmytuEZj1b',
54
51
  mainnetPythOracle: '4CkQJBxhU8EZ2UjhigbtdaPbpTe6mqf811fipYBFbSYN',
55
52
  launchTs: 1639523193012,
@@ -57,7 +54,7 @@ exports.Markets = [
57
54
  {
58
55
  symbol: 'MATIC-PERP',
59
56
  baseAssetSymbol: 'MATIC',
60
- marketIndex: new bn_js_1.default(6),
57
+ marketIndex: new __1.BN(6),
61
58
  devnetPythOracle: 'FBirwuDFuRAu4iSGc7RGxN5koHB7EJM1wbCmyPuQoGur',
62
59
  mainnetPythOracle: '7KVswB9vkCgeM3SHP7aGDijvdRAHK8P5wi9JXViCrtYh',
63
60
  launchTs: 1641488603564,
@@ -65,7 +62,7 @@ exports.Markets = [
65
62
  {
66
63
  symbol: 'ATOM-PERP',
67
64
  baseAssetSymbol: 'ATOM',
68
- marketIndex: new bn_js_1.default(7),
65
+ marketIndex: new __1.BN(7),
69
66
  devnetPythOracle: '7YAze8qFUMkBnyLVdKT4TFUUFui99EwS5gfRArMcrvFk',
70
67
  mainnetPythOracle: 'CrCpTerNqtZvqLcKqz1k13oVeXV9WkMD2zA9hBKXrsbN',
71
68
  launchTs: 1641920238195,
@@ -73,7 +70,7 @@ exports.Markets = [
73
70
  {
74
71
  symbol: 'DOT-PERP',
75
72
  baseAssetSymbol: 'DOT',
76
- marketIndex: new bn_js_1.default(8),
73
+ marketIndex: new __1.BN(8),
77
74
  devnetPythOracle: '4dqq5VBpN4EwYb7wyywjjfknvMKu7m78j9mKZRXTj462',
78
75
  mainnetPythOracle: 'EcV1X1gY2yb4KXxjVQtTHTbioum2gvmPnFk4zYAt7zne',
79
76
  launchTs: 1642629253786,
@@ -81,7 +78,7 @@ exports.Markets = [
81
78
  {
82
79
  symbol: 'ADA-PERP',
83
80
  baseAssetSymbol: 'ADA',
84
- marketIndex: new bn_js_1.default(9),
81
+ marketIndex: new __1.BN(9),
85
82
  devnetPythOracle: '8oGTURNmSQkrBS1AQ5NjB2p8qY34UVmMA9ojrw8vnHus',
86
83
  mainnetPythOracle: '3pyn4svBbxJ9Wnn3RVeafyLWfzie6yC5eTig2S62v9SC',
87
84
  launchTs: 1643084413000,
@@ -89,11 +86,19 @@ exports.Markets = [
89
86
  {
90
87
  symbol: 'ALGO-PERP',
91
88
  baseAssetSymbol: 'ALGO',
92
- marketIndex: new bn_js_1.default(10),
89
+ marketIndex: new __1.BN(10),
93
90
  devnetPythOracle: 'c1A946dY5NHuVda77C8XXtXytyR3wK1SCP3eA9VRfC3',
94
91
  mainnetPythOracle: 'HqFyq1wh1xKvL7KDqqT7NJeSPdAqsDqnmBisUC2XdXAX',
95
92
  launchTs: 1643686767000,
96
93
  },
94
+ {
95
+ symbol: 'FTT-PERP',
96
+ baseAssetSymbol: 'FTT',
97
+ marketIndex: new __1.BN(11),
98
+ devnetPythOracle: '6vivTRs5ZPeeXbjo7dfburfaYDWoXjBtdtuYgQRuGfu',
99
+ mainnetPythOracle: '8JPJJkmDScpcNmBRKGZuPuG2GYAveQgP3t5gFuMymwvF',
100
+ launchTs: 1644382122000,
101
+ },
97
102
  // {
98
103
  // symbol: 'mSOL-PERP',
99
104
  // baseAssetSymbol: 'mSOL',
@@ -1,6 +1,8 @@
1
- import BN from 'bn.js';
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '../';
2
3
  export declare const ZERO: BN;
3
4
  export declare const ONE: BN;
5
+ export declare const TWO: BN;
4
6
  export declare const TEN_THOUSAND: BN;
5
7
  export declare const BN_MAX: BN;
6
8
  export declare const MAX_LEVERAGE: BN;
@@ -11,6 +13,7 @@ export declare const MARK_PRICE_PRECISION: BN;
11
13
  export declare const FUNDING_PAYMENT_PRECISION: BN;
12
14
  export declare const PEG_PRECISION: BN;
13
15
  export declare const AMM_RESERVE_PRECISION: BN;
16
+ export declare const BASE_PRECISION: BN;
14
17
  export declare const AMM_TO_QUOTE_PRECISION_RATIO: BN;
15
18
  export declare const PRICE_TO_QUOTE_PRECISION: BN;
16
19
  export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
@@ -1,22 +1,21 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.PARTIAL_LIQUIDATION_RATIO = exports.FULL_LIQUIDATION_RATIO = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.ONE = exports.ZERO = void 0;
7
- const bn_js_1 = __importDefault(require("bn.js"));
8
- exports.ZERO = new bn_js_1.default(0);
9
- exports.ONE = new bn_js_1.default(1);
10
- exports.TEN_THOUSAND = new bn_js_1.default(10000);
11
- exports.BN_MAX = new bn_js_1.default(Number.MAX_SAFE_INTEGER);
12
- exports.MAX_LEVERAGE = new bn_js_1.default(5);
13
- exports.FULL_LIQUIDATION_RATIO = new bn_js_1.default(500);
14
- exports.PARTIAL_LIQUIDATION_RATIO = new bn_js_1.default(625);
15
- exports.QUOTE_PRECISION = new bn_js_1.default(Math.pow(10, 6));
16
- exports.MARK_PRICE_PRECISION = new bn_js_1.default(Math.pow(10, 10));
17
- exports.FUNDING_PAYMENT_PRECISION = new bn_js_1.default(10000);
18
- exports.PEG_PRECISION = new bn_js_1.default(1000);
19
- exports.AMM_RESERVE_PRECISION = new bn_js_1.default(Math.pow(10, 13));
3
+ exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.PARTIAL_LIQUIDATION_RATIO = exports.FULL_LIQUIDATION_RATIO = exports.MAX_LEVERAGE = exports.BN_MAX = exports.TEN_THOUSAND = exports.TWO = exports.ONE = exports.ZERO = void 0;
4
+ const __1 = require("../");
5
+ exports.ZERO = new __1.BN(0);
6
+ exports.ONE = new __1.BN(1);
7
+ exports.TWO = new __1.BN(2);
8
+ exports.TEN_THOUSAND = new __1.BN(10000);
9
+ exports.BN_MAX = new __1.BN(Number.MAX_SAFE_INTEGER);
10
+ exports.MAX_LEVERAGE = new __1.BN(5);
11
+ exports.FULL_LIQUIDATION_RATIO = new __1.BN(500);
12
+ exports.PARTIAL_LIQUIDATION_RATIO = new __1.BN(625);
13
+ exports.QUOTE_PRECISION = new __1.BN(Math.pow(10, 6));
14
+ exports.MARK_PRICE_PRECISION = new __1.BN(Math.pow(10, 10));
15
+ exports.FUNDING_PAYMENT_PRECISION = new __1.BN(10000);
16
+ exports.PEG_PRECISION = new __1.BN(1000);
17
+ exports.AMM_RESERVE_PRECISION = new __1.BN(Math.pow(10, 13));
18
+ exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION;
20
19
  exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.div(exports.QUOTE_PRECISION); // 10^7
21
20
  exports.PRICE_TO_QUOTE_PRECISION = exports.MARK_PRICE_PRECISION.div(exports.QUOTE_PRECISION);
22
21
  exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.mul(exports.PEG_PRECISION).div(exports.QUOTE_PRECISION); // 10^10