@haven-fi/solauto-sdk 1.0.505 → 1.0.508

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.
@@ -1,17 +1,20 @@
1
1
  import { Signer, TransactionBuilder } from "@metaplex-foundation/umi";
2
2
  import { PublicKey } from "@solana/web3.js";
3
3
  import { QuoteResponse } from "@jup-ag/api";
4
- export interface JupSwapDetails {
4
+ export interface JupSwapInput {
5
5
  inputMint: PublicKey;
6
6
  outputMint: PublicKey;
7
- destinationWallet: PublicKey;
8
7
  amount: bigint;
9
- slippageIncFactor?: number;
10
- exactOut?: boolean;
11
8
  exactIn?: boolean;
9
+ exactOut?: boolean;
10
+ }
11
+ export interface JupSwapDetails extends JupSwapInput {
12
+ destinationWallet: PublicKey;
13
+ slippageIncFactor?: number;
12
14
  addPadding?: boolean;
13
15
  jupQuote?: QuoteResponse;
14
16
  }
17
+ export declare function getJupQuote(swapDetails: JupSwapInput): Promise<QuoteResponse>;
15
18
  export interface JupSwapTransaction {
16
19
  jupQuote: QuoteResponse;
17
20
  priceImpactBps: number;
@@ -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;AAOrB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;IACtB,iBAAiB,EAAE,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAgBD,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,CAwG7B;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO;;GA0B5E"}
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,EAIL,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;;GA0B5E"}
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getJupQuote = getJupQuote;
3
4
  exports.getJupSwapTransaction = getJupSwapTransaction;
4
5
  exports.getJupPriceData = getJupPriceData;
5
6
  const umi_1 = require("@metaplex-foundation/umi");
@@ -9,7 +10,6 @@ const numberUtils_1 = require("./numberUtils");
9
10
  const api_1 = require("@jup-ag/api");
10
11
  const accountUtils_1 = require("./accountUtils");
11
12
  const generalUtils_1 = require("./generalUtils");
12
- const constants_1 = require("../constants");
13
13
  const jupApi = (0, api_1.createJupiterApiClient)();
14
14
  function createTransactionInstruction(instruction) {
15
15
  return new web3_js_1.TransactionInstruction({
@@ -22,22 +22,24 @@ function createTransactionInstruction(instruction) {
22
22
  data: Buffer.from(instruction.data, "base64"),
23
23
  });
24
24
  }
25
+ async function getJupQuote(swapDetails) {
26
+ const memecoinSwap = (0, generalUtils_1.tokenInfo)(swapDetails.inputMint).isMeme ||
27
+ (0, generalUtils_1.tokenInfo)(swapDetails.outputMint).isMeme;
28
+ return await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await jupApi.quoteGet({
29
+ amount: Number(swapDetails.amount),
30
+ inputMint: swapDetails.inputMint.toString(),
31
+ outputMint: swapDetails.outputMint.toString(),
32
+ swapMode: swapDetails.exactIn
33
+ ? "ExactOut"
34
+ : swapDetails.exactIn
35
+ ? "ExactIn"
36
+ : undefined,
37
+ slippageBps: memecoinSwap ? 500 : 200,
38
+ maxAccounts: !swapDetails.exactOut ? 40 : undefined,
39
+ }), 4, 200);
40
+ }
25
41
  async function getJupSwapTransaction(signer, swapDetails, attemptNum) {
26
- const memecoinSwap = constants_1.TOKEN_INFO[swapDetails.inputMint.toString()].isMeme ||
27
- constants_1.TOKEN_INFO[swapDetails.outputMint.toString()].isMeme;
28
- const quoteResponse = swapDetails.jupQuote ??
29
- (await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await jupApi.quoteGet({
30
- amount: Number(swapDetails.amount),
31
- inputMint: swapDetails.inputMint.toString(),
32
- outputMint: swapDetails.outputMint.toString(),
33
- swapMode: swapDetails.exactOut
34
- ? "ExactOut"
35
- : swapDetails.exactIn
36
- ? "ExactIn"
37
- : undefined,
38
- slippageBps: memecoinSwap ? 500 : 200,
39
- maxAccounts: !swapDetails.exactOut ? 40 : undefined,
40
- }), 4, 200));
42
+ const quoteResponse = swapDetails.jupQuote ?? (await getJupQuote(swapDetails));
41
43
  const priceImpactBps = Math.round((0, numberUtils_1.toBps)(parseFloat(quoteResponse.priceImpactPct))) + 1;
42
44
  const finalPriceSlippageBps = Math.round(Math.max(50, quoteResponse.slippageBps, priceImpactBps) *
43
45
  (1 + (swapDetails.slippageIncFactor ?? 0)));
@@ -1,11 +1,12 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
2
  import { PublicKey as UmiPublicKey } from "@metaplex-foundation/umi";
3
+ import { QuoteGetSwapModeEnum } from "@jup-ag/api";
3
4
  export declare function fetchTokenPrices(mints: PublicKey[]): Promise<number[]>;
4
5
  export declare function getPythPrices(mints: PublicKey[]): Promise<number[]>;
5
6
  export declare function getSwitchboardPrices(mints: PublicKey[]): Promise<number[]>;
6
7
  export declare function getJupTokenPrices(mints: PublicKey[]): Promise<number[]>;
7
8
  export declare function safeGetPrice(mint: PublicKey | UmiPublicKey | undefined): number | undefined;
8
- export declare function getPriceImpact(inputMint: PublicKey, inputAmount: bigint, outputMint: PublicKey): Promise<{
9
+ export declare function getPriceImpact(inputMint: PublicKey, outputMint: PublicKey, amount: bigint, swapMode: QuoteGetSwapModeEnum): Promise<{
9
10
  priceImpact: number;
10
11
  quote: import("@jup-ag/api").QuoteResponse;
11
12
  }>;
@@ -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;AAgBrE,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,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,SAAS;;;GAoBtB"}
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;AAcrE,OAAO,EAA0B,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE3E,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"}
@@ -36,7 +36,6 @@ const switchboardConstants_1 = require("../constants/switchboardConstants");
36
36
  const generalUtils_1 = require("./generalUtils");
37
37
  const OnDemand = __importStar(require("@switchboard-xyz/on-demand"));
38
38
  const jupiterUtils_1 = require("./jupiterUtils");
39
- const api_1 = require("@jup-ag/api");
40
39
  async function fetchTokenPrices(mints) {
41
40
  const currentTime = (0, generalUtils_1.currentUnixSeconds)();
42
41
  if (!mints.some((mint) => !(mint.toString() in solautoConstants_1.PRICES) ||
@@ -130,14 +129,14 @@ function safeGetPrice(mint) {
130
129
  }
131
130
  return undefined;
132
131
  }
133
- async function getPriceImpact(inputMint, inputAmount, outputMint) {
134
- const jupApi = (0, api_1.createJupiterApiClient)();
135
- const quoteResponse = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await jupApi.quoteGet({
136
- amount: Number(inputAmount),
137
- inputMint: inputMint.toString(),
138
- outputMint: outputMint.toString(),
139
- swapMode: "ExactIn",
140
- }), 4, 200);
132
+ async function getPriceImpact(inputMint, outputMint, amount, swapMode) {
133
+ const quoteResponse = await (0, jupiterUtils_1.getJupQuote)({
134
+ inputMint,
135
+ outputMint,
136
+ amount,
137
+ exactIn: swapMode === "ExactIn",
138
+ exactOut: swapMode === "ExactOut",
139
+ });
141
140
  return {
142
141
  priceImpact: parseFloat(quoteResponse.priceImpactPct),
143
142
  quote: quoteResponse,
@@ -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,EAAE,MAAM,iBAAiB,CAAC;AAajD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAoI9C,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;CACjB;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,CAwDjB;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe;;;EAsDxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CAgC9B;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CA6EzB"}
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;AAa5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAoI9C,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;CACjB;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,CAwDjB;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe;;;EAsDxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CAgC9B;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CAwFzB"}
@@ -7,6 +7,7 @@ exports.getJupSwapRebalanceDetails = getJupSwapRebalanceDetails;
7
7
  const generated_1 = require("../../generated");
8
8
  const generalUtils_1 = require("./generalUtils");
9
9
  const umi_web3js_adapters_1 = require("@metaplex-foundation/umi-web3js-adapters");
10
+ const jupiterUtils_1 = require("../jupiterUtils");
10
11
  const generalUtils_2 = require("../generalUtils");
11
12
  const numberUtils_1 = require("../numberUtils");
12
13
  const generalAccounts_1 = require("../../constants/generalAccounts");
@@ -165,10 +166,11 @@ async function getJupSwapRebalanceDetails(client, values, targetLiqUtilizationRa
165
166
  const output = values.rebalanceDirection === generated_1.RebalanceDirection.Boost
166
167
  ? client.solautoPositionState.supply
167
168
  : client.solautoPositionState.debt;
169
+ const rebalanceToZero = targetLiqUtilizationRateBps === 0;
168
170
  const usdToSwap = Math.abs(values.debtAdjustmentUsd) +
169
171
  (values.dcaTokenType === generated_1.TokenType.Debt ? values.amountUsdToDcaIn : 0);
170
172
  let inputAmount = (0, numberUtils_1.toBaseUnit)(usdToSwap / (0, priceUtils_1.safeGetPrice)(input.mint), input.decimals);
171
- const outputAmount = targetLiqUtilizationRateBps === 0
173
+ const outputAmount = rebalanceToZero
172
174
  ? output.amountUsed.baseUnit +
173
175
  BigInt(Math.round(Number(output.amountUsed.baseUnit) *
174
176
  // Add this small percentage to account for the APR on the debt between now and the transaction
@@ -177,33 +179,41 @@ async function getJupSwapRebalanceDetails(client, values, targetLiqUtilizationRa
177
179
  const repaying = values.rebalanceDirection === generated_1.RebalanceDirection.Repay;
178
180
  const { requiresFlashLoan, useDebtLiquidity } = rebalanceRequiresFlashLoan(client, values);
179
181
  const flashLoanRepayFromDebt = repaying && requiresFlashLoan && useDebtLiquidity;
180
- const exactOut =
181
- // targetLiqUtilizationRateBps === 0 ||
182
- // values.repayingCloseToMaxLtv ||
183
- flashLoanRepayFromDebt;
182
+ const exactOut = rebalanceToZero || flashLoanRepayFromDebt;
184
183
  const exactIn = !exactOut;
184
+ const jupSwapInput = {
185
+ inputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(input.mint),
186
+ outputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(output.mint),
187
+ exactIn,
188
+ exactOut,
189
+ amount: exactOut ? outputAmount : inputAmount,
190
+ };
185
191
  let jupQuote = undefined;
186
- if (targetLiqUtilizationRateBps === 0) {
187
- let priceImpact = 0;
188
- inputAmount += BigInt(Math.round(Number(inputAmount) * 0.001));
189
- do {
190
- const res = await (0, priceUtils_1.getPriceImpact)((0, umi_web3js_adapters_1.toWeb3JsPublicKey)(input.mint), inputAmount + BigInt(Math.round(Number(inputAmount) * priceImpact)), (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(output.mint));
191
- priceImpact = res.priceImpact;
192
- jupQuote = res.quote;
193
- inputAmount = BigInt(parseInt(res.quote.inAmount)) + BigInt(Math.round(Number(inputAmount) * 0.001));
194
- } while (parseInt(jupQuote.outAmount) < outputAmount && priceImpact > 0.001);
192
+ if (rebalanceToZero) {
193
+ try {
194
+ jupQuote = await (0, jupiterUtils_1.getJupQuote)(jupSwapInput);
195
+ }
196
+ catch {
197
+ let priceImpact = 0;
198
+ inputAmount += BigInt(Math.round(Number(inputAmount) * 0.001));
199
+ do {
200
+ const res = await (0, priceUtils_1.getPriceImpact)((0, umi_web3js_adapters_1.toWeb3JsPublicKey)(input.mint), (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(output.mint), inputAmount + BigInt(Math.round(Number(inputAmount) * priceImpact)), "ExactIn");
201
+ priceImpact = res.priceImpact;
202
+ jupQuote = res.quote;
203
+ inputAmount =
204
+ BigInt(parseInt(res.quote.inAmount)) +
205
+ BigInt(Math.round(Number(inputAmount) * 0.001));
206
+ } while (parseInt(jupQuote.outAmount) < outputAmount &&
207
+ priceImpact > 0.001);
208
+ }
195
209
  }
196
210
  const addPadding = exactOut;
197
211
  return {
198
- inputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(input.mint),
199
- outputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(output.mint),
212
+ ...jupSwapInput,
200
213
  destinationWallet: flashLoanRepayFromDebt
201
214
  ? (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(client.signer.publicKey)
202
215
  : client.solautoPosition,
203
216
  slippageIncFactor: 0.2 + (attemptNum ?? 0) * 0.25,
204
- amount: exactOut ? outputAmount : inputAmount,
205
- exactIn,
206
- exactOut,
207
217
  addPadding,
208
218
  jupQuote,
209
219
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.505",
3
+ "version": "1.0.508",
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",
@@ -9,22 +9,29 @@ import { fromBps, toBps } from "./numberUtils";
9
9
  import {
10
10
  createJupiterApiClient,
11
11
  Instruction,
12
+ QuoteGetSwapModeEnum,
12
13
  QuoteResponse,
13
14
  } from "@jup-ag/api";
14
15
  import { getTokenAccount } from "./accountUtils";
15
- import { consoleLog, retryWithExponentialBackoff } from "./generalUtils";
16
- import { TOKEN_INFO } from "../constants";
16
+ import {
17
+ consoleLog,
18
+ retryWithExponentialBackoff,
19
+ tokenInfo,
20
+ } from "./generalUtils";
17
21
 
18
22
  const jupApi = createJupiterApiClient();
19
23
 
20
- export interface JupSwapDetails {
24
+ export interface JupSwapInput {
21
25
  inputMint: PublicKey;
22
26
  outputMint: PublicKey;
23
- destinationWallet: PublicKey;
24
27
  amount: bigint;
25
- slippageIncFactor?: number;
26
- exactOut?: boolean;
27
28
  exactIn?: boolean;
29
+ exactOut?: boolean;
30
+ }
31
+
32
+ export interface JupSwapDetails extends JupSwapInput {
33
+ destinationWallet: PublicKey;
34
+ slippageIncFactor?: number;
28
35
  addPadding?: boolean;
29
36
  jupQuote?: QuoteResponse;
30
37
  }
@@ -43,6 +50,30 @@ function createTransactionInstruction(
43
50
  });
44
51
  }
45
52
 
53
+ export async function getJupQuote(swapDetails: JupSwapInput) {
54
+ const memecoinSwap =
55
+ tokenInfo(swapDetails.inputMint).isMeme ||
56
+ tokenInfo(swapDetails.outputMint).isMeme;
57
+
58
+ return await retryWithExponentialBackoff(
59
+ async () =>
60
+ await jupApi.quoteGet({
61
+ amount: Number(swapDetails.amount),
62
+ inputMint: swapDetails.inputMint.toString(),
63
+ outputMint: swapDetails.outputMint.toString(),
64
+ swapMode: swapDetails.exactIn
65
+ ? "ExactOut"
66
+ : swapDetails.exactIn
67
+ ? "ExactIn"
68
+ : undefined,
69
+ slippageBps: memecoinSwap ? 500 : 200,
70
+ maxAccounts: !swapDetails.exactOut ? 40 : undefined,
71
+ }),
72
+ 4,
73
+ 200
74
+ );
75
+ }
76
+
46
77
  export interface JupSwapTransaction {
47
78
  jupQuote: QuoteResponse;
48
79
  priceImpactBps: number;
@@ -57,29 +88,8 @@ export async function getJupSwapTransaction(
57
88
  swapDetails: JupSwapDetails,
58
89
  attemptNum?: number
59
90
  ): Promise<JupSwapTransaction> {
60
- const memecoinSwap =
61
- TOKEN_INFO[swapDetails.inputMint.toString()].isMeme ||
62
- TOKEN_INFO[swapDetails.outputMint.toString()].isMeme;
63
-
64
91
  const quoteResponse =
65
- swapDetails.jupQuote ??
66
- (await retryWithExponentialBackoff(
67
- async () =>
68
- await jupApi.quoteGet({
69
- amount: Number(swapDetails.amount),
70
- inputMint: swapDetails.inputMint.toString(),
71
- outputMint: swapDetails.outputMint.toString(),
72
- swapMode: swapDetails.exactOut
73
- ? "ExactOut"
74
- : swapDetails.exactIn
75
- ? "ExactIn"
76
- : undefined,
77
- slippageBps: memecoinSwap ? 500 : 200,
78
- maxAccounts: !swapDetails.exactOut ? 40 : undefined,
79
- }),
80
- 4,
81
- 200
82
- ));
92
+ swapDetails.jupQuote ?? (await getJupQuote(swapDetails));
83
93
 
84
94
  const priceImpactBps =
85
95
  Math.round(toBps(parseFloat(quoteResponse.priceImpactPct))) + 1;
@@ -12,8 +12,8 @@ import {
12
12
  zip,
13
13
  } from "./generalUtils";
14
14
  import * as OnDemand from "@switchboard-xyz/on-demand";
15
- import { getJupPriceData } from "./jupiterUtils";
16
- import { createJupiterApiClient } from "@jup-ag/api";
15
+ import { getJupPriceData, getJupQuote } from "./jupiterUtils";
16
+ import { createJupiterApiClient, QuoteGetSwapModeEnum } from "@jup-ag/api";
17
17
 
18
18
  export async function fetchTokenPrices(mints: PublicKey[]): Promise<number[]> {
19
19
  const currentTime = currentUnixSeconds();
@@ -169,22 +169,17 @@ export function safeGetPrice(
169
169
 
170
170
  export async function getPriceImpact(
171
171
  inputMint: PublicKey,
172
- inputAmount: bigint,
173
- outputMint: PublicKey
172
+ outputMint: PublicKey,
173
+ amount: bigint,
174
+ swapMode: QuoteGetSwapModeEnum
174
175
  ) {
175
- const jupApi = createJupiterApiClient();
176
-
177
- const quoteResponse = await retryWithExponentialBackoff(
178
- async () =>
179
- await jupApi.quoteGet({
180
- amount: Number(inputAmount),
181
- inputMint: inputMint.toString(),
182
- outputMint: outputMint.toString(),
183
- swapMode: "ExactIn",
184
- }),
185
- 4,
186
- 200
187
- );
176
+ const quoteResponse = await getJupQuote({
177
+ inputMint,
178
+ outputMint,
179
+ amount,
180
+ exactIn: swapMode === "ExactIn",
181
+ exactOut: swapMode === "ExactOut",
182
+ });
188
183
 
189
184
  return {
190
185
  priceImpact: parseFloat(quoteResponse.priceImpactPct),
@@ -15,7 +15,7 @@ import {
15
15
  } from "./generalUtils";
16
16
  import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
17
17
  import { QuoteResponse } from "@jup-ag/api";
18
- import { JupSwapDetails } from "../jupiterUtils";
18
+ import { getJupQuote, JupSwapDetails, JupSwapInput } from "../jupiterUtils";
19
19
  import { consoleLog, currentUnixSeconds } from "../generalUtils";
20
20
  import {
21
21
  fromBaseUnit,
@@ -354,6 +354,7 @@ export async function getJupSwapRebalanceDetails(
354
354
  ? client.solautoPositionState!.supply
355
355
  : client.solautoPositionState!.debt;
356
356
 
357
+ const rebalanceToZero = targetLiqUtilizationRateBps === 0;
357
358
  const usdToSwap =
358
359
  Math.abs(values.debtAdjustmentUsd) +
359
360
  (values.dcaTokenType === TokenType.Debt ? values.amountUsdToDcaIn : 0);
@@ -362,17 +363,16 @@ export async function getJupSwapRebalanceDetails(
362
363
  usdToSwap / safeGetPrice(input.mint)!,
363
364
  input.decimals
364
365
  );
365
- const outputAmount =
366
- targetLiqUtilizationRateBps === 0
367
- ? output.amountUsed.baseUnit +
368
- BigInt(
369
- Math.round(
370
- Number(output.amountUsed.baseUnit) *
371
- // Add this small percentage to account for the APR on the debt between now and the transaction
372
- 0.0001
373
- )
366
+ const outputAmount = rebalanceToZero
367
+ ? output.amountUsed.baseUnit +
368
+ BigInt(
369
+ Math.round(
370
+ Number(output.amountUsed.baseUnit) *
371
+ // Add this small percentage to account for the APR on the debt between now and the transaction
372
+ 0.0001
374
373
  )
375
- : toBaseUnit(usdToSwap / safeGetPrice(output.mint)!, output.decimals);
374
+ )
375
+ : toBaseUnit(usdToSwap / safeGetPrice(output.mint)!, output.decimals);
376
376
 
377
377
  const repaying = values.rebalanceDirection === RebalanceDirection.Repay;
378
378
 
@@ -383,41 +383,52 @@ export async function getJupSwapRebalanceDetails(
383
383
  const flashLoanRepayFromDebt =
384
384
  repaying && requiresFlashLoan && useDebtLiquidity;
385
385
 
386
- const exactOut =
387
- // targetLiqUtilizationRateBps === 0 ||
388
- // values.repayingCloseToMaxLtv ||
389
- flashLoanRepayFromDebt;
386
+ const exactOut = rebalanceToZero || flashLoanRepayFromDebt;
390
387
  const exactIn = !exactOut;
391
388
 
389
+ const jupSwapInput: JupSwapInput = {
390
+ inputMint: toWeb3JsPublicKey(input.mint),
391
+ outputMint: toWeb3JsPublicKey(output.mint),
392
+ exactIn,
393
+ exactOut,
394
+ amount: exactOut ? outputAmount : inputAmount,
395
+ };
396
+
392
397
  let jupQuote: QuoteResponse | undefined = undefined;
393
- if (targetLiqUtilizationRateBps === 0) {
394
- let priceImpact: number = 0;
395
- inputAmount += BigInt(Math.round(Number(inputAmount) * 0.001));
396
-
397
- do {
398
- const res = await getPriceImpact(
399
- toWeb3JsPublicKey(input.mint),
400
- inputAmount + BigInt(Math.round(Number(inputAmount) * priceImpact)),
401
- toWeb3JsPublicKey(output.mint)
398
+ if (rebalanceToZero) {
399
+ try {
400
+ jupQuote = await getJupQuote(jupSwapInput);
401
+ } catch {
402
+ let priceImpact: number = 0;
403
+ inputAmount += BigInt(Math.round(Number(inputAmount) * 0.001));
404
+
405
+ do {
406
+ const res = await getPriceImpact(
407
+ toWeb3JsPublicKey(input.mint),
408
+ toWeb3JsPublicKey(output.mint),
409
+ inputAmount + BigInt(Math.round(Number(inputAmount) * priceImpact)),
410
+ "ExactIn"
411
+ );
412
+ priceImpact = res.priceImpact;
413
+ jupQuote = res.quote;
414
+ inputAmount =
415
+ BigInt(parseInt(res.quote.inAmount)) +
416
+ BigInt(Math.round(Number(inputAmount) * 0.001));
417
+ } while (
418
+ parseInt(jupQuote.outAmount) < outputAmount &&
419
+ priceImpact > 0.001
402
420
  );
403
- priceImpact = res.priceImpact;
404
- jupQuote = res.quote;
405
- inputAmount = BigInt(parseInt(res.quote.inAmount)) + BigInt(Math.round(Number(inputAmount) * 0.001));
406
- } while (parseInt(jupQuote.outAmount) < outputAmount && priceImpact > 0.001);
421
+ }
407
422
  }
408
423
 
409
424
  const addPadding = exactOut;
410
425
 
411
426
  return {
412
- inputMint: toWeb3JsPublicKey(input.mint),
413
- outputMint: toWeb3JsPublicKey(output.mint),
427
+ ...jupSwapInput,
414
428
  destinationWallet: flashLoanRepayFromDebt
415
429
  ? toWeb3JsPublicKey(client.signer.publicKey)
416
430
  : client.solautoPosition,
417
431
  slippageIncFactor: 0.2 + (attemptNum ?? 0) * 0.25,
418
- amount: exactOut ? outputAmount : inputAmount,
419
- exactIn,
420
- exactOut,
421
432
  addPadding,
422
433
  jupQuote,
423
434
  };
@@ -21,15 +21,12 @@ import {
21
21
  } from "../../src/transactions/transactionsManager";
22
22
  import { PublicKey } from "@solana/web3.js";
23
23
  import {
24
- INF,
25
24
  SOLAUTO_PROD_PROGRAM,
26
25
  SOLAUTO_TEST_PROGRAM,
27
26
  USDC,
28
27
  } from "../../src/constants";
29
28
  import {
30
29
  buildHeliusApiUrl,
31
- fetchTokenPrices,
32
- getJupPriceData,
33
30
  getQnComputeUnitPriceEstimate,
34
31
  getSolautoManagedPositions,
35
32
  } from "../../src/utils";
@@ -56,23 +53,18 @@ describe("Solauto Marginfi tests", async () => {
56
53
  const supplyDecimals = 6;
57
54
  const debtDecimals = 6;
58
55
 
59
- // await client.initialize({
60
- // signer,
61
- // positionId,
62
- // authority: new PublicKey("He4ka5Q3N1UvZikZvykdi47xyk5PoVP2tcQL5sVp31Sz"),
63
- // // new: true,
64
- // // marginfiAccount: new PublicKey(
65
- // // ""
66
- // // ),
67
- // // marginfiGroup: new PublicKey(""),
68
- // // supplyMint: new PublicKey(""),
69
- // // debtMint: new PublicKey(USDC),
70
- // });
71
-
72
- console.log(
73
- JSON.stringify(await getJupPriceData([new PublicKey(INF)], true), null, 2)
74
- );
75
- return;
56
+ await client.initialize({
57
+ signer,
58
+ positionId,
59
+ authority: new PublicKey("He4ka5Q3N1UvZikZvykdi47xyk5PoVP2tcQL5sVp31Sz"),
60
+ // new: true,
61
+ // marginfiAccount: new PublicKey(
62
+ // ""
63
+ // ),
64
+ // marginfiGroup: new PublicKey(""),
65
+ // supplyMint: new PublicKey(""),
66
+ // debtMint: new PublicKey(USDC),
67
+ });
76
68
 
77
69
  // console.log(
78
70
  // JSON.stringify(