@haven-fi/solauto-sdk 1.0.535 → 1.0.537

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.
@@ -24,7 +24,7 @@ export interface JupSwapTransaction {
24
24
  swapIx: TransactionBuilder;
25
25
  }
26
26
  export declare function getJupSwapTransaction(signer: Signer, swapDetails: JupSwapDetails, attemptNum?: number): Promise<JupSwapTransaction>;
27
- export declare function getJupPriceData(mints: PublicKey[], extraInfo?: boolean): Promise<{
27
+ export declare function getJupPriceData(mints: PublicKey[], extraInfo?: boolean, mayIncludeSpamTokens?: boolean): Promise<{
28
28
  [key: string]: any;
29
29
  }>;
30
30
  //# sourceMappingURL=jupiterUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jupiterUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jupiterUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,kBAAkB,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAA0B,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAGL,aAAa,EACd,MAAM,aAAa,CAAC;AAUrB,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,iBAAiB,EAAE,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAgBD,wBAAsB,WAAW,CAAC,WAAW,EAAE,YAAY,0BAsB1D;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,aAAa,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,iBAAiB,EAAE,kBAAkB,CAAC;IACtC,aAAa,EAAE,kBAAkB,CAAC;IAClC,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,cAAc,EAC3B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAmF7B;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO;;GA6B5E"}
1
+ {"version":3,"file":"jupiterUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jupiterUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,kBAAkB,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAA0B,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAGL,aAAa,EACd,MAAM,aAAa,CAAC;AAUrB,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,iBAAiB,EAAE,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAgBD,wBAAsB,WAAW,CAAC,WAAW,EAAE,YAAY,0BAsB1D;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,aAAa,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,iBAAiB,EAAE,kBAAkB,CAAC;IACtC,aAAa,EAAE,kBAAkB,CAAC;IAClC,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,cAAc,EAC3B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAmF7B;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,EAAE,OAAO;;GA6B5G"}
@@ -85,7 +85,7 @@ async function getJupSwapTransaction(signer, swapDetails, attemptNum) {
85
85
  swapIx: (0, umi_1.transactionBuilder)().add((0, solanaUtils_1.getWrappedInstruction)(signer, createTransactionInstruction(instructions.swapInstruction))),
86
86
  };
87
87
  }
88
- async function getJupPriceData(mints, extraInfo) {
88
+ async function getJupPriceData(mints, extraInfo, mayIncludeSpamTokens) {
89
89
  const data = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
90
90
  const res = await (await fetch("https://api.jup.ag/price/v2?ids=" +
91
91
  mints.map((x) => x.toString()).join(",") +
@@ -98,7 +98,7 @@ async function getJupPriceData(mints, extraInfo) {
98
98
  Boolean(Object.values(result)
99
99
  .map((x) => parseFloat(x.price))
100
100
  .filter((x) => x <= 0).length);
101
- if (invalidValues) {
101
+ if (invalidValues && !mayIncludeSpamTokens) {
102
102
  throw new Error("Invalid price values");
103
103
  }
104
104
  return result;
@@ -4,7 +4,7 @@ import { QuoteGetSwapModeEnum } from "@jup-ag/api";
4
4
  export declare function fetchTokenPrices(mints: PublicKey[]): Promise<number[]>;
5
5
  export declare function getPythPrices(mints: PublicKey[]): Promise<number[]>;
6
6
  export declare function getSwitchboardPrices(mints: PublicKey[]): Promise<number[]>;
7
- export declare function getJupTokenPrices(mints: PublicKey[]): Promise<number[]>;
7
+ export declare function getJupTokenPrices(mints: PublicKey[], mayIncludeSpamTokens?: boolean): Promise<number[]>;
8
8
  export declare function safeGetPrice(mint: PublicKey | UmiPublicKey | undefined): number | undefined;
9
9
  export declare function getPriceImpact(inputMint: PublicKey, outputMint: PublicKey, amount: bigint, swapMode: QuoteGetSwapModeEnum): Promise<{
10
10
  priceImpact: number;
@@ -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;AAarE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqC5E;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,qBAwCrD;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgDnB;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,qBAQzD;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAKpB;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,SAAS,EACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,oBAAoB;;;GAc/B"}
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;AAarE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyC5E;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,qBAwCrD;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAoDnB;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,SAAS,EAAE,EAClB,oBAAoB,CAAC,EAAE,OAAO,qBAa/B;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAKpB;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,SAAS,EACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,oBAAoB;;;GAc/B"}
@@ -44,12 +44,14 @@ async function fetchTokenPrices(mints) {
44
44
  }
45
45
  const pythMints = mints.filter((x) => x.toString() in pythConstants_1.PYTH_PRICE_FEED_IDS);
46
46
  const switchboardMints = mints.filter((x) => x.toString() in switchboardConstants_1.SWITCHBOARD_PRICE_FEED_IDS);
47
- const [pythData, switchboardData] = await Promise.all([
47
+ const otherMints = mints.filter((x) => !pythMints.includes(x) && !switchboardMints.includes(x));
48
+ const [pythData, switchboardData, jupData] = await Promise.all([
48
49
  (0, generalUtils_1.zip)(pythMints, await getPythPrices(pythMints)),
49
50
  (0, generalUtils_1.zip)(switchboardMints, await getSwitchboardPrices(switchboardMints)),
51
+ (0, generalUtils_1.zip)(otherMints, await getJupTokenPrices(otherMints, true)),
50
52
  ]);
51
53
  const prices = mints.map((mint) => {
52
- const item = [...pythData, ...switchboardData].find((data) => data[0].equals(mint));
54
+ const item = [...pythData, ...switchboardData, ...jupData].find((data) => data[0].equals(mint));
53
55
  return item ? item[1] : 0;
54
56
  });
55
57
  for (var i = 0; i < mints.length; i++) {
@@ -102,7 +104,7 @@ async function getSwitchboardPrices(mints) {
102
104
  if (p.filter((x) => !x || isNaN(Number(x)) || Number(x) < 0).length > 0) {
103
105
  throw new Error("Unable to fetch Switchboard prices");
104
106
  }
105
- return p;
107
+ return p.map((x) => typeof x === "string" ? parseFloat(x) : Number(x));
106
108
  }, 2, 350);
107
109
  }
108
110
  catch {
@@ -111,17 +113,19 @@ async function getSwitchboardPrices(mints) {
111
113
  if (prices.length === 0) {
112
114
  prices = Array(mints.length).fill(0);
113
115
  }
114
- const missingPrices = (0, generalUtils_1.zip)(mints, prices).filter((x) => !x[1] || isNaN(Number(x)));
116
+ const missingPrices = (0, generalUtils_1.zip)(mints, prices).filter((x) => !x[1] || isNaN(Number(x[1])));
115
117
  const jupPrices = (0, generalUtils_1.zip)(missingPrices.map((x) => x[0]), await getJupTokenPrices(missingPrices.map((x) => x[0])));
116
118
  prices = prices.map((x, i) => x ? x : jupPrices.find((y) => y[0].toString() === mints[i].toString())[1]);
117
119
  return prices;
118
120
  }
119
- async function getJupTokenPrices(mints) {
121
+ async function getJupTokenPrices(mints, mayIncludeSpamTokens) {
120
122
  if (mints.length == 0) {
121
123
  return [];
122
124
  }
123
- const data = await (0, jupiterUtils_1.getJupPriceData)(mints);
124
- return Object.values(data).map((x) => parseFloat(x.price));
125
+ const data = await (0, jupiterUtils_1.getJupPriceData)(mints, false, mayIncludeSpamTokens);
126
+ return Object.values(data).map((x) => x !== null && typeof x === "object" && "price" in x
127
+ ? parseFloat(x.price)
128
+ : 0);
125
129
  }
126
130
  function safeGetPrice(mint) {
127
131
  if (mint && mint?.toString() in solautoConstants_1.PRICES) {
@@ -1 +1 @@
1
- {"version":3,"file":"rebalanceUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/rebalanceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,aAAa,EAEb,kBAAkB,EAClB,yBAAyB,EACzB,SAAS,EACV,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAe,cAAc,EAAgB,MAAM,iBAAiB,CAAC;AAc5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqI9C,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,GAAG,EAAE,WAAW,GAAG,SAAS,EAC5B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,2BAA2B,CAAC,EAAE,MAAM,GACnC,eAAe,CA4EjB;AAoDD,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAkG5C;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,qBAAqB,EACrC,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CA2B9B;AA4CD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,cAAc,CAAC,EAAE,qBAAqB,EACtC,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CA2EzB"}
1
+ {"version":3,"file":"rebalanceUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/rebalanceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,aAAa,EAEb,kBAAkB,EAClB,yBAAyB,EACzB,SAAS,EACV,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAe,cAAc,EAAgB,MAAM,iBAAiB,CAAC;AAc5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqI9C,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,GAAG,EAAE,WAAW,GAAG,SAAS,EAC5B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,2BAA2B,CAAC,EAAE,MAAM,GACnC,eAAe,CA4EjB;AAoDD,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAoG5C;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,qBAAqB,EACrC,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CA2B9B;AA4CD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,cAAc,CAAC,EAAE,qBAAqB,EACtC,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CA4EzB"}
@@ -179,7 +179,9 @@ async function getFlashLoanRequirements(client, values, attemptNum) {
179
179
  signerFlashLoan =
180
180
  sufficientSignerSupplyLiquidity || sufficientSignerDebtLiquidity;
181
181
  if (signerFlashLoan) {
182
- useDebtLiquidity = !sufficientSignerSupplyLiquidity;
182
+ useDebtLiquidity =
183
+ values.rebalanceDirection === generated_1.RebalanceDirection.Boost ||
184
+ !sufficientSignerSupplyLiquidity;
183
185
  }
184
186
  else {
185
187
  throw new Error(`Need at least ${values.debtAdjustmentUsd / debtPrice} ${(0, generalUtils_2.tokenInfo)(client.debtMint).ticker} or ${values.debtAdjustmentUsd / supplyPrice} ${(0, generalUtils_2.tokenInfo)(client.supplyMint).ticker} to perform the transaction`);
@@ -249,7 +251,7 @@ async function getJupSwapRebalanceDetails(client, values, flRequirements, target
249
251
  const usdToSwap = Math.abs(values.debtAdjustmentUsd) +
250
252
  (values.dcaTokenType === generated_1.TokenType.Debt ? values.amountUsdToDcaIn : 0);
251
253
  let inputAmount = (0, numberUtils_1.toBaseUnit)(usdToSwap / (0, priceUtils_1.safeGetPrice)(input.mint), input.decimals);
252
- const outputAmount = rebalanceToZero
254
+ let outputAmount = rebalanceToZero
253
255
  ? output.amountUsed.baseUnit +
254
256
  BigInt(Math.round(Number(output.amountUsed.baseUnit) *
255
257
  // Add this small percentage to account for the APR on the debt between now and the transaction
@@ -260,7 +262,7 @@ async function getJupSwapRebalanceDetails(client, values, flRequirements, target
260
262
  const exactOut = flashLoanRepayFromDebt && !rebalanceToZero;
261
263
  // || rebalanceToZero
262
264
  const exactIn = !exactOut;
263
- if (exactIn && rebalanceToZero) {
265
+ if (exactIn && (rebalanceToZero || values.repayingCloseToMaxLtv)) {
264
266
  inputAmount = inputAmount + BigInt(Math.round(Number(inputAmount) * 0.005));
265
267
  }
266
268
  const jupSwapInput = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.535",
3
+ "version": "1.0.537",
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",
@@ -171,7 +171,7 @@ export async function getJupSwapTransaction(
171
171
  };
172
172
  }
173
173
 
174
- export async function getJupPriceData(mints: PublicKey[], extraInfo?: boolean) {
174
+ export async function getJupPriceData(mints: PublicKey[], extraInfo?: boolean, mayIncludeSpamTokens?: boolean) {
175
175
  const data = await retryWithExponentialBackoff(async () => {
176
176
  const res = await (
177
177
  await fetch(
@@ -185,14 +185,14 @@ export async function getJupPriceData(mints: PublicKey[], extraInfo?: boolean) {
185
185
  throw new Error("Failed to get token prices using Jupiter");
186
186
  }
187
187
 
188
- const invalidValues =
188
+ const invalidValues =
189
189
  Boolean(Object.values(result).filter((x) => x === null).length) ||
190
190
  Boolean(
191
191
  Object.values(result)
192
192
  .map((x) => parseFloat((x as any).price))
193
193
  .filter((x) => x <= 0).length
194
194
  );
195
- if (invalidValues) {
195
+ if (invalidValues && !mayIncludeSpamTokens) {
196
196
  throw new Error("Invalid price values");
197
197
  }
198
198
 
@@ -30,14 +30,18 @@ export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
30
30
  const switchboardMints = mints.filter(
31
31
  (x) => x.toString() in SWITCHBOARD_PRICE_FEED_IDS
32
32
  );
33
+ const otherMints = mints.filter(
34
+ (x) => !pythMints.includes(x) && !switchboardMints.includes(x)
35
+ );
33
36
 
34
- const [pythData, switchboardData] = await Promise.all([
37
+ const [pythData, switchboardData, jupData] = await Promise.all([
35
38
  zip(pythMints, await getPythPrices(pythMints)),
36
39
  zip(switchboardMints, await getSwitchboardPrices(switchboardMints)),
40
+ zip(otherMints, await getJupTokenPrices(otherMints, true)),
37
41
  ]);
38
42
 
39
43
  const prices = mints.map((mint) => {
40
- const item = [...pythData, ...switchboardData].find((data) =>
44
+ const item = [...pythData, ...switchboardData, ...jupData].find((data) =>
41
45
  data[0].equals(mint)
42
46
  );
43
47
  return item ? item[1] : 0;
@@ -115,11 +119,15 @@ export async function getSwitchboardPrices(
115
119
  );
116
120
 
117
121
  const p = res.flatMap((x) => x.results[0]);
118
- if (p.filter((x) => !x || isNaN(Number(x)) || Number(x) < 0).length > 0) {
122
+ if (
123
+ p.filter((x) => !x || isNaN(Number(x)) || Number(x) < 0).length > 0
124
+ ) {
119
125
  throw new Error("Unable to fetch Switchboard prices");
120
126
  }
121
127
 
122
- return p;
128
+ return p.map((x) =>
129
+ typeof x === "string" ? parseFloat(x) : Number(x)
130
+ );
123
131
  },
124
132
  2,
125
133
  350
@@ -133,7 +141,7 @@ export async function getSwitchboardPrices(
133
141
  }
134
142
 
135
143
  const missingPrices = zip(mints, prices).filter(
136
- (x) => !x[1] || isNaN(Number(x))
144
+ (x) => !x[1] || isNaN(Number(x[1]))
137
145
  );
138
146
  const jupPrices = zip(
139
147
  missingPrices.map((x) => x[0]),
@@ -147,14 +155,21 @@ export async function getSwitchboardPrices(
147
155
  return prices;
148
156
  }
149
157
 
150
- export async function getJupTokenPrices(mints: PublicKey[]) {
158
+ export async function getJupTokenPrices(
159
+ mints: PublicKey[],
160
+ mayIncludeSpamTokens?: boolean
161
+ ) {
151
162
  if (mints.length == 0) {
152
163
  return [];
153
164
  }
154
165
 
155
- const data = await getJupPriceData(mints);
166
+ const data = await getJupPriceData(mints, false, mayIncludeSpamTokens);
156
167
 
157
- return Object.values(data).map((x) => parseFloat(x.price as string));
168
+ return Object.values(data).map((x) =>
169
+ x !== null && typeof x === "object" && "price" in x
170
+ ? parseFloat(x.price as string)
171
+ : 0
172
+ );
158
173
  }
159
174
 
160
175
  export function safeGetPrice(
@@ -397,7 +397,9 @@ export async function getFlashLoanRequirements(
397
397
  signerFlashLoan =
398
398
  sufficientSignerSupplyLiquidity || sufficientSignerDebtLiquidity;
399
399
  if (signerFlashLoan) {
400
- useDebtLiquidity = !sufficientSignerSupplyLiquidity;
400
+ useDebtLiquidity =
401
+ values.rebalanceDirection === RebalanceDirection.Boost ||
402
+ !sufficientSignerSupplyLiquidity;
401
403
  } else {
402
404
  throw new Error(
403
405
  `Need at least ${values.debtAdjustmentUsd / debtPrice} ${tokenInfo(client.debtMint).ticker} or ${values.debtAdjustmentUsd / supplyPrice} ${tokenInfo(client.supplyMint).ticker} to perform the transaction`
@@ -525,7 +527,7 @@ export async function getJupSwapRebalanceDetails(
525
527
  usdToSwap / safeGetPrice(input.mint)!,
526
528
  input.decimals
527
529
  );
528
- const outputAmount = rebalanceToZero
530
+ let outputAmount = rebalanceToZero
529
531
  ? output.amountUsed.baseUnit +
530
532
  BigInt(
531
533
  Math.round(
@@ -545,9 +547,10 @@ export async function getJupSwapRebalanceDetails(
545
547
  // || rebalanceToZero
546
548
  const exactIn = !exactOut;
547
549
 
548
- if (exactIn && rebalanceToZero) {
550
+ if (exactIn && (rebalanceToZero || values.repayingCloseToMaxLtv)) {
549
551
  inputAmount = inputAmount + BigInt(Math.round(Number(inputAmount) * 0.005));
550
552
  }
553
+
551
554
  const jupSwapInput: JupSwapInput = {
552
555
  inputMint: toWeb3JsPublicKey(input.mint),
553
556
  outputMint: toWeb3JsPublicKey(output.mint),
@@ -44,12 +44,12 @@ import { PriorityFeeSetting } from "../../src/types";
44
44
  import { buildIronforgeApiUrl, fromBaseUnit, tokenInfo, USD_DECIMALS } from "../../dist";
45
45
 
46
46
  describe("Solauto Marginfi tests", async () => {
47
- const signer = setupTest();
48
- // const signer = setupTest("solauto-manager");
47
+ // const signer = setupTest();
48
+ const signer = setupTest("solauto-manager");
49
49
 
50
- const payForTransactions = false;
51
- const testProgram = true;
52
- const positionId = 1;
50
+ const payForTransactions = true;
51
+ const testProgram = false;
52
+ const positionId = 3;
53
53
 
54
54
  it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => {
55
55
  const client = new SolautoMarginfiClient(
@@ -65,7 +65,7 @@ describe("Solauto Marginfi tests", async () => {
65
65
  await client.initialize({
66
66
  signer,
67
67
  positionId,
68
- // authority: new PublicKey("FKYQs7KgRvaKQHxXwb8HKfoBcFdSxLL3JvHWpPdVQ16v"),
68
+ authority: new PublicKey("FKYQs7KgRvaKQHxXwb8HKfoBcFdSxLL3JvHWpPdVQ16v"),
69
69
  // new: true,
70
70
  // marginfiAccount: new PublicKey(
71
71
  // ""
@@ -145,7 +145,7 @@ describe("Solauto Marginfi tests", async () => {
145
145
  transactionItems.push(
146
146
  new TransactionItem(
147
147
  async (attemptNum) =>
148
- await buildSolautoRebalanceTransaction(client, 2000, attemptNum),
148
+ await buildSolautoRebalanceTransaction(client, undefined, attemptNum),
149
149
  "rebalance"
150
150
  )
151
151
  );