@drift-labs/sdk 0.2.0-master.24 → 0.2.0-master.26
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/pollingClearingHouseAccountSubscriber.d.ts +13 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
- package/lib/accounts/types.d.ts +8 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
- package/lib/addresses/pda.d.ts +8 -6
- package/lib/addresses/pda.js +35 -27
- package/lib/admin.d.ts +9 -6
- package/lib/admin.js +90 -54
- package/lib/clearingHouse.d.ts +71 -42
- package/lib/clearingHouse.js +765 -282
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +19 -17
- package/lib/clearingHouseUser.js +145 -123
- package/lib/config.d.ts +7 -7
- package/lib/config.js +21 -21
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/events/eventSubscriber.d.ts +4 -2
- package/lib/events/eventSubscriber.js +16 -9
- package/lib/events/fetchLogs.d.ts +10 -1
- package/lib/events/fetchLogs.js +27 -7
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +6 -2
- package/lib/events/types.d.ts +4 -2
- package/lib/events/types.js +2 -0
- package/lib/examples/makeTradeExample.js +18 -6
- package/lib/idl/clearing_house.json +1128 -347
- package/lib/index.d.ts +6 -3
- package/lib/index.js +6 -3
- package/lib/math/amm.d.ts +5 -3
- package/lib/math/amm.js +42 -4
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +10 -9
- package/lib/math/market.js +29 -6
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +5 -5
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +19 -0
- package/lib/math/spotBalance.js +176 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +2 -0
- package/lib/math/spotPosition.js +8 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +148 -39
- package/lib/types.js +37 -9
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +106 -0
- package/my-script/multiConnections.ts +119 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.js +249 -0
- package/src/accounts/bulkUserStatsSubscription.js +75 -0
- package/src/accounts/bulkUserSubscription.js +75 -0
- package/src/accounts/fetch.js +92 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
- package/src/accounts/pollingOracleSubscriber.js +156 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
- package/src/accounts/pollingUserAccountSubscriber.js +208 -0
- package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
- package/src/accounts/types.js +28 -0
- package/src/accounts/types.ts +11 -9
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +138 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
- package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
- package/src/addresses/pda.js +186 -0
- package/src/addresses/pda.ts +56 -42
- package/src/admin.js +1284 -0
- package/src/admin.ts +149 -75
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.js +3433 -0
- package/src/clearingHouse.ts +1097 -380
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.js +874 -0
- package/src/clearingHouseUser.ts +237 -172
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/clearingHouseUserStats.js +115 -0
- package/src/clearingHouseUserStatsConfig.js +2 -0
- package/src/config.js +80 -0
- package/src/config.ts +30 -30
- package/src/constants/numericConstants.js +18 -11
- package/src/constants/numericConstants.ts +17 -15
- package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/spotMarkets.js +51 -0
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/events/eventList.js +66 -23
- package/src/events/eventSubscriber.js +202 -0
- package/src/events/eventSubscriber.ts +20 -12
- package/src/events/fetchLogs.js +117 -0
- package/src/events/fetchLogs.ts +35 -8
- package/src/events/pollingLogProvider.js +113 -0
- package/src/events/pollingLogProvider.ts +10 -2
- package/src/events/sort.js +41 -0
- package/src/events/txEventCache.js +22 -19
- package/src/events/types.js +25 -0
- package/src/events/types.ts +7 -1
- package/src/events/webSocketLogProvider.js +76 -0
- package/src/examples/makeTradeExample.ts +27 -6
- package/src/factory/bigNum.js +183 -180
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +1128 -347
- package/src/index.js +75 -0
- package/src/index.ts +6 -3
- package/src/math/amm.js +422 -0
- package/src/math/amm.ts +73 -5
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +4 -3
- package/src/math/funding.js +223 -175
- package/src/math/funding.ts +7 -7
- package/src/math/insurance.js +27 -0
- package/src/math/margin.js +77 -0
- package/src/math/margin.ts +34 -23
- package/src/math/market.js +105 -0
- package/src/math/market.ts +71 -19
- package/src/math/oracles.js +40 -10
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.js +153 -0
- package/src/math/orders.ts +5 -5
- package/src/math/position.js +172 -0
- package/src/math/position.ts +31 -31
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.js +176 -0
- package/src/math/spotBalance.ts +290 -0
- package/src/math/spotMarket.js +8 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.js +8 -0
- package/src/math/spotPosition.ts +6 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.js +81 -74
- package/src/math/trade.ts +4 -4
- package/src/math/utils.js +8 -7
- package/src/oracles/oracleClientCache.js +10 -9
- package/src/oracles/pythClient.js +52 -17
- package/src/oracles/quoteAssetOracleClient.js +44 -13
- package/src/oracles/switchboardClient.js +69 -37
- package/src/oracles/types.js +1 -1
- package/src/orderParams.js +14 -6
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.js +102 -0
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.js +2 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.js +67 -20
- package/src/token/index.js +4 -4
- package/src/tokenFaucet.js +288 -154
- package/src/tx/retryTxSender.js +280 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.js +1 -1
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.js +7 -6
- package/src/types.js +216 -0
- package/src/types.ts +131 -39
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +46 -11
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +46 -12
- package/src/wallet.js +55 -18
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/addresses/marketAddresses.js +0 -26
- package/src/constants/banks.js +0 -42
- package/src/examples/makeTradeExample.js +0 -80
- package/src/math/bankBalance.ts +0 -258
- package/src/math/state.js +0 -15
- package/src/math/utils.js.map +0 -1
- package/src/util/getTokenAddress.js +0 -9
package/lib/math/position.js
CHANGED
|
@@ -52,36 +52,36 @@ exports.calculateBaseAssetValue = calculateBaseAssetValue;
|
|
|
52
52
|
* calculatePositionPNL
|
|
53
53
|
* = BaseAssetAmount * (Avg Exit Price - Avg Entry Price)
|
|
54
54
|
* @param market
|
|
55
|
-
* @param
|
|
55
|
+
* @param PerpPosition
|
|
56
56
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
57
57
|
* @param oraclePriceData
|
|
58
58
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
59
59
|
*/
|
|
60
|
-
function calculatePositionPNL(market,
|
|
61
|
-
if (
|
|
62
|
-
return
|
|
60
|
+
function calculatePositionPNL(market, perpPosition, withFunding = false, oraclePriceData) {
|
|
61
|
+
if (perpPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
62
|
+
return perpPosition.quoteAssetAmount;
|
|
63
63
|
}
|
|
64
|
-
const baseAssetValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market,
|
|
65
|
-
const baseAssetValueSign =
|
|
64
|
+
const baseAssetValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, perpPosition, oraclePriceData);
|
|
65
|
+
const baseAssetValueSign = perpPosition.baseAssetAmount.isNeg()
|
|
66
66
|
? new __1.BN(-1)
|
|
67
67
|
: new __1.BN(1);
|
|
68
68
|
let pnl = baseAssetValue
|
|
69
69
|
.mul(baseAssetValueSign)
|
|
70
|
-
.add(
|
|
70
|
+
.add(perpPosition.quoteAssetAmount);
|
|
71
71
|
if (withFunding) {
|
|
72
|
-
const fundingRatePnL = calculatePositionFundingPNL(market,
|
|
72
|
+
const fundingRatePnL = calculatePositionFundingPNL(market, perpPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
73
73
|
pnl = pnl.add(fundingRatePnL);
|
|
74
74
|
}
|
|
75
75
|
return pnl;
|
|
76
76
|
}
|
|
77
77
|
exports.calculatePositionPNL = calculatePositionPNL;
|
|
78
|
-
function calculateUnsettledPnl(market,
|
|
79
|
-
const unrealizedPnl = calculatePositionPNL(market,
|
|
78
|
+
function calculateUnsettledPnl(market, perpPosition, oraclePriceData) {
|
|
79
|
+
const unrealizedPnl = calculatePositionPNL(market, perpPosition, true, oraclePriceData);
|
|
80
80
|
let unsettledPnl = unrealizedPnl;
|
|
81
81
|
if (unrealizedPnl.gt(numericConstants_1.ZERO)) {
|
|
82
|
-
const fundingPnL = calculatePositionFundingPNL(market,
|
|
83
|
-
const maxPositivePnl = __1.BN.max(
|
|
84
|
-
.sub(
|
|
82
|
+
const fundingPnL = calculatePositionFundingPNL(market, perpPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
83
|
+
const maxPositivePnl = __1.BN.max(perpPosition.quoteAssetAmount
|
|
84
|
+
.sub(perpPosition.quoteEntryAmount)
|
|
85
85
|
.add(fundingPnL), numericConstants_1.ZERO);
|
|
86
86
|
unsettledPnl = __1.BN.min(maxPositivePnl, unrealizedPnl);
|
|
87
87
|
}
|
|
@@ -91,23 +91,23 @@ exports.calculateUnsettledPnl = calculateUnsettledPnl;
|
|
|
91
91
|
/**
|
|
92
92
|
*
|
|
93
93
|
* @param market
|
|
94
|
-
* @param
|
|
94
|
+
* @param PerpPosition
|
|
95
95
|
* @returns // TODO-PRECISION
|
|
96
96
|
*/
|
|
97
|
-
function calculatePositionFundingPNL(market,
|
|
98
|
-
if (
|
|
97
|
+
function calculatePositionFundingPNL(market, perpPosition) {
|
|
98
|
+
if (perpPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
99
99
|
return numericConstants_1.ZERO;
|
|
100
100
|
}
|
|
101
101
|
let ammCumulativeFundingRate;
|
|
102
|
-
if (
|
|
102
|
+
if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
103
103
|
ammCumulativeFundingRate = market.amm.cumulativeFundingRateLong;
|
|
104
104
|
}
|
|
105
105
|
else {
|
|
106
106
|
ammCumulativeFundingRate = market.amm.cumulativeFundingRateShort;
|
|
107
107
|
}
|
|
108
108
|
const perPositionFundingRate = ammCumulativeFundingRate
|
|
109
|
-
.sub(
|
|
110
|
-
.mul(
|
|
109
|
+
.sub(perpPosition.lastCumulativeFundingRate)
|
|
110
|
+
.mul(perpPosition.baseAssetAmount)
|
|
111
111
|
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
112
112
|
.div(numericConstants_1.FUNDING_PAYMENT_PRECISION)
|
|
113
113
|
.mul(new __1.BN(-1));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { SpotMarketAccount, SpotBalanceType, MarginCategory } from '../types';
|
|
3
|
+
import { BN } from '@project-serum/anchor';
|
|
4
|
+
export declare function getBalance(tokenAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
|
|
5
|
+
export declare function getTokenAmount(balanceAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
|
|
6
|
+
export declare function calculateAssetWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
|
|
7
|
+
export declare function calculateLiabilityWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
|
|
8
|
+
export declare function calculateUtilization(bank: SpotMarketAccount): BN;
|
|
9
|
+
export declare function calculateInterestRate(bank: SpotMarketAccount): BN;
|
|
10
|
+
export declare function calculateDepositRate(bank: SpotMarketAccount): BN;
|
|
11
|
+
export declare function calculateBorrowRate(bank: SpotMarketAccount): BN;
|
|
12
|
+
export declare function calculateInterestAccumulated(bank: SpotMarketAccount, now: BN): {
|
|
13
|
+
borrowInterest: BN;
|
|
14
|
+
depositInterest: BN;
|
|
15
|
+
};
|
|
16
|
+
export declare function calculateWithdrawLimit(spotMarket: SpotMarketAccount, now: BN): {
|
|
17
|
+
borrowLimit: BN;
|
|
18
|
+
withdrawLimit: BN;
|
|
19
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenAmount = exports.getBalance = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
6
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
8
|
+
function getBalance(tokenAmount, spotMarket, balanceType) {
|
|
9
|
+
const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - spotMarket.decimals));
|
|
10
|
+
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
11
|
+
? spotMarket.cumulativeDepositInterest
|
|
12
|
+
: spotMarket.cumulativeBorrowInterest;
|
|
13
|
+
let balance = tokenAmount.mul(precisionIncrease).div(cumulativeInterest);
|
|
14
|
+
if (!balance.eq(numericConstants_1.ZERO) && (0, types_1.isVariant)(balanceType, 'borrow')) {
|
|
15
|
+
balance = balance.add(numericConstants_1.ONE);
|
|
16
|
+
}
|
|
17
|
+
return balance;
|
|
18
|
+
}
|
|
19
|
+
exports.getBalance = getBalance;
|
|
20
|
+
function getTokenAmount(balanceAmount, spotMarket, balanceType) {
|
|
21
|
+
const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - spotMarket.decimals));
|
|
22
|
+
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
23
|
+
? spotMarket.cumulativeDepositInterest
|
|
24
|
+
: spotMarket.cumulativeBorrowInterest;
|
|
25
|
+
return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
|
|
26
|
+
}
|
|
27
|
+
exports.getTokenAmount = getTokenAmount;
|
|
28
|
+
function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
|
|
29
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
|
|
30
|
+
let sizeInAmmReservePrecision;
|
|
31
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
32
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
36
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
37
|
+
.div(sizePrecision);
|
|
38
|
+
}
|
|
39
|
+
let assetWeight;
|
|
40
|
+
switch (marginCategory) {
|
|
41
|
+
case 'Initial':
|
|
42
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.initialAssetWeight);
|
|
43
|
+
break;
|
|
44
|
+
case 'Maintenance':
|
|
45
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.maintenanceAssetWeight);
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
assetWeight = spotMarket.initialAssetWeight;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return assetWeight;
|
|
52
|
+
}
|
|
53
|
+
exports.calculateAssetWeight = calculateAssetWeight;
|
|
54
|
+
function calculateLiabilityWeight(balanceAmount, spotMarket, marginCategory) {
|
|
55
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
|
|
56
|
+
let sizeInAmmReservePrecision;
|
|
57
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
58
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
62
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
63
|
+
.div(sizePrecision);
|
|
64
|
+
}
|
|
65
|
+
let assetWeight;
|
|
66
|
+
switch (marginCategory) {
|
|
67
|
+
case 'Initial':
|
|
68
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.initialLiabilityWeight, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
69
|
+
break;
|
|
70
|
+
case 'Maintenance':
|
|
71
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.maintenanceLiabilityWeight, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
assetWeight = spotMarket.initialLiabilityWeight;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
return assetWeight;
|
|
78
|
+
}
|
|
79
|
+
exports.calculateLiabilityWeight = calculateLiabilityWeight;
|
|
80
|
+
function calculateUtilization(bank) {
|
|
81
|
+
const tokenDepositAmount = getTokenAmount(bank.depositBalance, bank, types_1.SpotBalanceType.DEPOSIT);
|
|
82
|
+
const tokenBorrowAmount = getTokenAmount(bank.borrowBalance, bank, types_1.SpotBalanceType.BORROW);
|
|
83
|
+
let utilization;
|
|
84
|
+
if (tokenBorrowAmount.eq(numericConstants_1.ZERO) && tokenDepositAmount.eq(numericConstants_1.ZERO)) {
|
|
85
|
+
utilization = numericConstants_1.ZERO;
|
|
86
|
+
}
|
|
87
|
+
else if (tokenDepositAmount.eq(numericConstants_1.ZERO)) {
|
|
88
|
+
utilization = numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
utilization = tokenBorrowAmount
|
|
92
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
93
|
+
.div(tokenDepositAmount);
|
|
94
|
+
}
|
|
95
|
+
return utilization;
|
|
96
|
+
}
|
|
97
|
+
exports.calculateUtilization = calculateUtilization;
|
|
98
|
+
function calculateInterestRate(bank) {
|
|
99
|
+
const utilization = calculateUtilization(bank);
|
|
100
|
+
let interestRate;
|
|
101
|
+
if (utilization.gt(bank.optimalUtilization)) {
|
|
102
|
+
const surplusUtilization = utilization.sub(bank.optimalUtilization);
|
|
103
|
+
const borrowRateSlope = bank.maxBorrowRate
|
|
104
|
+
.sub(bank.optimalBorrowRate)
|
|
105
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
106
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(bank.optimalUtilization));
|
|
107
|
+
interestRate = bank.optimalBorrowRate.add(surplusUtilization
|
|
108
|
+
.mul(borrowRateSlope)
|
|
109
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const borrowRateSlope = bank.optimalBorrowRate
|
|
113
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
114
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(bank.optimalUtilization));
|
|
115
|
+
interestRate = utilization
|
|
116
|
+
.mul(borrowRateSlope)
|
|
117
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
118
|
+
}
|
|
119
|
+
return interestRate;
|
|
120
|
+
}
|
|
121
|
+
exports.calculateInterestRate = calculateInterestRate;
|
|
122
|
+
function calculateDepositRate(bank) {
|
|
123
|
+
const utilization = calculateUtilization(bank);
|
|
124
|
+
const borrowRate = calculateBorrowRate(bank);
|
|
125
|
+
const depositRate = borrowRate
|
|
126
|
+
.mul(utilization)
|
|
127
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
128
|
+
return depositRate;
|
|
129
|
+
}
|
|
130
|
+
exports.calculateDepositRate = calculateDepositRate;
|
|
131
|
+
function calculateBorrowRate(bank) {
|
|
132
|
+
return calculateInterestRate(bank);
|
|
133
|
+
}
|
|
134
|
+
exports.calculateBorrowRate = calculateBorrowRate;
|
|
135
|
+
function calculateInterestAccumulated(bank, now) {
|
|
136
|
+
const interestRate = calculateInterestRate(bank);
|
|
137
|
+
const timeSinceLastUpdate = now.sub(bank.lastInterestTs);
|
|
138
|
+
const modifiedBorrowRate = interestRate.mul(timeSinceLastUpdate);
|
|
139
|
+
const utilization = calculateUtilization(bank);
|
|
140
|
+
const modifiedDepositRate = modifiedBorrowRate
|
|
141
|
+
.mul(utilization)
|
|
142
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
143
|
+
const borrowInterest = bank.cumulativeBorrowInterest
|
|
144
|
+
.mul(modifiedBorrowRate)
|
|
145
|
+
.div(numericConstants_1.ONE_YEAR)
|
|
146
|
+
.div(numericConstants_1.SPOT_MARKET_INTEREST_PRECISION)
|
|
147
|
+
.add(numericConstants_1.ONE);
|
|
148
|
+
const depositInterest = bank.cumulativeDepositInterest
|
|
149
|
+
.mul(modifiedDepositRate)
|
|
150
|
+
.div(numericConstants_1.ONE_YEAR)
|
|
151
|
+
.div(numericConstants_1.SPOT_MARKET_INTEREST_PRECISION);
|
|
152
|
+
return { borrowInterest, depositInterest };
|
|
153
|
+
}
|
|
154
|
+
exports.calculateInterestAccumulated = calculateInterestAccumulated;
|
|
155
|
+
function calculateWithdrawLimit(spotMarket, now) {
|
|
156
|
+
const marketDepositTokenAmount = getTokenAmount(spotMarket.depositBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
157
|
+
const marketBorrowTokenAmount = getTokenAmount(spotMarket.borrowBalance, spotMarket, types_1.SpotBalanceType.BORROW);
|
|
158
|
+
const twentyFourHours = new anchor_1.BN(60 * 60 * 24);
|
|
159
|
+
const sinceLast = now.sub(spotMarket.lastTwapTs);
|
|
160
|
+
const sinceStart = anchor_1.BN.max(numericConstants_1.ZERO, twentyFourHours.sub(sinceLast));
|
|
161
|
+
const borrowTokenTwapLive = spotMarket.borrowTokenTwap
|
|
162
|
+
.mul(sinceStart)
|
|
163
|
+
.add(marketBorrowTokenAmount.mul(sinceLast))
|
|
164
|
+
.div(sinceLast.add(sinceLast));
|
|
165
|
+
const depositTokenTwapLive = spotMarket.depositTokenTwap
|
|
166
|
+
.mul(sinceStart)
|
|
167
|
+
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
168
|
+
.div(sinceLast.add(sinceLast));
|
|
169
|
+
const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(10)))); // between ~15-90% utilization with friction on twap
|
|
170
|
+
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
|
|
171
|
+
return {
|
|
172
|
+
borrowLimit: maxBorrowTokens.sub(marketBorrowTokenAmount),
|
|
173
|
+
withdrawLimit: marketDepositTokenAmount.sub(minDepositTokens),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
exports.calculateWithdrawLimit = calculateWithdrawLimit;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.castNumberToSpotPrecision = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
function castNumberToSpotPrecision(value, spotMarket) {
|
|
6
|
+
return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
|
|
7
|
+
}
|
|
8
|
+
exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isSpotPositionAvailable = void 0;
|
|
4
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
function isSpotPositionAvailable(position) {
|
|
6
|
+
return position.balance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
|
|
7
|
+
}
|
|
8
|
+
exports.isSpotPositionAvailable = isSpotPositionAvailable;
|
package/lib/math/state.js
CHANGED
|
@@ -8,8 +8,8 @@ exports.getExchangeFee = void 0;
|
|
|
8
8
|
* @returns Precision : basis points (bps)
|
|
9
9
|
*/
|
|
10
10
|
function getExchangeFee(state) {
|
|
11
|
-
const exchangeFee = state.
|
|
12
|
-
state.
|
|
11
|
+
const exchangeFee = state.perpFeeStructure.feeNumerator.toNumber() /
|
|
12
|
+
state.perpFeeStructure.feeDenominator.toNumber();
|
|
13
13
|
return exchangeFee;
|
|
14
14
|
}
|
|
15
15
|
exports.getExchangeFee = getExchangeFee;
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import {
|
|
2
|
+
import { PerpMarketAccount, PositionDirection } from '../types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
import { AssetType } from './amm';
|
|
5
5
|
import { OraclePriceData } from '../oracles/types';
|
|
@@ -21,7 +21,7 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
|
|
|
21
21
|
*
|
|
22
22
|
* 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
|
|
23
23
|
*/
|
|
24
|
-
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market:
|
|
24
|
+
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: PerpMarketAccount, inputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [BN, BN, BN, BN];
|
|
25
25
|
/**
|
|
26
26
|
* Calculates acquired amounts for trade executed
|
|
27
27
|
* @param direction
|
|
@@ -33,7 +33,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
|
|
|
33
33
|
* | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
|
|
34
34
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
35
35
|
*/
|
|
36
|
-
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market:
|
|
36
|
+
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: PerpMarketAccount, inputAssetType: AssetType, oraclePriceData: OraclePriceData, useSpread?: boolean): [BN, BN, BN];
|
|
37
37
|
/**
|
|
38
38
|
* calculateTargetPriceTrade
|
|
39
39
|
* simple function for finding arbitraging trades
|
|
@@ -51,4 +51,4 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
|
|
|
51
51
|
* targetPrice => the target price MARK_PRICE_PRECISION
|
|
52
52
|
* ]
|
|
53
53
|
*/
|
|
54
|
-
export declare function calculateTargetPriceTrade(market:
|
|
54
|
+
export declare function calculateTargetPriceTrade(market: PerpMarketAccount, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [PositionDirection, BN, BN, BN];
|
package/lib/orderParams.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { OptionalOrderParams, OrderTriggerCondition } from './types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
|
-
export declare function getLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
|
|
4
|
+
export declare function getLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'> & {
|
|
5
5
|
price: BN;
|
|
6
6
|
}): OptionalOrderParams;
|
|
7
|
-
export declare function getTriggerMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
|
|
7
|
+
export declare function getTriggerMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'> & {
|
|
8
8
|
triggerCondition: OrderTriggerCondition;
|
|
9
9
|
triggerPrice: BN;
|
|
10
10
|
}): OptionalOrderParams;
|
|
11
|
-
export declare function getTriggerLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
|
|
11
|
+
export declare function getTriggerLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'> & {
|
|
12
12
|
triggerCondition: OrderTriggerCondition;
|
|
13
13
|
triggerPrice: BN;
|
|
14
14
|
price: BN;
|
|
15
15
|
}): OptionalOrderParams;
|
|
16
|
-
export declare function getMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType'>): OptionalOrderParams;
|
|
16
|
+
export declare function getMarketOrderParams(params: Omit<OptionalOrderParams, 'orderType' | 'marketType'>): OptionalOrderParams;
|
package/lib/orderParams.js
CHANGED
|
@@ -3,18 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
function getLimitOrderParams(params) {
|
|
6
|
-
return Object.assign({}, params, {
|
|
6
|
+
return Object.assign({}, params, {
|
|
7
|
+
orderType: types_1.OrderType.LIMIT,
|
|
8
|
+
});
|
|
7
9
|
}
|
|
8
10
|
exports.getLimitOrderParams = getLimitOrderParams;
|
|
9
11
|
function getTriggerMarketOrderParams(params) {
|
|
10
|
-
return Object.assign({}, params, {
|
|
12
|
+
return Object.assign({}, params, {
|
|
13
|
+
orderType: types_1.OrderType.TRIGGER_MARKET,
|
|
14
|
+
});
|
|
11
15
|
}
|
|
12
16
|
exports.getTriggerMarketOrderParams = getTriggerMarketOrderParams;
|
|
13
17
|
function getTriggerLimitOrderParams(params) {
|
|
14
|
-
return Object.assign({}, params, {
|
|
18
|
+
return Object.assign({}, params, {
|
|
19
|
+
orderType: types_1.OrderType.TRIGGER_LIMIT,
|
|
20
|
+
});
|
|
15
21
|
}
|
|
16
22
|
exports.getTriggerLimitOrderParams = getTriggerLimitOrderParams;
|
|
17
23
|
function getMarketOrderParams(params) {
|
|
18
|
-
return Object.assign({}, params, {
|
|
24
|
+
return Object.assign({}, params, {
|
|
25
|
+
orderType: types_1.OrderType.MARKET,
|
|
26
|
+
});
|
|
19
27
|
}
|
|
20
28
|
exports.getMarketOrderParams = getMarketOrderParams;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
|
|
3
|
+
import { Market, Orderbook } from '@project-serum/serum';
|
|
4
|
+
import { SerumMarketSubscriberConfig } from './types';
|
|
5
|
+
export declare class SerumSubscriber {
|
|
6
|
+
connection: Connection;
|
|
7
|
+
programId: PublicKey;
|
|
8
|
+
marketAddress: PublicKey;
|
|
9
|
+
accountLoader: BulkAccountLoader;
|
|
10
|
+
market: Market;
|
|
11
|
+
subscribed: boolean;
|
|
12
|
+
asksAddress: PublicKey;
|
|
13
|
+
asks: Orderbook;
|
|
14
|
+
asksCallbackId: string;
|
|
15
|
+
lastAsksSlot: number;
|
|
16
|
+
bidsAddress: PublicKey;
|
|
17
|
+
bids: Orderbook;
|
|
18
|
+
bidsCallbackId: string;
|
|
19
|
+
lastBidsSlot: number;
|
|
20
|
+
constructor(config: SerumMarketSubscriberConfig);
|
|
21
|
+
subscribe(): Promise<void>;
|
|
22
|
+
unsubscribe(): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SerumSubscriber = void 0;
|
|
4
|
+
const serum_1 = require("@project-serum/serum");
|
|
5
|
+
class SerumSubscriber {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.connection = config.connection;
|
|
8
|
+
this.programId = config.programId;
|
|
9
|
+
this.marketAddress = config.marketAddress;
|
|
10
|
+
this.accountLoader = config.accountSubscription.accountLoader;
|
|
11
|
+
}
|
|
12
|
+
async subscribe() {
|
|
13
|
+
if (this.subscribed) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
this.market = await serum_1.Market.load(this.connection, this.marketAddress, undefined, this.programId);
|
|
17
|
+
this.asksAddress = this.market.asksAddress;
|
|
18
|
+
this.asks = await this.market.loadAsks(this.connection);
|
|
19
|
+
this.asksCallbackId = this.accountLoader.addAccount(this.asksAddress, (buffer, slot) => {
|
|
20
|
+
this.lastAsksSlot = slot;
|
|
21
|
+
this.asks = serum_1.Orderbook.decode(this.market, buffer);
|
|
22
|
+
console.log(this.asks.getL2(3));
|
|
23
|
+
});
|
|
24
|
+
this.bidsAddress = this.market.bidsAddress;
|
|
25
|
+
this.bids = await this.market.loadBids(this.connection);
|
|
26
|
+
this.bidsCallbackId = this.accountLoader.addAccount(this.bidsAddress, (buffer, slot) => {
|
|
27
|
+
this.lastBidsSlot = slot;
|
|
28
|
+
this.bids = serum_1.Orderbook.decode(this.market, buffer);
|
|
29
|
+
});
|
|
30
|
+
this.subscribed = true;
|
|
31
|
+
}
|
|
32
|
+
async unsubscribe() {
|
|
33
|
+
if (!this.subscribed) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.accountLoader.removeAccount(this.asksAddress, this.asksCallbackId);
|
|
37
|
+
this.accountLoader.removeAccount(this.bidsAddress, this.bidsCallbackId);
|
|
38
|
+
this.subscribed = false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.SerumSubscriber = SerumSubscriber;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
|
|
3
|
+
export declare type SerumMarketSubscriberConfig = {
|
|
4
|
+
connection: Connection;
|
|
5
|
+
programId: PublicKey;
|
|
6
|
+
marketAddress: PublicKey;
|
|
7
|
+
accountSubscription: {
|
|
8
|
+
type: 'polling';
|
|
9
|
+
accountLoader: BulkAccountLoader;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
@@ -11,7 +11,7 @@ export declare class RetryTxSender implements TxSender {
|
|
|
11
11
|
retrySleep: number;
|
|
12
12
|
additionalConnections: Connection[];
|
|
13
13
|
constructor(provider: AnchorProvider, timeout?: number, retrySleep?: number, additionalConnections?: Connection[]);
|
|
14
|
-
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
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
|
confirmTransaction(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
|
|
17
17
|
getTimestamp(): number;
|
package/lib/tx/retryTxSender.js
CHANGED
|
@@ -15,14 +15,16 @@ class RetryTxSender {
|
|
|
15
15
|
this.retrySleep = retrySleep !== null && retrySleep !== void 0 ? retrySleep : DEFAULT_RETRY;
|
|
16
16
|
this.additionalConnections = additionalConnections;
|
|
17
17
|
}
|
|
18
|
-
async send(tx, additionalSigners, opts) {
|
|
18
|
+
async send(tx, additionalSigners, opts, preSigned) {
|
|
19
19
|
if (additionalSigners === undefined) {
|
|
20
20
|
additionalSigners = [];
|
|
21
21
|
}
|
|
22
22
|
if (opts === undefined) {
|
|
23
23
|
opts = this.provider.opts;
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
if (!preSigned) {
|
|
26
|
+
await this.prepareTx(tx, additionalSigners, opts);
|
|
27
|
+
}
|
|
26
28
|
const rawTransaction = tx.serialize();
|
|
27
29
|
const startTime = this.getTimestamp();
|
|
28
30
|
let txid;
|
package/lib/tx/types.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export declare type TxSigAndSlot = {
|
|
|
6
6
|
};
|
|
7
7
|
export interface TxSender {
|
|
8
8
|
provider: Provider;
|
|
9
|
-
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
9
|
+
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
10
10
|
}
|