@drift-labs/sdk 2.8.0 → 2.9.0-beta.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.
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { SpotMarketAccount, PerpMarketAccount, OracleSource, StateAccount, UserAccount, UserStatsAccount } from '../types';
3
4
  import StrictEventEmitter from 'strict-event-emitter-types';
4
5
  import { EventEmitter } from 'events';
@@ -67,7 +67,7 @@ export declare class DLOB {
67
67
  getLimitBids(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
68
68
  getAsks(marketIndex: number, fallbackAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
69
69
  getBids(marketIndex: number, fallbackBid: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
70
- findCrossingLimitOrders(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): NodeToFill[];
70
+ findCrossingLimitOrders(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
71
71
  determineMakerAndTaker(askNode: DLOBNode, bidNode: DLOBNode): {
72
72
  takerNode: DLOBNode;
73
73
  makerNode: DLOBNode;
package/lib/dlob/DLOB.js CHANGED
@@ -261,7 +261,7 @@ class DLOB {
261
261
  }
262
262
  findLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, fallbackAsk, fallbackBid) {
263
263
  const nodesToFill = new Array();
264
- const crossingNodes = this.findCrossingLimitOrders(marketIndex, slot, marketType, oraclePriceData);
264
+ const crossingNodes = this.findCrossingLimitOrders(marketIndex, slot, marketType, oraclePriceData, fallbackAsk, fallbackBid);
265
265
  for (const crossingNode of crossingNodes) {
266
266
  nodesToFill.push(crossingNode);
267
267
  }
@@ -584,7 +584,7 @@ class DLOB {
584
584
  return bestPrice.gt(currentPrice);
585
585
  });
586
586
  }
587
- findCrossingLimitOrders(marketIndex, slot, marketType, oraclePriceData) {
587
+ findCrossingLimitOrders(marketIndex, slot, marketType, oraclePriceData, fallbackAsk, fallbackBid) {
588
588
  const nodesToFill = new Array();
589
589
  for (const askNode of this.getLimitAsks(marketIndex, slot, marketType, oraclePriceData)) {
590
590
  for (const bidNode of this.getLimitBids(marketIndex, slot, marketType, oraclePriceData)) {
@@ -602,6 +602,22 @@ class DLOB {
602
602
  continue;
603
603
  }
604
604
  const { takerNode, makerNode } = this.determineMakerAndTaker(askNode, bidNode);
605
+ // extra guard against bad fills for limit orders where auction is incomplete
606
+ if (!(0, __1.isAuctionComplete)(takerNode.order, slot)) {
607
+ let bidPrice;
608
+ let askPrice;
609
+ if ((0, __1.isVariant)(takerNode.order.direction, 'long')) {
610
+ bidPrice = __1.BN.min(takerNode.getPrice(oraclePriceData, slot), fallbackAsk || __1.BN_MAX);
611
+ askPrice = makerNode.getPrice(oraclePriceData, slot);
612
+ }
613
+ else {
614
+ bidPrice = makerNode.getPrice(oraclePriceData, slot);
615
+ askPrice = __1.BN.max(takerNode.getPrice(oraclePriceData, slot), fallbackBid || __1.ZERO);
616
+ }
617
+ if (bidPrice.lt(askPrice)) {
618
+ continue;
619
+ }
620
+ }
605
621
  const bidBaseRemaining = bidOrder.baseAssetAmount.sub(bidOrder.baseAssetAmountFilled);
606
622
  const askBaseRemaining = askOrder.baseAssetAmount.sub(askOrder.baseAssetAmountFilled);
607
623
  const baseFilled = __1.BN.min(bidBaseRemaining, askBaseRemaining);
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.8.0",
2
+ "version": "2.9.0-beta.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -22,10 +22,10 @@ class RetryTxSender {
22
22
  if (opts === undefined) {
23
23
  opts = this.provider.opts;
24
24
  }
25
- if (!preSigned) {
26
- await this.prepareTx(tx, additionalSigners, opts);
27
- }
28
- const rawTransaction = tx.serialize();
25
+ const signedTx = preSigned
26
+ ? tx
27
+ : await this.prepareTx(tx, additionalSigners, opts);
28
+ const rawTransaction = signedTx.serialize();
29
29
  const startTime = this.getTimestamp();
30
30
  let txid;
31
31
  try {
@@ -77,13 +77,13 @@ class RetryTxSender {
77
77
  async prepareTx(tx, additionalSigners, opts) {
78
78
  tx.feePayer = this.provider.wallet.publicKey;
79
79
  tx.recentBlockhash = (await this.provider.connection.getRecentBlockhash(opts.preflightCommitment)).blockhash;
80
- await this.provider.wallet.signTransaction(tx);
80
+ const signedTx = await this.provider.wallet.signTransaction(tx);
81
81
  additionalSigners
82
82
  .filter((s) => s !== undefined)
83
83
  .forEach((kp) => {
84
- tx.partialSign(kp);
84
+ signedTx.partialSign(kp);
85
85
  });
86
- return tx;
86
+ return signedTx;
87
87
  }
88
88
  async confirmTransaction(signature, commitment) {
89
89
  let decodedSignature;
@@ -31,7 +31,6 @@ class UserStatsMap {
31
31
  await (0, __1.bulkPollingUserStatsSubscribe)(userStatArray, this.accountSubscription.accountLoader);
32
32
  }
33
33
  for (const userStat of userStatArray) {
34
- await userStat.subscribe();
35
34
  this.userStatsMap.set(userStat.getAccount().authority.toString(), userStat);
36
35
  }
37
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.8.0",
3
+ "version": "2.9.0-beta.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assert = void 0;
4
+ function assert(condition, error) {
5
+ if (!condition) {
6
+ throw new Error(error || 'Unspecified AssertionError');
7
+ }
8
+ }
9
+ exports.assert = assert;
package/src/dlob/DLOB.ts CHANGED
@@ -26,6 +26,8 @@ import {
26
26
  UserMap,
27
27
  OrderRecord,
28
28
  OrderActionRecord,
29
+ ZERO,
30
+ BN_MAX,
29
31
  } from '..';
30
32
  import { PublicKey } from '@solana/web3.js';
31
33
  import { DLOBNode, DLOBNodeType, TriggerOrderNode } from '..';
@@ -440,7 +442,9 @@ export class DLOB {
440
442
  marketIndex,
441
443
  slot,
442
444
  marketType,
443
- oraclePriceData
445
+ oraclePriceData,
446
+ fallbackAsk,
447
+ fallbackBid
444
448
  );
445
449
 
446
450
  for (const crossingNode of crossingNodes) {
@@ -1009,7 +1013,9 @@ export class DLOB {
1009
1013
  marketIndex: number,
1010
1014
  slot: number,
1011
1015
  marketType: MarketType,
1012
- oraclePriceData: OraclePriceData
1016
+ oraclePriceData: OraclePriceData,
1017
+ fallbackAsk: BN | undefined,
1018
+ fallbackBid: BN | undefined
1013
1019
  ): NodeToFill[] {
1014
1020
  const nodesToFill = new Array<NodeToFill>();
1015
1021
 
@@ -1047,6 +1053,29 @@ export class DLOB {
1047
1053
  bidNode
1048
1054
  );
1049
1055
 
1056
+ // extra guard against bad fills for limit orders where auction is incomplete
1057
+ if (!isAuctionComplete(takerNode.order, slot)) {
1058
+ let bidPrice: BN;
1059
+ let askPrice: BN;
1060
+ if (isVariant(takerNode.order.direction, 'long')) {
1061
+ bidPrice = BN.min(
1062
+ takerNode.getPrice(oraclePriceData, slot),
1063
+ fallbackAsk || BN_MAX
1064
+ );
1065
+ askPrice = makerNode.getPrice(oraclePriceData, slot);
1066
+ } else {
1067
+ bidPrice = makerNode.getPrice(oraclePriceData, slot);
1068
+ askPrice = BN.max(
1069
+ takerNode.getPrice(oraclePriceData, slot),
1070
+ fallbackBid || ZERO
1071
+ );
1072
+ }
1073
+
1074
+ if (bidPrice.lt(askPrice)) {
1075
+ continue;
1076
+ }
1077
+ }
1078
+
1050
1079
  const bidBaseRemaining = bidOrder.baseAssetAmount.sub(
1051
1080
  bidOrder.baseAssetAmountFilled
1052
1081
  );
@@ -0,0 +1,157 @@
1
+ 'use strict';
2
+ var __awaiter =
3
+ (this && this.__awaiter) ||
4
+ function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) {
6
+ return value instanceof P
7
+ ? value
8
+ : new P(function (resolve) {
9
+ resolve(value);
10
+ });
11
+ }
12
+ return new (P || (P = Promise))(function (resolve, reject) {
13
+ function fulfilled(value) {
14
+ try {
15
+ step(generator.next(value));
16
+ } catch (e) {
17
+ reject(e);
18
+ }
19
+ }
20
+ function rejected(value) {
21
+ try {
22
+ step(generator['throw'](value));
23
+ } catch (e) {
24
+ reject(e);
25
+ }
26
+ }
27
+ function step(result) {
28
+ result.done
29
+ ? resolve(result.value)
30
+ : adopt(result.value).then(fulfilled, rejected);
31
+ }
32
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
33
+ });
34
+ };
35
+ Object.defineProperty(exports, '__esModule', { value: true });
36
+ exports.getTokenAddress = void 0;
37
+ const anchor_1 = require('@project-serum/anchor');
38
+ const __1 = require('..');
39
+ const spl_token_1 = require('@solana/spl-token');
40
+ const web3_js_1 = require('@solana/web3.js');
41
+ const __2 = require('..');
42
+ const banks_1 = require('../constants/spotMarkets');
43
+ const getTokenAddress = (mintAddress, userPubKey) => {
44
+ return spl_token_1.Token.getAssociatedTokenAddress(
45
+ new web3_js_1.PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
46
+ spl_token_1.TOKEN_PROGRAM_ID,
47
+ new web3_js_1.PublicKey(mintAddress),
48
+ new web3_js_1.PublicKey(userPubKey)
49
+ );
50
+ };
51
+ exports.getTokenAddress = getTokenAddress;
52
+ const main = () =>
53
+ __awaiter(void 0, void 0, void 0, function* () {
54
+ // Initialize Drift SDK
55
+ const sdkConfig = __2.initialize({ env: 'devnet' });
56
+ // Set up the Wallet and Provider
57
+ const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
58
+ const keypair = web3_js_1.Keypair.fromSecretKey(
59
+ Uint8Array.from(JSON.parse(privateKey))
60
+ );
61
+ const wallet = new __1.Wallet(keypair);
62
+ // Set up the Connection
63
+ const rpcAddress = process.env.RPC_ADDRESS; // can use: https://api.devnet.solana.com for devnet; https://api.mainnet-beta.solana.com for mainnet;
64
+ const connection = new web3_js_1.Connection(rpcAddress);
65
+ // Set up the Provider
66
+ const provider = new anchor_1.AnchorProvider(
67
+ connection,
68
+ wallet,
69
+ anchor_1.AnchorProvider.defaultOptions()
70
+ );
71
+ // Check SOL Balance
72
+ const lamportsBalance = yield connection.getBalance(wallet.publicKey);
73
+ console.log('SOL balance:', lamportsBalance / Math.pow(10, 9));
74
+ // Misc. other things to set up
75
+ const usdcTokenAddress = yield exports.getTokenAddress(
76
+ sdkConfig.USDC_MINT_ADDRESS,
77
+ wallet.publicKey.toString()
78
+ );
79
+ // Set up the Drift Clearing House
80
+ const clearingHousePublicKey = new web3_js_1.PublicKey(
81
+ sdkConfig.DRIFT_PROGRAM_ID
82
+ );
83
+ const clearingHouse = new __2.ClearingHouse({
84
+ connection,
85
+ wallet: provider.wallet,
86
+ programID: clearingHousePublicKey,
87
+ });
88
+ yield clearingHouse.subscribe();
89
+ // Set up Clearing House user client
90
+ const user = new __2.ClearingHouseUser({
91
+ clearingHouse,
92
+ userAccountPublicKey: yield clearingHouse.getUserAccountPublicKey(),
93
+ });
94
+ //// Check if clearing house account exists for the current wallet
95
+ const userAccountExists = yield user.exists();
96
+ if (!userAccountExists) {
97
+ //// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
98
+ const depositAmount = new anchor_1.BN(10000).mul(__2.QUOTE_PRECISION);
99
+ yield clearingHouse.initializeUserAccountAndDepositCollateral(
100
+ depositAmount,
101
+ yield exports.getTokenAddress(
102
+ usdcTokenAddress.toString(),
103
+ wallet.publicKey.toString()
104
+ ),
105
+ banks_1.SpotMarkets['devnet'][0].marketIndex
106
+ );
107
+ }
108
+ yield user.subscribe();
109
+ // Get current price
110
+ const solMarketInfo = sdkConfig.PERP_MARKETS.find(
111
+ (market) => market.baseAssetSymbol === 'SOL'
112
+ );
113
+ const currentMarketPrice = __2.calculateMarkPrice(
114
+ clearingHouse.getMarketAccount(solMarketInfo.marketIndex),
115
+ undefined
116
+ );
117
+ const formattedPrice = __2.convertToNumber(
118
+ currentMarketPrice,
119
+ __2.PRICE_PRECISION
120
+ );
121
+ console.log(`Current Market Price is $${formattedPrice}`);
122
+ // Estimate the slippage for a $5000 LONG trade
123
+ const solMarketAccount = clearingHouse.getMarketAccount(
124
+ solMarketInfo.marketIndex
125
+ );
126
+ const longAmount = new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION);
127
+ const slippage = __2.convertToNumber(
128
+ __2.calculateTradeSlippage(
129
+ __2.PositionDirection.LONG,
130
+ longAmount,
131
+ solMarketAccount,
132
+ 'quote',
133
+ undefined
134
+ )[0],
135
+ __2.PRICE_PRECISION
136
+ );
137
+ console.log(
138
+ `Slippage for a $5000 LONG on the SOL market would be $${slippage}`
139
+ );
140
+ // Make a $5000 LONG trade
141
+ yield clearingHouse.openPosition(
142
+ __2.PositionDirection.LONG,
143
+ longAmount,
144
+ solMarketInfo.marketIndex
145
+ );
146
+ console.log(`LONGED $5000 SOL`);
147
+ // Reduce the position by $2000
148
+ const reduceAmount = new anchor_1.BN(2000).mul(__2.QUOTE_PRECISION);
149
+ yield clearingHouse.openPosition(
150
+ __2.PositionDirection.SHORT,
151
+ reduceAmount,
152
+ solMarketInfo.marketIndex
153
+ );
154
+ // Close the rest of the position
155
+ yield clearingHouse.closePosition(solMarketInfo.marketIndex);
156
+ });
157
+ main();
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.8.0",
2
+ "version": "2.9.0-beta.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTokenAccount = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ function parseTokenAccount(data) {
7
+ const accountInfo = spl_token_1.AccountLayout.decode(data);
8
+ accountInfo.mint = new web3_js_1.PublicKey(accountInfo.mint);
9
+ accountInfo.owner = new web3_js_1.PublicKey(accountInfo.owner);
10
+ accountInfo.amount = spl_token_1.u64.fromBuffer(accountInfo.amount);
11
+ if (accountInfo.delegateOption === 0) {
12
+ accountInfo.delegate = null;
13
+ // eslint-disable-next-line new-cap
14
+ accountInfo.delegatedAmount = new spl_token_1.u64(0);
15
+ }
16
+ else {
17
+ accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate);
18
+ accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(accountInfo.delegatedAmount);
19
+ }
20
+ accountInfo.isInitialized = accountInfo.state !== 0;
21
+ accountInfo.isFrozen = accountInfo.state === 2;
22
+ if (accountInfo.isNativeOption === 1) {
23
+ accountInfo.rentExemptReserve = spl_token_1.u64.fromBuffer(accountInfo.isNative);
24
+ accountInfo.isNative = true;
25
+ }
26
+ else {
27
+ accountInfo.rentExemptReserve = null;
28
+ accountInfo.isNative = false;
29
+ }
30
+ if (accountInfo.closeAuthorityOption === 0) {
31
+ accountInfo.closeAuthority = null;
32
+ }
33
+ else {
34
+ accountInfo.closeAuthority = new web3_js_1.PublicKey(accountInfo.closeAuthority);
35
+ }
36
+ return accountInfo;
37
+ }
38
+ exports.parseTokenAccount = parseTokenAccount;
@@ -52,11 +52,11 @@ export class RetryTxSender implements TxSender {
52
52
  opts = this.provider.opts;
53
53
  }
54
54
 
55
- if (!preSigned) {
56
- await this.prepareTx(tx, additionalSigners, opts);
57
- }
55
+ const signedTx = preSigned
56
+ ? tx
57
+ : await this.prepareTx(tx, additionalSigners, opts);
58
58
 
59
- const rawTransaction = tx.serialize();
59
+ const rawTransaction = signedTx.serialize();
60
60
  const startTime = this.getTimestamp();
61
61
 
62
62
  let txid: TransactionSignature;
@@ -123,14 +123,14 @@ export class RetryTxSender implements TxSender {
123
123
  )
124
124
  ).blockhash;
125
125
 
126
- await this.provider.wallet.signTransaction(tx);
126
+ const signedTx = await this.provider.wallet.signTransaction(tx);
127
127
  additionalSigners
128
128
  .filter((s): s is Signer => s !== undefined)
129
129
  .forEach((kp) => {
130
- tx.partialSign(kp);
130
+ signedTx.partialSign(kp);
131
131
  });
132
132
 
133
- return tx;
133
+ return signedTx;
134
134
  }
135
135
 
136
136
  async confirmTransaction(
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wrapInTx = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const COMPUTE_UNITS_DEFAULT = 200000;
6
+ function wrapInTx(instruction, computeUnits = 600000 // TODO, requires less code change
7
+ ) {
8
+ const tx = new web3_js_1.Transaction();
9
+ if (computeUnits != COMPUTE_UNITS_DEFAULT) {
10
+ tx.add(web3_js_1.ComputeBudgetProgram.requestUnits({
11
+ units: computeUnits,
12
+ additionalFee: 0,
13
+ }));
14
+ }
15
+ return tx.add(instruction);
16
+ }
17
+ exports.wrapInTx = wrapInTx;
@@ -68,7 +68,6 @@ export class UserStatsMap {
68
68
  }
69
69
 
70
70
  for (const userStat of userStatArray) {
71
- await userStat.subscribe();
72
71
  this.userStatsMap.set(
73
72
  userStat.getAccount().authority.toString(),
74
73
  userStat
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.findComputeUnitConsumption = void 0;
13
+ function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const tx = yield connection.getTransaction(txSignature, { commitment });
16
+ const computeUnits = [];
17
+ const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of ([0-9]{0,7}) compute units`);
18
+ tx.meta.logMessages.forEach((logMessage) => {
19
+ const match = logMessage.match(regex);
20
+ if (match && match[1]) {
21
+ computeUnits.push(match[1]);
22
+ }
23
+ });
24
+ return computeUnits;
25
+ });
26
+ }
27
+ exports.findComputeUnitConsumption = findComputeUnitConsumption;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTokenAddress = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const getTokenAddress = (mintAddress, userPubKey) => {
7
+ return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
8
+ };
9
+ exports.getTokenAddress = getTokenAddress;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promiseTimeout = void 0;
4
+ function promiseTimeout(promise, timeoutMs) {
5
+ let timeoutId;
6
+ const timeoutPromise = new Promise((resolve) => {
7
+ timeoutId = setTimeout(() => resolve(null), timeoutMs);
8
+ });
9
+ return Promise.race([promise, timeoutPromise]).then((result) => {
10
+ clearTimeout(timeoutId);
11
+ return result;
12
+ });
13
+ }
14
+ exports.promiseTimeout = promiseTimeout;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.estimateTps = void 0;
13
+ function estimateTps(programId, connection, failed) {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ let signatures = yield connection.getSignaturesForAddress(programId, undefined, 'finalized');
16
+ if (failed) {
17
+ signatures = signatures.filter((signature) => signature.err);
18
+ }
19
+ const numberOfSignatures = signatures.length;
20
+ if (numberOfSignatures === 0) {
21
+ return 0;
22
+ }
23
+ return (numberOfSignatures /
24
+ (signatures[0].blockTime - signatures[numberOfSignatures - 1].blockTime));
25
+ });
26
+ }
27
+ exports.estimateTps = estimateTps;
@@ -369,14 +369,16 @@ describe('DLOB Tests', () => {
369
369
  expect(b).to.equal(3);
370
370
 
371
371
  dlob.clear();
372
- let thrown = false;
373
- try {
374
- const bids1 = dlob.getBids(marketIndex, vBid, 0, MarketType.PERP, oracle);
375
- bids1.next();
376
- } catch (e) {
377
- thrown = true;
378
- }
379
- expect(thrown, 'should throw after clearing').to.equal(true);
372
+
373
+ const bids1 = dlob.getBids(
374
+ marketIndex,
375
+ undefined,
376
+ 0,
377
+ MarketType.PERP,
378
+ oracle
379
+ );
380
+ bids1.next();
381
+ expect(bids1.next().done, 'bid generator should be done').to.equal(true);
380
382
  });
381
383
 
382
384
  it('DLOB orders', () => {