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

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 (48) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +3 -4
  2. package/lib/accounts/bulkAccountLoader.js +23 -4
  3. package/lib/accounts/types.d.ts +4 -0
  4. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -2
  5. package/lib/accounts/webSocketAccountSubscriber.js +43 -12
  6. package/lib/clearingHouse.d.ts +4 -0
  7. package/lib/clearingHouse.js +40 -0
  8. package/lib/clearingHouseUser.d.ts +3 -3
  9. package/lib/clearingHouseUser.js +16 -20
  10. package/lib/config.js +1 -1
  11. package/lib/constants/markets.d.ts +2 -1
  12. package/lib/constants/markets.js +20 -15
  13. package/lib/constants/numericConstants.d.ts +3 -1
  14. package/lib/constants/numericConstants.js +15 -17
  15. package/lib/examples/makeTradeExample.js +1 -1
  16. package/lib/idl/clearing_house.json +6 -2
  17. package/lib/math/conversion.d.ts +1 -1
  18. package/lib/math/insuranceFund.d.ts +2 -1
  19. package/lib/math/insuranceFund.js +3 -6
  20. package/lib/math/position.d.ts +2 -1
  21. package/lib/math/position.js +2 -5
  22. package/lib/math/utils.d.ts +2 -1
  23. package/lib/math/utils.js +3 -6
  24. package/lib/mockUSDCFaucet.d.ts +2 -1
  25. package/lib/orderParams.d.ts +2 -2
  26. package/lib/orderParams.js +7 -7
  27. package/lib/orders.d.ts +2 -1
  28. package/lib/types.d.ts +7 -5
  29. package/lib/types.js +2 -2
  30. package/package.json +9 -1
  31. package/src/accounts/bulkAccountLoader.ts +35 -15
  32. package/src/accounts/types.ts +5 -0
  33. package/src/accounts/webSocketAccountSubscriber.ts +67 -17
  34. package/src/clearingHouse.ts +56 -0
  35. package/src/clearingHouseUser.ts +2 -2
  36. package/src/config.ts +1 -1
  37. package/src/constants/markets.ts +9 -1
  38. package/src/constants/numericConstants.ts +2 -1
  39. package/src/examples/makeTradeExample.ts +4 -1
  40. package/src/idl/clearing_house.json +6 -2
  41. package/src/math/conversion.ts +1 -1
  42. package/src/math/insuranceFund.ts +1 -1
  43. package/src/math/position.ts +1 -1
  44. package/src/math/utils.ts +1 -1
  45. package/src/mockUSDCFaucet.ts +1 -1
  46. package/src/orderParams.ts +4 -4
  47. package/src/orders.ts +1 -1
  48. package/src/types.ts +4 -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) {
@@ -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
@@ -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(".");
@@ -177,7 +173,7 @@ class ClearingHouseUser {
177
173
  */
178
174
  getTotalCollateral() {
179
175
  var _a;
180
- return ((_a = this.getUserAccount().collateral.add(this.getUnrealizedPNL(true))) !== null && _a !== void 0 ? _a : new bn_js_1.default(0));
176
+ return ((_a = this.getUserAccount().collateral.add(this.getUnrealizedPNL(true))) !== null && _a !== void 0 ? _a : new _1.BN(0));
181
177
  }
182
178
  /**
183
179
  * calculates sum of position value across all positions
@@ -345,9 +341,9 @@ class ClearingHouseUser {
345
341
  const proposedMarketPosition = {
346
342
  marketIndex: targetMarket.marketIndex,
347
343
  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),
344
+ lastCumulativeFundingRate: new _1.BN(0),
345
+ quoteAssetAmount: new _1.BN(0),
346
+ openOrders: new _1.BN(0),
351
347
  };
352
348
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
353
349
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
@@ -364,7 +360,7 @@ class ClearingHouseUser {
364
360
  // if the position value after the trade is less than total collateral, there is no liq price
365
361
  if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
366
362
  proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
367
- return new bn_js_1.default(-1);
363
+ return new _1.BN(-1);
368
364
  }
369
365
  // get current margin ratio based on current collateral and proposed total position value
370
366
  let marginRatio;
@@ -391,7 +387,7 @@ class ClearingHouseUser {
391
387
  if (numericConstants_1.TEN_THOUSAND.lte(pctChange)) {
392
388
  // no liquidation price, position is a fully/over collateralized long
393
389
  // handle as NaN on UI
394
- return new bn_js_1.default(-1);
390
+ return new _1.BN(-1);
395
391
  }
396
392
  pctChange = numericConstants_1.TEN_THOUSAND.sub(pctChange);
397
393
  }
@@ -420,7 +416,7 @@ class ClearingHouseUser {
420
416
  const tpv = this.getTotalPositionValue();
421
417
  const partialLev = 16;
422
418
  const maintLev = 20;
423
- const thisLev = partial ? new bn_js_1.default(partialLev) : new bn_js_1.default(maintLev);
419
+ const thisLev = partial ? new _1.BN(partialLev) : new _1.BN(maintLev);
424
420
  // calculate the total position value ignoring any value from the target market of the trade
425
421
  const totalCurrentPositionValueIgnoringTargetUSDC = this.getTotalPositionValueExcludingMarket(targetMarket.marketIndex);
426
422
  const currentMarketPosition = this.getUserPosition(targetMarket.marketIndex) ||
@@ -432,8 +428,8 @@ class ClearingHouseUser {
432
428
  marketIndex: targetMarket.marketIndex,
433
429
  baseAssetAmount: proposedBaseAssetAmount,
434
430
  lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
435
- quoteAssetAmount: new bn_js_1.default(0),
436
- openOrders: new bn_js_1.default(0),
431
+ quoteAssetAmount: new _1.BN(0),
432
+ openOrders: new _1.BN(0),
437
433
  };
438
434
  const market = this.clearingHouse.getMarket(proposedMarketPosition.marketIndex);
439
435
  const proposedMarketPositionValueUSDC = _1.calculateBaseAssetValue(market, proposedMarketPosition);
@@ -453,14 +449,14 @@ class ClearingHouseUser {
453
449
  .mul(thisLev)
454
450
  .sub(tpv)
455
451
  .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
456
- .div(thisLev.add(new bn_js_1.default(1)));
452
+ .div(thisLev.add(new _1.BN(1)));
457
453
  }
458
454
  else {
459
455
  priceDelt = tc
460
456
  .mul(thisLev)
461
457
  .sub(tpv)
462
458
  .mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
463
- .div(thisLev.sub(new bn_js_1.default(1)));
459
+ .div(thisLev.sub(new _1.BN(1)));
464
460
  }
465
461
  let currentPrice;
466
462
  if (positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
@@ -475,15 +471,15 @@ class ClearingHouseUser {
475
471
  // if the position value after the trade is less than total collateral, there is no liq price
476
472
  if (targetTotalPositionValueUSDC.lte(totalFreeCollateralUSDC) &&
477
473
  proposedMarketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
478
- return new bn_js_1.default(-1);
474
+ return new _1.BN(-1);
479
475
  }
480
476
  if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
481
- return new bn_js_1.default(-1);
477
+ return new _1.BN(-1);
482
478
  const eatMargin2 = priceDelt
483
479
  .mul(numericConstants_1.AMM_RESERVE_PRECISION)
484
480
  .div(proposedBaseAssetAmount);
485
481
  if (eatMargin2.gt(currentPrice)) {
486
- return new bn_js_1.default(-1);
482
+ return new _1.BN(-1);
487
483
  }
488
484
  const liqPrice = currentPrice.sub(eatMargin2);
489
485
  return liqPrice;
@@ -536,7 +532,7 @@ class ClearingHouseUser {
536
532
  const currentLeverage = this.getLeverage();
537
533
  // remaining leverage
538
534
  // let remainingLeverage = userMaxLeverageSetting;
539
- const remainingLeverage = bn_js_1.default.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
535
+ const remainingLeverage = _1.BN.max(userMaxLeverageSetting.sub(currentLeverage), numericConstants_1.ZERO);
540
536
  // get total collateral
541
537
  const totalCollateral = this.getTotalCollateral();
542
538
  // position side allowed based purely on current leverage
@@ -545,7 +541,7 @@ class ClearingHouseUser {
545
541
  .div(numericConstants_1.TEN_THOUSAND);
546
542
  // 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
543
  const oppositeSizeValueUSDC = getOppositePositionValueUSDC();
548
- maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new bn_js_1.default(2)));
544
+ maxPositionSize = maxPositionSize.add(oppositeSizeValueUSDC.mul(new _1.BN(2)));
549
545
  // subtract oneMillionth of maxPositionSize
550
546
  // => to avoid rounding errors when taking max leverage
551
547
  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,4 +1,5 @@
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;
4
5
  export declare const TEN_THOUSAND: BN;
@@ -11,6 +12,7 @@ export declare const MARK_PRICE_PRECISION: BN;
11
12
  export declare const FUNDING_PAYMENT_PRECISION: BN;
12
13
  export declare const PEG_PRECISION: BN;
13
14
  export declare const AMM_RESERVE_PRECISION: BN;
15
+ export declare const BASE_PRECISION: BN;
14
16
  export declare const AMM_TO_QUOTE_PRECISION_RATIO: BN;
15
17
  export declare const PRICE_TO_QUOTE_PRECISION: BN;
16
18
  export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
@@ -1,22 +1,20 @@
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.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.TEN_THOUSAND = new __1.BN(10000);
8
+ exports.BN_MAX = new __1.BN(Number.MAX_SAFE_INTEGER);
9
+ exports.MAX_LEVERAGE = new __1.BN(5);
10
+ exports.FULL_LIQUIDATION_RATIO = new __1.BN(500);
11
+ exports.PARTIAL_LIQUIDATION_RATIO = new __1.BN(625);
12
+ exports.QUOTE_PRECISION = new __1.BN(Math.pow(10, 6));
13
+ exports.MARK_PRICE_PRECISION = new __1.BN(Math.pow(10, 10));
14
+ exports.FUNDING_PAYMENT_PRECISION = new __1.BN(10000);
15
+ exports.PEG_PRECISION = new __1.BN(1000);
16
+ exports.AMM_RESERVE_PRECISION = new __1.BN(Math.pow(10, 13));
17
+ exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION;
20
18
  exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.div(exports.QUOTE_PRECISION); // 10^7
21
19
  exports.PRICE_TO_QUOTE_PRECISION = exports.MARK_PRICE_PRECISION.div(exports.QUOTE_PRECISION);
22
20
  exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.mul(exports.PEG_PRECISION).div(exports.QUOTE_PRECISION); // 10^10
@@ -53,7 +53,7 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
53
53
  // Get current price
54
54
  const solMarketInfo = __2.Markets.find((market) => market.baseAssetSymbol === 'SOL');
55
55
  const currentMarketPrice = __2.calculateMarkPrice(clearingHouse.getMarket(solMarketInfo.marketIndex));
56
- const formattedPrice = __2.convertToNumber(currentMarketPrice, __2.QUOTE_PRECISION);
56
+ const formattedPrice = __2.convertToNumber(currentMarketPrice, __2.MARK_PRICE_PRECISION);
57
57
  console.log(`Current Market Price is $${formattedPrice}`);
58
58
  // Estimate the slippage for a $5000 LONG trade
59
59
  const solMarketAccount = clearingHouse.getMarket(solMarketInfo.marketIndex);
@@ -3547,6 +3547,10 @@
3547
3547
  "name": "price",
3548
3548
  "type": "u128"
3549
3549
  },
3550
+ {
3551
+ "name": "userBaseAssetAmount",
3552
+ "type": "i128"
3553
+ },
3550
3554
  {
3551
3555
  "name": "quoteAssetAmount",
3552
3556
  "type": "u128"
@@ -3734,10 +3738,10 @@
3734
3738
  "name": "Limit"
3735
3739
  },
3736
3740
  {
3737
- "name": "Stop"
3741
+ "name": "TriggerMarket"
3738
3742
  },
3739
3743
  {
3740
- "name": "StopLimit"
3744
+ "name": "TriggerLimit"
3741
3745
  }
3742
3746
  ]
3743
3747
  }
@@ -1,3 +1,3 @@
1
- import BN from 'bn.js';
1
+ import { BN } from '../';
2
2
  export declare const convertToNumber: (bigNumber: BN, precision?: BN) => number;
3
3
  export declare const convertBaseAssetAmountToNumber: (baseAssetAmount: BN) => number;