@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.
Files changed (72) hide show
  1. package/README.md +35 -6
  2. package/dist/constants/marginfiAccounts.d.ts.map +1 -1
  3. package/dist/constants/solautoConstants.d.ts +2 -1
  4. package/dist/constants/solautoConstants.d.ts.map +1 -1
  5. package/dist/generated/instructions/marginfiRebalance.d.ts +5 -3
  6. package/dist/generated/instructions/marginfiRebalance.d.ts.map +1 -1
  7. package/dist/generated/instructions/marginfiRebalance.js +2 -1
  8. package/dist/generated/instructions/marginfiRefreshData.d.ts +7 -2
  9. package/dist/generated/instructions/marginfiRefreshData.d.ts.map +1 -1
  10. package/dist/generated/instructions/marginfiRefreshData.js +8 -4
  11. package/dist/generated/types/index.d.ts +1 -0
  12. package/dist/generated/types/index.d.ts.map +1 -1
  13. package/dist/generated/types/index.js +1 -0
  14. package/dist/generated/types/priceType.d.ts +15 -0
  15. package/dist/generated/types/priceType.d.ts.map +1 -0
  16. package/dist/generated/types/priceType.js +22 -0
  17. package/dist/services/rebalance/rebalanceSwapManager.d.ts.map +1 -1
  18. package/dist/services/rebalance/rebalanceSwapManager.js +8 -8
  19. package/dist/services/rebalance/rebalanceTxBuilder.d.ts +2 -0
  20. package/dist/services/rebalance/rebalanceTxBuilder.d.ts.map +1 -1
  21. package/dist/services/rebalance/rebalanceTxBuilder.js +21 -10
  22. package/dist/services/rebalance/rebalanceValues.d.ts +2 -2
  23. package/dist/services/rebalance/rebalanceValues.d.ts.map +1 -1
  24. package/dist/services/rebalance/rebalanceValues.js +17 -17
  25. package/dist/services/solauto/solautoClient.d.ts +2 -2
  26. package/dist/services/solauto/solautoClient.d.ts.map +1 -1
  27. package/dist/services/solauto/solautoClient.js +27 -28
  28. package/dist/services/solauto/solautoMarginfiClient.d.ts +2 -2
  29. package/dist/services/solauto/solautoMarginfiClient.d.ts.map +1 -1
  30. package/dist/services/solauto/solautoMarginfiClient.js +12 -10
  31. package/dist/services/transactions/transactionUtils.d.ts.map +1 -1
  32. package/dist/services/transactions/transactionUtils.js +10 -9
  33. package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts +3 -3
  34. package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts.map +1 -1
  35. package/dist/solautoPosition/marginfiSolautoPositionEx.js +9 -9
  36. package/dist/solautoPosition/solautoPositionEx.d.ts +44 -33
  37. package/dist/solautoPosition/solautoPositionEx.d.ts.map +1 -1
  38. package/dist/solautoPosition/solautoPositionEx.js +109 -90
  39. package/dist/types/solauto.d.ts +2 -1
  40. package/dist/types/solauto.d.ts.map +1 -1
  41. package/dist/utils/instructionUtils.js +2 -2
  42. package/dist/utils/marginfiUtils.d.ts +2 -2
  43. package/dist/utils/marginfiUtils.d.ts.map +1 -1
  44. package/dist/utils/marginfiUtils.js +5 -5
  45. package/dist/utils/priceUtils.d.ts +11 -5
  46. package/dist/utils/priceUtils.d.ts.map +1 -1
  47. package/dist/utils/priceUtils.js +45 -21
  48. package/local/logPositions.ts +12 -12
  49. package/local/shared.ts +1 -1
  50. package/local/txSandbox.ts +27 -32
  51. package/local/updateMarginfiLUT.ts +13 -6
  52. package/package.json +2 -1
  53. package/src/constants/marginfiAccounts.ts +0 -1
  54. package/src/constants/solautoConstants.ts +1 -1
  55. package/src/generated/instructions/marginfiRebalance.ts +9 -3
  56. package/src/generated/instructions/marginfiRefreshData.ts +27 -7
  57. package/src/generated/types/index.ts +1 -0
  58. package/src/generated/types/priceType.ts +22 -0
  59. package/src/services/rebalance/rebalanceSwapManager.ts +8 -12
  60. package/src/services/rebalance/rebalanceTxBuilder.ts +41 -11
  61. package/src/services/rebalance/rebalanceValues.ts +22 -16
  62. package/src/services/solauto/solautoClient.ts +30 -30
  63. package/src/services/solauto/solautoMarginfiClient.ts +13 -10
  64. package/src/services/transactions/transactionUtils.ts +11 -9
  65. package/src/solautoPosition/marginfiSolautoPositionEx.ts +11 -10
  66. package/src/solautoPosition/solautoPositionEx.ts +141 -117
  67. package/src/types/solauto.ts +2 -0
  68. package/src/utils/instructionUtils.ts +2 -2
  69. package/src/utils/marginfiUtils.ts +12 -8
  70. package/src/utils/priceUtils.ts +66 -22
  71. package/tests/transactions/shared.ts +2 -5
  72. package/tests/unit/rebalanceCalculations.ts +9 -12
@@ -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
- export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
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) => PRICES[mint.toString()].price);
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
- price: Number(prices[i]),
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(mints: PublicKey[]) {
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 prices: number[] = await retryWithExponentialBackoff(
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
- if (x.price.expo > 0) {
86
- return Number(toBaseUnit(Number(x.price.price), x.price.expo));
87
- } else if (x.price.expo < 0) {
88
- return fromBaseUnit(BigInt(x.price.price), Math.abs(x.price.expo));
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<number[]> {
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(getSortedPriceData({ ...prices, ...jupPrices }, mints));
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(mints: PublicKey[]) {
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
- return Object.values(data).map((x) =>
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
- return PRICES[mint!.toString()].price;
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().decimals)
68
+ toBaseUnit(supplyUsd / supplyPrice, client.pos.supplyMintInfo.decimals)
72
69
  ),
73
70
  borrow(
74
71
  client,
75
- toBaseUnit(debtUsd / debtPrice, client.pos.debtMintInfo().decimals)
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
- LendingPlatform,
9
- SolautoSettingsParameters,
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
- } from "../../src/utils";
18
- import { LOCAL_IRONFORGE_API_URL, USDC } from "../../src/constants";
19
- import {
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/solautoPosition";
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().liqThresholdBps
47
+ client.pos.state.liqThresholdBps
51
48
  );
52
49
  assert(
53
50
  Math.round(newLiqUtilizationRateBps) ===