@haven-fi/solauto-sdk 1.0.629 → 1.0.631
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 +32 -2
- 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 +112 -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 +29 -27
- package/local/updateMarginfiLUT.ts +13 -6
- package/package.json +1 -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 +145 -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
package/src/utils/priceUtils.ts
CHANGED
@@ -14,8 +14,17 @@ import {
|
|
14
14
|
zip,
|
15
15
|
} from "./generalUtils";
|
16
16
|
import { getJupPriceData } from "./jupiterUtils";
|
17
|
+
import { PriceType } from "../generated";
|
17
18
|
|
18
|
-
|
19
|
+
interface PriceResult {
|
20
|
+
realtimePrice: number;
|
21
|
+
emaPrice?: number;
|
22
|
+
}
|
23
|
+
|
24
|
+
export async function fetchTokenPrices(
|
25
|
+
mints: PublicKey[],
|
26
|
+
priceType: PriceType = PriceType.Realtime
|
27
|
+
): Promise<number[]> {
|
19
28
|
const currentTime = currentUnixSeconds();
|
20
29
|
if (
|
21
30
|
!mints.some(
|
@@ -24,7 +33,12 @@ export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
|
|
24
33
|
currentTime - PRICES[mint.toString()].time > 3
|
25
34
|
)
|
26
35
|
) {
|
27
|
-
return mints.map((mint) =>
|
36
|
+
return mints.map((mint) => {
|
37
|
+
const priceData = PRICES[mint.toString()];
|
38
|
+
return priceType === PriceType.Ema
|
39
|
+
? priceData.emaPrice
|
40
|
+
: priceData.realtimePrice;
|
41
|
+
});
|
28
42
|
}
|
29
43
|
|
30
44
|
const pythMints = mints.filter((x) => x.toString() in PYTH_PRICE_FEED_IDS);
|
@@ -36,7 +50,7 @@ export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
|
|
36
50
|
);
|
37
51
|
|
38
52
|
const [pythData, switchboardData, jupData] = await Promise.all([
|
39
|
-
zip(pythMints, await getPythPrices(pythMints)),
|
53
|
+
zip(pythMints, await getPythPrices(pythMints, priceType)),
|
40
54
|
zip(switchboardMints, await getSwitchboardPrices(switchboardMints)),
|
41
55
|
zip(otherMints, await getJupTokenPrices(otherMints)),
|
42
56
|
]);
|
@@ -45,20 +59,29 @@ export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
|
|
45
59
|
const item = [...pythData, ...switchboardData, ...jupData].find((data) =>
|
46
60
|
data[0].equals(mint)
|
47
61
|
);
|
48
|
-
return item ? item[1] : 0;
|
62
|
+
return item ? item[1] : { realtimePrice: 0 };
|
49
63
|
});
|
50
64
|
|
51
65
|
for (var i = 0; i < mints.length; i++) {
|
66
|
+
const realtimePrice = prices[i].realtimePrice;
|
52
67
|
PRICES[mints[i].toString()] = {
|
53
|
-
|
68
|
+
realtimePrice,
|
69
|
+
emaPrice: prices[i].emaPrice ?? realtimePrice,
|
54
70
|
time: currentUnixSeconds(),
|
55
71
|
};
|
56
72
|
}
|
57
73
|
|
58
|
-
return prices
|
74
|
+
return prices.map((x) =>
|
75
|
+
priceType === PriceType.Ema
|
76
|
+
? (x.emaPrice ?? x.realtimePrice)
|
77
|
+
: x.realtimePrice
|
78
|
+
);
|
59
79
|
}
|
60
80
|
|
61
|
-
export async function getPythPrices(
|
81
|
+
export async function getPythPrices(
|
82
|
+
mints: PublicKey[],
|
83
|
+
priceType: PriceType
|
84
|
+
): Promise<PriceResult[]> {
|
62
85
|
if (mints.length === 0) {
|
63
86
|
return [];
|
64
87
|
}
|
@@ -72,7 +95,17 @@ export async function getPythPrices(mints: PublicKey[]) {
|
|
72
95
|
`https://hermes.pyth.network/v2/updates/price/latest?${priceFeedIds.map((x) => `ids%5B%5D=${x}`).join("&")}`
|
73
96
|
);
|
74
97
|
|
75
|
-
const
|
98
|
+
const derivePrice = (price: number, exponent: number) => {
|
99
|
+
if (exponent > 0) {
|
100
|
+
return Number(toBaseUnit(Number(price), exponent));
|
101
|
+
} else if (exponent < 0) {
|
102
|
+
return fromBaseUnit(BigInt(price), Math.abs(exponent));
|
103
|
+
} else {
|
104
|
+
return Number(price);
|
105
|
+
}
|
106
|
+
};
|
107
|
+
|
108
|
+
const prices: PriceResult[] = await retryWithExponentialBackoff(
|
76
109
|
async () => {
|
77
110
|
let resp = await getReq();
|
78
111
|
let status = resp.status;
|
@@ -82,13 +115,10 @@ export async function getPythPrices(mints: PublicKey[]) {
|
|
82
115
|
|
83
116
|
const json = await resp.json();
|
84
117
|
const prices = json.parsed.map((x: any) => {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
} else {
|
90
|
-
return Number(x.price.price);
|
91
|
-
}
|
118
|
+
return {
|
119
|
+
realtimePrice: derivePrice(x.price.price, x.price.expo),
|
120
|
+
emaPrice: derivePrice(x.ema_price.price, x.ema_price.expo),
|
121
|
+
};
|
92
122
|
});
|
93
123
|
|
94
124
|
return prices;
|
@@ -118,7 +148,7 @@ function getSortedPriceData(
|
|
118
148
|
|
119
149
|
export async function getSwitchboardPrices(
|
120
150
|
mints: PublicKey[]
|
121
|
-
): Promise<
|
151
|
+
): Promise<PriceResult[]> {
|
122
152
|
if (mints.length === 0) {
|
123
153
|
return [];
|
124
154
|
}
|
@@ -165,34 +195,48 @@ export async function getSwitchboardPrices(
|
|
165
195
|
await getJupTokenPrices(missingMints.map((x) => new PublicKey(x)))
|
166
196
|
).reduce(
|
167
197
|
(acc, [key, value]) => {
|
168
|
-
acc[key.toString()] = value;
|
198
|
+
acc[key.toString()] = value.realtimePrice;
|
169
199
|
return acc;
|
170
200
|
},
|
171
201
|
{} as Record<string, number>
|
172
202
|
);
|
173
203
|
|
174
|
-
return Object.values(
|
204
|
+
return Object.values(
|
205
|
+
getSortedPriceData({ ...prices, ...jupPrices }, mints)
|
206
|
+
).map((x) => {
|
207
|
+
return { realtimePrice: x };
|
208
|
+
});
|
175
209
|
}
|
176
210
|
|
177
|
-
export async function getJupTokenPrices(
|
211
|
+
export async function getJupTokenPrices(
|
212
|
+
mints: PublicKey[]
|
213
|
+
): Promise<PriceResult[]> {
|
178
214
|
if (mints.length == 0) {
|
179
215
|
return [];
|
180
216
|
}
|
181
217
|
|
182
218
|
const data = getSortedPriceData(await getJupPriceData(mints), mints);
|
183
219
|
|
184
|
-
|
220
|
+
const prices = Object.values(data).map((x) =>
|
185
221
|
x !== null && typeof x === "object" && "price" in x
|
186
222
|
? parseFloat(x.price as string)
|
187
223
|
: 0
|
188
224
|
);
|
225
|
+
|
226
|
+
return prices.map((x) => {
|
227
|
+
return { realtimePrice: x };
|
228
|
+
});
|
189
229
|
}
|
190
230
|
|
191
231
|
export function safeGetPrice(
|
192
|
-
mint: PublicKey | UmiPublicKey | string | undefined
|
232
|
+
mint: PublicKey | UmiPublicKey | string | undefined,
|
233
|
+
priceType: PriceType = PriceType.Realtime
|
193
234
|
): number | undefined {
|
194
235
|
if (mint && mint?.toString() in PRICES) {
|
195
|
-
|
236
|
+
const priceData = PRICES[mint!.toString()];
|
237
|
+
return priceType === PriceType.Ema
|
238
|
+
? priceData.emaPrice
|
239
|
+
: priceData.realtimePrice;
|
196
240
|
}
|
197
241
|
return undefined;
|
198
242
|
}
|
@@ -9,13 +9,10 @@ import {
|
|
9
9
|
LOCAL_IRONFORGE_API_URL,
|
10
10
|
maxBoostToBps,
|
11
11
|
maxRepayToBps,
|
12
|
-
RebalanceTxBuilder,
|
13
12
|
SOLAUTO_PROD_PROGRAM,
|
14
13
|
SOLAUTO_TEST_PROGRAM,
|
15
|
-
solautoAction,
|
16
14
|
SolautoSettingsParametersInpArgs,
|
17
15
|
toBaseUnit,
|
18
|
-
TransactionItem,
|
19
16
|
TransactionsManager,
|
20
17
|
USDC,
|
21
18
|
deposit,
|
@@ -68,11 +65,11 @@ export async function e2eTransactionTest(
|
|
68
65
|
openSolautoPosition(client, settings),
|
69
66
|
deposit(
|
70
67
|
client,
|
71
|
-
toBaseUnit(supplyUsd / supplyPrice, client.pos.supplyMintInfo
|
68
|
+
toBaseUnit(supplyUsd / supplyPrice, client.pos.supplyMintInfo.decimals)
|
72
69
|
),
|
73
70
|
borrow(
|
74
71
|
client,
|
75
|
-
toBaseUnit(debtUsd / debtPrice, client.pos.debtMintInfo
|
72
|
+
toBaseUnit(debtUsd / debtPrice, client.pos.debtMintInfo.decimals)
|
76
73
|
),
|
77
74
|
rebalance(client, 0),
|
78
75
|
withdraw(client, "All"),
|
@@ -5,26 +5,22 @@ import { NATIVE_MINT } from "@solana/spl-token";
|
|
5
5
|
import { publicKey } from "@metaplex-foundation/umi";
|
6
6
|
import { setupTest } from "../shared";
|
7
7
|
import {
|
8
|
-
|
9
|
-
|
10
|
-
} from "../../src/generated";
|
11
|
-
import {
|
8
|
+
LOCAL_IRONFORGE_API_URL,
|
9
|
+
USDC,
|
12
10
|
fromBps,
|
13
11
|
getLiqUtilzationRateBps,
|
14
12
|
getClient,
|
15
13
|
fetchTokenPrices,
|
16
14
|
safeGetPrice,
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
LendingPlatform,
|
16
|
+
PriceType,
|
17
|
+
SolautoSettingsParameters,
|
20
18
|
getRebalanceValues,
|
21
19
|
SolautoClient,
|
22
20
|
SolautoFeesBps,
|
23
|
-
} from "../../src/services";
|
24
|
-
import {
|
25
21
|
createFakePositionState,
|
26
22
|
MarginfiSolautoPositionEx,
|
27
|
-
} from "../../src
|
23
|
+
} from "../../src";
|
28
24
|
|
29
25
|
const signer = setupTest(undefined, true);
|
30
26
|
|
@@ -35,11 +31,12 @@ function assertAccurateRebalance(
|
|
35
31
|
) {
|
36
32
|
const { endResult } = getRebalanceValues(
|
37
33
|
client.pos,
|
34
|
+
PriceType.Realtime,
|
38
35
|
targetLiqUtilizationRateBps,
|
39
36
|
SolautoFeesBps.create(
|
40
37
|
false,
|
41
38
|
targetLiqUtilizationRateBps,
|
42
|
-
client.pos.netWorthUsd
|
39
|
+
client.pos.netWorthUsd
|
43
40
|
),
|
44
41
|
50
|
45
42
|
);
|
@@ -47,7 +44,7 @@ function assertAccurateRebalance(
|
|
47
44
|
const newLiqUtilizationRateBps = getLiqUtilzationRateBps(
|
48
45
|
endResult.supplyUsd,
|
49
46
|
endResult.debtUsd,
|
50
|
-
client.pos.state
|
47
|
+
client.pos.state.liqThresholdBps
|
51
48
|
);
|
52
49
|
assert(
|
53
50
|
Math.round(newLiqUtilizationRateBps) ===
|