@haven-fi/solauto-sdk 1.0.628 → 1.0.630
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/README.md +35 -6
- package/dist/constants/marginfiAccounts.d.ts.map +1 -1
- package/dist/constants/solautoConstants.d.ts +2 -1
- package/dist/constants/solautoConstants.d.ts.map +1 -1
- package/dist/generated/instructions/marginfiRebalance.d.ts +5 -3
- package/dist/generated/instructions/marginfiRebalance.d.ts.map +1 -1
- package/dist/generated/instructions/marginfiRebalance.js +2 -1
- package/dist/generated/instructions/marginfiRefreshData.d.ts +7 -2
- package/dist/generated/instructions/marginfiRefreshData.d.ts.map +1 -1
- package/dist/generated/instructions/marginfiRefreshData.js +8 -4
- package/dist/generated/types/index.d.ts +1 -0
- package/dist/generated/types/index.d.ts.map +1 -1
- package/dist/generated/types/index.js +1 -0
- package/dist/generated/types/priceType.d.ts +15 -0
- package/dist/generated/types/priceType.d.ts.map +1 -0
- package/dist/generated/types/priceType.js +22 -0
- package/dist/services/rebalance/rebalanceSwapManager.d.ts.map +1 -1
- package/dist/services/rebalance/rebalanceSwapManager.js +8 -8
- package/dist/services/rebalance/rebalanceTxBuilder.d.ts +2 -0
- package/dist/services/rebalance/rebalanceTxBuilder.d.ts.map +1 -1
- package/dist/services/rebalance/rebalanceTxBuilder.js +21 -10
- package/dist/services/rebalance/rebalanceValues.d.ts +2 -2
- package/dist/services/rebalance/rebalanceValues.d.ts.map +1 -1
- package/dist/services/rebalance/rebalanceValues.js +17 -17
- package/dist/services/solauto/solautoClient.d.ts +2 -2
- package/dist/services/solauto/solautoClient.d.ts.map +1 -1
- package/dist/services/solauto/solautoClient.js +27 -28
- package/dist/services/solauto/solautoMarginfiClient.d.ts +2 -2
- package/dist/services/solauto/solautoMarginfiClient.d.ts.map +1 -1
- package/dist/services/solauto/solautoMarginfiClient.js +12 -10
- package/dist/services/transactions/transactionUtils.d.ts.map +1 -1
- package/dist/services/transactions/transactionUtils.js +10 -9
- package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts +3 -3
- package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts.map +1 -1
- package/dist/solautoPosition/marginfiSolautoPositionEx.js +9 -9
- package/dist/solautoPosition/solautoPositionEx.d.ts +44 -33
- package/dist/solautoPosition/solautoPositionEx.d.ts.map +1 -1
- package/dist/solautoPosition/solautoPositionEx.js +109 -90
- package/dist/types/solauto.d.ts +2 -1
- package/dist/types/solauto.d.ts.map +1 -1
- package/dist/utils/instructionUtils.js +2 -2
- package/dist/utils/marginfiUtils.d.ts +2 -2
- package/dist/utils/marginfiUtils.d.ts.map +1 -1
- package/dist/utils/marginfiUtils.js +5 -5
- package/dist/utils/priceUtils.d.ts +11 -5
- package/dist/utils/priceUtils.d.ts.map +1 -1
- package/dist/utils/priceUtils.js +45 -21
- package/local/logPositions.ts +12 -12
- package/local/shared.ts +1 -1
- package/local/txSandbox.ts +27 -32
- package/local/updateMarginfiLUT.ts +13 -6
- package/package.json +2 -1
- package/src/constants/marginfiAccounts.ts +0 -1
- package/src/constants/solautoConstants.ts +1 -1
- package/src/generated/instructions/marginfiRebalance.ts +9 -3
- package/src/generated/instructions/marginfiRefreshData.ts +27 -7
- package/src/generated/types/index.ts +1 -0
- package/src/generated/types/priceType.ts +22 -0
- package/src/services/rebalance/rebalanceSwapManager.ts +8 -12
- package/src/services/rebalance/rebalanceTxBuilder.ts +41 -11
- package/src/services/rebalance/rebalanceValues.ts +22 -16
- package/src/services/solauto/solautoClient.ts +30 -30
- package/src/services/solauto/solautoMarginfiClient.ts +13 -10
- package/src/services/transactions/transactionUtils.ts +11 -9
- package/src/solautoPosition/marginfiSolautoPositionEx.ts +11 -10
- package/src/solautoPosition/solautoPositionEx.ts +141 -117
- package/src/types/solauto.ts +2 -0
- package/src/utils/instructionUtils.ts +2 -2
- package/src/utils/marginfiUtils.ts +12 -8
- package/src/utils/priceUtils.ts +66 -22
- package/tests/transactions/shared.ts +2 -5
- package/tests/unit/rebalanceCalculations.ts +9 -12
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.SolautoPositionEx = void 0;
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
4
5
|
const umi_web3js_adapters_1 = require("@metaplex-foundation/umi-web3js-adapters");
|
5
6
|
const generated_1 = require("../generated");
|
6
7
|
const utils_1 = require("../utils");
|
@@ -23,103 +24,124 @@ class SolautoPositionEx {
|
|
23
24
|
this._data = args.data;
|
24
25
|
this.firstState = { ...args.data.state };
|
25
26
|
}
|
26
|
-
exists() {
|
27
|
+
get exists() {
|
27
28
|
return this._data.position !== undefined;
|
28
29
|
}
|
29
|
-
authority() {
|
30
|
+
get authority() {
|
30
31
|
return this._data.authority
|
31
32
|
? (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this._data.authority)
|
32
|
-
:
|
33
|
+
: web3_js_1.PublicKey.default;
|
33
34
|
}
|
34
|
-
positionId() {
|
35
|
+
get positionId() {
|
35
36
|
return this._data.positionId ? this._data.positionId[0] : undefined;
|
36
37
|
}
|
37
|
-
|
38
|
-
return
|
38
|
+
get positionType() {
|
39
|
+
return this._data.positionType;
|
39
40
|
}
|
40
|
-
|
41
|
+
get strategyName() {
|
42
|
+
return (0, utils_1.solautoStrategyName)(this.supplyMint, this.debtMint);
|
43
|
+
}
|
44
|
+
liqUtilizationRateBps(priceType) {
|
45
|
+
return (0, utils_1.getLiqUtilzationRateBps)(this.supplyUsd(priceType), this.debtUsd(priceType), this.state.liqThresholdBps);
|
46
|
+
}
|
47
|
+
get data() {
|
41
48
|
return this._data;
|
42
49
|
}
|
43
|
-
state() {
|
44
|
-
return this.data
|
50
|
+
get state() {
|
51
|
+
return this.data.state;
|
52
|
+
}
|
53
|
+
get settings() {
|
54
|
+
return this.contextUpdates?.settings ?? this.data.position?.settings;
|
55
|
+
}
|
56
|
+
updateSettings(settings) {
|
57
|
+
this.data.position.settings = settings;
|
58
|
+
}
|
59
|
+
get dca() {
|
60
|
+
return this.contextUpdates?.dca ?? this.data.position?.dca;
|
61
|
+
}
|
62
|
+
updateDca(dca) {
|
63
|
+
this.data.position.dca = dca;
|
45
64
|
}
|
46
|
-
|
47
|
-
return
|
65
|
+
get supplyMint() {
|
66
|
+
return (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this.state.supply.mint);
|
48
67
|
}
|
49
|
-
|
50
|
-
return
|
68
|
+
get supplyMintInfo() {
|
69
|
+
return (0, utils_1.tokenInfo)(this.supplyMint);
|
51
70
|
}
|
52
|
-
|
53
|
-
return (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this.state
|
71
|
+
get debtMint() {
|
72
|
+
return (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this.state.debt.mint);
|
54
73
|
}
|
55
|
-
|
56
|
-
return (0, utils_1.tokenInfo)(this.
|
74
|
+
get debtMintInfo() {
|
75
|
+
return (0, utils_1.tokenInfo)(this.debtMint);
|
57
76
|
}
|
58
|
-
|
59
|
-
return (0,
|
77
|
+
get boostToBps() {
|
78
|
+
return Math.min(this.settings?.boostToBps ?? 0, this.maxBoostToBps);
|
60
79
|
}
|
61
|
-
|
62
|
-
return (0, utils_1.
|
80
|
+
get maxBoostToBps() {
|
81
|
+
return (0, utils_1.maxBoostToBps)(this.state.maxLtvBps, this.state.liqThresholdBps);
|
63
82
|
}
|
64
|
-
|
65
|
-
return
|
83
|
+
get boostFromBps() {
|
84
|
+
return this.boostToBps - (this.settings?.boostGap ?? 0);
|
66
85
|
}
|
67
|
-
|
68
|
-
return
|
86
|
+
get repayToBps() {
|
87
|
+
return Math.min(this.settings?.repayToBps ?? 0, this.maxRepayToBps);
|
69
88
|
}
|
70
|
-
|
71
|
-
return
|
89
|
+
get maxRepayToBps() {
|
90
|
+
return (0, utils_1.maxRepayToBps)(this.state.maxLtvBps, this.state.liqThresholdBps);
|
72
91
|
}
|
73
|
-
repayFromBps() {
|
74
|
-
return (
|
92
|
+
get repayFromBps() {
|
93
|
+
return (this.settings?.repayToBps ?? 0) + (this.settings?.repayGap ?? 0);
|
75
94
|
}
|
76
|
-
|
77
|
-
return (0, utils_1.
|
95
|
+
get maxRepayFromBps() {
|
96
|
+
return (0, utils_1.maxRepayFromBps)(this.state.maxLtvBps, this.state.liqThresholdBps);
|
78
97
|
}
|
79
|
-
|
80
|
-
return (0, utils_1.
|
98
|
+
get netWorth() {
|
99
|
+
return (0, utils_1.calcNetWorth)(this.state);
|
81
100
|
}
|
82
|
-
|
83
|
-
return (0, utils_1.
|
101
|
+
get netWorthUsd() {
|
102
|
+
return (0, utils_1.calcNetWorthUsd)(this.state);
|
84
103
|
}
|
85
|
-
|
86
|
-
|
104
|
+
get totalSupply() {
|
105
|
+
return (0, utils_1.calcTotalSupply)(this.state);
|
106
|
+
}
|
107
|
+
supplyUsd(priceType) {
|
108
|
+
const supplyPrice = (0, utils_1.safeGetPrice)(this.supplyMint, priceType);
|
87
109
|
return supplyPrice
|
88
|
-
? (0, utils_1.calcTotalSupply)(this.state
|
89
|
-
: (0, utils_1.calcSupplyUsd)(this.state
|
110
|
+
? (0, utils_1.calcTotalSupply)(this.state) * supplyPrice
|
111
|
+
: (0, utils_1.calcSupplyUsd)(this.state);
|
90
112
|
}
|
91
|
-
totalDebt() {
|
92
|
-
return (0, utils_1.calcTotalDebt)(this.state
|
113
|
+
get totalDebt() {
|
114
|
+
return (0, utils_1.calcTotalDebt)(this.state);
|
93
115
|
}
|
94
|
-
debtUsd() {
|
95
|
-
const debtPrice = (0, utils_1.safeGetPrice)(this.debtMint
|
116
|
+
debtUsd(priceType) {
|
117
|
+
const debtPrice = (0, utils_1.safeGetPrice)(this.debtMint, priceType);
|
96
118
|
return debtPrice
|
97
|
-
? (0, utils_1.calcTotalDebt)(this.state
|
98
|
-
: (0, utils_1.calcDebtUsd)(this.state
|
119
|
+
? (0, utils_1.calcTotalDebt)(this.state) * debtPrice
|
120
|
+
: (0, utils_1.calcDebtUsd)(this.state);
|
99
121
|
}
|
100
|
-
supplyLiquidityDepositable() {
|
101
|
-
return (0, utils_1.supplyLiquidityDepositable)(this.state
|
122
|
+
get supplyLiquidityDepositable() {
|
123
|
+
return (0, utils_1.supplyLiquidityDepositable)(this.state);
|
102
124
|
}
|
103
|
-
supplyLiquidityUsdDepositable() {
|
104
|
-
return (0, utils_1.supplyLiquidityUsdDepositable)(this.state
|
125
|
+
get supplyLiquidityUsdDepositable() {
|
126
|
+
return (0, utils_1.supplyLiquidityUsdDepositable)(this.state);
|
105
127
|
}
|
106
|
-
supplyLiquidityUsdAvailable() {
|
107
|
-
return
|
128
|
+
get supplyLiquidityUsdAvailable() {
|
129
|
+
return this.supplyLiquidityAvailable * ((0, utils_1.safeGetPrice)(this.supplyMint) ?? 0);
|
108
130
|
}
|
109
|
-
debtLiquidityAvailable() {
|
110
|
-
return (0, utils_1.debtLiquidityAvailable)(this.state
|
131
|
+
get debtLiquidityAvailable() {
|
132
|
+
return (0, utils_1.debtLiquidityAvailable)(this.state);
|
111
133
|
}
|
112
|
-
debtLiquidityUsdAvailable() {
|
113
|
-
return (0, utils_1.debtLiquidityUsdAvailable)(this.state
|
134
|
+
get debtLiquidityUsdAvailable() {
|
135
|
+
return (0, utils_1.debtLiquidityUsdAvailable)(this.state);
|
114
136
|
}
|
115
137
|
sufficientLiquidityToBoost() {
|
116
|
-
const limitsUpToDate = this.debtLiquidityUsdAvailable
|
117
|
-
this.supplyLiquidityUsdDepositable
|
138
|
+
const limitsUpToDate = this.debtLiquidityUsdAvailable !== 0 ||
|
139
|
+
this.supplyLiquidityUsdDepositable !== 0;
|
118
140
|
if (limitsUpToDate) {
|
119
|
-
const { debtAdjustmentUsd } = (0, rebalance_1.getDebtAdjustment)(this.state
|
141
|
+
const { debtAdjustmentUsd } = (0, rebalance_1.getDebtAdjustment)(this.state.liqThresholdBps, { supplyUsd: this.supplyUsd(), debtUsd: this.debtUsd() }, this.boostToBps, { solauto: 50, lpBorrow: 50, flashLoan: 50 } // TODO: get true data here instead of magic numbers
|
120
142
|
);
|
121
|
-
const sufficientLiquidity = this.debtLiquidityUsdAvailable
|
122
|
-
this.supplyLiquidityUsdDepositable
|
143
|
+
const sufficientLiquidity = this.debtLiquidityUsdAvailable * 0.95 > debtAdjustmentUsd &&
|
144
|
+
this.supplyLiquidityUsdDepositable * 0.95 > debtAdjustmentUsd;
|
123
145
|
if (!sufficientLiquidity) {
|
124
146
|
(0, utils_1.consoleLog)("Insufficient liquidity to further boost");
|
125
147
|
}
|
@@ -128,28 +150,28 @@ class SolautoPositionEx {
|
|
128
150
|
return true;
|
129
151
|
}
|
130
152
|
eligibleForRebalance(bpsDistanceThreshold = 0) {
|
131
|
-
if (!this.settings
|
153
|
+
if (!this.settings || !this.supplyUsd()) {
|
132
154
|
return undefined;
|
133
155
|
}
|
134
|
-
|
135
|
-
|
156
|
+
const realtimeLiqUtilRateBps = this.liqUtilizationRateBps(generated_1.PriceType.Realtime);
|
157
|
+
const emaLiqUtilRateBps = this.liqUtilizationRateBps(generated_1.PriceType.Ema);
|
158
|
+
if (this.repayFromBps - realtimeLiqUtilRateBps <= bpsDistanceThreshold) {
|
159
|
+
return "repay";
|
160
|
+
}
|
161
|
+
else if (realtimeLiqUtilRateBps - this.boostFromBps <= bpsDistanceThreshold ||
|
162
|
+
emaLiqUtilRateBps - this.boostFromBps <= bpsDistanceThreshold) {
|
136
163
|
const sufficientLiquidity = this.sufficientLiquidityToBoost();
|
137
164
|
return sufficientLiquidity ? "boost" : undefined;
|
138
165
|
}
|
139
|
-
else if (this.repayFromBps() - this.state().liqUtilizationRateBps <=
|
140
|
-
bpsDistanceThreshold) {
|
141
|
-
return "repay";
|
142
|
-
}
|
143
166
|
return undefined;
|
144
167
|
}
|
145
168
|
eligibleForRefresh() {
|
146
169
|
if (this._data.selfManaged)
|
147
170
|
return false;
|
148
|
-
return ((0, utils_1.currentUnixSeconds)() - Number(this.state
|
149
|
-
60 * 60 * 24 * 7);
|
171
|
+
return ((0, utils_1.currentUnixSeconds)() - Number(this.state.lastRefreshed) > 60 * 60 * 24 * 7);
|
150
172
|
}
|
151
173
|
canRefreshPositionState() {
|
152
|
-
if (Number(this.state
|
174
|
+
if (Number(this.state.lastRefreshed) >
|
153
175
|
(0, utils_1.currentUnixSeconds)() - constants_1.MIN_POSITION_STATE_FRESHNESS_SECS &&
|
154
176
|
!this.contextUpdates?.positionUpdates()) {
|
155
177
|
return false;
|
@@ -157,48 +179,45 @@ class SolautoPositionEx {
|
|
157
179
|
return true;
|
158
180
|
}
|
159
181
|
async utilizationRateBpsDrift() {
|
160
|
-
const supplyPrice = (0, utils_1.safeGetPrice)(this.state
|
161
|
-
const debtPrice = (0, utils_1.safeGetPrice)(this.state
|
182
|
+
const supplyPrice = (0, utils_1.safeGetPrice)(this.state.supply.mint) ?? 0;
|
183
|
+
const debtPrice = (0, utils_1.safeGetPrice)(this.state.debt.mint) ?? 0;
|
162
184
|
const oldState = await (0, utils_1.positionStateWithLatestPrices)(this.firstState, supplyPrice, debtPrice);
|
163
|
-
const newState = await (0, utils_1.positionStateWithLatestPrices)(this.state
|
185
|
+
const newState = await (0, utils_1.positionStateWithLatestPrices)(this.state, supplyPrice, debtPrice);
|
164
186
|
return newState.liqUtilizationRateBps - oldState.liqUtilizationRateBps;
|
165
187
|
}
|
166
188
|
updateSupply(newSupplyUsd, supplyPrice) {
|
167
189
|
this._data.state.supply.amountUsed.baseAmountUsdValue =
|
168
190
|
(0, utils_1.toRoundedUsdValue)(newSupplyUsd);
|
169
|
-
this._data.state.supply.amountUsed.baseUnit = (0, utils_1.toBaseUnit)(newSupplyUsd / (supplyPrice ?? (0, utils_1.safeGetPrice)(this.supplyMint
|
191
|
+
this._data.state.supply.amountUsed.baseUnit = (0, utils_1.toBaseUnit)(newSupplyUsd / (supplyPrice ?? (0, utils_1.safeGetPrice)(this.supplyMint) ?? 0), this.supplyMintInfo.decimals);
|
170
192
|
}
|
171
193
|
updateDebt(newDebtUsd, debtPrice) {
|
172
194
|
this._data.state.debt.amountUsed.baseAmountUsdValue =
|
173
195
|
(0, utils_1.toRoundedUsdValue)(newDebtUsd);
|
174
|
-
this._data.state.debt.amountUsed.baseUnit = (0, utils_1.toBaseUnit)(newDebtUsd / (debtPrice ?? (0, utils_1.safeGetPrice)(this.debtMint
|
196
|
+
this._data.state.debt.amountUsed.baseUnit = (0, utils_1.toBaseUnit)(newDebtUsd / (debtPrice ?? (0, utils_1.safeGetPrice)(this.debtMint) ?? 0), this.debtMintInfo.decimals);
|
175
197
|
}
|
176
198
|
updateNetWorth(supplyPrice) {
|
177
199
|
const netWorthUsd = this.supplyUsd() - this.debtUsd();
|
178
200
|
this._data.state.netWorth.baseAmountUsdValue =
|
179
201
|
(0, utils_1.toRoundedUsdValue)(netWorthUsd);
|
180
|
-
this._data.state.netWorth.baseUnit = (0, utils_1.toBaseUnit)(netWorthUsd / (supplyPrice ?? (0, utils_1.safeGetPrice)(this.supplyMint
|
202
|
+
this._data.state.netWorth.baseUnit = (0, utils_1.toBaseUnit)(netWorthUsd / (supplyPrice ?? (0, utils_1.safeGetPrice)(this.supplyMint) ?? 0), this.supplyMintInfo.decimals);
|
181
203
|
}
|
182
|
-
updateLiqUtilizationRate() {
|
183
|
-
this._data.state.liqUtilizationRateBps = (0, utils_1.getLiqUtilzationRateBps)(this.supplyUsd(), this.debtUsd(), this.state
|
204
|
+
updateLiqUtilizationRate(priceType) {
|
205
|
+
this._data.state.liqUtilizationRateBps = (0, utils_1.getLiqUtilzationRateBps)(this.supplyUsd(priceType), this.debtUsd(priceType), this.state.liqThresholdBps);
|
184
206
|
}
|
185
|
-
async updateWithLatestPrices(
|
186
|
-
if (!supplyPrice || !debtPrice) {
|
187
|
-
[supplyPrice, debtPrice] = await (0, utils_1.fetchTokenPrices)([
|
188
|
-
this.supplyMint(),
|
189
|
-
this.debtMint(),
|
190
|
-
]);
|
207
|
+
async updateWithLatestPrices(data) {
|
208
|
+
if (!data.supplyPrice || !data.debtPrice) {
|
209
|
+
[data.supplyPrice, data.debtPrice] = await (0, utils_1.fetchTokenPrices)([this.supplyMint, this.debtMint], data.priceType);
|
191
210
|
}
|
192
|
-
const supplyUsd = this.totalSupply
|
193
|
-
const debtUsd = this.totalDebt
|
194
|
-
this.updateSupply(supplyUsd, supplyPrice);
|
195
|
-
this.updateDebt(debtUsd, debtPrice);
|
196
|
-
this.updateNetWorth(supplyPrice);
|
211
|
+
const supplyUsd = this.totalSupply * data.supplyPrice;
|
212
|
+
const debtUsd = this.totalDebt * data.debtPrice;
|
213
|
+
this.updateSupply(supplyUsd, data.supplyPrice);
|
214
|
+
this.updateDebt(debtUsd, data.debtPrice);
|
215
|
+
this.updateNetWorth(data.supplyPrice);
|
197
216
|
this.updateLiqUtilizationRate();
|
198
217
|
}
|
199
218
|
simulateRebalance(unixTime, supplyPrice, debtPrice, targetLiqUtilizationRateBps) {
|
200
219
|
this._data.state.lastRefreshed = BigInt(unixTime);
|
201
|
-
const rebalance = (0, rebalance_1.getRebalanceValues)(this, targetLiqUtilizationRateBps, rebalance_1.SolautoFeesBps.create(true, targetLiqUtilizationRateBps, this.netWorthUsd
|
220
|
+
const rebalance = (0, rebalance_1.getRebalanceValues)(this, generated_1.PriceType.Realtime, targetLiqUtilizationRateBps, rebalance_1.SolautoFeesBps.create(true, targetLiqUtilizationRateBps, this.netWorthUsd));
|
202
221
|
this.updateSupply(rebalance.endResult.supplyUsd, supplyPrice);
|
203
222
|
this.updateDebt(rebalance.endResult.debtUsd, debtPrice);
|
204
223
|
this.updateNetWorth(supplyPrice);
|
package/dist/types/solauto.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
2
|
-
import { LendingPlatform, PositionType, SolautoRebalanceType, TokenType } from "../generated";
|
2
|
+
import { LendingPlatform, PositionType, PriceType, SolautoRebalanceType, TokenType } from "../generated";
|
3
3
|
import { TransactionBuilder } from "@metaplex-foundation/umi";
|
4
4
|
import { RebalanceValues } from "../services/rebalance";
|
5
5
|
import { QuoteResponse } from "@jup-ag/api";
|
@@ -44,6 +44,7 @@ export interface RebalanceDetails {
|
|
44
44
|
flashLoan?: FlashLoanDetails;
|
45
45
|
swapQuote: QuoteResponse;
|
46
46
|
targetLiqUtilizationRateBps?: number;
|
47
|
+
priceType: PriceType;
|
47
48
|
}
|
48
49
|
export type ProgramEnv = "Prod" | "Staging";
|
49
50
|
//# sourceMappingURL=solauto.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"solauto.d.ts","sourceRoot":"","sources":["../../src/types/solauto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,oBAAY,kBAAkB;IAC5B,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,OAAO,WAAW;IAClB,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAED,eAAO,MAAM,wBAAwB,EAEhC,kBAAkB,EAAE,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,oBAAoB,CAAC;IACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,aAAa,CAAC;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;
|
1
|
+
{"version":3,"file":"solauto.d.ts","sourceRoot":"","sources":["../../src/types/solauto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,oBAAY,kBAAkB;IAC5B,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,OAAO,WAAW;IAClB,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAED,eAAO,MAAM,wBAAwB,EAEhC,kBAAkB,EAAE,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,oBAAoB,CAAC;IACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,aAAa,CAAC;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC"}
|
@@ -84,10 +84,10 @@ function rebalance(client, targetLiqUtilizationRateBps) {
|
|
84
84
|
function swapThenDeposit(client, depositMint, depositAmountBaseUnit) {
|
85
85
|
return [
|
86
86
|
new services_1.TransactionItem(async () => {
|
87
|
-
const memeSwap = (0, generalUtils_1.tokenInfo)(client.pos.supplyMint
|
87
|
+
const memeSwap = (0, generalUtils_1.tokenInfo)(client.pos.supplyMint).isMeme;
|
88
88
|
const swapInput = {
|
89
89
|
inputMint: depositMint,
|
90
|
-
outputMint: client.pos.supplyMint
|
90
|
+
outputMint: client.pos.supplyMint,
|
91
91
|
amount: depositAmountBaseUnit,
|
92
92
|
exactIn: true,
|
93
93
|
slippageBps: memeSwap ? 300 : 50,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
2
2
|
import { Program, Umi } from "@metaplex-foundation/umi";
|
3
3
|
import { ProgramEnv, MarginfiAssetAccounts } from "../types";
|
4
|
-
import { PositionState } from "../generated";
|
4
|
+
import { PositionState, PriceType } from "../generated";
|
5
5
|
import { MarginfiBankAccountsMap } from "../constants";
|
6
6
|
import { Bank, MarginfiAccount } from "../marginfi-sdk";
|
7
7
|
import { ContextUpdates } from "./solautoUtils";
|
@@ -49,7 +49,7 @@ type BanksCache = {
|
|
49
49
|
export declare function getMarginfiAccountPositionState(umi: Umi, lpUserAccount: {
|
50
50
|
pk?: PublicKey;
|
51
51
|
data?: MarginfiAccount | null;
|
52
|
-
}, marginfiGroup?: PublicKey, supply?: BankSelection, debt?: BankSelection, programEnv?: ProgramEnv, contextUpdates?: ContextUpdates): Promise<{
|
52
|
+
}, marginfiGroup?: PublicKey, supply?: BankSelection, debt?: BankSelection, programEnv?: ProgramEnv, contextUpdates?: ContextUpdates, priceType?: PriceType): Promise<{
|
53
53
|
supplyBank: Bank | null;
|
54
54
|
debtBank: Bank | null;
|
55
55
|
state: PositionState;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"marginfiUtils.d.ts","sourceRoot":"","sources":["../../src/utils/marginfiUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAa,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAKnE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;
|
1
|
+
{"version":3,"file":"marginfiUtils.d.ts","sourceRoot":"","sources":["../../src/utils/marginfiUtils.ts"],"names":[],"mappings":"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"}
|
@@ -246,13 +246,13 @@ function getBankLiquidityAvailableBaseUnit(bank, availableToDeposit) {
|
|
246
246
|
}
|
247
247
|
return BigInt(Math.floor(amountCanBeUsed));
|
248
248
|
}
|
249
|
-
async function getTokenUsage(bank, isAsset, shares, amountUsedAdjustment) {
|
249
|
+
async function getTokenUsage(bank, isAsset, shares, amountUsedAdjustment, priceType) {
|
250
250
|
let amountUsed = 0;
|
251
251
|
let amountCanBeUsed = BigInt(0);
|
252
252
|
let marketPrice = 0;
|
253
253
|
let originationFee = 0;
|
254
254
|
if (bank !== null) {
|
255
|
-
[marketPrice] = await (0, priceUtils_1.fetchTokenPrices)([(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(bank.mint)]);
|
255
|
+
[marketPrice] = await (0, priceUtils_1.fetchTokenPrices)([(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(bank.mint)], priceType);
|
256
256
|
const [assetShareValue, liabilityShareValue] = getUpToDateShareValues(bank);
|
257
257
|
const shareValue = isAsset ? assetShareValue : liabilityShareValue;
|
258
258
|
amountUsed = shares * shareValue + Number(amountUsedAdjustment ?? 0);
|
@@ -289,7 +289,7 @@ async function getBank(umi, data, marginfiGroup) {
|
|
289
289
|
? await (0, marginfi_sdk_1.safeFetchBank)(umi, (0, umi_1.publicKey)((0, constants_1.getMarginfiAccounts)(undefined, marginfiGroup).bankAccounts[marginfiGroup?.toString() ?? ""][data?.mint.toString()].bank), { commitment: "confirmed" })
|
290
290
|
: null;
|
291
291
|
}
|
292
|
-
async function getMarginfiAccountPositionState(umi, lpUserAccount, marginfiGroup, supply, debt, programEnv, contextUpdates) {
|
292
|
+
async function getMarginfiAccountPositionState(umi, lpUserAccount, marginfiGroup, supply, debt, programEnv, contextUpdates, priceType) {
|
293
293
|
let marginfiAccount = lpUserAccount.data ??
|
294
294
|
(lpUserAccount.pk
|
295
295
|
? await (0, marginfi_sdk_1.safeFetchMarginfiAccount)(umi, (0, umi_1.publicKey)(lpUserAccount.pk), {
|
@@ -326,7 +326,7 @@ async function getMarginfiAccountPositionState(umi, lpUserAccount, marginfiGroup
|
|
326
326
|
if (!supply.mint) {
|
327
327
|
supply.mint = (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(supplyBank.mint);
|
328
328
|
}
|
329
|
-
supplyUsage = await getTokenUsage(supplyBank, true, (0, numberUtils_1.bytesToI80F48)(supplyBalances[0].assetShares.value), contextUpdates?.supplyAdjustment);
|
329
|
+
supplyUsage = await getTokenUsage(supplyBank, true, (0, numberUtils_1.bytesToI80F48)(supplyBalances[0].assetShares.value), contextUpdates?.supplyAdjustment, priceType);
|
330
330
|
}
|
331
331
|
if (debtBalances.length > 0) {
|
332
332
|
if (debtBank === null) {
|
@@ -337,7 +337,7 @@ async function getMarginfiAccountPositionState(umi, lpUserAccount, marginfiGroup
|
|
337
337
|
if (!debt.mint) {
|
338
338
|
debt.mint = (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(debtBank.mint);
|
339
339
|
}
|
340
|
-
debtUsage = await getTokenUsage(debtBank, false, (0, numberUtils_1.bytesToI80F48)(debtBalances[0].liabilityShares.value), contextUpdates?.debtAdjustment);
|
340
|
+
debtUsage = await getTokenUsage(debtBank, false, (0, numberUtils_1.bytesToI80F48)(debtBalances[0].liabilityShares.value), contextUpdates?.debtAdjustment, priceType);
|
341
341
|
}
|
342
342
|
}
|
343
343
|
if (supplyBank === null) {
|
@@ -1,8 +1,14 @@
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
2
2
|
import { PublicKey as UmiPublicKey } from "@metaplex-foundation/umi";
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
import { PriceType } from "../generated";
|
4
|
+
interface PriceResult {
|
5
|
+
realtimePrice: number;
|
6
|
+
emaPrice?: number;
|
7
|
+
}
|
8
|
+
export declare function fetchTokenPrices(mints: PublicKey[], priceType?: PriceType): Promise<number[]>;
|
9
|
+
export declare function getPythPrices(mints: PublicKey[], priceType: PriceType): Promise<PriceResult[]>;
|
10
|
+
export declare function getSwitchboardPrices(mints: PublicKey[]): Promise<PriceResult[]>;
|
11
|
+
export declare function getJupTokenPrices(mints: PublicKey[]): Promise<PriceResult[]>;
|
12
|
+
export declare function safeGetPrice(mint: PublicKey | UmiPublicKey | string | undefined, priceType?: PriceType): number | undefined;
|
13
|
+
export {};
|
8
14
|
//# sourceMappingURL=priceUtils.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"priceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/priceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;
|
1
|
+
{"version":3,"file":"priceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/priceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAerE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,UAAU,WAAW;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,EAAE,EAClB,SAAS,GAAE,SAA8B,GACxC,OAAO,CAAC,MAAM,EAAE,CAAC,CAoDnB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,EAAE,EAClB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,WAAW,EAAE,CAAC,CA+CxB;AAkBD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CA0DxB;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAgBxB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,EACnD,SAAS,GAAE,SAA8B,GACxC,MAAM,GAAG,SAAS,CAQpB"}
|
package/dist/utils/priceUtils.js
CHANGED
@@ -34,38 +34,59 @@ const constants_1 = require("../constants");
|
|
34
34
|
const numberUtils_1 = require("./numberUtils");
|
35
35
|
const generalUtils_1 = require("./generalUtils");
|
36
36
|
const jupiterUtils_1 = require("./jupiterUtils");
|
37
|
-
|
37
|
+
const generated_1 = require("../generated");
|
38
|
+
async function fetchTokenPrices(mints, priceType = generated_1.PriceType.Realtime) {
|
38
39
|
const currentTime = (0, generalUtils_1.currentUnixSeconds)();
|
39
40
|
if (!mints.some((mint) => !(mint.toString() in constants_1.PRICES) ||
|
40
41
|
currentTime - constants_1.PRICES[mint.toString()].time > 3)) {
|
41
|
-
return mints.map((mint) =>
|
42
|
+
return mints.map((mint) => {
|
43
|
+
const priceData = constants_1.PRICES[mint.toString()];
|
44
|
+
return priceType === generated_1.PriceType.Ema
|
45
|
+
? priceData.emaPrice
|
46
|
+
: priceData.realtimePrice;
|
47
|
+
});
|
42
48
|
}
|
43
49
|
const pythMints = mints.filter((x) => x.toString() in constants_1.PYTH_PRICE_FEED_IDS);
|
44
50
|
const switchboardMints = mints.filter((x) => x.toString() in Object.keys(constants_1.SWITCHBOARD_PRICE_FEED_IDS));
|
45
51
|
const otherMints = mints.filter((x) => !pythMints.includes(x) && !switchboardMints.includes(x));
|
46
52
|
const [pythData, switchboardData, jupData] = await Promise.all([
|
47
|
-
(0, generalUtils_1.zip)(pythMints, await getPythPrices(pythMints)),
|
53
|
+
(0, generalUtils_1.zip)(pythMints, await getPythPrices(pythMints, priceType)),
|
48
54
|
(0, generalUtils_1.zip)(switchboardMints, await getSwitchboardPrices(switchboardMints)),
|
49
55
|
(0, generalUtils_1.zip)(otherMints, await getJupTokenPrices(otherMints)),
|
50
56
|
]);
|
51
57
|
const prices = mints.map((mint) => {
|
52
58
|
const item = [...pythData, ...switchboardData, ...jupData].find((data) => data[0].equals(mint));
|
53
|
-
return item ? item[1] : 0;
|
59
|
+
return item ? item[1] : { realtimePrice: 0 };
|
54
60
|
});
|
55
61
|
for (var i = 0; i < mints.length; i++) {
|
62
|
+
const realtimePrice = prices[i].realtimePrice;
|
56
63
|
constants_1.PRICES[mints[i].toString()] = {
|
57
|
-
|
64
|
+
realtimePrice,
|
65
|
+
emaPrice: prices[i].emaPrice ?? realtimePrice,
|
58
66
|
time: (0, generalUtils_1.currentUnixSeconds)(),
|
59
67
|
};
|
60
68
|
}
|
61
|
-
return prices
|
69
|
+
return prices.map((x) => priceType === generated_1.PriceType.Ema
|
70
|
+
? (x.emaPrice ?? x.realtimePrice)
|
71
|
+
: x.realtimePrice);
|
62
72
|
}
|
63
|
-
async function getPythPrices(mints) {
|
73
|
+
async function getPythPrices(mints, priceType) {
|
64
74
|
if (mints.length === 0) {
|
65
75
|
return [];
|
66
76
|
}
|
67
77
|
const priceFeedIds = mints.map((mint) => constants_1.PYTH_PRICE_FEED_IDS[mint.toString()]);
|
68
78
|
const getReq = async () => await fetch(`https://hermes.pyth.network/v2/updates/price/latest?${priceFeedIds.map((x) => `ids%5B%5D=${x}`).join("&")}`);
|
79
|
+
const derivePrice = (price, exponent) => {
|
80
|
+
if (exponent > 0) {
|
81
|
+
return Number((0, numberUtils_1.toBaseUnit)(Number(price), exponent));
|
82
|
+
}
|
83
|
+
else if (exponent < 0) {
|
84
|
+
return (0, numberUtils_1.fromBaseUnit)(BigInt(price), Math.abs(exponent));
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
return Number(price);
|
88
|
+
}
|
89
|
+
};
|
69
90
|
const prices = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
70
91
|
let resp = await getReq();
|
71
92
|
let status = resp.status;
|
@@ -74,15 +95,10 @@ async function getPythPrices(mints) {
|
|
74
95
|
}
|
75
96
|
const json = await resp.json();
|
76
97
|
const prices = json.parsed.map((x) => {
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
return (0, numberUtils_1.fromBaseUnit)(BigInt(x.price.price), Math.abs(x.price.expo));
|
82
|
-
}
|
83
|
-
else {
|
84
|
-
return Number(x.price.price);
|
85
|
-
}
|
98
|
+
return {
|
99
|
+
realtimePrice: derivePrice(x.price.price, x.price.expo),
|
100
|
+
emaPrice: derivePrice(x.ema_price.price, x.ema_price.expo),
|
101
|
+
};
|
86
102
|
});
|
87
103
|
return prices;
|
88
104
|
}, 5, 200);
|
@@ -129,23 +145,31 @@ async function getSwitchboardPrices(mints) {
|
|
129
145
|
}
|
130
146
|
const missingMints = mints.filter((x) => !prices[x.toString()]);
|
131
147
|
const jupPrices = (0, generalUtils_1.zip)(missingMints, await getJupTokenPrices(missingMints.map((x) => new web3_js_1.PublicKey(x)))).reduce((acc, [key, value]) => {
|
132
|
-
acc[key.toString()] = value;
|
148
|
+
acc[key.toString()] = value.realtimePrice;
|
133
149
|
return acc;
|
134
150
|
}, {});
|
135
|
-
return Object.values(getSortedPriceData({ ...prices, ...jupPrices }, mints))
|
151
|
+
return Object.values(getSortedPriceData({ ...prices, ...jupPrices }, mints)).map((x) => {
|
152
|
+
return { realtimePrice: x };
|
153
|
+
});
|
136
154
|
}
|
137
155
|
async function getJupTokenPrices(mints) {
|
138
156
|
if (mints.length == 0) {
|
139
157
|
return [];
|
140
158
|
}
|
141
159
|
const data = getSortedPriceData(await (0, jupiterUtils_1.getJupPriceData)(mints), mints);
|
142
|
-
|
160
|
+
const prices = Object.values(data).map((x) => x !== null && typeof x === "object" && "price" in x
|
143
161
|
? parseFloat(x.price)
|
144
162
|
: 0);
|
163
|
+
return prices.map((x) => {
|
164
|
+
return { realtimePrice: x };
|
165
|
+
});
|
145
166
|
}
|
146
|
-
function safeGetPrice(mint) {
|
167
|
+
function safeGetPrice(mint, priceType = generated_1.PriceType.Realtime) {
|
147
168
|
if (mint && mint?.toString() in constants_1.PRICES) {
|
148
|
-
|
169
|
+
const priceData = constants_1.PRICES[mint.toString()];
|
170
|
+
return priceType === generated_1.PriceType.Ema
|
171
|
+
? priceData.emaPrice
|
172
|
+
: priceData.realtimePrice;
|
149
173
|
}
|
150
174
|
return undefined;
|
151
175
|
}
|
package/local/logPositions.ts
CHANGED
@@ -7,6 +7,7 @@ import {
|
|
7
7
|
getSolanaRpcConnection,
|
8
8
|
getSolautoManagedPositions,
|
9
9
|
LOCAL_IRONFORGE_API_URL,
|
10
|
+
PriceType,
|
10
11
|
safeGetPrice,
|
11
12
|
SOLAUTO_PROD_PROGRAM,
|
12
13
|
} from "../src";
|
@@ -96,7 +97,7 @@ async function main(filterWhitelist: boolean) {
|
|
96
97
|
umi,
|
97
98
|
positions.map((x) => new PublicKey(x.publicKey!))
|
98
99
|
)
|
99
|
-
).sort((a, b) => a.netWorthUsd
|
100
|
+
).sort((a, b) => a.netWorthUsd - b.netWorthUsd);
|
100
101
|
|
101
102
|
const tokensUsed = Array.from(
|
102
103
|
new Set(
|
@@ -114,17 +115,17 @@ async function main(filterWhitelist: boolean) {
|
|
114
115
|
let awaitingBoostPositions = 0;
|
115
116
|
|
116
117
|
for (const pos of positionsEx) {
|
117
|
-
await pos.updateWithLatestPrices(
|
118
|
-
safeGetPrice(pos.
|
119
|
-
safeGetPrice(pos.
|
120
|
-
);
|
118
|
+
await pos.updateWithLatestPrices({
|
119
|
+
supplyPrice: safeGetPrice(pos.supplyMint),
|
120
|
+
debtPrice: safeGetPrice(pos.debtMint),
|
121
|
+
});
|
121
122
|
|
122
123
|
const actionToTake = pos.eligibleForRebalance(0);
|
123
124
|
|
124
|
-
const repayFrom = pos.settings
|
125
|
+
const repayFrom = pos.settings!.repayToBps + pos.settings!.repayGap;
|
125
126
|
const unhealthy = actionToTake === "repay";
|
126
127
|
const healthText = unhealthy
|
127
|
-
? `(Unhealthy: ${pos.state
|
128
|
+
? `(Unhealthy: ${pos.state.liqUtilizationRateBps - repayFrom}bps)`
|
128
129
|
: "";
|
129
130
|
if (unhealthy) {
|
130
131
|
unhealthyPositions += 1;
|
@@ -138,10 +139,10 @@ async function main(filterWhitelist: boolean) {
|
|
138
139
|
|
139
140
|
console.log(
|
140
141
|
pos.publicKey.toString(),
|
141
|
-
`(${pos.
|
142
|
+
`(${pos.authority.toString()} ${pos.positionId})`
|
142
143
|
);
|
143
144
|
console.log(
|
144
|
-
`${pos.strategyName
|
145
|
+
`${pos.strategyName}: $${formatNumber(pos.netWorthUsd, 2, 10000, 2)} ${healthText} ${boostText}`
|
145
146
|
);
|
146
147
|
}
|
147
148
|
|
@@ -153,15 +154,14 @@ async function main(filterWhitelist: boolean) {
|
|
153
154
|
);
|
154
155
|
console.log(
|
155
156
|
"Total users:",
|
156
|
-
Array.from(new Set(positionsEx.map((x) => x.
|
157
|
-
.length
|
157
|
+
Array.from(new Set(positionsEx.map((x) => x.authority.toString()))).length
|
158
158
|
);
|
159
159
|
|
160
160
|
const tvl = positionsEx
|
161
161
|
.map((x) => x.supplyUsd())
|
162
162
|
.reduce((acc, curr) => acc + curr, 0);
|
163
163
|
const netWorth = positionsEx
|
164
|
-
.map((x) => x.netWorthUsd
|
164
|
+
.map((x) => x.netWorthUsd)
|
165
165
|
.reduce((acc, curr) => acc + curr, 0);
|
166
166
|
|
167
167
|
console.log(`TVL: $${formatNumber(tvl, 2, 10000, 2)}`);
|