@drift-labs/sdk 2.130.0-beta.8 → 2.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/accounts/grpcAccountSubscriber.d.ts +1 -0
  3. package/lib/browser/accounts/grpcAccountSubscriber.js +16 -12
  4. package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +1 -0
  5. package/lib/browser/accounts/grpcProgramAccountSubscriber.js +16 -12
  6. package/lib/browser/accounts/types.d.ts +5 -0
  7. package/lib/browser/adminClient.d.ts +2 -2
  8. package/lib/browser/adminClient.js +14 -14
  9. package/lib/browser/dlob/DLOB.d.ts +3 -3
  10. package/lib/browser/dlob/DLOB.js +14 -8
  11. package/lib/browser/dlob/DLOBNode.d.ts +5 -3
  12. package/lib/browser/dlob/DLOBNode.js +12 -11
  13. package/lib/browser/dlob/DLOBSubscriber.js +1 -1
  14. package/lib/browser/dlob/NodeList.d.ts +3 -1
  15. package/lib/browser/dlob/NodeList.js +2 -2
  16. package/lib/browser/dlob/orderBookLevels.d.ts +6 -0
  17. package/lib/browser/dlob/orderBookLevels.js +5 -2
  18. package/lib/browser/driftClient.js +15 -2
  19. package/lib/browser/idl/drift.json +82 -11
  20. package/lib/browser/math/amm.d.ts +4 -0
  21. package/lib/browser/math/amm.js +25 -9
  22. package/lib/browser/math/market.d.ts +10 -0
  23. package/lib/browser/math/market.js +76 -1
  24. package/lib/browser/math/orders.d.ts +1 -0
  25. package/lib/browser/math/orders.js +13 -1
  26. package/lib/browser/math/state.d.ts +1 -0
  27. package/lib/browser/math/state.js +6 -1
  28. package/lib/browser/oracles/types.d.ts +1 -0
  29. package/lib/browser/oracles/utils.js +1 -3
  30. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -1
  31. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -3
  32. package/lib/browser/types.d.ts +7 -0
  33. package/lib/browser/types.js +6 -1
  34. package/lib/node/accounts/grpcAccountSubscriber.d.ts +1 -0
  35. package/lib/node/accounts/grpcAccountSubscriber.d.ts.map +1 -1
  36. package/lib/node/accounts/grpcAccountSubscriber.js +16 -12
  37. package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +1 -0
  38. package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts.map +1 -1
  39. package/lib/node/accounts/grpcProgramAccountSubscriber.js +16 -12
  40. package/lib/node/accounts/types.d.ts +5 -0
  41. package/lib/node/accounts/types.d.ts.map +1 -1
  42. package/lib/node/adminClient.d.ts +2 -2
  43. package/lib/node/adminClient.d.ts.map +1 -1
  44. package/lib/node/adminClient.js +14 -14
  45. package/lib/node/dlob/DLOB.d.ts +3 -3
  46. package/lib/node/dlob/DLOB.d.ts.map +1 -1
  47. package/lib/node/dlob/DLOB.js +14 -8
  48. package/lib/node/dlob/DLOBNode.d.ts +5 -3
  49. package/lib/node/dlob/DLOBNode.d.ts.map +1 -1
  50. package/lib/node/dlob/DLOBNode.js +12 -11
  51. package/lib/node/dlob/DLOBSubscriber.d.ts.map +1 -1
  52. package/lib/node/dlob/DLOBSubscriber.js +1 -1
  53. package/lib/node/dlob/NodeList.d.ts +3 -1
  54. package/lib/node/dlob/NodeList.d.ts.map +1 -1
  55. package/lib/node/dlob/NodeList.js +2 -2
  56. package/lib/node/dlob/orderBookLevels.d.ts +6 -0
  57. package/lib/node/dlob/orderBookLevels.d.ts.map +1 -1
  58. package/lib/node/dlob/orderBookLevels.js +5 -2
  59. package/lib/node/driftClient.d.ts.map +1 -1
  60. package/lib/node/driftClient.js +15 -2
  61. package/lib/node/idl/drift.json +82 -11
  62. package/lib/node/math/amm.d.ts +4 -0
  63. package/lib/node/math/amm.d.ts.map +1 -1
  64. package/lib/node/math/amm.js +25 -9
  65. package/lib/node/math/market.d.ts +10 -0
  66. package/lib/node/math/market.d.ts.map +1 -1
  67. package/lib/node/math/market.js +76 -1
  68. package/lib/node/math/orders.d.ts +1 -0
  69. package/lib/node/math/orders.d.ts.map +1 -1
  70. package/lib/node/math/orders.js +13 -1
  71. package/lib/node/math/state.d.ts +1 -0
  72. package/lib/node/math/state.d.ts.map +1 -1
  73. package/lib/node/math/state.js +6 -1
  74. package/lib/node/oracles/types.d.ts +1 -0
  75. package/lib/node/oracles/types.d.ts.map +1 -1
  76. package/lib/node/oracles/utils.d.ts.map +1 -1
  77. package/lib/node/oracles/utils.js +1 -3
  78. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -1
  79. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  80. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -3
  81. package/lib/node/types.d.ts +7 -0
  82. package/lib/node/types.d.ts.map +1 -1
  83. package/lib/node/types.js +6 -1
  84. package/package.json +1 -1
  85. package/src/accounts/grpcAccountSubscriber.ts +24 -11
  86. package/src/accounts/grpcProgramAccountSubscriber.ts +26 -11
  87. package/src/accounts/types.ts +5 -0
  88. package/src/adminClient.ts +29 -27
  89. package/src/dlob/DLOB.ts +30 -6
  90. package/src/dlob/DLOBNode.ts +21 -10
  91. package/src/dlob/DLOBSubscriber.ts +2 -1
  92. package/src/dlob/NodeList.ts +5 -2
  93. package/src/dlob/orderBookLevels.ts +8 -2
  94. package/src/driftClient.ts +18 -4
  95. package/src/idl/drift.json +83 -12
  96. package/src/math/amm.ts +49 -10
  97. package/src/math/market.ts +105 -0
  98. package/src/math/orders.ts +18 -0
  99. package/src/math/state.ts +7 -1
  100. package/src/oracles/types.ts +1 -0
  101. package/src/oracles/utils.ts +1 -3
  102. package/src/orderSubscriber/OrderSubscriber.ts +16 -2
  103. package/src/types.ts +9 -0
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.130.0-beta.8
1
+ 2.130.0-beta.16
@@ -9,6 +9,7 @@ export declare class grpcAccountSubscriber<T> extends WebSocketAccountSubscriber
9
9
  private stream;
10
10
  private commitmentLevel;
11
11
  listenerId?: number;
12
+ private enableReconnect;
12
13
  private constructor();
13
14
  static create<U>(grpcConfigs: GrpcConfigs, accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => U, resubOpts?: ResubOpts): Promise<grpcAccountSubscriber<U>>;
14
15
  subscribe(onChange: (data: T) => void): Promise<void>;
@@ -29,10 +29,11 @@ const Buffer = __importStar(require("buffer"));
29
29
  const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
30
30
  const grpc_1 = require("../isomorphic/grpc");
31
31
  class grpcAccountSubscriber extends webSocketAccountSubscriber_1.WebSocketAccountSubscriber {
32
- constructor(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
32
+ constructor(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts, enableReconnect = false) {
33
33
  super(accountName, program, accountPublicKey, decodeBuffer, resubOpts);
34
34
  this.client = client;
35
35
  this.commitmentLevel = commitmentLevel;
36
+ this.enableReconnect = enableReconnect;
36
37
  }
37
38
  static async create(grpcConfigs, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
38
39
  var _a, _b;
@@ -40,7 +41,7 @@ class grpcAccountSubscriber extends webSocketAccountSubscriber_1.WebSocketAccoun
40
41
  const commitmentLevel =
41
42
  // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
42
43
  (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : CommitmentLevel.CONFIRMED;
43
- return new grpcAccountSubscriber(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts);
44
+ return new grpcAccountSubscriber(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts, grpcConfigs.enableReconnect);
44
45
  }
45
46
  async subscribe(onChange) {
46
47
  if (this.listenerId != null || this.isUnsubscribing) {
@@ -70,16 +71,19 @@ class grpcAccountSubscriber extends webSocketAccountSubscriber_1.WebSocketAccoun
70
71
  entry: {},
71
72
  transactionsStatus: {},
72
73
  };
73
- this.stream.on('error', (error) => {
74
- // @ts-ignore
75
- if (error.code === 1) {
76
- // expected: 1 CANCELLED: Cancelled on client
77
- return;
78
- }
79
- else {
80
- console.error('GRPC unexpected error caught:', error);
81
- }
82
- });
74
+ if (this.enableReconnect) {
75
+ this.stream.on('error', (error) => {
76
+ // @ts-ignore
77
+ if (error.code === 1) {
78
+ // expected: 1 CANCELLED: Cancelled on client
79
+ console.error('GRPC (grpcAccountSubscriber) Cancelled on client caught:', error);
80
+ return;
81
+ }
82
+ else {
83
+ console.error('GRPC (grpcAccountSubscriber) unexpected error caught:', error);
84
+ }
85
+ });
86
+ }
83
87
  this.stream.on('data', (chunk) => {
84
88
  var _a;
85
89
  if (!chunk.account) {
@@ -9,6 +9,7 @@ export declare class grpcProgramAccountSubscriber<T> extends WebSocketProgramAcc
9
9
  private stream;
10
10
  private commitmentLevel;
11
11
  listenerId?: number;
12
+ private enableReconnect;
12
13
  private constructor();
13
14
  static create<U>(grpcConfigs: GrpcConfigs, subscriptionName: string, accountDiscriminator: string, program: Program, decodeBufferFn: (accountName: string, ix: Buffer) => U, options?: {
14
15
  filters: MemcmpFilter[];
@@ -35,10 +35,11 @@ const grpc_1 = require("../isomorphic/grpc");
35
35
  class grpcProgramAccountSubscriber extends webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber {
36
36
  constructor(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
37
37
  filters: [],
38
- }, resubOpts) {
38
+ }, resubOpts, enableReconnect = false) {
39
39
  super(subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts);
40
40
  this.client = client;
41
41
  this.commitmentLevel = commitmentLevel;
42
+ this.enableReconnect = enableReconnect;
42
43
  }
43
44
  static async create(grpcConfigs, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
44
45
  filters: [],
@@ -48,7 +49,7 @@ class grpcProgramAccountSubscriber extends webSocketProgramAccountSubscriber_1.W
48
49
  const commitmentLevel =
49
50
  // @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
50
51
  (_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : CommitmentLevel.CONFIRMED;
51
- return new grpcProgramAccountSubscriber(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts);
52
+ return new grpcProgramAccountSubscriber(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts, grpcConfigs.enableReconnect);
52
53
  }
53
54
  async subscribe(onChange) {
54
55
  if (this.listenerId != null || this.isUnsubscribing) {
@@ -83,16 +84,19 @@ class grpcProgramAccountSubscriber extends webSocketProgramAccountSubscriber_1.W
83
84
  entry: {},
84
85
  transactionsStatus: {},
85
86
  };
86
- this.stream.on('error', (error) => {
87
- // @ts-ignore
88
- if (error.code === 1) {
89
- // expected: 1 CANCELLED: Cancelled on client
90
- return;
91
- }
92
- else {
93
- console.error('GRPC unexpected error caught:', error);
94
- }
95
- });
87
+ if (this.enableReconnect) {
88
+ this.stream.on('error', (error) => {
89
+ // @ts-ignore
90
+ if (error.code === 1) {
91
+ // expected: 1 CANCELLED: Cancelled on client
92
+ console.error('GRPC (grpcProgramAccountSubscriber) Cancelled on client caught:', error);
93
+ return;
94
+ }
95
+ else {
96
+ console.error('GRPC (grpcProgramAccountSubscriber) unexpected error caught:', error);
97
+ }
98
+ });
99
+ }
96
100
  this.stream.on('data', (chunk) => {
97
101
  var _a;
98
102
  if (!chunk.account) {
@@ -158,6 +158,11 @@ export type GrpcConfigs = {
158
158
  token: string;
159
159
  commitmentLevel?: CommitmentLevel;
160
160
  channelOptions?: ChannelOptions;
161
+ /**
162
+ * Whether to enable automatic reconnection on connection loss .
163
+ * Defaults to false, will throw on connection loss.
164
+ */
165
+ enableReconnect?: boolean;
161
166
  };
162
167
  export interface HighLeverageModeConfigAccountSubscriber {
163
168
  eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
@@ -230,8 +230,8 @@ export declare class AdminClient extends DriftClient {
230
230
  getUpdateProtectedMakerModeConfigIx(maxUsers: number, reduceOnly: boolean, currentUsers: undefined): Promise<TransactionInstruction>;
231
231
  adminDeposit(marketIndex: number, amount: BN, depositUserAccount: PublicKey, adminTokenAccount?: PublicKey): Promise<TransactionSignature>;
232
232
  getAdminDepositIx(marketIndex: number, amount: BN, depositUserAccount: PublicKey, adminTokenAccount?: PublicKey): Promise<TransactionInstruction>;
233
- updateDisableBitFlagsMMOracle(disable: boolean): Promise<TransactionSignature>;
234
- getUpdateDisableBitFlagsMMOracleIx(disable: boolean): Promise<TransactionInstruction>;
235
233
  zeroMMOracleFields(marketIndex: number): Promise<TransactionSignature>;
236
234
  getZeroMMOracleFieldsIx(marketIndex: number): Promise<TransactionInstruction>;
235
+ updateFeatureBitFlagsMMOracle(enable: boolean): Promise<TransactionSignature>;
236
+ getUpdateFeatureBitFlagsMMOracleIx(enable: boolean): Promise<TransactionInstruction>;
237
237
  }
@@ -2103,36 +2103,36 @@ class AdminClient extends driftClient_1.DriftClient {
2103
2103
  },
2104
2104
  });
2105
2105
  }
2106
- async updateDisableBitFlagsMMOracle(disable) {
2107
- const updateDisableBitFlagsMMOracleIx = await this.getUpdateDisableBitFlagsMMOracleIx(disable);
2108
- const tx = await this.buildTransaction(updateDisableBitFlagsMMOracleIx);
2106
+ async zeroMMOracleFields(marketIndex) {
2107
+ const zeroMMOracleFieldsIx = await this.getZeroMMOracleFieldsIx(marketIndex);
2108
+ const tx = await this.buildTransaction(zeroMMOracleFieldsIx);
2109
2109
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
2110
2110
  return txSig;
2111
2111
  }
2112
- async getUpdateDisableBitFlagsMMOracleIx(disable) {
2113
- return await this.program.instruction.updateDisableBitflagsMmOracle(disable, {
2112
+ async getZeroMMOracleFieldsIx(marketIndex) {
2113
+ return await this.program.instruction.zeroMmOracleFields({
2114
2114
  accounts: {
2115
2115
  admin: this.isSubscribed
2116
2116
  ? this.getStateAccount().admin
2117
2117
  : this.wallet.publicKey,
2118
2118
  state: await this.getStatePublicKey(),
2119
+ perpMarket: await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex),
2119
2120
  },
2120
2121
  });
2121
2122
  }
2122
- async zeroMMOracleFields(marketIndex) {
2123
- const zeroMMOracleFieldsIx = await this.getZeroMMOracleFieldsIx(marketIndex);
2124
- const tx = await this.buildTransaction(zeroMMOracleFieldsIx);
2123
+ async updateFeatureBitFlagsMMOracle(enable) {
2124
+ const updateFeatureBitFlagsMMOracleIx = await this.getUpdateFeatureBitFlagsMMOracleIx(enable);
2125
+ const tx = await this.buildTransaction(updateFeatureBitFlagsMMOracleIx);
2125
2126
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
2126
2127
  return txSig;
2127
2128
  }
2128
- async getZeroMMOracleFieldsIx(marketIndex) {
2129
- return await this.program.instruction.zeroMmOracleFields({
2129
+ async getUpdateFeatureBitFlagsMMOracleIx(enable) {
2130
+ return await this.program.instruction.updateFeatureBitFlagsMmOracle(enable, {
2130
2131
  accounts: {
2131
- admin: this.isSubscribed
2132
- ? this.getStateAccount().admin
2133
- : this.wallet.publicKey,
2132
+ admin: this.useHotWalletAdmin
2133
+ ? this.wallet.publicKey
2134
+ : this.getStateAccount().admin,
2134
2135
  state: await this.getStatePublicKey(),
2135
- perpMarket: await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex),
2136
2136
  },
2137
2137
  });
2138
2138
  }
@@ -75,8 +75,8 @@ export declare class DLOB {
75
75
  * @returns a promise that resolves when the DLOB is initialized
76
76
  */
77
77
  initFromUserMap(userMap: UserMap, slot: number): Promise<boolean>;
78
- insertOrder(order: Order, userAccount: string, slot: number, isUserProtectedMaker: boolean, onInsert?: OrderBookCallback): void;
79
- insertSignedMsgOrder(order: Order, userAccount: string, isUserProtectedMaker: boolean, onInsert?: OrderBookCallback): void;
78
+ insertOrder(order: Order, userAccount: string, slot: number, isUserProtectedMaker: boolean, baseAssetAmount: BN, onInsert?: OrderBookCallback): void;
79
+ insertSignedMsgOrder(order: Order, userAccount: string, isUserProtectedMaker: boolean, baseAssetAmount?: BN, onInsert?: OrderBookCallback): void;
80
80
  addOrderList(marketType: MarketTypeStr, marketIndex: number): void;
81
81
  delete(order: Order, userAccount: PublicKey, slot: number, isUserProtectedMaker: boolean, onDelete?: OrderBookCallback): void;
82
82
  getListForOnChainOrder(order: Order, slot: number, isProtectedMaker: boolean): NodeList<any> | undefined;
@@ -133,7 +133,7 @@ export declare class DLOB {
133
133
  getTakeProfits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
134
134
  getTakeProfitMarkets(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
135
135
  getTakeProfitLimits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
136
- findNodesToTrigger(marketIndex: number, slot: number, oraclePrice: BN, marketType: MarketType, stateAccount: StateAccount): NodeToTrigger[];
136
+ findNodesToTrigger(marketIndex: number, slot: number, triggerPrice: BN, marketType: MarketType, stateAccount: StateAccount): NodeToTrigger[];
137
137
  printTop(driftClient: DriftClient, slotSubscriber: SlotSubscriber, marketIndex: number, marketType: MarketType): void;
138
138
  getDLOBOrders(): DLOBOrders;
139
139
  getNodeLists(): Generator<NodeList<DLOBNodeType>>;
@@ -65,6 +65,7 @@ class DLOB {
65
65
  * @returns a promise that resolves when the DLOB is initialized
66
66
  */
67
67
  async initFromUserMap(userMap, slot) {
68
+ var _a;
68
69
  if (this.initialized) {
69
70
  return false;
70
71
  }
@@ -75,13 +76,18 @@ class DLOB {
75
76
  const userAccountPubkeyString = userAccountPubkey.toString();
76
77
  const protectedMaker = (0, userStatus_1.isUserProtectedMaker)(userAccount);
77
78
  for (const order of userAccount.orders) {
78
- this.insertOrder(order, userAccountPubkeyString, slot, protectedMaker);
79
+ let baseAssetAmount = order.baseAssetAmount;
80
+ if (order.reduceOnly) {
81
+ const existingBaseAmount = ((_a = userAccount.perpPositions.find((pos) => pos.marketIndex === order.marketIndex && pos.openOrders > 0)) === null || _a === void 0 ? void 0 : _a.baseAssetAmount) || numericConstants_1.ZERO;
82
+ baseAssetAmount = (0, orders_1.calculateOrderBaseAssetAmount)(order, existingBaseAmount);
83
+ }
84
+ this.insertOrder(order, userAccountPubkeyString, slot, protectedMaker, baseAssetAmount);
79
85
  }
80
86
  }
81
87
  this.initialized = true;
82
88
  return true;
83
89
  }
84
- insertOrder(order, userAccount, slot, isUserProtectedMaker, onInsert) {
90
+ insertOrder(order, userAccount, slot, isUserProtectedMaker, baseAssetAmount, onInsert) {
85
91
  var _a;
86
92
  if (!(0, types_1.isVariant)(order.status, 'open')) {
87
93
  return;
@@ -98,12 +104,12 @@ class DLOB {
98
104
  .get(marketType)
99
105
  .add((0, NodeList_1.getOrderSignature)(order.orderId, userAccount));
100
106
  }
101
- (_a = this.getListForOnChainOrder(order, slot, isUserProtectedMaker)) === null || _a === void 0 ? void 0 : _a.insert(order, marketType, userAccount, isUserProtectedMaker, this.protectedMakerParamsMap[marketType].get(order.marketIndex));
107
+ (_a = this.getListForOnChainOrder(order, slot, isUserProtectedMaker)) === null || _a === void 0 ? void 0 : _a.insert(order, marketType, userAccount, isUserProtectedMaker, this.protectedMakerParamsMap[marketType].get(order.marketIndex), baseAssetAmount);
102
108
  if (onInsert) {
103
109
  onInsert();
104
110
  }
105
111
  }
106
- insertSignedMsgOrder(order, userAccount, isUserProtectedMaker, onInsert) {
112
+ insertSignedMsgOrder(order, userAccount, isUserProtectedMaker, baseAssetAmount, onInsert) {
107
113
  const marketType = (0, types_1.getVariant)(order.marketType);
108
114
  const marketIndex = order.marketIndex;
109
115
  const bidOrAsk = (0, types_1.isVariant)(order.direction, 'long') ? 'bid' : 'ask';
@@ -116,7 +122,7 @@ class DLOB {
116
122
  this.orderLists
117
123
  .get(marketType)
118
124
  .get(marketIndex)
119
- .signedMsg[bidOrAsk].insert(order, marketType, userAccount, isUserProtectedMaker, this.protectedMakerParamsMap[marketType].get(order.marketIndex));
125
+ .signedMsg[bidOrAsk].insert(order, marketType, userAccount, isUserProtectedMaker, this.protectedMakerParamsMap[marketType].get(order.marketIndex), baseAssetAmount);
120
126
  if (onInsert) {
121
127
  onInsert();
122
128
  }
@@ -847,7 +853,7 @@ class DLOB {
847
853
  }
848
854
  }
849
855
  }
850
- findNodesToTrigger(marketIndex, slot, oraclePrice, marketType, stateAccount) {
856
+ findNodesToTrigger(marketIndex, slot, triggerPrice, marketType, stateAccount) {
851
857
  if ((0, exchangeStatus_1.exchangePaused)(stateAccount)) {
852
858
  return [];
853
859
  }
@@ -859,7 +865,7 @@ class DLOB {
859
865
  : undefined;
860
866
  if (triggerAboveList) {
861
867
  for (const node of triggerAboveList.getGenerator()) {
862
- if (oraclePrice.gt(node.order.triggerPrice)) {
868
+ if (triggerPrice.gt(node.order.triggerPrice)) {
863
869
  nodesToTrigger.push({
864
870
  node: node,
865
871
  });
@@ -874,7 +880,7 @@ class DLOB {
874
880
  : undefined;
875
881
  if (triggerBelowList) {
876
882
  for (const node of triggerBelowList.getGenerator()) {
877
- if (oraclePrice.lt(node.order.triggerPrice)) {
883
+ if (triggerPrice.lt(node.order.triggerPrice)) {
878
884
  nodesToTrigger.push({
879
885
  node: node,
880
886
  });
@@ -12,6 +12,7 @@ export interface DLOBNode {
12
12
  isProtectedMaker: boolean;
13
13
  protectedMakerParams?: ProtectedMakerParams;
14
14
  isSignedMsg: boolean | undefined;
15
+ baseAssetAmount: BN;
15
16
  }
16
17
  export declare abstract class OrderNode implements DLOBNode {
17
18
  order: Order;
@@ -21,8 +22,9 @@ export declare abstract class OrderNode implements DLOBNode {
21
22
  haveTrigger: boolean;
22
23
  isProtectedMaker: boolean;
23
24
  protectedMakerParams?: ProtectedMakerParams;
25
+ baseAssetAmount: BN;
24
26
  isSignedMsg: boolean;
25
- constructor(order: Order, userAccount: string, isProtectedMaker: boolean, protectedMakerParams?: ProtectedMakerParams, isSignedMsg?: boolean);
27
+ constructor(order: Order, userAccount: string, isProtectedMaker: boolean, protectedMakerParams?: ProtectedMakerParams, baseAssetAmount?: BN, isSignedMsg?: boolean);
26
28
  abstract getSortValue(order: Order): BN;
27
29
  getLabel(): string;
28
30
  getPrice(oraclePriceData: OraclePriceData, slot: number): BN;
@@ -57,7 +59,7 @@ export declare class TriggerOrderNode extends OrderNode {
57
59
  export declare class SignedMsgOrderNode extends OrderNode {
58
60
  next?: SignedMsgOrderNode;
59
61
  previous?: SignedMsgOrderNode;
60
- constructor(order: Order, userAccount: string);
62
+ constructor(order: Order, userAccount: string, baseAssetAmount?: BN);
61
63
  getSortValue(order: Order): BN;
62
64
  }
63
65
  export type DLOBNodeMap = {
@@ -70,4 +72,4 @@ export type DLOBNodeMap = {
70
72
  signedMsg: SignedMsgOrderNode;
71
73
  };
72
74
  export type DLOBNodeType = 'signedMsg' | 'restingLimit' | 'takingLimit' | 'floatingLimit' | 'protectedFloatingLimit' | 'market' | ('trigger' & keyof DLOBNodeMap);
73
- export declare function createNode<T extends DLOBNodeType>(nodeType: T, order: Order, userAccount: string, isProtectedMaker: boolean, protectedMakerParams?: ProtectedMakerParams): DLOBNodeMap[T];
75
+ export declare function createNode<T extends DLOBNodeType>(nodeType: T, order: Order, userAccount: string, isProtectedMaker: boolean, protectedMakerParams?: ProtectedMakerParams, baseAssetAmount?: BN): DLOBNodeMap[T];
@@ -8,7 +8,7 @@ const types_1 = require("../types");
8
8
  const conversion_1 = require("../math/conversion");
9
9
  const NodeList_1 = require("./NodeList");
10
10
  class OrderNode {
11
- constructor(order, userAccount, isProtectedMaker, protectedMakerParams, isSignedMsg = false) {
11
+ constructor(order, userAccount, isProtectedMaker, protectedMakerParams, baseAssetAmount, isSignedMsg = false) {
12
12
  this.haveFilled = false;
13
13
  this.haveTrigger = false;
14
14
  // Copy the order over to the node
@@ -17,6 +17,7 @@ class OrderNode {
17
17
  this.sortValue = this.getSortValue(order);
18
18
  this.isProtectedMaker = isProtectedMaker;
19
19
  this.protectedMakerParams = protectedMakerParams;
20
+ this.baseAssetAmount = baseAssetAmount !== null && baseAssetAmount !== void 0 ? baseAssetAmount : order.baseAssetAmount;
20
21
  this.isSignedMsg = isSignedMsg;
21
22
  }
22
23
  getLabel() {
@@ -85,30 +86,30 @@ class TriggerOrderNode extends OrderNode {
85
86
  exports.TriggerOrderNode = TriggerOrderNode;
86
87
  // We'll use the signedMsg uuid for the order id since it's not yet on-chain
87
88
  class SignedMsgOrderNode extends OrderNode {
88
- constructor(order, userAccount) {
89
- super(order, userAccount, false, undefined, true);
89
+ constructor(order, userAccount, baseAssetAmount) {
90
+ super(order, userAccount, false, undefined, baseAssetAmount, true);
90
91
  }
91
92
  getSortValue(order) {
92
93
  return order.slot;
93
94
  }
94
95
  }
95
96
  exports.SignedMsgOrderNode = SignedMsgOrderNode;
96
- function createNode(nodeType, order, userAccount, isProtectedMaker, protectedMakerParams) {
97
+ function createNode(nodeType, order, userAccount, isProtectedMaker, protectedMakerParams, baseAssetAmount) {
97
98
  switch (nodeType) {
98
99
  case 'floatingLimit':
99
- return new FloatingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams);
100
+ return new FloatingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams, baseAssetAmount);
100
101
  case 'protectedFloatingLimit':
101
- return new FloatingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams);
102
+ return new FloatingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams, baseAssetAmount);
102
103
  case 'restingLimit':
103
- return new RestingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams);
104
+ return new RestingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams, baseAssetAmount);
104
105
  case 'takingLimit':
105
- return new TakingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams);
106
+ return new TakingLimitOrderNode(order, userAccount, isProtectedMaker, protectedMakerParams, baseAssetAmount);
106
107
  case 'market':
107
- return new MarketOrderNode(order, userAccount, isProtectedMaker, undefined);
108
+ return new MarketOrderNode(order, userAccount, isProtectedMaker, undefined, baseAssetAmount);
108
109
  case 'trigger':
109
- return new TriggerOrderNode(order, userAccount, isProtectedMaker, undefined);
110
+ return new TriggerOrderNode(order, userAccount, isProtectedMaker, undefined, baseAssetAmount);
110
111
  case 'signedMsg':
111
- return new SignedMsgOrderNode(order, userAccount);
112
+ return new SignedMsgOrderNode(order, userAccount, baseAssetAmount);
112
113
  default:
113
114
  throw Error(`Unknown DLOBNode type ${nodeType}`);
114
115
  }
@@ -83,7 +83,7 @@ class DLOBSubscriber {
83
83
  fallbackL2Generators = [
84
84
  (0, orderBookLevels_1.getVammL2Generator)({
85
85
  marketAccount: this.driftClient.getPerpMarketAccount(marketIndex),
86
- oraclePriceData,
86
+ oraclePriceData: this.driftClient.getMMOracleDataForPerpMarket(marketIndex),
87
87
  numOrders: numVammOrders !== null && numVammOrders !== void 0 ? numVammOrders : depth,
88
88
  topOfBookQuoteAmounts: marketIndex < 3
89
89
  ? orderBookLevels_1.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS
@@ -1,5 +1,7 @@
1
+ /// <reference types="bn.js" />
1
2
  import { MarketTypeStr, Order, ProtectedMakerParams } from '../types';
2
3
  import { DLOBNode, DLOBNodeMap } from './DLOBNode';
4
+ import { BN } from '@coral-xyz/anchor';
3
5
  export type SortDirection = 'asc' | 'desc';
4
6
  export declare function getOrderSignature(orderId: number, userAccount: string): string;
5
7
  export interface DLOBNodeGenerator {
@@ -13,7 +15,7 @@ export declare class NodeList<NodeType extends keyof DLOBNodeMap> implements DLO
13
15
  nodeMap: Map<string, DLOBNodeMap[NodeType]>;
14
16
  constructor(nodeType: NodeType, sortDirection: SortDirection);
15
17
  clear(): void;
16
- insert(order: Order, marketType: MarketTypeStr, userAccount: string, isProtectedMaker: boolean, protectedMakerParamsMap?: ProtectedMakerParams): void;
18
+ insert(order: Order, marketType: MarketTypeStr, userAccount: string, isProtectedMaker: boolean, protectedMakerParamsMap?: ProtectedMakerParams, baseAssetAmount?: BN): void;
17
19
  prependNode(currentNode: DLOBNodeMap[NodeType], newNode: DLOBNodeMap[NodeType]): boolean;
18
20
  update(order: Order, userAccount: string): void;
19
21
  remove(order: Order, userAccount: string): void;
@@ -19,11 +19,11 @@ class NodeList {
19
19
  this.length = 0;
20
20
  this.nodeMap.clear();
21
21
  }
22
- insert(order, marketType, userAccount, isProtectedMaker, protectedMakerParamsMap) {
22
+ insert(order, marketType, userAccount, isProtectedMaker, protectedMakerParamsMap, baseAssetAmount) {
23
23
  if (!(0, types_1.isVariant)(order.status, 'open')) {
24
24
  return;
25
25
  }
26
- const newNode = (0, DLOBNode_1.createNode)(this.nodeType, order, userAccount, isProtectedMaker, protectedMakerParamsMap);
26
+ const newNode = (0, DLOBNode_1.createNode)(this.nodeType, order, userAccount, isProtectedMaker, protectedMakerParamsMap, baseAssetAmount);
27
27
  const orderSignature = getOrderSignature(order.orderId, userAccount);
28
28
  if (this.nodeMap.has(orderSignature)) {
29
29
  return;
@@ -34,6 +34,12 @@ export type L3OrderBook = {
34
34
  };
35
35
  export declare const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
36
36
  export declare const MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
37
+ /**
38
+ * Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
39
+ * @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
40
+ * @param oraclePriceData
41
+ * @param slot
42
+ */
37
43
  export declare function getL2GeneratorFromDLOBNodes(dlobNodes: Generator<DLOBNode>, oraclePriceData: OraclePriceData, slot: number): Generator<L2Level>;
38
44
  export declare function mergeL2LevelGenerators(l2LevelGenerators: Generator<L2Level>[], compare: (a: L2Level, b: L2Level) => boolean): Generator<L2Level>;
39
45
  export declare function createL2Levels(generator: Generator<L2Level>, depth: number): L2Level[];
@@ -19,16 +19,19 @@ exports.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = [
19
19
  new anchor_1.BN(20000).mul(numericConstants_1.QUOTE_PRECISION),
20
20
  new anchor_1.BN(50000).mul(numericConstants_1.QUOTE_PRECISION),
21
21
  ];
22
+ const INDICATIVE_QUOTES_PUBKEY = 'inDNdu3ML4vG5LNExqcwuCQtLcCU8KfK5YM2qYV3JJz';
22
23
  /**
23
24
  * Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
24
25
  * @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
25
26
  * @param oraclePriceData
26
27
  * @param slot
27
28
  */
28
- const INDICATIVE_QUOTES_PUBKEY = 'inDNdu3ML4vG5LNExqcwuCQtLcCU8KfK5YM2qYV3JJz';
29
29
  function* getL2GeneratorFromDLOBNodes(dlobNodes, oraclePriceData, slot) {
30
30
  for (const dlobNode of dlobNodes) {
31
- const size = dlobNode.order.baseAssetAmount.sub(dlobNode.order.baseAssetAmountFilled);
31
+ const size = dlobNode.baseAssetAmount.sub(dlobNode.order.baseAssetAmountFilled);
32
+ if (size.lte(numericConstants_1.ZERO)) {
33
+ continue;
34
+ }
32
35
  yield {
33
36
  size,
34
37
  price: dlobNode.getPrice(oraclePriceData, slot),
@@ -4417,15 +4417,27 @@ class DriftClient {
4417
4417
  this.eventEmitter.emit(eventName, data);
4418
4418
  }
4419
4419
  getOracleDataForPerpMarket(marketIndex) {
4420
- return this.accountSubscriber.getOraclePriceDataAndSlotForPerpMarket(marketIndex).data;
4420
+ const perpMarket = this.getPerpMarketAccount(marketIndex);
4421
+ const isMMOracleActive = !perpMarket.amm.mmOracleSlot.eq(numericConstants_1.ZERO);
4422
+ return {
4423
+ ...this.accountSubscriber.getOraclePriceDataAndSlotForPerpMarket(marketIndex).data,
4424
+ isMMOracleActive,
4425
+ };
4421
4426
  }
4422
4427
  getMMOracleDataForPerpMarket(marketIndex) {
4423
4428
  const perpMarket = this.getPerpMarketAccount(marketIndex);
4424
4429
  const oracleData = this.getOracleDataForPerpMarket(marketIndex);
4425
4430
  const stateAccountAndSlot = this.accountSubscriber.getStateAccountAndSlot();
4431
+ const pctDiff = perpMarket.amm.mmOraclePrice
4432
+ .sub(oracleData.price)
4433
+ .abs()
4434
+ .mul(numericConstants_1.PERCENTAGE_PRECISION)
4435
+ .div(anchor_1.BN.max(oracleData.price, numericConstants_1.ONE));
4426
4436
  if (!(0, oracles_1.isOracleValid)(perpMarket, oracleData, stateAccountAndSlot.data.oracleGuardRails, stateAccountAndSlot.slot) ||
4427
4437
  perpMarket.amm.mmOraclePrice.eq(numericConstants_1.ZERO) ||
4428
- perpMarket.amm.mmOracleSlot < oracleData.slot) {
4438
+ perpMarket.amm.mmOracleSlot < oracleData.slot ||
4439
+ pctDiff.gt(numericConstants_1.PERCENTAGE_PRECISION.divn(100)) // 1% threshold
4440
+ ) {
4429
4441
  return { ...oracleData, fetchedWithMMOracle: true };
4430
4442
  }
4431
4443
  else {
@@ -4440,6 +4452,7 @@ class DriftClient {
4440
4452
  confidence: conf,
4441
4453
  hasSufficientNumberOfDataPoints: true,
4442
4454
  fetchedWithMMOracle: true,
4455
+ isMMOracleActive: oracleData.isMMOracleActive,
4443
4456
  };
4444
4457
  }
4445
4458
  }