@haven-fi/solauto-sdk 1.0.582 → 1.0.584

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/dist/constants/solautoConstants.d.ts +1 -0
  2. package/dist/constants/solautoConstants.d.ts.map +1 -1
  3. package/dist/constants/solautoConstants.js +4 -10
  4. package/dist/generated/accounts/solautoPosition.js +2 -2
  5. package/dist/generated/errors/solauto.d.ts +14 -2
  6. package/dist/generated/errors/solauto.d.ts.map +1 -1
  7. package/dist/generated/errors/solauto.js +27 -5
  8. package/dist/generated/instructions/claimReferralFees.d.ts +1 -1
  9. package/dist/generated/instructions/claimReferralFees.d.ts.map +1 -1
  10. package/dist/generated/instructions/closePosition.d.ts +1 -1
  11. package/dist/generated/instructions/closePosition.d.ts.map +1 -1
  12. package/dist/generated/instructions/closePosition.js +2 -2
  13. package/dist/generated/instructions/marginfiOpenPosition.d.ts +1 -3
  14. package/dist/generated/instructions/marginfiOpenPosition.d.ts.map +1 -1
  15. package/dist/generated/instructions/marginfiOpenPosition.js +0 -1
  16. package/dist/generated/instructions/marginfiRebalance.d.ts +7 -3
  17. package/dist/generated/instructions/marginfiRebalance.d.ts.map +1 -1
  18. package/dist/generated/instructions/marginfiRebalance.js +3 -1
  19. package/dist/generated/types/index.d.ts +7 -1
  20. package/dist/generated/types/index.d.ts.map +1 -1
  21. package/dist/generated/types/index.js +7 -1
  22. package/dist/generated/types/positionData.d.ts +2 -2
  23. package/dist/generated/types/positionData.d.ts.map +1 -1
  24. package/dist/generated/types/positionData.js +1 -1
  25. package/dist/generated/types/positionState.d.ts +7 -7
  26. package/dist/generated/types/positionState.d.ts.map +1 -1
  27. package/dist/generated/types/positionState.js +3 -3
  28. package/dist/generated/types/{positionTokenUsage.d.ts → positionTokenState.d.ts} +6 -8
  29. package/dist/generated/types/positionTokenState.d.ts.map +1 -0
  30. package/dist/generated/types/{positionTokenUsage.js → positionTokenState.js} +6 -7
  31. package/dist/generated/types/rebalanceData.d.ts +7 -13
  32. package/dist/generated/types/rebalanceData.d.ts.map +1 -1
  33. package/dist/generated/types/rebalanceData.js +3 -6
  34. package/dist/generated/types/rebalanceDirection.d.ts +3 -2
  35. package/dist/generated/types/rebalanceDirection.d.ts.map +1 -1
  36. package/dist/generated/types/rebalanceDirection.js +3 -2
  37. package/dist/generated/types/rebalanceInstructionData.d.ts +27 -0
  38. package/dist/generated/types/rebalanceInstructionData.d.ts.map +1 -0
  39. package/dist/generated/types/rebalanceInstructionData.js +22 -0
  40. package/dist/generated/types/rebalanceStateValues.d.ts +27 -0
  41. package/dist/generated/types/rebalanceStateValues.d.ts.map +1 -0
  42. package/dist/generated/types/rebalanceStateValues.js +22 -0
  43. package/dist/generated/types/rebalanceStep.d.ts +15 -0
  44. package/dist/generated/types/rebalanceStep.d.ts.map +1 -0
  45. package/dist/generated/types/rebalanceStep.js +22 -0
  46. package/dist/generated/types/solautoRebalanceType.d.ts +4 -5
  47. package/dist/generated/types/solautoRebalanceType.d.ts.map +1 -1
  48. package/dist/generated/types/solautoRebalanceType.js +4 -5
  49. package/dist/generated/types/solautoSettingsParameters.d.ts +2 -15
  50. package/dist/generated/types/solautoSettingsParameters.d.ts.map +1 -1
  51. package/dist/generated/types/solautoSettingsParameters.js +1 -5
  52. package/dist/generated/types/solautoSettingsParametersInp.d.ts +1 -12
  53. package/dist/generated/types/solautoSettingsParametersInp.d.ts.map +1 -1
  54. package/dist/generated/types/solautoSettingsParametersInp.js +0 -3
  55. package/dist/generated/types/swapType.d.ts +15 -0
  56. package/dist/generated/types/swapType.d.ts.map +1 -0
  57. package/dist/generated/types/swapType.js +22 -0
  58. package/dist/generated/types/tokenBalanceChange.d.ts +21 -0
  59. package/dist/generated/types/tokenBalanceChange.d.ts.map +1 -0
  60. package/dist/generated/types/tokenBalanceChange.js +19 -0
  61. package/dist/generated/types/tokenBalanceChangeType.d.ts +18 -0
  62. package/dist/generated/types/tokenBalanceChangeType.d.ts.map +1 -0
  63. package/dist/generated/types/tokenBalanceChangeType.js +25 -0
  64. package/dist/generated/types/updatePositionData.d.ts +2 -2
  65. package/dist/generated/types/updatePositionData.d.ts.map +1 -1
  66. package/dist/generated/types/updatePositionData.js +1 -1
  67. package/dist/index.d.ts +8 -6
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +5 -5
  70. package/dist/marginfi-sdk/types/interestRateConfig.d.ts +3 -1
  71. package/dist/marginfi-sdk/types/interestRateConfig.d.ts.map +1 -1
  72. package/dist/marginfi-sdk/types/interestRateConfig.js +2 -1
  73. package/dist/services/flashLoans/flProviderAggregator.d.ts +19 -0
  74. package/dist/services/flashLoans/flProviderAggregator.d.ts.map +1 -0
  75. package/dist/services/flashLoans/flProviderAggregator.js +46 -0
  76. package/dist/services/flashLoans/flProviderBase.d.ts +23 -0
  77. package/dist/services/flashLoans/flProviderBase.d.ts.map +1 -0
  78. package/dist/services/flashLoans/flProviderBase.js +37 -0
  79. package/dist/services/flashLoans/index.d.ts +4 -0
  80. package/dist/services/flashLoans/index.d.ts.map +1 -0
  81. package/dist/services/flashLoans/index.js +19 -0
  82. package/dist/services/flashLoans/marginfiFlProvider.d.ts +25 -0
  83. package/dist/services/flashLoans/marginfiFlProvider.d.ts.map +1 -0
  84. package/dist/services/flashLoans/marginfiFlProvider.js +246 -0
  85. package/dist/services/index.d.ts +6 -0
  86. package/dist/services/index.d.ts.map +1 -0
  87. package/dist/services/index.js +21 -0
  88. package/dist/services/rebalance/index.d.ts +3 -0
  89. package/dist/services/rebalance/index.d.ts.map +1 -0
  90. package/dist/services/rebalance/index.js +18 -0
  91. package/dist/services/rebalance/rebalanceSwapManager.d.ts +30 -0
  92. package/dist/services/rebalance/rebalanceSwapManager.d.ts.map +1 -0
  93. package/dist/services/rebalance/rebalanceSwapManager.js +144 -0
  94. package/dist/services/rebalance/rebalanceTxBuilder.d.ts +22 -0
  95. package/dist/services/rebalance/rebalanceTxBuilder.d.ts.map +1 -0
  96. package/dist/services/rebalance/rebalanceTxBuilder.js +200 -0
  97. package/dist/services/rebalance/rebalanceValues.d.ts +31 -0
  98. package/dist/services/rebalance/rebalanceValues.d.ts.map +1 -0
  99. package/dist/services/rebalance/rebalanceValues.js +118 -0
  100. package/dist/services/rebalance/solautoFees.d.ts +13 -0
  101. package/dist/services/rebalance/solautoFees.d.ts.map +1 -0
  102. package/dist/services/rebalance/solautoFees.js +54 -0
  103. package/dist/services/solauto/index.d.ts +5 -0
  104. package/dist/services/solauto/index.d.ts.map +1 -0
  105. package/dist/{clients → services/solauto}/referralStateManager.d.ts +4 -5
  106. package/dist/services/solauto/referralStateManager.d.ts.map +1 -0
  107. package/dist/{clients → services/solauto}/referralStateManager.js +10 -12
  108. package/dist/services/solauto/solautoClient.d.ts +59 -0
  109. package/dist/services/solauto/solautoClient.d.ts.map +1 -0
  110. package/dist/{clients → services/solauto}/solautoClient.js +78 -109
  111. package/dist/services/solauto/solautoMarginfiClient.d.ts +34 -0
  112. package/dist/services/solauto/solautoMarginfiClient.d.ts.map +1 -0
  113. package/dist/services/solauto/solautoMarginfiClient.js +322 -0
  114. package/dist/{clients → services/solauto}/txHandler.d.ts +11 -2
  115. package/dist/services/solauto/txHandler.d.ts.map +1 -0
  116. package/dist/services/solauto/txHandler.js +38 -0
  117. package/dist/services/swap/index.d.ts +2 -0
  118. package/dist/services/swap/index.d.ts.map +1 -0
  119. package/dist/{utils/solauto → services/swap}/index.js +1 -2
  120. package/dist/services/swap/jupSwapManager.d.ts +37 -0
  121. package/dist/services/swap/jupSwapManager.d.ts.map +1 -0
  122. package/dist/services/swap/jupSwapManager.js +108 -0
  123. package/dist/services/transactions/index.d.ts.map +1 -0
  124. package/dist/{transactions → services/transactions}/transactionUtils.d.ts +3 -5
  125. package/dist/services/transactions/transactionUtils.d.ts.map +1 -0
  126. package/dist/{transactions → services/transactions}/transactionUtils.js +29 -137
  127. package/dist/{transactions → services/transactions}/transactionsManager.d.ts +4 -4
  128. package/dist/services/transactions/transactionsManager.d.ts.map +1 -0
  129. package/dist/{transactions → services/transactions}/transactionsManager.js +10 -8
  130. package/dist/solautoPosition/index.d.ts +4 -0
  131. package/dist/solautoPosition/index.d.ts.map +1 -0
  132. package/dist/solautoPosition/index.js +19 -0
  133. package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts +14 -0
  134. package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts.map +1 -0
  135. package/dist/solautoPosition/marginfiSolautoPositionEx.js +73 -0
  136. package/dist/solautoPosition/solautoPositionEx.d.ts +67 -0
  137. package/dist/solautoPosition/solautoPositionEx.d.ts.map +1 -0
  138. package/dist/solautoPosition/solautoPositionEx.js +143 -0
  139. package/dist/solautoPosition/utils.d.ts +17 -0
  140. package/dist/solautoPosition/utils.d.ts.map +1 -0
  141. package/dist/solautoPosition/utils.js +115 -0
  142. package/dist/types/solauto.d.ts +19 -1
  143. package/dist/types/solauto.d.ts.map +1 -1
  144. package/dist/utils/generalUtils.d.ts +1 -0
  145. package/dist/utils/generalUtils.d.ts.map +1 -1
  146. package/dist/utils/generalUtils.js +9 -1
  147. package/dist/utils/index.d.ts +1 -1
  148. package/dist/utils/index.d.ts.map +1 -1
  149. package/dist/utils/index.js +1 -1
  150. package/dist/utils/jitoUtils.d.ts.map +1 -1
  151. package/dist/utils/jupiterUtils.d.ts +3 -28
  152. package/dist/utils/jupiterUtils.d.ts.map +1 -1
  153. package/dist/utils/jupiterUtils.js +2 -73
  154. package/dist/utils/marginfiUtils.d.ts +4 -3
  155. package/dist/utils/marginfiUtils.d.ts.map +1 -1
  156. package/dist/utils/marginfiUtils.js +47 -18
  157. package/dist/utils/numberUtils.d.ts +3 -6
  158. package/dist/utils/numberUtils.d.ts.map +1 -1
  159. package/dist/utils/numberUtils.js +13 -48
  160. package/dist/utils/solanaUtils.js +2 -2
  161. package/dist/utils/{solauto/generalUtils.d.ts → solautoUtils.d.ts} +9 -16
  162. package/dist/utils/solautoUtils.d.ts.map +1 -0
  163. package/dist/utils/{solauto/generalUtils.js → solautoUtils.js} +49 -173
  164. package/local/createTokenAccounts.ts +1 -5
  165. package/local/logPositions.ts +22 -68
  166. package/local/shared.ts +29 -24
  167. package/local/txSandbox.ts +66 -0
  168. package/local/updateMarginfiLUT.ts +80 -4
  169. package/package.json +3 -6
  170. package/src/constants/solautoConstants.ts +4 -9
  171. package/src/generated/accounts/solautoPosition.ts +2 -2
  172. package/src/generated/errors/solauto.ts +45 -4
  173. package/src/generated/instructions/claimReferralFees.ts +1 -1
  174. package/src/generated/instructions/closePosition.ts +3 -3
  175. package/src/generated/instructions/marginfiOpenPosition.ts +0 -7
  176. package/src/generated/instructions/marginfiRebalance.ts +12 -3
  177. package/src/generated/types/index.ts +7 -1
  178. package/src/generated/types/positionData.ts +3 -3
  179. package/src/generated/types/positionState.ts +12 -12
  180. package/src/generated/types/{positionTokenUsage.ts → positionTokenState.ts} +13 -16
  181. package/src/generated/types/rebalanceData.ts +16 -27
  182. package/src/generated/types/rebalanceDirection.ts +1 -0
  183. package/src/generated/types/rebalanceInstructionData.ts +62 -0
  184. package/src/generated/types/rebalanceStateValues.ts +59 -0
  185. package/src/generated/types/rebalanceStep.ts +25 -0
  186. package/src/generated/types/solautoRebalanceType.ts +0 -1
  187. package/src/generated/types/solautoSettingsParameters.ts +4 -25
  188. package/src/generated/types/solautoSettingsParametersInp.ts +2 -24
  189. package/src/generated/types/swapType.ts +22 -0
  190. package/src/generated/types/tokenBalanceChange.ts +46 -0
  191. package/src/generated/types/tokenBalanceChangeType.ts +28 -0
  192. package/src/generated/types/updatePositionData.ts +3 -3
  193. package/src/index.ts +8 -8
  194. package/src/marginfi-sdk/types/interestRateConfig.ts +6 -2
  195. package/src/services/flashLoans/flProviderAggregator.ts +74 -0
  196. package/src/services/flashLoans/flProviderBase.ts +88 -0
  197. package/src/services/flashLoans/index.ts +3 -0
  198. package/src/services/flashLoans/marginfiFlProvider.ts +392 -0
  199. package/src/services/index.ts +5 -0
  200. package/src/services/rebalance/index.ts +2 -0
  201. package/src/services/rebalance/rebalanceSwapManager.ts +218 -0
  202. package/src/services/rebalance/rebalanceTxBuilder.ts +330 -0
  203. package/src/services/rebalance/rebalanceValues.ts +232 -0
  204. package/src/services/rebalance/solautoFees.ts +61 -0
  205. package/src/services/solauto/index.ts +4 -0
  206. package/src/{clients → services/solauto}/referralStateManager.ts +17 -31
  207. package/src/{clients → services/solauto}/solautoClient.ts +142 -205
  208. package/src/services/solauto/solautoMarginfiClient.ts +472 -0
  209. package/src/services/solauto/txHandler.ts +69 -0
  210. package/src/services/swap/index.ts +1 -0
  211. package/src/services/swap/jupSwapManager.ts +189 -0
  212. package/src/{transactions → services/transactions}/transactionUtils.ts +40 -280
  213. package/src/{transactions → services/transactions}/transactionsManager.ts +15 -10
  214. package/src/solautoPosition/index.ts +3 -0
  215. package/src/solautoPosition/marginfiSolautoPositionEx.ts +111 -0
  216. package/src/solautoPosition/solautoPositionEx.ts +281 -0
  217. package/src/solautoPosition/utils.ts +188 -0
  218. package/src/types/solauto.ts +30 -2
  219. package/src/utils/generalUtils.ts +9 -1
  220. package/src/utils/index.ts +2 -2
  221. package/src/utils/jitoUtils.ts +0 -4
  222. package/src/utils/jupiterUtils.ts +3 -164
  223. package/src/utils/marginfiUtils.ts +77 -43
  224. package/src/utils/numberUtils.ts +18 -77
  225. package/src/utils/solanaUtils.ts +1 -1
  226. package/src/utils/{solauto/generalUtils.ts → solautoUtils.ts} +67 -288
  227. package/tests/transactions/shared.ts +135 -0
  228. package/tests/transactions/solautoMarginfi.ts +8 -198
  229. package/tests/unit/accounts.ts +3 -10
  230. package/tests/unit/lookupTables.ts +23 -2
  231. package/tests/unit/rebalanceCalculations.ts +65 -343
  232. package/dist/clients/index.d.ts +0 -5
  233. package/dist/clients/index.d.ts.map +0 -1
  234. package/dist/clients/referralStateManager.d.ts.map +0 -1
  235. package/dist/clients/solautoClient.d.ts +0 -71
  236. package/dist/clients/solautoClient.d.ts.map +0 -1
  237. package/dist/clients/solautoMarginfiClient.d.ts +0 -51
  238. package/dist/clients/solautoMarginfiClient.d.ts.map +0 -1
  239. package/dist/clients/solautoMarginfiClient.js +0 -497
  240. package/dist/clients/txHandler.d.ts.map +0 -1
  241. package/dist/clients/txHandler.js +0 -23
  242. package/dist/generated/types/positionTokenUsage.d.ts.map +0 -1
  243. package/dist/transactions/index.d.ts.map +0 -1
  244. package/dist/transactions/transactionUtils.d.ts.map +0 -1
  245. package/dist/transactions/transactionsManager.d.ts.map +0 -1
  246. package/dist/utils/solauto/generalUtils.d.ts.map +0 -1
  247. package/dist/utils/solauto/index.d.ts +0 -3
  248. package/dist/utils/solauto/index.d.ts.map +0 -1
  249. package/dist/utils/solauto/rebalanceUtils.d.ts +0 -30
  250. package/dist/utils/solauto/rebalanceUtils.d.ts.map +0 -1
  251. package/dist/utils/solauto/rebalanceUtils.js +0 -287
  252. package/src/clients/index.ts +0 -4
  253. package/src/clients/solautoMarginfiClient.ts +0 -774
  254. package/src/clients/txHandler.ts +0 -38
  255. package/src/utils/solauto/index.ts +0 -2
  256. package/src/utils/solauto/rebalanceUtils.ts +0 -562
  257. package/dist/{clients → services/solauto}/index.js +2 -2
  258. /package/dist/{transactions → services/transactions}/index.d.ts +0 -0
  259. /package/dist/{transactions → services/transactions}/index.js +0 -0
  260. /package/src/{transactions → services/transactions}/index.ts +0 -0
@@ -0,0 +1,88 @@
1
+ import {
2
+ Signer,
3
+ transactionBuilder,
4
+ TransactionBuilder,
5
+ Umi,
6
+ } from "@metaplex-foundation/umi";
7
+ import { PublicKey } from "@solana/web3.js";
8
+ import {
9
+ fromBaseUnit,
10
+ getTokenAccount,
11
+ safeGetPrice,
12
+ splTokenTransferUmiIx,
13
+ tokenInfo,
14
+ } from "../../utils";
15
+ import { TokenType } from "../../generated";
16
+ import { FlashLoanDetails } from "../../types";
17
+ import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
18
+
19
+ export abstract class FlProviderBase {
20
+ protected flSigners: Signer[] = [];
21
+
22
+ constructor(
23
+ protected umi: Umi,
24
+ protected signer: Signer,
25
+ protected supplyMint: PublicKey,
26
+ protected debtMint: PublicKey
27
+ ) {}
28
+
29
+ abstract initialize(): Promise<void>;
30
+
31
+ lutAccountsToAdd(): PublicKey[] {
32
+ return [];
33
+ }
34
+
35
+ otherSigners(): Signer[] {
36
+ return this.flSigners;
37
+ }
38
+
39
+ mint(source: TokenType) {
40
+ return source === TokenType.Supply ? this.supplyMint : this.debtMint;
41
+ }
42
+
43
+ abstract liquidityAvailable(source: TokenType): bigint;
44
+ liquidityAvailableUsd(source: TokenType): number {
45
+ return (
46
+ fromBaseUnit(
47
+ this.liquidityAvailable(source),
48
+ tokenInfo(this.mint(source)).decimals
49
+ ) * (safeGetPrice(this.mint(source)) ?? 0)
50
+ );
51
+ }
52
+
53
+ abstract flFeeBps(source: TokenType, signerFlashLoan?: boolean): number;
54
+ abstract flashBorrow(
55
+ flashLoan: FlashLoanDetails,
56
+ destTokenAccount: PublicKey
57
+ ): TransactionBuilder;
58
+ abstract flashRepay(flashLoan: FlashLoanDetails): TransactionBuilder;
59
+
60
+ protected signerFlashBorrow(
61
+ flashLoan: FlashLoanDetails,
62
+ destTokenAccount: PublicKey
63
+ ): TransactionBuilder {
64
+ if (
65
+ !destTokenAccount.equals(
66
+ getTokenAccount(
67
+ toWeb3JsPublicKey(this.signer.publicKey),
68
+ flashLoan.mint
69
+ )
70
+ )
71
+ ) {
72
+ return transactionBuilder().add(
73
+ splTokenTransferUmiIx(
74
+ this.signer,
75
+ getTokenAccount(
76
+ toWeb3JsPublicKey(this.signer.publicKey),
77
+ flashLoan.mint
78
+ ),
79
+ destTokenAccount,
80
+ toWeb3JsPublicKey(this.signer.publicKey),
81
+ flashLoan.baseUnitAmount
82
+ )
83
+ );
84
+ } else {
85
+ return transactionBuilder();
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./flProviderAggregator";
2
+ export * from "./flProviderBase";
3
+ export * from "./marginfiFlProvider";
@@ -0,0 +1,392 @@
1
+ import {
2
+ AccountMeta,
3
+ createSignerFromKeypair,
4
+ publicKey,
5
+ Signer,
6
+ transactionBuilder,
7
+ TransactionBuilder,
8
+ } from "@metaplex-foundation/umi";
9
+ import { MARGINFI_ACCOUNTS } from "../../constants";
10
+ import {
11
+ Bank,
12
+ lendingAccountBorrow,
13
+ lendingAccountCloseBalance,
14
+ lendingAccountEndFlashloan,
15
+ lendingAccountRepay,
16
+ lendingAccountStartFlashloan,
17
+ MarginfiAccount,
18
+ marginfiAccountInitialize,
19
+ safeFetchAllBank,
20
+ } from "../../marginfi-sdk";
21
+ import { FlProviderBase } from "./flProviderBase";
22
+ import { PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js";
23
+ import {
24
+ bytesToI80F48,
25
+ consoleLog,
26
+ fetchTokenPrices,
27
+ findMarginfiAccounts,
28
+ fromBaseUnit,
29
+ getBankLiquidityAvailableBaseUnit,
30
+ getEmptyMarginfiAccountsByAuthority,
31
+ getTokenAccount,
32
+ rpcAccountCreated,
33
+ safeGetPrice,
34
+ tokenInfo,
35
+ } from "../../utils";
36
+ import { TokenType } from "../../generated";
37
+ import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
38
+ import { FlashLoanDetails } from "../../types";
39
+
40
+ interface IMFIAccount {
41
+ signer?: Signer;
42
+ accountPk: PublicKey;
43
+ accountData?: MarginfiAccount;
44
+ }
45
+
46
+ export class MarginfiFlProvider extends FlProviderBase {
47
+ private existingMarginfiAccounts!: MarginfiAccount[];
48
+ private supplyBankLiquiditySource!: Bank;
49
+ private debtBankLiquiditySource!: Bank;
50
+ private supplyImfiAccount!: IMFIAccount;
51
+ private debtImfiAccount!: IMFIAccount;
52
+
53
+ async initialize() {
54
+ await this.setAvailableBanks();
55
+ this.existingMarginfiAccounts = await getEmptyMarginfiAccountsByAuthority(
56
+ this.umi,
57
+ toWeb3JsPublicKey(this.signer.publicKey)
58
+ );
59
+ if (
60
+ this.liquidityBank(TokenType.Supply).group.toString() !==
61
+ this.liquidityBank(TokenType.Debt).group.toString()
62
+ ) {
63
+ this.setIntermediaryAccount([TokenType.Supply]);
64
+ this.setIntermediaryAccount([TokenType.Debt]);
65
+ } else {
66
+ this.setIntermediaryAccount([TokenType.Supply, TokenType.Debt]);
67
+ }
68
+ }
69
+
70
+ private async setAvailableBanks() {
71
+ const availableBanks: string[] = [];
72
+ const checkIfUsable = (group: string, mint: PublicKey) => {
73
+ if (Object.keys(MARGINFI_ACCOUNTS[group]).includes(mint.toString())) {
74
+ availableBanks.push(MARGINFI_ACCOUNTS[group][mint.toString()].bank);
75
+ }
76
+ };
77
+
78
+ for (const group of Object.keys(MARGINFI_ACCOUNTS)) {
79
+ checkIfUsable(group, this.supplyMint);
80
+ checkIfUsable(group, this.debtMint);
81
+ }
82
+
83
+ const banks = await safeFetchAllBank(
84
+ this.umi,
85
+ availableBanks.map((x) => publicKey(x))
86
+ );
87
+
88
+ if (!safeGetPrice(this.supplyMint) || !safeGetPrice(this.debtMint)) {
89
+ await fetchTokenPrices([this.supplyMint, this.debtMint]);
90
+ }
91
+
92
+ const mapBanksAndBalances = (mint: PublicKey) =>
93
+ banks
94
+ .filter((x) => toWeb3JsPublicKey(x.mint).equals(mint))
95
+ .map((x) => {
96
+ return [
97
+ fromBaseUnit(
98
+ getBankLiquidityAvailableBaseUnit(x, false),
99
+ tokenInfo(mint).decimals
100
+ ) * safeGetPrice(mint)!,
101
+ x,
102
+ ] as const;
103
+ })
104
+ .sort((a, b) => b[0] - a[0]);
105
+
106
+ const supplyBanks = mapBanksAndBalances(this.supplyMint);
107
+ const debtBanks = mapBanksAndBalances(this.debtMint);
108
+
109
+ this.supplyBankLiquiditySource = supplyBanks[0][1];
110
+ this.debtBankLiquiditySource = debtBanks[0][1];
111
+ }
112
+
113
+ private setIntermediaryAccount(sources: TokenType[]) {
114
+ const compatibleMarginfiAccounts = this.existingMarginfiAccounts.filter(
115
+ (x) => x.group.toString() == this.liquidityBank(sources[0]).group
116
+ );
117
+
118
+ const signer =
119
+ compatibleMarginfiAccounts.length > 0
120
+ ? undefined
121
+ : createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair());
122
+ const accountPk =
123
+ compatibleMarginfiAccounts.length > 0
124
+ ? toWeb3JsPublicKey(compatibleMarginfiAccounts[0].publicKey)
125
+ : toWeb3JsPublicKey(signer!.publicKey);
126
+ const accountData =
127
+ compatibleMarginfiAccounts.length > 0
128
+ ? compatibleMarginfiAccounts[0]
129
+ : undefined;
130
+
131
+ if (signer) {
132
+ this.flSigners.push(signer);
133
+ }
134
+
135
+ consoleLog("Intermediary MF account:", accountPk.toString());
136
+ for (const s of sources) {
137
+ const data: IMFIAccount = {
138
+ signer,
139
+ accountPk,
140
+ accountData,
141
+ };
142
+ if (s === TokenType.Supply) {
143
+ this.supplyImfiAccount = data;
144
+ } else {
145
+ this.debtImfiAccount = data;
146
+ }
147
+ }
148
+ }
149
+
150
+ async initializeIMfiAccounts(): Promise<TransactionBuilder> {
151
+ const supplyImfiAccount = this.iMfiAccount(TokenType.Supply);
152
+ const debtImfiAccount = this.iMfiAccount(TokenType.Debt);
153
+
154
+ const [supplyImfiRpcAccount, debtImfiRpcAccount] =
155
+ await this.umi.rpc.getAccounts([
156
+ publicKey(supplyImfiAccount.accountPk),
157
+ publicKey(debtImfiAccount.accountPk),
158
+ ]);
159
+
160
+ let tx = transactionBuilder();
161
+
162
+ if (!rpcAccountCreated(supplyImfiRpcAccount)) {
163
+ tx = tx.add(
164
+ marginfiAccountInitialize(this.umi, {
165
+ marginfiAccount: supplyImfiAccount.signer!,
166
+ marginfiGroup: this.supplyBankLiquiditySource.group,
167
+ authority: this.signer,
168
+ feePayer: this.signer,
169
+ })
170
+ );
171
+ }
172
+
173
+ if (
174
+ supplyImfiAccount.accountPk.toString() !==
175
+ debtImfiAccount.accountPk.toString() &&
176
+ !rpcAccountCreated(debtImfiRpcAccount)
177
+ ) {
178
+ tx = tx.add(
179
+ marginfiAccountInitialize(this.umi, {
180
+ marginfiAccount: debtImfiAccount.signer!,
181
+ marginfiGroup: this.debtBankLiquiditySource.group,
182
+ authority: this.signer,
183
+ feePayer: this.signer,
184
+ })
185
+ );
186
+ }
187
+
188
+ return tx;
189
+ }
190
+
191
+ lutAccountsToAdd(): PublicKey[] {
192
+ return [
193
+ ...super.lutAccountsToAdd(),
194
+ ...Array.from(
195
+ new Set([
196
+ this.iMfiAccount(TokenType.Supply).accountPk.toString(),
197
+ this.iMfiAccount(TokenType.Debt).accountPk.toString(),
198
+ ])
199
+ ).map((x) => new PublicKey(x)),
200
+ ];
201
+ }
202
+
203
+ private liquidityBank(source: TokenType): Bank {
204
+ return source === TokenType.Supply
205
+ ? this.supplyBankLiquiditySource
206
+ : this.debtBankLiquiditySource;
207
+ }
208
+
209
+ private iMfiAccount(source: TokenType): IMFIAccount {
210
+ return source === TokenType.Supply
211
+ ? this.supplyImfiAccount
212
+ : this.debtImfiAccount;
213
+ }
214
+
215
+ liquidityAvailable(source: TokenType): bigint {
216
+ return getBankLiquidityAvailableBaseUnit(this.liquidityBank(source), false);
217
+ }
218
+
219
+ flFeeBps(source: TokenType, signerFlashLoan?: boolean): number {
220
+ if (signerFlashLoan) {
221
+ return 0;
222
+ }
223
+
224
+ return bytesToI80F48(
225
+ this.liquidityBank(source).config.interestRateConfig
226
+ .protocolOriginationFee.value
227
+ );
228
+ }
229
+
230
+ flashBorrow(
231
+ flashLoan: FlashLoanDetails,
232
+ destTokenAccount: PublicKey
233
+ ): TransactionBuilder {
234
+ if (flashLoan.signerFlashLoan) {
235
+ return this.signerFlashBorrow(flashLoan, destTokenAccount);
236
+ }
237
+
238
+ const bank = this.liquidityBank(flashLoan.liquiditySource);
239
+ const associatedBankAccs = findMarginfiAccounts(
240
+ toWeb3JsPublicKey(bank.publicKey)
241
+ );
242
+ const iMfiAccount = this.iMfiAccount(flashLoan.liquiditySource)!;
243
+
244
+ return transactionBuilder()
245
+ .add(
246
+ lendingAccountStartFlashloan(this.umi, {
247
+ endIndex: 0, // We set this after building the transaction
248
+ ixsSysvar: publicKey(SYSVAR_INSTRUCTIONS_PUBKEY),
249
+ marginfiAccount: publicKey(iMfiAccount.accountPk),
250
+ signer: this.signer,
251
+ })
252
+ )
253
+ .add(
254
+ lendingAccountBorrow(this.umi, {
255
+ amount: flashLoan.baseUnitAmount,
256
+ bank: publicKey(bank),
257
+ bankLiquidityVault: publicKey(associatedBankAccs.liquidityVault),
258
+ bankLiquidityVaultAuthority: publicKey(
259
+ associatedBankAccs.vaultAuthority
260
+ ),
261
+ destinationTokenAccount: publicKey(destTokenAccount),
262
+ marginfiAccount: publicKey(iMfiAccount.accountPk),
263
+ marginfiGroup: this.liquidityBank(flashLoan.liquiditySource).group,
264
+ signer: this.signer,
265
+ })
266
+ );
267
+ }
268
+
269
+ flashRepay(flashLoan: FlashLoanDetails): TransactionBuilder {
270
+ if (flashLoan.signerFlashLoan) {
271
+ return transactionBuilder();
272
+ }
273
+
274
+ const bank = this.liquidityBank(flashLoan.liquiditySource);
275
+ const associatedBankAccs = findMarginfiAccounts(
276
+ toWeb3JsPublicKey(bank.publicKey)
277
+ );
278
+ const marginfiGroup = toWeb3JsPublicKey(
279
+ this.liquidityBank(flashLoan.liquiditySource).group
280
+ );
281
+ const iMfiAccount = this.iMfiAccount(flashLoan.liquiditySource)!;
282
+
283
+ const remainingAccounts: AccountMeta[] = [];
284
+ let includedFlashLoanToken = false;
285
+
286
+ if (iMfiAccount?.accountData) {
287
+ iMfiAccount.accountData.lendingAccount.balances.forEach(async (x) => {
288
+ if (x.active) {
289
+ if (x.bankPk.toString() === bank.publicKey.toString()) {
290
+ includedFlashLoanToken = true;
291
+ }
292
+
293
+ // TODO: Don't dynamically pull from bank until Marginfi sorts out their price oracle issues.
294
+ // const bankData = await safeFetchBank(this.umi, publicKey(accounts.data.bank));
295
+ // const priceOracle = bankData!.config.oracleKeys[0];
296
+ const priceOracle = publicKey(
297
+ findMarginfiAccounts(toWeb3JsPublicKey(x.bankPk)).priceOracle
298
+ );
299
+
300
+ remainingAccounts.push(
301
+ ...[
302
+ {
303
+ pubkey: x.bankPk,
304
+ isSigner: false,
305
+ isWritable: false,
306
+ },
307
+ {
308
+ pubkey: priceOracle,
309
+ isSigner: false,
310
+ isWritable: false,
311
+ },
312
+ ]
313
+ );
314
+ }
315
+ });
316
+ }
317
+ if (!iMfiAccount.accountData || !includedFlashLoanToken) {
318
+ remainingAccounts.push(
319
+ ...[
320
+ {
321
+ pubkey: bank.publicKey,
322
+ isSigner: false,
323
+ isWritable: false,
324
+ },
325
+ {
326
+ pubkey: publicKey(associatedBankAccs.priceOracle),
327
+ isSigner: false,
328
+ isWritable: false,
329
+ },
330
+ ]
331
+ );
332
+ }
333
+
334
+ const banksRequiringBalanceClose = Array.from(
335
+ new Set([
336
+ bank.publicKey.toString(),
337
+ ...(iMfiAccount.accountData?.lendingAccount.balances ?? [])
338
+ .filter((x) => x.active && bytesToI80F48(x.liabilityShares.value) > 0)
339
+ .map((x) => x.bankPk.toString()),
340
+ ])
341
+ );
342
+
343
+ return transactionBuilder()
344
+ .add(
345
+ lendingAccountRepay(this.umi, {
346
+ amount: flashLoan.baseUnitAmount,
347
+ repayAll: null,
348
+ bank: bank.publicKey,
349
+ bankLiquidityVault: publicKey(associatedBankAccs.liquidityVault),
350
+ marginfiAccount: publicKey(iMfiAccount.accountPk),
351
+ marginfiGroup: publicKey(marginfiGroup),
352
+ signer: this.signer,
353
+ signerTokenAccount: publicKey(
354
+ getTokenAccount(
355
+ toWeb3JsPublicKey(this.signer.publicKey),
356
+ flashLoan.mint
357
+ )
358
+ ),
359
+ })
360
+ )
361
+ .add(
362
+ banksRequiringBalanceClose.map((x) =>
363
+ this.closeBalance(
364
+ iMfiAccount.accountPk,
365
+ new PublicKey(x),
366
+ marginfiGroup
367
+ )
368
+ )
369
+ )
370
+ .add(
371
+ lendingAccountEndFlashloan(this.umi, {
372
+ marginfiAccount: publicKey(iMfiAccount.accountPk),
373
+ signer: this.signer,
374
+ }).addRemainingAccounts(remainingAccounts)
375
+ );
376
+ }
377
+
378
+ closeBalance(
379
+ marginfiAccount: PublicKey,
380
+ bank: PublicKey,
381
+ marginfiGroup: PublicKey
382
+ ) {
383
+ return transactionBuilder().add(
384
+ lendingAccountCloseBalance(this.umi, {
385
+ signer: this.signer,
386
+ marginfiAccount: publicKey(marginfiAccount),
387
+ bank: publicKey(bank),
388
+ marginfiGroup: publicKey(marginfiGroup),
389
+ })
390
+ );
391
+ }
392
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./flashLoans";
2
+ export * from "./rebalance";
3
+ export * from "./solauto";
4
+ export * from "./swap";
5
+ export * from "./transactions";
@@ -0,0 +1,2 @@
1
+ export * from "./rebalanceTxBuilder";
2
+ export * from "./rebalanceValues";
@@ -0,0 +1,218 @@
1
+ import { QuoteResponse } from "@jup-ag/api";
2
+ import { FlashLoanRequirements } from "../../types";
3
+ import { SolautoClient } from "../solauto";
4
+ import { JupSwapManager, SwapParams, SwapInput } from "../swap";
5
+ import { RebalanceValues } from "./rebalanceValues";
6
+ import { RebalanceDirection, TokenType } from "../../generated";
7
+ import {
8
+ consoleLog,
9
+ fromBaseUnit,
10
+ getLiqUtilzationRateBps,
11
+ maxRepayToBps,
12
+ safeGetPrice,
13
+ toBaseUnit,
14
+ tokenInfo,
15
+ } from "../../utils";
16
+ import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
17
+
18
+ export class RebalanceSwapManager {
19
+ public swapParams!: SwapParams;
20
+ public swapQuote?: QuoteResponse;
21
+ public flBorrowAmount?: bigint;
22
+
23
+ private jupSwapManager!: JupSwapManager;
24
+
25
+ constructor(
26
+ private client: SolautoClient,
27
+ private values: RebalanceValues,
28
+ private flRequirements?: FlashLoanRequirements,
29
+ private targetLiqUtilizationRateBps?: number
30
+ ) {
31
+ this.jupSwapManager = new JupSwapManager(client.signer);
32
+ }
33
+
34
+ private isBoost() {
35
+ return this.values.rebalanceDirection === RebalanceDirection.Boost;
36
+ }
37
+
38
+ private usdToSwap() {
39
+ return Math.abs(this.values.debtAdjustmentUsd);
40
+ }
41
+
42
+ private postRebalanceLiqUtilizationRateBps(swapOutputAmount?: bigint) {
43
+ let supplyUsd = this.client.solautoPosition.supplyUsd();
44
+ // TODO: add token balance change
45
+ let debtUsd = this.client.solautoPosition.debtUsd();
46
+
47
+ const outputToken = toWeb3JsPublicKey(
48
+ this.isBoost()
49
+ ? this.client.solautoPosition.state().supply.mint
50
+ : this.client.solautoPosition.state().debt.mint
51
+ );
52
+ const swapOutputUsd = swapOutputAmount
53
+ ? fromBaseUnit(swapOutputAmount, tokenInfo(outputToken).decimals) *
54
+ (safeGetPrice(outputToken) ?? 0)
55
+ : this.usdToSwap();
56
+
57
+ supplyUsd = this.isBoost()
58
+ ? supplyUsd + swapOutputUsd
59
+ : supplyUsd - this.usdToSwap();
60
+ debtUsd = this.isBoost()
61
+ ? debtUsd + this.usdToSwap()
62
+ : debtUsd - swapOutputUsd;
63
+
64
+ return getLiqUtilzationRateBps(
65
+ supplyUsd,
66
+ debtUsd,
67
+ this.client.solautoPosition.state().liqThresholdBps ?? 0
68
+ );
69
+ }
70
+
71
+ private async findSufficientQuote(
72
+ swapInput: SwapInput,
73
+ criteria: {
74
+ minOutputAmount?: bigint;
75
+ minLiqUtilizationRateBps?: number;
76
+ maxLiqUtilizationRateBps?: number;
77
+ }
78
+ ): Promise<QuoteResponse> {
79
+ let swapQuote: QuoteResponse;
80
+ let insufficient: boolean = false;
81
+
82
+ for (let i = 0; i < 10; i++) {
83
+ consoleLog("Finding sufficient quote...");
84
+ swapQuote = await this.jupSwapManager.getQuote(swapInput);
85
+
86
+ const outputAmount = parseInt(swapQuote.outAmount);
87
+ const postRebalanceRate = this.postRebalanceLiqUtilizationRateBps(
88
+ BigInt(outputAmount)
89
+ );
90
+ insufficient = criteria.minOutputAmount
91
+ ? outputAmount < Number(criteria.minOutputAmount)
92
+ : criteria.minLiqUtilizationRateBps
93
+ ? postRebalanceRate < criteria.minLiqUtilizationRateBps
94
+ : postRebalanceRate > criteria.maxLiqUtilizationRateBps!;
95
+
96
+ if (insufficient) {
97
+ consoleLog("Insufficient swap quote:", swapQuote);
98
+ swapInput.amount = this.bigIntWithIncrement(swapInput.amount, 0.01);
99
+ } else {
100
+ break;
101
+ }
102
+ }
103
+
104
+ return swapQuote!;
105
+ }
106
+
107
+ private swapDetails() {
108
+ const input = this.isBoost()
109
+ ? this.client.solautoPosition.state().debt
110
+ : this.client.solautoPosition.state().supply;
111
+ const output = this.isBoost()
112
+ ? this.client.solautoPosition.state().supply
113
+ : this.client.solautoPosition.state().debt;
114
+
115
+ let inputAmount = toBaseUnit(
116
+ this.usdToSwap() / safeGetPrice(input.mint)!,
117
+ input.decimals
118
+ );
119
+
120
+ return {
121
+ input,
122
+ output,
123
+ inputAmount,
124
+ };
125
+ }
126
+
127
+ private bigIntWithIncrement(num: bigint, inc: number) {
128
+ return num + BigInt(Math.round(Number(num) * inc));
129
+ }
130
+
131
+ async setSwapParams(attemptNum: number) {
132
+ const rebalanceToZero = this.targetLiqUtilizationRateBps === 0;
133
+ let { input, output, inputAmount } = this.swapDetails();
134
+
135
+ let outputAmount = rebalanceToZero
136
+ ? output.amountUsed.baseUnit +
137
+ BigInt(
138
+ Math.round(
139
+ Number(output.amountUsed.baseUnit) *
140
+ // Add this small percentage to account for the APR on the debt between now and the transaction
141
+ 0.0001
142
+ )
143
+ )
144
+ : toBaseUnit(
145
+ this.usdToSwap() / safeGetPrice(output.mint)!,
146
+ output.decimals
147
+ );
148
+
149
+ const flashLoanRepayFromDebt =
150
+ !this.isBoost() &&
151
+ this.flRequirements &&
152
+ this.flRequirements.liquiditySource === TokenType.Debt;
153
+
154
+ const exactOut = flashLoanRepayFromDebt && !rebalanceToZero;
155
+ const exactIn = !exactOut;
156
+
157
+ if (exactIn && (rebalanceToZero || this.values.repayingCloseToMaxLtv)) {
158
+ inputAmount = this.bigIntWithIncrement(inputAmount, 0.005);
159
+ }
160
+
161
+ const swapAmount = exactOut
162
+ ? this.flRequirements
163
+ ? this.bigIntWithIncrement(
164
+ outputAmount,
165
+ this.flRequirements.flFeeBps ?? 0
166
+ )
167
+ : outputAmount
168
+ : inputAmount;
169
+ const swapInput: SwapInput = {
170
+ inputMint: toWeb3JsPublicKey(input.mint),
171
+ outputMint: toWeb3JsPublicKey(output.mint),
172
+ exactIn,
173
+ exactOut,
174
+ amount: swapAmount,
175
+ };
176
+ consoleLog("Swap input:", swapInput);
177
+
178
+ if (exactIn && (rebalanceToZero || this.values.repayingCloseToMaxLtv)) {
179
+ this.swapQuote = await this.findSufficientQuote(swapInput, {
180
+ minOutputAmount: rebalanceToZero ? outputAmount : undefined,
181
+ maxLiqUtilizationRateBps: this.values.repayingCloseToMaxLtv
182
+ ? maxRepayToBps(
183
+ this.client.solautoPosition.state().maxLtvBps ?? 0,
184
+ this.client.solautoPosition.state().liqThresholdBps ?? 0
185
+ ) - 15
186
+ : undefined,
187
+ });
188
+ }
189
+
190
+ if (this.flRequirements) {
191
+ this.flBorrowAmount = exactOut
192
+ ? outputAmount
193
+ : this.swapQuote
194
+ ? BigInt(parseInt(this.swapQuote.inAmount))
195
+ : inputAmount;
196
+ }
197
+
198
+ this.swapParams = {
199
+ ...swapInput,
200
+ destinationWallet: flashLoanRepayFromDebt
201
+ ? toWeb3JsPublicKey(this.client.signer.publicKey)
202
+ : this.client.solautoPosition.publicKey,
203
+ slippageIncFactor: 0.2 + attemptNum * 0.25,
204
+ };
205
+ }
206
+
207
+ async getSwapTxData() {
208
+ const { jupQuote, lookupTableAddresses, setupInstructions, swapIx } =
209
+ await this.jupSwapManager.getJupSwapTxData(this.swapParams);
210
+
211
+ return {
212
+ swapQuote: jupQuote,
213
+ lookupTableAddresses,
214
+ setupInstructions,
215
+ swapIx,
216
+ };
217
+ }
218
+ }