@drift-labs/sdk 2.28.0-beta.3 → 2.28.0-beta.5

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.
@@ -1,4 +1,4 @@
1
1
  import { BN } from '@coral-xyz/anchor';
2
2
  import { MarginCategory, SpotBalanceType, SpotMarketAccount } from '../types';
3
- export declare function castNumberToSpotPrecision(value: number, spotMarket: SpotMarketAccount): BN;
3
+ export declare function castNumberToSpotPrecision(value: number | BN, spotMarket: SpotMarketAccount): BN;
4
4
  export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType): number;
@@ -6,7 +6,12 @@ const types_1 = require("../types");
6
6
  const spotBalance_1 = require("./spotBalance");
7
7
  const numericConstants_1 = require("../constants/numericConstants");
8
8
  function castNumberToSpotPrecision(value, spotMarket) {
9
- return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
9
+ if (typeof value === 'number') {
10
+ return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
11
+ }
12
+ else {
13
+ return value.mul(new anchor_1.BN(Math.pow(10, spotMarket.decimals)));
14
+ }
10
15
  }
11
16
  exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
12
17
  function calculateSpotMarketMarginRatio(market, marginCategory, size, balanceType) {
@@ -2,3 +2,12 @@ import { BN } from '../';
2
2
  export declare function clampBN(x: BN, min: BN, max: BN): BN;
3
3
  export declare const squareRootBN: (n: BN) => BN;
4
4
  export declare const divCeil: (a: BN, b: BN) => BN;
5
+ /**
6
+ * calculates the time remaining until the next update based on a rounded, "on-the-hour" update schedule
7
+ * this schedule is used for Perpetual Funding Rate and Revenue -> Insurance Updates
8
+ * @param now: current blockchain unix timestamp
9
+ * @param lastUpdateTs: the unix timestamp of the last update
10
+ * @param updatePeriod: desired interval between updates (in seconds)
11
+ * @returns: timeRemainingUntilUpdate (in seconds)
12
+ */
13
+ export declare function timeRemainingUntilUpdate(now: BN, lastUpdateTs: BN, updatePeriod: BN): BN;
package/lib/math/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.divCeil = exports.squareRootBN = exports.clampBN = void 0;
3
+ exports.timeRemainingUntilUpdate = exports.divCeil = exports.squareRootBN = exports.clampBN = void 0;
4
4
  const __1 = require("../");
5
5
  function clampBN(x, min, max) {
6
6
  return __1.BN.max(min, __1.BN.min(x, max));
@@ -34,3 +34,41 @@ const divCeil = (a, b) => {
34
34
  }
35
35
  };
36
36
  exports.divCeil = divCeil;
37
+ /**
38
+ * calculates the time remaining until the next update based on a rounded, "on-the-hour" update schedule
39
+ * this schedule is used for Perpetual Funding Rate and Revenue -> Insurance Updates
40
+ * @param now: current blockchain unix timestamp
41
+ * @param lastUpdateTs: the unix timestamp of the last update
42
+ * @param updatePeriod: desired interval between updates (in seconds)
43
+ * @returns: timeRemainingUntilUpdate (in seconds)
44
+ */
45
+ function timeRemainingUntilUpdate(now, lastUpdateTs, updatePeriod) {
46
+ const timeSinceLastUpdate = now.sub(lastUpdateTs);
47
+ // round next update time to be available on the hour
48
+ let nextUpdateWait = updatePeriod;
49
+ if (updatePeriod.gt(new __1.BN(1))) {
50
+ const lastUpdateDelay = lastUpdateTs.umod(updatePeriod);
51
+ if (!lastUpdateDelay.isZero()) {
52
+ const maxDelayForNextPeriod = updatePeriod.div(new __1.BN(3));
53
+ const twoFundingPeriods = updatePeriod.mul(new __1.BN(2));
54
+ if (lastUpdateDelay.gt(maxDelayForNextPeriod)) {
55
+ // too late for on the hour next period, delay to following period
56
+ nextUpdateWait = twoFundingPeriods.sub(lastUpdateDelay);
57
+ }
58
+ else {
59
+ // allow update on the hour
60
+ nextUpdateWait = updatePeriod.sub(lastUpdateDelay);
61
+ }
62
+ if (nextUpdateWait.gt(twoFundingPeriods)) {
63
+ nextUpdateWait = nextUpdateWait.sub(updatePeriod);
64
+ }
65
+ }
66
+ }
67
+ const timeRemainingUntilUpdate = nextUpdateWait
68
+ .sub(timeSinceLastUpdate)
69
+ .isNeg()
70
+ ? __1.ZERO
71
+ : nextUpdateWait.sub(timeSinceLastUpdate);
72
+ return timeRemainingUntilUpdate;
73
+ }
74
+ exports.timeRemainingUntilUpdate = timeRemainingUntilUpdate;
@@ -99,8 +99,7 @@ class PhoenixSubscriber {
99
99
  return this.getL2Levels('asks');
100
100
  }
101
101
  *getL2Levels(side) {
102
- // @ts-ignore
103
- const basePrecision = Math.pow(10, this.market.header.baseParams.decimals);
102
+ const basePrecision = Math.pow(10, this.market.data.header.baseParams.decimals);
104
103
  const pricePrecision = numericConstants_1.PRICE_PRECISION.toNumber();
105
104
  const ladder = (0, phoenix_sdk_1.getMarketUiLadder)(this.market, this.lastSlot, this.lastUnixTimestamp, 20);
106
105
  for (let i = 0; i < ladder[side].length; i++) {
@@ -14,7 +14,7 @@ export declare class RetryTxSender implements TxSender {
14
14
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
15
15
  prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
16
16
  getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
17
- sendVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
17
+ sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
18
18
  sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
19
19
  confirmTransaction(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
20
20
  getTimestamp(): number;
@@ -54,8 +54,7 @@ class RetryTxSender {
54
54
  const tx = new web3_js_1.VersionedTransaction(message);
55
55
  return tx;
56
56
  }
57
- async sendVersionedTransaction(ixs, lookupTableAccounts, additionalSigners, opts) {
58
- const tx = await this.getVersionedTransaction(ixs, lookupTableAccounts, additionalSigners, opts);
57
+ async sendVersionedTransaction(tx, additionalSigners, opts) {
59
58
  // @ts-ignore
60
59
  tx.sign(additionalSigners.concat(this.provider.wallet.payer));
61
60
  return this.sendRawTransaction(tx.serialize(), opts);
package/lib/tx/types.d.ts CHANGED
@@ -8,7 +8,7 @@ export type TxSigAndSlot = {
8
8
  export interface TxSender {
9
9
  provider: Provider;
10
10
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
11
- sendVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
11
+ sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
12
12
  getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
13
13
  sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
14
14
  }
package/lib/types.d.ts CHANGED
@@ -904,7 +904,6 @@ export type OrderParams = {
904
904
  immediateOrCancel: boolean;
905
905
  triggerPrice: BN | null;
906
906
  triggerCondition: OrderTriggerCondition;
907
- positionLimit: BN;
908
907
  oraclePriceOffset: number | null;
909
908
  auctionDuration: number | null;
910
909
  maxTs: BN | null;
package/lib/types.js CHANGED
@@ -255,7 +255,6 @@ exports.DefaultOrderParams = {
255
255
  immediateOrCancel: false,
256
256
  triggerPrice: null,
257
257
  triggerCondition: OrderTriggerCondition.ABOVE,
258
- positionLimit: _1.ZERO,
259
258
  oraclePriceOffset: null,
260
259
  auctionDuration: null,
261
260
  maxTs: null,
package/lib/user.d.ts CHANGED
@@ -42,6 +42,13 @@ export declare class User {
42
42
  * @returns userSpotPosition
43
43
  */
44
44
  getSpotPosition(marketIndex: number): SpotPosition | undefined;
45
+ /**
46
+ * Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
47
+ * Positive if it is a deposit, negative if it is a borrow.
48
+ *
49
+ * @param marketIndex
50
+ */
51
+ getTokenAmount(marketIndex: number): BN;
45
52
  getEmptyPosition(marketIndex: number): PerpPosition;
46
53
  getClonedPosition(position: PerpPosition): PerpPosition;
47
54
  /**
@@ -54,6 +61,7 @@ export declare class User {
54
61
  * @returns Order
55
62
  */
56
63
  getOrderByUserOrderId(userOrderId: number): Order | undefined;
64
+ getOpenOrders(): Order[];
57
65
  getUserAccountPublicKey(): PublicKey;
58
66
  exists(): Promise<boolean>;
59
67
  /**
package/lib/user.js CHANGED
@@ -76,6 +76,20 @@ class User {
76
76
  getSpotPosition(marketIndex) {
77
77
  return this.getUserAccount().spotPositions.find((position) => position.marketIndex === marketIndex);
78
78
  }
79
+ /**
80
+ * Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
81
+ * Positive if it is a deposit, negative if it is a borrow.
82
+ *
83
+ * @param marketIndex
84
+ */
85
+ getTokenAmount(marketIndex) {
86
+ const spotPosition = this.getSpotPosition(marketIndex);
87
+ if (spotPosition === undefined) {
88
+ return numericConstants_1.ZERO;
89
+ }
90
+ const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
91
+ return (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarket, spotPosition.balanceType), spotPosition.balanceType);
92
+ }
79
93
  getEmptyPosition(marketIndex) {
80
94
  return {
81
95
  baseAssetAmount: numericConstants_1.ZERO,
@@ -112,6 +126,10 @@ class User {
112
126
  getOrderByUserOrderId(userOrderId) {
113
127
  return this.getUserAccount().orders.find((order) => order.userOrderId === userOrderId);
114
128
  }
129
+ getOpenOrders() {
130
+ var _a;
131
+ return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.filter((order) => (0, types_1.isVariant)(order.status, 'open'));
132
+ }
115
133
  getUserAccountPublicKey() {
116
134
  return this.userAccountPublicKey;
117
135
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.28.0-beta.3",
3
+ "version": "2.28.0-beta.5",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
package/src/config.ts CHANGED
@@ -27,11 +27,13 @@ type DriftConfig = {
27
27
 
28
28
  export type DriftEnv = 'devnet' | 'mainnet-beta';
29
29
 
30
+ export const DRIFT_PROGRAM_ID = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH';
31
+
30
32
  export const configs: { [key in DriftEnv]: DriftConfig } = {
31
33
  devnet: {
32
34
  ENV: 'devnet',
33
35
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
34
- DRIFT_PROGRAM_ID: 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH',
36
+ DRIFT_PROGRAM_ID,
35
37
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
36
38
  SERUM_V3: 'DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY',
37
39
  PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
@@ -44,7 +46,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
44
46
  'mainnet-beta': {
45
47
  ENV: 'mainnet-beta',
46
48
  PYTH_ORACLE_MAPPING_ADDRESS: 'AHtgzX45WTKfkPG53L6WYhGEXwQkN1BVknET3sVsLL8J',
47
- DRIFT_PROGRAM_ID: 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH',
49
+ DRIFT_PROGRAM_ID,
48
50
  USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
49
51
  SERUM_V3: 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX',
50
52
  PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
@@ -114,6 +114,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
114
114
  launchTs: 1683125906000,
115
115
  oracleSource: OracleSource.PYTH,
116
116
  },
117
+ {
118
+ fullName: 'Pepe',
119
+ category: ['Meme'],
120
+ symbol: '1MPEPE-PERP',
121
+ baseAssetSymbol: '1MPEPE',
122
+ marketIndex: 10,
123
+ oracle: new PublicKey('Gz9RfgDeAFSsH7BHDGyNTgCik74rjNwsodJpsCizzmkj'),
124
+ launchTs: 1683125906000,
125
+ oracleSource: OracleSource.PYTH_1M,
126
+ },
117
127
  ];
118
128
 
119
129
  export const MainnetPerpMarkets: PerpMarketConfig[] = [
@@ -217,6 +227,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
217
227
  launchTs: 1683125906000,
218
228
  oracleSource: OracleSource.PYTH,
219
229
  },
230
+ {
231
+ fullName: 'Pepe',
232
+ category: ['Meme'],
233
+ symbol: '1MPEPE-PERP',
234
+ baseAssetSymbol: '1MPEPE',
235
+ marketIndex: 10,
236
+ oracle: new PublicKey('FSfxunDmjjbDV2QxpyxFCAPKmYJHSLnLuvQXDLkMzLBm'),
237
+ launchTs: 1683125906000,
238
+ oracleSource: OracleSource.PYTH_1M,
239
+ },
220
240
  ];
221
241
 
222
242
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -107,8 +107,8 @@ export class DLOBSubscriber {
107
107
  if (isPerp) {
108
108
  const perpMarketAccount =
109
109
  this.driftClient.getPerpMarketAccount(marketIndex);
110
- oraclePriceData = this.driftClient.getOraclePriceDataAndSlot(
111
- perpMarketAccount.amm.oracle
110
+ oraclePriceData = this.driftClient.getOracleDataForPerpMarket(
111
+ perpMarketAccount.marketIndex
112
112
  );
113
113
  fallbackBid = calculateBidPrice(perpMarketAccount, oraclePriceData);
114
114
  fallbackAsk = calculateAskPrice(perpMarketAccount, oraclePriceData);