@haven-fi/solauto-sdk 1.0.128 → 1.0.129

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,7 +12,6 @@ const generalUtils_1 = require("../utils/generalUtils");
12
12
  const marginfi_sdk_1 = require("../marginfi-sdk");
13
13
  const marginfiUtils_1 = require("../utils/marginfiUtils");
14
14
  const numberUtils_1 = require("../utils/numberUtils");
15
- const constants_1 = require("../constants");
16
15
  const utils_1 = require("../utils");
17
16
  class SolautoMarginfiClient extends solautoClient_1.SolautoClient {
18
17
  constructor() {
@@ -418,8 +417,8 @@ class SolautoMarginfiClient extends solautoClient_1.SolautoClient {
418
417
  const freshState = await (0, marginfiUtils_1.getMarginfiAccountPositionState)(this.umi, this.marginfiAccountPk, this.supplyMint, this.debtMint, this.livePositionUpdates);
419
418
  if (freshState) {
420
419
  this.log("Fresh state", freshState);
421
- const supplyPrice = constants_1.PRICES[(freshState?.supply.mint ?? web3_js_1.PublicKey.default).toString()].price;
422
- const debtPrice = constants_1.PRICES[(freshState?.debt.mint ?? web3_js_1.PublicKey.default).toString()].price;
420
+ const supplyPrice = (0, generalUtils_1.safeGetPrice)(freshState?.supply.mint);
421
+ const debtPrice = (0, generalUtils_1.safeGetPrice)(freshState?.debt.mint);
423
422
  this.log("Supply price: ", supplyPrice);
424
423
  this.log("Debt price: ", debtPrice);
425
424
  this.log("Liq threshold bps:", freshState.liqThresholdBps);
@@ -1 +1 @@
1
- {"version":3,"file":"transactionUtils.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAClB,GAAG,EAGJ,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,SAAS,EAA8B,MAAM,iBAAiB,CAAC;AAKxE,OAAO,EAEL,aAAa,EASd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AA6MzD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,EACtB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA+G7B;AAmLD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CA4BnD;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,aAAa,EACrB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CACN;IACE,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,GACD,SAAS,CACZ,CA4HA;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,GAAG,EACR,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,SAAS,GACtB,OAAO,CAAC,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,CAmCrD"}
1
+ {"version":3,"file":"transactionUtils.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAClB,GAAG,EAGJ,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,SAAS,EAA8B,MAAM,iBAAiB,CAAC;AAKxE,OAAO,EAEL,aAAa,EASd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AA8MzD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,EACtB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA+G7B;AAmLD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CA4BnD;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,aAAa,EACrB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CACN;IACE,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,GACD,SAAS,CACZ,CA4HA;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,GAAG,EACR,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,SAAS,GACtB,OAAO,CAAC,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,CAmCrD"}
@@ -17,7 +17,6 @@ const numberUtils_1 = require("../utils/numberUtils");
17
17
  const generalUtils_2 = require("../utils/solauto/generalUtils");
18
18
  const accountUtils_1 = require("../utils/accountUtils");
19
19
  const marginfi_sdk_1 = require("../marginfi-sdk");
20
- const constants_1 = require("../constants");
21
20
  function getWSolUsage(client, solautoActions, initiatingDcaIn, cancellingDcaIn) {
22
21
  const supplyIsWsol = client.supplyMint.equals(spl_token_1.NATIVE_MINT);
23
22
  const debtIsWsol = client.debtMint.equals(spl_token_1.NATIVE_MINT);
@@ -331,7 +330,7 @@ async function buildSolautoRebalanceTransaction(client, targetLiqUtilizationRate
331
330
  client.log("Not eligible for a rebalance");
332
331
  return undefined;
333
332
  }
334
- const values = (0, rebalanceUtils_1.getRebalanceValues)(client.solautoPositionState, client.solautoPositionSettings(), client.solautoPositionActiveDca(), (0, generalUtils_1.currentUnixSeconds)(), constants_1.PRICES[client.supplyMint.toString()].price, constants_1.PRICES[client.debtMint.toString()].price, targetLiqUtilizationRateBps);
333
+ const values = (0, rebalanceUtils_1.getRebalanceValues)(client.solautoPositionState, client.solautoPositionSettings(), client.solautoPositionActiveDca(), (0, generalUtils_1.currentUnixSeconds)(), (0, generalUtils_1.safeGetPrice)(client.supplyMint), (0, generalUtils_1.safeGetPrice)(client.debtMint), targetLiqUtilizationRateBps);
335
334
  client.log("Rebalance values: ", values);
336
335
  const swapDetails = (0, rebalanceUtils_1.getJupSwapRebalanceDetails)(client, values, targetLiqUtilizationRateBps, attemptNum);
337
336
  const { jupQuote, lookupTableAddresses, setupInstructions, tokenLedgerIx, swapIx, } = await (0, jupiterUtils_1.getJupSwapTransaction)(client.signer, swapDetails, attemptNum);
@@ -1,12 +1,13 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
- import { MaybeRpcAccount, Umi } from "@metaplex-foundation/umi";
2
+ import { MaybeRpcAccount, Umi, PublicKey as UmiPublicKey } from "@metaplex-foundation/umi";
3
3
  export declare function generateRandomU8(): number;
4
4
  export declare function generateRandomU64(): bigint;
5
5
  export declare function currentUnixSeconds(): number;
6
6
  export declare function getSolanaAccountCreated(umi: Umi, pk: PublicKey): Promise<boolean>;
7
7
  export declare function rpcAccountCreated(account: MaybeRpcAccount): boolean;
8
8
  export declare function arraysAreEqual(arrayA: number[], arrayB: number[]): boolean;
9
- export declare function getTokenPrices(mints: PublicKey[]): Promise<number[]>;
9
+ export declare function fetchTokenPrices(mints: PublicKey[]): Promise<number[]>;
10
+ export declare function safeGetPrice(mint: PublicKey | UmiPublicKey): number | undefined;
10
11
  export type ErrorsToThrow = Array<new (...args: any[]) => Error>;
11
12
  export declare function retryWithExponentialBackoff<T>(fn: (attemptNum: number) => Promise<T>, retries?: number, delay?: number, errorsToThrow?: ErrorsToThrow): Promise<T>;
12
13
  //# sourceMappingURL=generalUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAa,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAK3E,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAU1E;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C1E;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAEjE,wBAAgB,2BAA2B,CAAC,CAAC,EAC3C,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAY,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA8BZ"}
1
+ {"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAa,GAAG,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAKtG,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAU1E;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C5E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAK/E;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAEjE,wBAAgB,2BAA2B,CAAC,CAAC,EAC3C,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAY,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA8BZ"}
@@ -6,7 +6,8 @@ exports.currentUnixSeconds = currentUnixSeconds;
6
6
  exports.getSolanaAccountCreated = getSolanaAccountCreated;
7
7
  exports.rpcAccountCreated = rpcAccountCreated;
8
8
  exports.arraysAreEqual = arraysAreEqual;
9
- exports.getTokenPrices = getTokenPrices;
9
+ exports.fetchTokenPrices = fetchTokenPrices;
10
+ exports.safeGetPrice = safeGetPrice;
10
11
  exports.retryWithExponentialBackoff = retryWithExponentialBackoff;
11
12
  const umi_1 = require("@metaplex-foundation/umi");
12
13
  const pythConstants_1 = require("../constants/pythConstants");
@@ -44,7 +45,7 @@ function arraysAreEqual(arrayA, arrayB) {
44
45
  }
45
46
  return true;
46
47
  }
47
- async function getTokenPrices(mints) {
48
+ async function fetchTokenPrices(mints) {
48
49
  const currentTime = currentUnixSeconds();
49
50
  if (!mints.some((mint) => !(mint.toString() in solautoConstants_1.PRICES) ||
50
51
  currentTime - solautoConstants_1.PRICES[mint.toString()].time > 3)) {
@@ -79,6 +80,12 @@ async function getTokenPrices(mints) {
79
80
  }
80
81
  return prices;
81
82
  }
83
+ function safeGetPrice(mint) {
84
+ if (mint.toString() in solautoConstants_1.PRICES) {
85
+ return solautoConstants_1.PRICES[mint.toString()].price;
86
+ }
87
+ return undefined;
88
+ }
82
89
  function retryWithExponentialBackoff(fn, retries = 5, delay = 150, errorsToThrow) {
83
90
  return new Promise((resolve, reject) => {
84
91
  const attempt = (attemptNum) => {
@@ -11,7 +11,6 @@ const umi_web3js_adapters_1 = require("@metaplex-foundation/umi-web3js-adapters"
11
11
  const marginfi_sdk_1 = require("../marginfi-sdk");
12
12
  const generalUtils_1 = require("./generalUtils");
13
13
  const numberUtils_1 = require("./numberUtils");
14
- const solautoConstants_1 = require("../constants/solautoConstants");
15
14
  const marginfiAccounts_1 = require("../constants/marginfiAccounts");
16
15
  const generalAccounts_1 = require("../constants/generalAccounts");
17
16
  const solanaUtils_1 = require("./solanaUtils");
@@ -36,7 +35,7 @@ async function getMaxLtvAndLiqThreshold(umi, supply, debt, supplyPrice) {
36
35
  debt.bank = await (0, marginfi_sdk_1.safeFetchBank)(umi, (0, umi_1.publicKey)(marginfiAccounts_1.MARGINFI_ACCOUNTS[debt.mint.toString()].bank));
37
36
  }
38
37
  if (!supplyPrice) {
39
- const [price] = await (0, generalUtils_1.getTokenPrices)([
38
+ const [price] = await (0, generalUtils_1.fetchTokenPrices)([
40
39
  (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(supply.bank.mint),
41
40
  ]);
42
41
  supplyPrice = price;
@@ -101,7 +100,7 @@ async function getTokenUsage(umi, bank, isAsset, shares, amountUsedAdjustment) {
101
100
  let amountCanBeUsed = 0;
102
101
  let marketPrice = 0;
103
102
  if (bank !== null) {
104
- [marketPrice] = await (0, generalUtils_1.getTokenPrices)([(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(bank.mint)]);
103
+ [marketPrice] = await (0, generalUtils_1.fetchTokenPrices)([(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(bank.mint)]);
105
104
  const [assetShareValue, liabilityShareValue] = await getUpToDateShareValues(umi, bank);
106
105
  const shareValue = isAsset ? assetShareValue : liabilityShareValue;
107
106
  amountUsed = shares * shareValue + Number(amountUsedAdjustment ?? 0);
@@ -181,7 +180,7 @@ async function getMarginfiAccountPositionState(umi, marginfiAccountPk, supplyMin
181
180
  if (!debtUsage) {
182
181
  debtUsage = await getTokenUsage(umi, debtBank, false, 0, livePositionUpdates?.debtAdjustment);
183
182
  }
184
- const supplyPrice = solautoConstants_1.PRICES[supplyMint.toString()].price;
183
+ const supplyPrice = (0, generalUtils_1.safeGetPrice)(supplyMint);
185
184
  let [maxLtv, liqThreshold] = await getMaxLtvAndLiqThreshold(umi, {
186
185
  mint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(supplyBank.mint),
187
186
  bank: supplyBank,
@@ -213,7 +213,7 @@ async function getAllPositionsByAuthority(umi, user) {
213
213
  }
214
214
  async function positionStateWithLatestPrices(state, supplyPrice, debtPrice) {
215
215
  if (!supplyPrice || !debtPrice) {
216
- [supplyPrice, debtPrice] = await (0, generalUtils_1.getTokenPrices)([
216
+ [supplyPrice, debtPrice] = await (0, generalUtils_1.fetchTokenPrices)([
217
217
  (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(state.supply.mint),
218
218
  (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(state.debt.mint),
219
219
  ]);
@@ -138,11 +138,11 @@ function getFlashLoanDetails(client, values, jupQuote) {
138
138
  let flashLoanTokenPrice = 0;
139
139
  if (values.increasingLeverage) {
140
140
  flashLoanToken = client.solautoPositionState.debt;
141
- flashLoanTokenPrice = solautoConstants_1.PRICES[client.debtMint.toString()].price;
141
+ flashLoanTokenPrice = (0, generalUtils_2.safeGetPrice)(client.debtMint);
142
142
  }
143
143
  else {
144
144
  flashLoanToken = client.solautoPositionState.supply;
145
- flashLoanTokenPrice = solautoConstants_1.PRICES[client.supplyMint.toString()].price;
145
+ flashLoanTokenPrice = (0, generalUtils_2.safeGetPrice)(client.supplyMint);
146
146
  }
147
147
  const exactAmountBaseUnit = jupQuote && jupQuote.swapMode === "ExactOut"
148
148
  ? BigInt(parseInt(jupQuote.inAmount))
@@ -166,15 +166,15 @@ function getJupSwapRebalanceDetails(client, values, targetLiqUtilizationRateBps,
166
166
  : client.solautoPositionState.debt;
167
167
  const usdToSwap = Math.abs(values.debtAdjustmentUsd) + values.amountUsdToDcaIn;
168
168
  const inputPrice = values.increasingLeverage
169
- ? solautoConstants_1.PRICES[client.debtMint.toString()].price
170
- : solautoConstants_1.PRICES[client.supplyMint.toString()].price;
169
+ ? (0, generalUtils_2.safeGetPrice)(client.debtMint)
170
+ : (0, generalUtils_2.safeGetPrice)(client.supplyMint);
171
171
  const inputAmount = (0, numberUtils_1.toBaseUnit)(usdToSwap / inputPrice, input.decimals);
172
172
  const rebalancingToZero = targetLiqUtilizationRateBps === 0;
173
173
  return {
174
174
  inputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(input.mint),
175
175
  outputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(output.mint),
176
176
  destinationWallet: client.solautoPosition,
177
- slippageBpsIncFactor: 0.25 + (attemptNum ?? 0) * 0.2,
177
+ slippageBpsIncFactor: 0.5 + (attemptNum ?? 0) * 0.2,
178
178
  amount: rebalancingToZero
179
179
  ? client.solautoPositionState.debt.amountUsed.baseUnit +
180
180
  BigInt(Math.round(Number(client.solautoPositionState.debt.amountUsed.baseUnit) *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.128",
3
+ "version": "1.0.129",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "description": "Typescript SDK for the Solauto program on the Solana blockchain",
@@ -32,7 +32,7 @@ import {
32
32
  marginfiRefreshData,
33
33
  } from "../generated";
34
34
  import { getMarginfiAccountPDA, getTokenAccount } from "../utils/accountUtils";
35
- import { generateRandomU64 } from "../utils/generalUtils";
35
+ import { generateRandomU64, safeGetPrice } from "../utils/generalUtils";
36
36
  import {
37
37
  MARGINFI_PROGRAM_ID,
38
38
  MarginfiAccount,
@@ -630,8 +630,8 @@ export class SolautoMarginfiClient extends SolautoClient {
630
630
 
631
631
  if (freshState) {
632
632
  this.log("Fresh state", freshState);
633
- const supplyPrice = PRICES[(freshState?.supply.mint ?? PublicKey.default).toString()].price;
634
- const debtPrice = PRICES[(freshState?.debt.mint ?? PublicKey.default).toString()].price;
633
+ const supplyPrice = safeGetPrice(freshState?.supply.mint)!;
634
+ const debtPrice = safeGetPrice(freshState?.debt.mint)!;
635
635
  this.log("Supply price: ", supplyPrice);
636
636
  this.log("Debt price: ", debtPrice);
637
637
  this.log("Liq threshold bps:", freshState.liqThresholdBps);
@@ -39,6 +39,7 @@ import {
39
39
  currentUnixSeconds,
40
40
  getSolanaAccountCreated,
41
41
  rpcAccountCreated,
42
+ safeGetPrice,
42
43
  } from "../utils/generalUtils";
43
44
  import { SolautoMarginfiClient } from "../clients/solautoMarginfiClient";
44
45
  import {
@@ -586,8 +587,8 @@ export async function buildSolautoRebalanceTransaction(
586
587
  client.solautoPositionSettings(),
587
588
  client.solautoPositionActiveDca(),
588
589
  currentUnixSeconds(),
589
- PRICES[client.supplyMint.toString()].price,
590
- PRICES[client.debtMint.toString()].price,
590
+ safeGetPrice(client.supplyMint)!,
591
+ safeGetPrice(client.debtMint)!,
591
592
  targetLiqUtilizationRateBps
592
593
  );
593
594
  client.log("Rebalance values: ", values);
@@ -1,5 +1,5 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
- import { MaybeRpcAccount, publicKey, Umi } from "@metaplex-foundation/umi";
2
+ import { MaybeRpcAccount, publicKey, Umi, PublicKey as UmiPublicKey } from "@metaplex-foundation/umi";
3
3
  import { PYTH_PRICE_FEED_IDS } from "../constants/pythConstants";
4
4
  import { fromBaseUnit, toBaseUnit } from "./numberUtils";
5
5
  import { PRICES } from "../constants/solautoConstants";
@@ -45,7 +45,7 @@ export function arraysAreEqual(arrayA: number[], arrayB: number[]): boolean {
45
45
  return true;
46
46
  }
47
47
 
48
- export async function getTokenPrices(mints: PublicKey[]): Promise<number[]> {
48
+ export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
49
49
  const currentTime = currentUnixSeconds();
50
50
  if (
51
51
  !mints.some(
@@ -94,6 +94,13 @@ export async function getTokenPrices(mints: PublicKey[]): Promise<number[]> {
94
94
  return prices;
95
95
  }
96
96
 
97
+ export function safeGetPrice(mint: PublicKey | UmiPublicKey): number | undefined {
98
+ if (mint.toString() in PRICES) {
99
+ return PRICES[mint.toString()].price;
100
+ }
101
+ return undefined;
102
+ }
103
+
97
104
  export type ErrorsToThrow = Array<new (...args: any[]) => Error>;
98
105
 
99
106
  export function retryWithExponentialBackoff<T>(
@@ -8,7 +8,7 @@ import {
8
8
  safeFetchBank,
9
9
  safeFetchMarginfiAccount,
10
10
  } from "../marginfi-sdk";
11
- import { currentUnixSeconds, getTokenPrices } from "./generalUtils";
11
+ import { currentUnixSeconds, fetchTokenPrices, safeGetPrice } from "./generalUtils";
12
12
  import {
13
13
  bytesToI80F48,
14
14
  fromBaseUnit,
@@ -72,7 +72,7 @@ export async function getMaxLtvAndLiqThreshold(
72
72
  }
73
73
 
74
74
  if (!supplyPrice) {
75
- const [price] = await getTokenPrices([
75
+ const [price] = await fetchTokenPrices([
76
76
  toWeb3JsPublicKey(supply.bank!.mint),
77
77
  ]);
78
78
  supplyPrice = price;
@@ -177,7 +177,7 @@ async function getTokenUsage(
177
177
  let marketPrice = 0;
178
178
 
179
179
  if (bank !== null) {
180
- [marketPrice] = await getTokenPrices([toWeb3JsPublicKey(bank.mint)]);
180
+ [marketPrice] = await fetchTokenPrices([toWeb3JsPublicKey(bank.mint)]);
181
181
  const [assetShareValue, liabilityShareValue] = await getUpToDateShareValues(
182
182
  umi,
183
183
  bank
@@ -335,7 +335,7 @@ export async function getMarginfiAccountPositionState(
335
335
  );
336
336
  }
337
337
 
338
- const supplyPrice = PRICES[supplyMint!.toString()].price;
338
+ const supplyPrice = safeGetPrice(supplyMint!)!;
339
339
  let [maxLtv, liqThreshold] = await getMaxLtvAndLiqThreshold(
340
340
  umi,
341
341
  {
@@ -13,7 +13,7 @@ import {
13
13
  getSolautoPositionAccountDataSerializer,
14
14
  getSolautoPositionSize,
15
15
  } from "../../generated";
16
- import { currentUnixSeconds, getTokenPrices } from "../generalUtils";
16
+ import { currentUnixSeconds, fetchTokenPrices } from "../generalUtils";
17
17
  import {
18
18
  fromBaseUnit,
19
19
  getLiqUtilzationRateBps,
@@ -323,7 +323,7 @@ export async function positionStateWithLatestPrices(
323
323
  debtPrice?: number
324
324
  ): Promise<PositionState> {
325
325
  if (!supplyPrice || !debtPrice) {
326
- [supplyPrice, debtPrice] = await getTokenPrices([
326
+ [supplyPrice, debtPrice] = await fetchTokenPrices([
327
327
  toWeb3JsPublicKey(state.supply.mint),
328
328
  toWeb3JsPublicKey(state.debt.mint),
329
329
  ]);
@@ -14,7 +14,7 @@ import {
14
14
  import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
15
15
  import { QuoteResponse } from "@jup-ag/api";
16
16
  import { JupSwapDetails } from "../jupiterUtils";
17
- import { currentUnixSeconds } from "../generalUtils";
17
+ import { currentUnixSeconds, safeGetPrice } from "../generalUtils";
18
18
  import {
19
19
  fromBaseUnit,
20
20
  fromBps,
@@ -300,10 +300,10 @@ export function getFlashLoanDetails(
300
300
  let flashLoanTokenPrice = 0;
301
301
  if (values.increasingLeverage) {
302
302
  flashLoanToken = client.solautoPositionState!.debt;
303
- flashLoanTokenPrice = PRICES[client.debtMint.toString()].price;
303
+ flashLoanTokenPrice = safeGetPrice(client.debtMint)!;
304
304
  } else {
305
305
  flashLoanToken = client.solautoPositionState!.supply;
306
- flashLoanTokenPrice = PRICES[client.supplyMint.toString()].price;
306
+ flashLoanTokenPrice = safeGetPrice(client.supplyMint)!;
307
307
  }
308
308
 
309
309
  const exactAmountBaseUnit =
@@ -346,8 +346,8 @@ export function getJupSwapRebalanceDetails(
346
346
  Math.abs(values.debtAdjustmentUsd) + values.amountUsdToDcaIn;
347
347
 
348
348
  const inputPrice = values.increasingLeverage
349
- ? PRICES[client.debtMint.toString()].price
350
- : PRICES[client.supplyMint.toString()].price;
349
+ ? safeGetPrice(client.debtMint)
350
+ : safeGetPrice(client.supplyMint);
351
351
  const inputAmount = toBaseUnit(usdToSwap / inputPrice!, input.decimals);
352
352
 
353
353
  const rebalancingToZero = targetLiqUtilizationRateBps === 0;
@@ -355,7 +355,7 @@ export function getJupSwapRebalanceDetails(
355
355
  inputMint: toWeb3JsPublicKey(input.mint),
356
356
  outputMint: toWeb3JsPublicKey(output.mint),
357
357
  destinationWallet: client.solautoPosition,
358
- slippageBpsIncFactor: 0.25 + (attemptNum ?? 0) * 0.2,
358
+ slippageBpsIncFactor: 0.5 + (attemptNum ?? 0) * 0.2,
359
359
  amount: rebalancingToZero
360
360
  ? client.solautoPositionState!.debt.amountUsed.baseUnit +
361
361
  BigInt(
@@ -11,7 +11,7 @@ import {
11
11
  import { buildSolautoRebalanceTransaction } from "../../src/transactions/transactionUtils";
12
12
  import { maxBoostToBps, maxRepayFromBps, maxRepayToBps, toBaseUnit } from "../../src/utils/numberUtils";
13
13
  import { NATIVE_MINT } from "@solana/spl-token";
14
- import { getTokenPrices } from "../../src/utils/generalUtils";
14
+ import { fetchTokenPrices } from "../../src/utils/generalUtils";
15
15
  import {
16
16
  TransactionItem,
17
17
  TransactionsManager,
@@ -70,7 +70,7 @@ describe("Solauto Marginfi tests", async () => {
70
70
  // const initialSupplyUsd = 150;
71
71
  // transactionItems.push(
72
72
  // new TransactionItem(async () => {
73
- // const [supplyPrice] = await getTokenPrices([supply]);
73
+ // const [supplyPrice] = await fetchTokenPrices([supply]);
74
74
  // return {
75
75
  // tx: client.protocolInteraction(
76
76
  // solautoAction("Deposit", [
@@ -109,7 +109,7 @@ describe("Solauto Marginfi tests", async () => {
109
109
  // const initialSupplyUsd = 50;
110
110
  // transactionItems.push(
111
111
  // new TransactionItem(async () => {
112
- // const [supplyPrice] = await getTokenPrices([supply]);
112
+ // const [supplyPrice] = await fetchTokenPrices([supply]);
113
113
  // return {
114
114
  // tx: client.protocolInteraction(
115
115
  // solautoAction("Deposit", [
@@ -31,7 +31,8 @@ import {
31
31
  } from "../../src/utils/solauto/generalUtils";
32
32
  import {
33
33
  currentUnixSeconds,
34
- getTokenPrices,
34
+ fetchTokenPrices,
35
+ safeGetPrice,
35
36
  } from "../../src/utils/generalUtils";
36
37
  import { USDC_MINT } from "../../src/constants/tokenConstants";
37
38
  import { PRICES } from "../../src/constants";
@@ -50,8 +51,8 @@ function assertAccurateRebalance(
50
51
  client.solautoPositionSettings(),
51
52
  client.solautoPositionActiveDca(),
52
53
  currentUnixSeconds(),
53
- PRICES[client.supplyMint.toString()].price,
54
- PRICES[client.debtMint.toString()].price,
54
+ safeGetPrice(client.supplyMint)!,
55
+ safeGetPrice(client.debtMint)!,
55
56
  targetLiqUtilizationRateBps
56
57
  );
57
58
 
@@ -124,7 +125,7 @@ async function getFakePosition(
124
125
  createFakePositionState(
125
126
  {
126
127
  amountUsed: supplyUsd / supplyPrice,
127
- price: PRICES[NATIVE_MINT.toString()].price,
128
+ price: safeGetPrice(NATIVE_MINT)!,
128
129
  mint: NATIVE_MINT,
129
130
  },
130
131
  {
@@ -282,7 +283,7 @@ describe("Rebalance tests", async () => {
282
283
  let supplyPrice: number, debtPrice: number;
283
284
 
284
285
  before(async () => {
285
- [supplyPrice, debtPrice] = await getTokenPrices([
286
+ [supplyPrice, debtPrice] = await fetchTokenPrices([
286
287
  NATIVE_MINT,
287
288
  new PublicKey(USDC_MINT),
288
289
  ]);