@drift-labs/sdk 0.2.0-master.12 → 0.2.0-master.15
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.
- package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
- package/lib/accounts/bulkUserStatsSubscription.js +21 -0
- package/lib/accounts/bulkUserSubscription.js +0 -1
- package/lib/accounts/fetch.d.ts +2 -1
- package/lib/accounts/fetch.js +9 -1
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
- package/lib/accounts/types.d.ts +14 -2
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
- package/lib/addresses/pda.d.ts +1 -0
- package/lib/addresses/pda.js +8 -1
- package/lib/admin.d.ts +2 -0
- package/lib/admin.js +18 -0
- package/lib/clearingHouse.d.ts +17 -1
- package/lib/clearingHouse.js +195 -14
- package/lib/clearingHouseConfig.d.ts +1 -0
- package/lib/clearingHouseUser.d.ts +5 -0
- package/lib/clearingHouseUser.js +97 -3
- package/lib/clearingHouseUserStats.d.ts +17 -0
- package/lib/clearingHouseUserStats.js +36 -0
- package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
- package/{src/clearingHouseConfig.js → lib/clearingHouseUserStatsConfig.js} +0 -0
- package/lib/config.js +1 -1
- package/lib/factory/bigNum.js +7 -9
- package/lib/idl/clearing_house.json +620 -64
- package/lib/math/amm.js +2 -2
- package/lib/math/bankBalance.d.ts +4 -0
- package/lib/math/bankBalance.js +24 -2
- package/lib/math/oracles.d.ts +3 -0
- package/lib/math/oracles.js +25 -5
- package/lib/math/position.js +2 -1
- package/lib/math/trade.js +2 -2
- package/lib/types.d.ts +57 -9
- package/lib/types.js +6 -0
- package/package.json +1 -1
- package/src/accounts/bulkUserStatsSubscription.ts +33 -0
- package/src/accounts/bulkUserSubscription.ts +0 -1
- package/src/accounts/fetch.ts +27 -2
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
- package/src/accounts/types.ts +18 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
- package/src/addresses/pda.ts +13 -0
- package/src/admin.ts +29 -1
- package/src/clearingHouse.ts +318 -15
- package/src/clearingHouseConfig.ts +1 -0
- package/src/clearingHouseUser.ts +113 -10
- package/src/clearingHouseUserStats.ts +53 -0
- package/src/clearingHouseUserStatsConfig.ts +18 -0
- package/src/config.ts +1 -1
- package/src/factory/bigNum.ts +6 -7
- package/src/idl/clearing_house.json +620 -64
- package/src/math/amm.ts +8 -5
- package/src/math/bankBalance.ts +50 -1
- package/src/math/oracles.ts +42 -5
- package/src/math/position.ts +2 -1
- package/src/math/trade.ts +2 -2
- package/src/types.ts +61 -9
- package/tests/bn/test.ts +8 -0
- package/src/accounts/bulkAccountLoader.js +0 -197
- package/src/accounts/bulkUserSubscription.js +0 -33
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
- package/src/accounts/pollingOracleSubscriber.js +0 -93
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
- package/src/accounts/pollingUserAccountSubscriber.js +0 -132
- package/src/accounts/types.js +0 -10
- package/src/accounts/utils.js +0 -7
- package/src/accounts/webSocketAccountSubscriber.js +0 -93
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
- package/src/addresses/marketAddresses.js +0 -26
- package/src/assert/assert.js +0 -9
- package/src/clearingHouseUserConfig.js +0 -2
- package/src/constants/banks.js +0 -42
- package/src/constants/markets.js +0 -42
- package/src/constants/numericConstants.js +0 -41
- package/src/events/eventList.js +0 -77
- package/src/events/eventSubscriber.js +0 -139
- package/src/events/fetchLogs.js +0 -50
- package/src/events/pollingLogProvider.js +0 -64
- package/src/events/sort.js +0 -44
- package/src/events/txEventCache.js +0 -71
- package/src/events/types.js +0 -20
- package/src/events/webSocketLogProvider.js +0 -41
- package/src/examples/makeTradeExample.js +0 -80
- package/src/factory/bigNum.js +0 -390
- package/src/factory/oracleClient.js +0 -20
- package/src/index.js +0 -69
- package/src/math/amm.js +0 -369
- package/src/math/auction.js +0 -42
- package/src/math/conversion.js +0 -11
- package/src/math/funding.js +0 -248
- package/src/math/oracles.js +0 -26
- package/src/math/repeg.js +0 -128
- package/src/math/state.js +0 -15
- package/src/math/trade.js +0 -253
- package/src/math/utils.js +0 -26
- package/src/math/utils.js.map +0 -1
- package/src/mockUSDCFaucet.js +0 -280
- package/src/oracles/oracleClientCache.js +0 -19
- package/src/oracles/pythClient.js +0 -46
- package/src/oracles/quoteAssetOracleClient.js +0 -32
- package/src/oracles/switchboardClient.js +0 -69
- package/src/oracles/types.js +0 -2
- package/src/orderParams.js +0 -20
- package/src/slot/SlotSubscriber.js +0 -39
- package/src/token/index.js +0 -38
- package/src/tokenFaucet.js +0 -189
- package/src/tx/types.js +0 -2
- package/src/tx/utils.js +0 -17
- package/src/types.js +0 -125
- package/src/userName.js +0 -20
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
- package/src/wallet.js +0 -35
package/src/math/amm.ts
CHANGED
|
@@ -33,11 +33,14 @@ export function calculatePegFromTargetPrice(
|
|
|
33
33
|
baseAssetReserve: BN,
|
|
34
34
|
quoteAssetReserve: BN
|
|
35
35
|
): BN {
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
return BN.max(
|
|
37
|
+
targetPrice
|
|
38
|
+
.mul(baseAssetReserve)
|
|
39
|
+
.div(quoteAssetReserve)
|
|
40
|
+
.add(PRICE_DIV_PEG.div(new BN(2)))
|
|
41
|
+
.div(PRICE_DIV_PEG),
|
|
42
|
+
ONE
|
|
43
|
+
);
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
export function calculateOptimalPegAndBudget(
|
package/src/math/bankBalance.ts
CHANGED
|
@@ -187,7 +187,7 @@ export function calculateInterestAccumulated(
|
|
|
187
187
|
.div(BANK_UTILIZATION_PRECISION);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
const timeSinceLastUpdate = now.sub(bank.
|
|
190
|
+
const timeSinceLastUpdate = now.sub(bank.lastInterestTs);
|
|
191
191
|
|
|
192
192
|
const modifiedBorrowRate = interest_rate.mul(timeSinceLastUpdate);
|
|
193
193
|
|
|
@@ -207,3 +207,52 @@ export function calculateInterestAccumulated(
|
|
|
207
207
|
|
|
208
208
|
return { borrowInterest, depositInterest };
|
|
209
209
|
}
|
|
210
|
+
|
|
211
|
+
export function calculateWithdrawLimit(
|
|
212
|
+
bank: BankAccount,
|
|
213
|
+
now: BN
|
|
214
|
+
): { borrowLimit: BN; withdrawLimit: BN } {
|
|
215
|
+
const bankDepositTokenAmount = getTokenAmount(
|
|
216
|
+
bank.depositBalance,
|
|
217
|
+
bank,
|
|
218
|
+
BankBalanceType.DEPOSIT
|
|
219
|
+
);
|
|
220
|
+
const bankBorrowTokenAmount = getTokenAmount(
|
|
221
|
+
bank.borrowBalance,
|
|
222
|
+
bank,
|
|
223
|
+
BankBalanceType.BORROW
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const twentyFourHours = new BN(60 * 60 * 24);
|
|
227
|
+
const sinceLast = now.sub(bank.lastTwapTs);
|
|
228
|
+
const sinceStart = BN.max(ZERO, twentyFourHours.sub(sinceLast));
|
|
229
|
+
const borrowTokenTwapLive = bank.borrowTokenTwap
|
|
230
|
+
.mul(sinceStart)
|
|
231
|
+
.add(bankBorrowTokenAmount.mul(sinceLast))
|
|
232
|
+
.div(sinceLast.add(sinceLast));
|
|
233
|
+
|
|
234
|
+
const depositTokenTwapLive = bank.depositTokenTwap
|
|
235
|
+
.mul(sinceStart)
|
|
236
|
+
.add(bankDepositTokenAmount.mul(sinceLast))
|
|
237
|
+
.div(sinceLast.add(sinceLast));
|
|
238
|
+
|
|
239
|
+
const maxBorrowTokens = BN.min(
|
|
240
|
+
BN.max(
|
|
241
|
+
bankDepositTokenAmount.div(new BN(6)),
|
|
242
|
+
borrowTokenTwapLive.add(borrowTokenTwapLive.div(new BN(5)))
|
|
243
|
+
),
|
|
244
|
+
bankDepositTokenAmount.sub(bankDepositTokenAmount.div(new BN(10)))
|
|
245
|
+
); // between ~15-90% utilization with friction on twap
|
|
246
|
+
|
|
247
|
+
const minDepositTokens = depositTokenTwapLive.sub(
|
|
248
|
+
BN.min(
|
|
249
|
+
BN.max(depositTokenTwapLive.div(new BN(5)), bank.withdrawGuardThreshold),
|
|
250
|
+
depositTokenTwapLive
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
borrowLimit: maxBorrowTokens.sub(bankBorrowTokenAmount),
|
|
256
|
+
withdrawLimit: bankDepositTokenAmount.sub(minDepositTokens),
|
|
257
|
+
};
|
|
258
|
+
}
|
package/src/math/oracles.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { AMM, OracleGuardRails } from '../types';
|
|
2
2
|
import { OraclePriceData } from '../oracles/types';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
BID_ASK_SPREAD_PRECISION,
|
|
5
|
+
MARK_PRICE_PRECISION,
|
|
6
|
+
ONE,
|
|
7
|
+
ZERO,
|
|
8
|
+
} from '../constants/numericConstants';
|
|
4
9
|
import { BN } from '../index';
|
|
5
10
|
|
|
6
11
|
export function isOracleValid(
|
|
@@ -9,7 +14,7 @@ export function isOracleValid(
|
|
|
9
14
|
oracleGuardRails: OracleGuardRails,
|
|
10
15
|
slot: number
|
|
11
16
|
): boolean {
|
|
12
|
-
const isOraclePriceNonPositive = oraclePriceData.price.
|
|
17
|
+
const isOraclePriceNonPositive = oraclePriceData.price.lte(ZERO);
|
|
13
18
|
const isOraclePriceTooVolatile =
|
|
14
19
|
oraclePriceData.price
|
|
15
20
|
.div(BN.max(ONE, amm.lastOraclePriceTwap))
|
|
@@ -18,9 +23,11 @@ export function isOracleValid(
|
|
|
18
23
|
.div(BN.max(ONE, oraclePriceData.price))
|
|
19
24
|
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
20
25
|
|
|
21
|
-
const isConfidenceTooLarge =
|
|
22
|
-
.
|
|
23
|
-
.
|
|
26
|
+
const isConfidenceTooLarge = new BN(amm.baseSpread)
|
|
27
|
+
.add(BN.max(ONE, oraclePriceData.confidence))
|
|
28
|
+
.mul(BID_ASK_SPREAD_PRECISION)
|
|
29
|
+
.div(oraclePriceData.price)
|
|
30
|
+
.gt(new BN(amm.maxSpread));
|
|
24
31
|
|
|
25
32
|
const oracleIsStale = oraclePriceData.slot
|
|
26
33
|
.sub(new BN(slot))
|
|
@@ -34,3 +41,33 @@ export function isOracleValid(
|
|
|
34
41
|
isConfidenceTooLarge
|
|
35
42
|
);
|
|
36
43
|
}
|
|
44
|
+
|
|
45
|
+
export function isOracleTooDivergent(
|
|
46
|
+
amm: AMM,
|
|
47
|
+
oraclePriceData: OraclePriceData,
|
|
48
|
+
oracleGuardRails: OracleGuardRails,
|
|
49
|
+
now: BN
|
|
50
|
+
): boolean {
|
|
51
|
+
const sinceLastUpdate = now.sub(amm.lastOraclePriceTwapTs);
|
|
52
|
+
const sinceStart = BN.max(ZERO, new BN(60 * 5).sub(sinceLastUpdate));
|
|
53
|
+
const oracleTwap5min = amm.lastOraclePriceTwap5min
|
|
54
|
+
.mul(sinceStart)
|
|
55
|
+
.add(oraclePriceData.price)
|
|
56
|
+
.mul(sinceLastUpdate)
|
|
57
|
+
.div(sinceStart.add(sinceLastUpdate));
|
|
58
|
+
|
|
59
|
+
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
60
|
+
const oracleSpreadPct = oracleSpread
|
|
61
|
+
.mul(MARK_PRICE_PRECISION)
|
|
62
|
+
.div(oracleTwap5min);
|
|
63
|
+
|
|
64
|
+
const tooDivergent = oracleSpreadPct
|
|
65
|
+
.abs()
|
|
66
|
+
.gte(
|
|
67
|
+
BID_ASK_SPREAD_PRECISION.mul(
|
|
68
|
+
oracleGuardRails.priceDivergence.markOracleDivergenceNumerator
|
|
69
|
+
).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator)
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return tooDivergent;
|
|
73
|
+
}
|
package/src/math/position.ts
CHANGED
|
@@ -189,7 +189,8 @@ export function positionIsAvailable(position: UserPosition): boolean {
|
|
|
189
189
|
return (
|
|
190
190
|
position.baseAssetAmount.eq(ZERO) &&
|
|
191
191
|
position.openOrders.eq(ZERO) &&
|
|
192
|
-
position.quoteAssetAmount.eq(ZERO)
|
|
192
|
+
position.quoteAssetAmount.eq(ZERO) &&
|
|
193
|
+
position.lpShares.eq(ZERO)
|
|
193
194
|
);
|
|
194
195
|
}
|
|
195
196
|
|
package/src/math/trade.ts
CHANGED
|
@@ -177,13 +177,13 @@ export function calculateTradeAcquiredAmounts(
|
|
|
177
177
|
|
|
178
178
|
const acquiredBase = amm.baseAssetReserve.sub(newBaseAssetReserve);
|
|
179
179
|
const acquiredQuote = amm.quoteAssetReserve.sub(newQuoteAssetReserve);
|
|
180
|
-
const
|
|
180
|
+
const acquiredQuoteAssetAmount = calculateQuoteAssetAmountSwapped(
|
|
181
181
|
acquiredQuote.abs(),
|
|
182
182
|
amm.pegMultiplier,
|
|
183
183
|
swapDirection
|
|
184
184
|
);
|
|
185
185
|
|
|
186
|
-
return [acquiredBase, acquiredQuote,
|
|
186
|
+
return [acquiredBase, acquiredQuote, acquiredQuoteAssetAmount];
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
/**
|
package/src/types.ts
CHANGED
|
@@ -177,6 +177,8 @@ export type LiquidationRecord = {
|
|
|
177
177
|
liquidateBorrow: LiquidateBorrowRecord;
|
|
178
178
|
liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
|
|
179
179
|
liquidatePerpPnlForDeposit: LiquidatePerpPnlForDepositRecord;
|
|
180
|
+
perpBankruptcy: PerpBankruptcyRecord;
|
|
181
|
+
borrowBankruptcy: BorrowBankruptcyRecord;
|
|
180
182
|
};
|
|
181
183
|
|
|
182
184
|
export class LiquidationType {
|
|
@@ -188,6 +190,12 @@ export class LiquidationType {
|
|
|
188
190
|
static readonly LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
|
|
189
191
|
liquidatePerpPnlForDeposit: {},
|
|
190
192
|
};
|
|
193
|
+
static readonly PERP_BANKRUPTCY = {
|
|
194
|
+
perpBankruptcy: {},
|
|
195
|
+
};
|
|
196
|
+
static readonly BORROW_BANKRUPTCY = {
|
|
197
|
+
borrowBankruptcy: {},
|
|
198
|
+
};
|
|
191
199
|
}
|
|
192
200
|
|
|
193
201
|
export type LiquidatePerpRecord = {
|
|
@@ -231,14 +239,27 @@ export type LiquidatePerpPnlForDepositRecord = {
|
|
|
231
239
|
assetTransfer: BN;
|
|
232
240
|
};
|
|
233
241
|
|
|
242
|
+
export type PerpBankruptcyRecord = {
|
|
243
|
+
marketIndex: BN;
|
|
244
|
+
pnl: BN;
|
|
245
|
+
cumulativeFundingRateDelta: BN;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export type BorrowBankruptcyRecord = {
|
|
249
|
+
bankIndex: BN;
|
|
250
|
+
borrowAmount: BN;
|
|
251
|
+
cumulativeDepositInterestDelta: BN;
|
|
252
|
+
};
|
|
253
|
+
|
|
234
254
|
export type SettlePnlRecord = {
|
|
235
255
|
ts: BN;
|
|
256
|
+
user: PublicKey;
|
|
236
257
|
marketIndex: BN;
|
|
237
258
|
pnl: BN;
|
|
238
259
|
baseAssetAmount: BN;
|
|
239
260
|
quoteAssetAmountAfter: BN;
|
|
240
261
|
quoteEntryamount: BN;
|
|
241
|
-
|
|
262
|
+
settlePrice: BN;
|
|
242
263
|
};
|
|
243
264
|
|
|
244
265
|
export type OrderRecord = {
|
|
@@ -329,7 +350,8 @@ export type BankAccount = {
|
|
|
329
350
|
cumulativeBorrowInterest: BN;
|
|
330
351
|
depositBalance: BN;
|
|
331
352
|
borrowBalance: BN;
|
|
332
|
-
|
|
353
|
+
lastInterestTs: BN;
|
|
354
|
+
lastTwapTs: BN;
|
|
333
355
|
oracle: PublicKey;
|
|
334
356
|
initialAssetWeight: BN;
|
|
335
357
|
maintenanceAssetWeight: BN;
|
|
@@ -337,6 +359,11 @@ export type BankAccount = {
|
|
|
337
359
|
maintenanceLiabilityWeight: BN;
|
|
338
360
|
liquidationFee: BN;
|
|
339
361
|
imfFactor: BN;
|
|
362
|
+
|
|
363
|
+
withdrawGuardThreshold: BN;
|
|
364
|
+
depositTokenTwap: BN;
|
|
365
|
+
borrowTokenTwap: BN;
|
|
366
|
+
utilizationTwap: BN;
|
|
340
367
|
};
|
|
341
368
|
|
|
342
369
|
export type PoolBalance = {
|
|
@@ -350,8 +377,10 @@ export type AMM = {
|
|
|
350
377
|
lastFundingRate: BN;
|
|
351
378
|
lastFundingRateTs: BN;
|
|
352
379
|
lastMarkPriceTwap: BN;
|
|
380
|
+
lastMarkPriceTwap5min: BN;
|
|
353
381
|
lastMarkPriceTwapTs: BN;
|
|
354
382
|
lastOraclePriceTwap: BN;
|
|
383
|
+
lastOraclePriceTwap5min: BN;
|
|
355
384
|
lastOraclePriceTwapTs: BN;
|
|
356
385
|
lastOracleMarkSpreadPct: BN;
|
|
357
386
|
lastOracleConfPct: BN;
|
|
@@ -362,11 +391,16 @@ export type AMM = {
|
|
|
362
391
|
pegMultiplier: BN;
|
|
363
392
|
cumulativeFundingRateLong: BN;
|
|
364
393
|
cumulativeFundingRateShort: BN;
|
|
394
|
+
cumulativeFundingRateLp: BN;
|
|
365
395
|
cumulativeRepegRebateLong: BN;
|
|
366
396
|
cumulativeRepegRebateShort: BN;
|
|
367
397
|
totalFeeMinusDistributions: BN;
|
|
368
398
|
totalFeeWithdrawn: BN;
|
|
369
399
|
totalFee: BN;
|
|
400
|
+
cumulativeFundingPaymentPerLp: BN;
|
|
401
|
+
cumulativeFeePerLp: BN;
|
|
402
|
+
cumulativeNetBaseAssetAmountPerLp: BN;
|
|
403
|
+
userLpShares: BN;
|
|
370
404
|
minimumQuoteAssetTradeSize: BN;
|
|
371
405
|
baseAssetAmountStepSize: BN;
|
|
372
406
|
maxBaseAssetAmountRatio: number;
|
|
@@ -388,6 +422,8 @@ export type AMM = {
|
|
|
388
422
|
longSpread: BN;
|
|
389
423
|
shortSpread: BN;
|
|
390
424
|
maxSpread: number;
|
|
425
|
+
marketPosition: UserPosition;
|
|
426
|
+
marketPositionPerLp: UserPosition;
|
|
391
427
|
};
|
|
392
428
|
|
|
393
429
|
// # User Account Types
|
|
@@ -400,15 +436,21 @@ export type UserPosition = {
|
|
|
400
436
|
openOrders: BN;
|
|
401
437
|
openBids: BN;
|
|
402
438
|
openAsks: BN;
|
|
439
|
+
realizedPnl: BN;
|
|
440
|
+
lpShares: BN;
|
|
441
|
+
lastFeePerLp: BN;
|
|
442
|
+
lastNetBaseAssetAmountPerLp: BN;
|
|
443
|
+
lastNetQuoteAssetAmountPerLp: BN;
|
|
403
444
|
};
|
|
404
445
|
|
|
405
|
-
export type
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
446
|
+
export type UserStatsAccount = {
|
|
447
|
+
numberOfUsers: number;
|
|
448
|
+
makerVolume30D: BN;
|
|
449
|
+
takerVolume30D: BN;
|
|
450
|
+
fillerVolume30D: BN;
|
|
451
|
+
lastMakerVolume30DTs: BN;
|
|
452
|
+
lastTakerVolume30DTs: BN;
|
|
453
|
+
lastFillerVolume30DTs: BN;
|
|
412
454
|
fees: {
|
|
413
455
|
totalFeePaid: BN;
|
|
414
456
|
totalFeeRebate: BN;
|
|
@@ -416,9 +458,17 @@ export type UserAccount = {
|
|
|
416
458
|
totalReferralReward: BN;
|
|
417
459
|
totalRefereeDiscount: BN;
|
|
418
460
|
};
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
export type UserAccount = {
|
|
464
|
+
authority: PublicKey;
|
|
465
|
+
name: number[];
|
|
466
|
+
userId: number;
|
|
467
|
+
bankBalances: UserBankBalance[];
|
|
419
468
|
positions: UserPosition[];
|
|
420
469
|
orders: Order[];
|
|
421
470
|
beingLiquidated: boolean;
|
|
471
|
+
bankrupt: boolean;
|
|
422
472
|
nextLiquidationId: number;
|
|
423
473
|
};
|
|
424
474
|
|
|
@@ -515,11 +565,13 @@ export const DefaultOrderParams = {
|
|
|
515
565
|
|
|
516
566
|
export type MakerInfo = {
|
|
517
567
|
maker: PublicKey;
|
|
568
|
+
makerStats: PublicKey;
|
|
518
569
|
order: Order;
|
|
519
570
|
};
|
|
520
571
|
|
|
521
572
|
export type TakerInfo = {
|
|
522
573
|
taker: PublicKey;
|
|
574
|
+
takerStats: PublicKey;
|
|
523
575
|
order: Order;
|
|
524
576
|
};
|
|
525
577
|
|
package/tests/bn/test.ts
CHANGED
|
@@ -127,6 +127,14 @@ describe('BigNum Tests', () => {
|
|
|
127
127
|
expect(BigNum.fromPrint('123456789').toMillified(5)).to.equal('123.45M');
|
|
128
128
|
|
|
129
129
|
expect(BigNum.from(-95, 2).print()).to.equal('-0.95');
|
|
130
|
+
|
|
131
|
+
// Case 6 strange numbers
|
|
132
|
+
expect(BigNum.from('-100', 2).print()).to.equal('-1.00');
|
|
133
|
+
expect(BigNum.from('-8402189', 13).print()).to.equal('-0.0000008402189');
|
|
134
|
+
expect(BigNum.from('-10000000000000', 13).print()).to.equal(
|
|
135
|
+
'-1.0000000000000'
|
|
136
|
+
);
|
|
137
|
+
expect(BigNum.from('-100', 6).print()).to.equal('-0.000100');
|
|
130
138
|
});
|
|
131
139
|
|
|
132
140
|
it('can initialise from string values correctly', () => {
|
|
@@ -1,197 +0,0 @@
|
|
|
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.BulkAccountLoader = void 0;
|
|
13
|
-
const uuid_1 = require("uuid");
|
|
14
|
-
const promiseTimeout_1 = require("../util/promiseTimeout");
|
|
15
|
-
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
16
|
-
const oneMinute = 60 * 1000;
|
|
17
|
-
class BulkAccountLoader {
|
|
18
|
-
constructor(connection, commitment, pollingFrequency) {
|
|
19
|
-
this.accountsToLoad = new Map();
|
|
20
|
-
this.bufferAndSlotMap = new Map();
|
|
21
|
-
this.errorCallbacks = new Map();
|
|
22
|
-
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
23
|
-
this.mostRecentSlot = 0;
|
|
24
|
-
this.connection = connection;
|
|
25
|
-
this.commitment = commitment;
|
|
26
|
-
this.pollingFrequency = pollingFrequency;
|
|
27
|
-
}
|
|
28
|
-
addAccount(publicKey, callback) {
|
|
29
|
-
const existingSize = this.accountsToLoad.size;
|
|
30
|
-
const callbackId = uuid_1.v4();
|
|
31
|
-
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
32
|
-
if (existingAccountToLoad) {
|
|
33
|
-
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
const callbacks = new Map();
|
|
37
|
-
callbacks.set(callbackId, callback);
|
|
38
|
-
const newAccountToLoad = {
|
|
39
|
-
publicKey,
|
|
40
|
-
callbacks,
|
|
41
|
-
};
|
|
42
|
-
this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
|
|
43
|
-
}
|
|
44
|
-
if (existingSize === 0) {
|
|
45
|
-
this.startPolling();
|
|
46
|
-
}
|
|
47
|
-
// if a new account needs to be polled, remove the cached loadPromise in case client calls load immediately after
|
|
48
|
-
this.loadPromise = undefined;
|
|
49
|
-
return callbackId;
|
|
50
|
-
}
|
|
51
|
-
removeAccount(publicKey, callbackId) {
|
|
52
|
-
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
53
|
-
if (existingAccountToLoad) {
|
|
54
|
-
existingAccountToLoad.callbacks.delete(callbackId);
|
|
55
|
-
if (existingAccountToLoad.callbacks.size === 0) {
|
|
56
|
-
this.accountsToLoad.delete(existingAccountToLoad.publicKey.toString());
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (this.accountsToLoad.size === 0) {
|
|
60
|
-
this.stopPolling();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
addErrorCallbacks(callback) {
|
|
64
|
-
const callbackId = uuid_1.v4();
|
|
65
|
-
this.errorCallbacks.set(callbackId, callback);
|
|
66
|
-
return callbackId;
|
|
67
|
-
}
|
|
68
|
-
removeErrorCallbacks(callbackId) {
|
|
69
|
-
this.errorCallbacks.delete(callbackId);
|
|
70
|
-
}
|
|
71
|
-
chunks(array, size) {
|
|
72
|
-
return new Array(Math.ceil(array.length / size))
|
|
73
|
-
.fill(null)
|
|
74
|
-
.map((_, index) => index * size)
|
|
75
|
-
.map((begin) => array.slice(begin, begin + size));
|
|
76
|
-
}
|
|
77
|
-
load() {
|
|
78
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
-
if (this.loadPromise) {
|
|
80
|
-
const now = Date.now();
|
|
81
|
-
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
82
|
-
this.loadPromise = undefined;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
return this.loadPromise;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
this.loadPromise = new Promise((resolver) => {
|
|
89
|
-
this.loadPromiseResolver = resolver;
|
|
90
|
-
});
|
|
91
|
-
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
92
|
-
try {
|
|
93
|
-
const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
|
|
94
|
-
yield Promise.all(chunks.map((chunk) => {
|
|
95
|
-
return this.loadChunk(chunk);
|
|
96
|
-
}));
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
console.error(`Error in bulkAccountLoader.load()`);
|
|
100
|
-
console.error(e);
|
|
101
|
-
for (const [_, callback] of this.errorCallbacks) {
|
|
102
|
-
callback(e);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
finally {
|
|
106
|
-
this.loadPromiseResolver();
|
|
107
|
-
this.loadPromise = undefined;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
loadChunk(accountsToLoad) {
|
|
112
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
-
if (accountsToLoad.length === 0) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
const args = [
|
|
117
|
-
accountsToLoad.map((accountToLoad) => {
|
|
118
|
-
return accountToLoad.publicKey.toBase58();
|
|
119
|
-
}),
|
|
120
|
-
{ commitment: this.commitment },
|
|
121
|
-
];
|
|
122
|
-
const rpcResponse = yield promiseTimeout_1.promiseTimeout(
|
|
123
|
-
// @ts-ignore
|
|
124
|
-
this.connection._rpcRequest('getMultipleAccounts', args), 10 * 1000 // 30 second timeout
|
|
125
|
-
);
|
|
126
|
-
if (rpcResponse === null) {
|
|
127
|
-
this.log('request to rpc timed out');
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const newSlot = rpcResponse.result.context.slot;
|
|
131
|
-
if (newSlot > this.mostRecentSlot) {
|
|
132
|
-
this.mostRecentSlot = newSlot;
|
|
133
|
-
}
|
|
134
|
-
for (const i in accountsToLoad) {
|
|
135
|
-
const accountToLoad = accountsToLoad[i];
|
|
136
|
-
const key = accountToLoad.publicKey.toString();
|
|
137
|
-
const oldRPCResponse = this.bufferAndSlotMap.get(key);
|
|
138
|
-
let newBuffer = undefined;
|
|
139
|
-
if (rpcResponse.result.value[i]) {
|
|
140
|
-
const raw = rpcResponse.result.value[i].data[0];
|
|
141
|
-
const dataType = rpcResponse.result.value[i].data[1];
|
|
142
|
-
newBuffer = Buffer.from(raw, dataType);
|
|
143
|
-
}
|
|
144
|
-
if (!oldRPCResponse) {
|
|
145
|
-
this.bufferAndSlotMap.set(key, {
|
|
146
|
-
slot: newSlot,
|
|
147
|
-
buffer: newBuffer,
|
|
148
|
-
});
|
|
149
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
if (newSlot <= oldRPCResponse.slot) {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
const oldBuffer = oldRPCResponse.buffer;
|
|
156
|
-
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
157
|
-
this.bufferAndSlotMap.set(key, {
|
|
158
|
-
slot: newSlot,
|
|
159
|
-
buffer: newBuffer,
|
|
160
|
-
});
|
|
161
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
handleAccountCallbacks(accountToLoad, buffer, slot) {
|
|
167
|
-
for (const [_, callback] of accountToLoad.callbacks) {
|
|
168
|
-
callback(buffer, slot);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
getBufferAndSlot(publicKey) {
|
|
172
|
-
return this.bufferAndSlotMap.get(publicKey.toString());
|
|
173
|
-
}
|
|
174
|
-
startPolling() {
|
|
175
|
-
if (this.intervalId) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
|
|
179
|
-
}
|
|
180
|
-
stopPolling() {
|
|
181
|
-
if (this.intervalId) {
|
|
182
|
-
clearInterval(this.intervalId);
|
|
183
|
-
this.intervalId = undefined;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
log(msg) {
|
|
187
|
-
console.log(msg);
|
|
188
|
-
}
|
|
189
|
-
updatePollingFrequency(pollingFrequency) {
|
|
190
|
-
this.stopPolling();
|
|
191
|
-
this.pollingFrequency = pollingFrequency;
|
|
192
|
-
if (this.accountsToLoad.size > 0) {
|
|
193
|
-
this.startPolling();
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
exports.BulkAccountLoader = BulkAccountLoader;
|
|
@@ -1,33 +0,0 @@
|
|
|
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.bulkPollingUserSubscribe = void 0;
|
|
13
|
-
/**
|
|
14
|
-
* @param users
|
|
15
|
-
* @param accountLoader
|
|
16
|
-
*/
|
|
17
|
-
function bulkPollingUserSubscribe(users, accountLoader) {
|
|
18
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
if (users.length === 0) {
|
|
20
|
-
yield accountLoader.load();
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
yield Promise.all(users.map((user) => {
|
|
24
|
-
// Pull the keys from the authority map so we can skip fetching them in addToAccountLoader
|
|
25
|
-
return user.accountSubscriber.addToAccountLoader();
|
|
26
|
-
}));
|
|
27
|
-
yield accountLoader.load();
|
|
28
|
-
yield Promise.all(users.map((user) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
-
return user.subscribe();
|
|
30
|
-
})));
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
exports.bulkPollingUserSubscribe = bulkPollingUserSubscribe;
|