@haven-fi/solauto-sdk 1.0.127 → 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);
@@ -211,13 +211,13 @@ class TransactionsManager {
211
211
  choresBefore.prepend(updateLookupTable.updateLutTx);
212
212
  }
213
213
  if (choresBefore.getInstructions().length > 0) {
214
- const chore = new TransactionItem(async () => ({ tx: choresBefore }), "create account(s)");
214
+ const chore = new TransactionItem(async () => ({ tx: choresBefore }));
215
215
  await chore.initialize();
216
216
  items.unshift(chore);
217
217
  this.txHandler.log("Chores before: ", choresBefore.getInstructions().length);
218
218
  }
219
219
  if (choresAfter.getInstructions().length > 0) {
220
- const chore = new TransactionItem(async () => ({ tx: choresAfter }));
220
+ const chore = new TransactionItem(async () => ({ tx: choresAfter }), "closing temp accounts");
221
221
  await chore.initialize();
222
222
  items.push(chore);
223
223
  this.txHandler.log("Chores after: ", choresAfter.getInstructions().length);
@@ -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,
@@ -69,9 +69,9 @@ function getDebtAdjustmentUsd(liqThresholdBps, supplyUsd, debtUsd, targetLiqUtil
69
69
  function getSolautoFeesBps(isReferred, targetLiqUtilizationRateBps, positionNetWorthUsd) {
70
70
  const minSize = 10000; // Minimum position size
71
71
  const maxSize = 500000; // Maximum position size
72
- const maxFeeBps = 500; // Fee in basis points for minSize (5%)
72
+ const maxFeeBps = 200; // Fee in basis points for minSize (2%)
73
73
  const minFeeBps = 50; // Fee in basis points for maxSize (0.5%)
74
- const k = 0.55;
74
+ const k = 1.5;
75
75
  let feeBps = 0;
76
76
  if (targetLiqUtilizationRateBps !== undefined) {
77
77
  feeBps = minFeeBps;
@@ -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.127",
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);
@@ -320,10 +320,7 @@ export class TransactionsManager {
320
320
  choresBefore.prepend(updateLookupTable.updateLutTx);
321
321
  }
322
322
  if (choresBefore.getInstructions().length > 0) {
323
- const chore = new TransactionItem(
324
- async () => ({ tx: choresBefore }),
325
- "create account(s)"
326
- );
323
+ const chore = new TransactionItem(async () => ({ tx: choresBefore }));
327
324
  await chore.initialize();
328
325
  items.unshift(chore);
329
326
  this.txHandler.log(
@@ -332,7 +329,10 @@ export class TransactionsManager {
332
329
  );
333
330
  }
334
331
  if (choresAfter.getInstructions().length > 0) {
335
- const chore = new TransactionItem(async () => ({ tx: choresAfter }));
332
+ const chore = new TransactionItem(
333
+ async () => ({ tx: choresAfter }),
334
+ "closing temp accounts"
335
+ );
336
336
  await chore.initialize();
337
337
  items.push(chore);
338
338
  this.txHandler.log(
@@ -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
  {
@@ -97,9 +97,9 @@ export function getSolautoFeesBps(
97
97
  } {
98
98
  const minSize = 10_000; // Minimum position size
99
99
  const maxSize = 500_000; // Maximum position size
100
- const maxFeeBps = 500; // Fee in basis points for minSize (5%)
100
+ const maxFeeBps = 200; // Fee in basis points for minSize (2%)
101
101
  const minFeeBps = 50; // Fee in basis points for maxSize (0.5%)
102
- const k = 0.55;
102
+ const k = 1.5;
103
103
 
104
104
  let feeBps: number = 0;
105
105
 
@@ -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(
@@ -1,22 +1,17 @@
1
1
  import { describe, it } from "mocha";
2
2
  import { none, publicKey, some } from "@metaplex-foundation/umi";
3
3
  import { setupTest } from "../shared";
4
- import { SolautoMarginfiClient } from "../../src/clients/solautoMarginfiClient";
4
+ import {
5
+ SolautoMarginfiClient,
6
+ } from "../../src/clients/solautoMarginfiClient";
5
7
  import {
6
8
  solautoAction,
7
9
  SolautoSettingsParametersInpArgs,
8
10
  } from "../../src/generated";
9
11
  import { buildSolautoRebalanceTransaction } from "../../src/transactions/transactionUtils";
10
- import {
11
- getDebtAdjustmentUsd,
12
- getLiqUtilzationRateBps,
13
- maxBoostToBps,
14
- maxRepayFromBps,
15
- maxRepayToBps,
16
- toBaseUnit,
17
- } from "../../src/utils/numberUtils";
12
+ import { maxBoostToBps, maxRepayFromBps, maxRepayToBps, toBaseUnit } from "../../src/utils/numberUtils";
18
13
  import { NATIVE_MINT } from "@solana/spl-token";
19
- import { getTokenPrices } from "../../src/utils/generalUtils";
14
+ import { fetchTokenPrices } from "../../src/utils/generalUtils";
20
15
  import {
21
16
  TransactionItem,
22
17
  TransactionsManager,
@@ -33,22 +28,25 @@ describe("Solauto Marginfi tests", async () => {
33
28
  const positionId = 1;
34
29
 
35
30
  it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => {
31
+
36
32
  const client = new SolautoMarginfiClient(process.env.HELIUS_API_KEY!, true);
37
33
 
38
34
  const supply = NATIVE_MINT;
39
35
  const supplyDecimals = 9;
40
36
  const debtDecimals = 6;
41
37
 
42
- await client.initialize({
43
- signer,
44
- positionId,
45
- authority: new PublicKey("E5BBsR1sUToPc3jXVwhrK5ttSiy6xhWJDMdQLvkgNppe")
46
- // marginfiAccount: new PublicKey(
47
- // "4nNvUXF5YqHFcH2nGweSiuvy1ct7V5FXfoCLKFYUN36z"
48
- // ),
49
- // supplyMint: NATIVE_MINT,
50
- // debtMint: new PublicKey(USDC_MINT),
51
- });
38
+ await client.initialize(
39
+ {
40
+ signer,
41
+ positionId,
42
+ authority: new PublicKey("AprYCPiVeKMCgjQ2ZufwChMzvQ5kFjJo2ekTLSkXsQDm")
43
+ // marginfiAccount: new PublicKey(
44
+ // "4nNvUXF5YqHFcH2nGweSiuvy1ct7V5FXfoCLKFYUN36z"
45
+ // ),
46
+ // supplyMint: NATIVE_MINT,
47
+ // debtMint: new PublicKey(USDC_MINT),
48
+ }
49
+ );
52
50
 
53
51
  const transactionItems: TransactionItem[] = [];
54
52
  // const settingParams: SolautoSettingsParametersInpArgs = {
@@ -72,7 +70,7 @@ describe("Solauto Marginfi tests", async () => {
72
70
  // const initialSupplyUsd = 150;
73
71
  // transactionItems.push(
74
72
  // new TransactionItem(async () => {
75
- // const [supplyPrice] = await getTokenPrices([supply]);
73
+ // const [supplyPrice] = await fetchTokenPrices([supply]);
76
74
  // return {
77
75
  // tx: client.protocolInteraction(
78
76
  // solautoAction("Deposit", [
@@ -111,7 +109,7 @@ describe("Solauto Marginfi tests", async () => {
111
109
  // const initialSupplyUsd = 50;
112
110
  // transactionItems.push(
113
111
  // new TransactionItem(async () => {
114
- // const [supplyPrice] = await getTokenPrices([supply]);
112
+ // const [supplyPrice] = await fetchTokenPrices([supply]);
115
113
  // return {
116
114
  // tx: client.protocolInteraction(
117
115
  // solautoAction("Deposit", [
@@ -122,13 +120,13 @@ describe("Solauto Marginfi tests", async () => {
122
120
  // }, "deposit")
123
121
  // );
124
122
 
125
- // transactionItems.push(
126
- // new TransactionItem(
127
- // async (attemptNum) =>
128
- // await buildSolautoRebalanceTransaction(client, 1500, attemptNum),
129
- // "rebalance"
130
- // )
131
- // );
123
+ transactionItems.push(
124
+ new TransactionItem(
125
+ async (attemptNum) =>
126
+ await buildSolautoRebalanceTransaction(client, undefined, attemptNum),
127
+ "rebalance"
128
+ )
129
+ );
132
130
 
133
131
  // transactionItems.push(
134
132
  // new TransactionItem(
@@ -157,19 +155,11 @@ describe("Solauto Marginfi tests", async () => {
157
155
  // )
158
156
  // );
159
157
 
160
- // await new TransactionsManager(
161
- // client,
162
- // undefined,
163
- // !payForTransactions ? "only-simulate" : "normal",
164
- // useJitoBundle
165
- // ).clientSend(transactionItems);
166
-
167
- // const debtAdjustment = getDebtAdjustmentUsd(8696, 366, 165, 7000);
168
- // const newLiqUtilizationRate = getLiqUtilzationRateBps(366 + debtAdjustment, 165 + debtAdjustment, 8696);
169
- // console.log(newLiqUtilizationRate);
170
-
171
- console.log("CURRENT", Number(client.solautoPositionState?.supply.amountUsed.baseUnit));
172
- const freshState = await client.getFreshPositionState();
173
- console.log("FRESH", Number(freshState!.supply.amountUsed.baseUnit));
158
+ await new TransactionsManager(
159
+ client,
160
+ undefined,
161
+ !payForTransactions ? "only-simulate" : "normal",
162
+ useJitoBundle
163
+ ).clientSend(transactionItems);
174
164
  });
175
165
  });
@@ -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
  ]);