@kestrelfi/lyc-sdk 1.0.1 → 1.0.3

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 (738) hide show
  1. package/README.md +32 -0
  2. package/dist/carry-XU3WUD22.mjs +20 -0
  3. package/dist/carry-XU3WUD22.mjs.map +1 -0
  4. package/dist/chunk-2T23QQCX.mjs +3707 -0
  5. package/dist/chunk-2T23QQCX.mjs.map +1 -0
  6. package/dist/chunk-GOW6CARW.mjs +3969 -0
  7. package/dist/chunk-GOW6CARW.mjs.map +1 -0
  8. package/dist/chunk-ZPXXY3QV.mjs +9330 -0
  9. package/dist/chunk-ZPXXY3QV.mjs.map +1 -0
  10. package/dist/{sdks/long-yield-carry/src/idl/long_yield_carry.d.ts → core-DP6wfpME.d.mts} +3242 -84
  11. package/dist/core-DP6wfpME.d.ts +10485 -0
  12. package/dist/core.d.mts +8 -0
  13. package/dist/core.d.ts +8 -0
  14. package/dist/core.js +12348 -0
  15. package/dist/core.js.map +1 -0
  16. package/dist/core.mjs +72 -0
  17. package/dist/core.mjs.map +1 -0
  18. package/dist/index.d.mts +2537 -0
  19. package/dist/index.d.ts +2537 -0
  20. package/dist/index.js +23884 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/index.mjs +5898 -0
  23. package/dist/index.mjs.map +1 -0
  24. package/package.json +56 -10
  25. package/.env.example +0 -11
  26. package/dist/sdks/long-yield-carry/scripts/asyncBurn.d.ts +0 -1
  27. package/dist/sdks/long-yield-carry/scripts/asyncBurn.js +0 -117
  28. package/dist/sdks/long-yield-carry/scripts/burnToken.d.ts +0 -1
  29. package/dist/sdks/long-yield-carry/scripts/burnToken.js +0 -98
  30. package/dist/sdks/long-yield-carry/scripts/claimIncentives.d.ts +0 -1
  31. package/dist/sdks/long-yield-carry/scripts/claimIncentives.js +0 -108
  32. package/dist/sdks/long-yield-carry/scripts/closeCpiPlans.d.ts +0 -1
  33. package/dist/sdks/long-yield-carry/scripts/closeCpiPlans.js +0 -93
  34. package/dist/sdks/long-yield-carry/scripts/collectInterest.d.ts +0 -1
  35. package/dist/sdks/long-yield-carry/scripts/collectInterest.js +0 -164
  36. package/dist/sdks/long-yield-carry/scripts/collectProtocolFees.d.ts +0 -1
  37. package/dist/sdks/long-yield-carry/scripts/collectProtocolFees.js +0 -120
  38. package/dist/sdks/long-yield-carry/scripts/computeOptimalAllocations.d.ts +0 -1
  39. package/dist/sdks/long-yield-carry/scripts/computeOptimalAllocations.js +0 -84
  40. package/dist/sdks/long-yield-carry/scripts/createToken.d.ts +0 -1
  41. package/dist/sdks/long-yield-carry/scripts/createToken.js +0 -76
  42. package/dist/sdks/long-yield-carry/scripts/createTokenLendingPosition.d.ts +0 -1
  43. package/dist/sdks/long-yield-carry/scripts/createTokenLendingPosition.js +0 -157
  44. package/dist/sdks/long-yield-carry/scripts/createYieldingBank.d.ts +0 -1
  45. package/dist/sdks/long-yield-carry/scripts/createYieldingBank.js +0 -69
  46. package/dist/sdks/long-yield-carry/scripts/decreaseCarryPositions.d.ts +0 -1
  47. package/dist/sdks/long-yield-carry/scripts/decreaseCarryPositions.js +0 -247
  48. package/dist/sdks/long-yield-carry/scripts/depositUnlentCollateral.d.ts +0 -1
  49. package/dist/sdks/long-yield-carry/scripts/depositUnlentCollateral.js +0 -90
  50. package/dist/sdks/long-yield-carry/scripts/emergency/deleverageAll.d.ts +0 -1
  51. package/dist/sdks/long-yield-carry/scripts/emergency/deleverageAll.js +0 -202
  52. package/dist/sdks/long-yield-carry/scripts/emergency/triggerCircuitBreaker.d.ts +0 -1
  53. package/dist/sdks/long-yield-carry/scripts/emergency/triggerCircuitBreaker.js +0 -68
  54. package/dist/sdks/long-yield-carry/scripts/env.d.ts +0 -1
  55. package/dist/sdks/long-yield-carry/scripts/env.js +0 -8
  56. package/dist/sdks/long-yield-carry/scripts/findTxs.d.ts +0 -1
  57. package/dist/sdks/long-yield-carry/scripts/findTxs.js +0 -143
  58. package/dist/sdks/long-yield-carry/scripts/increaseCarryPositions.d.ts +0 -1
  59. package/dist/sdks/long-yield-carry/scripts/increaseCarryPositions.js +0 -112
  60. package/dist/sdks/long-yield-carry/scripts/inspect/format.d.ts +0 -13
  61. package/dist/sdks/long-yield-carry/scripts/inspect/format.js +0 -363
  62. package/dist/sdks/long-yield-carry/scripts/inspect.d.ts +0 -1
  63. package/dist/sdks/long-yield-carry/scripts/inspect.js +0 -108
  64. package/dist/sdks/long-yield-carry/scripts/localUtils.d.ts +0 -53
  65. package/dist/sdks/long-yield-carry/scripts/localUtils.js +0 -191
  66. package/dist/sdks/long-yield-carry/scripts/mintToken.d.ts +0 -1
  67. package/dist/sdks/long-yield-carry/scripts/mintToken.js +0 -103
  68. package/dist/sdks/long-yield-carry/scripts/processAsyncBurns.d.ts +0 -1
  69. package/dist/sdks/long-yield-carry/scripts/processAsyncBurns.js +0 -76
  70. package/dist/sdks/long-yield-carry/scripts/rebalanceToken.d.ts +0 -1
  71. package/dist/sdks/long-yield-carry/scripts/rebalanceToken.js +0 -210
  72. package/dist/sdks/long-yield-carry/scripts/rebalanceYieldingBank.d.ts +0 -1
  73. package/dist/sdks/long-yield-carry/scripts/rebalanceYieldingBank.js +0 -149
  74. package/dist/sdks/long-yield-carry/scripts/recollateralizeLoss.d.ts +0 -1
  75. package/dist/sdks/long-yield-carry/scripts/recollateralizeLoss.js +0 -64
  76. package/dist/sdks/long-yield-carry/scripts/refresh.d.ts +0 -1
  77. package/dist/sdks/long-yield-carry/scripts/refresh.js +0 -101
  78. package/dist/sdks/long-yield-carry/scripts/updateFees.d.ts +0 -1
  79. package/dist/sdks/long-yield-carry/scripts/updateFees.js +0 -369
  80. package/dist/sdks/long-yield-carry/scripts/updateGeneralLut.d.ts +0 -1
  81. package/dist/sdks/long-yield-carry/scripts/updateGeneralLut.js +0 -27
  82. package/dist/sdks/long-yield-carry/scripts/updateLendingPositionConfig.d.ts +0 -1
  83. package/dist/sdks/long-yield-carry/scripts/updateLendingPositionConfig.js +0 -127
  84. package/dist/sdks/long-yield-carry/scripts/updateTokenLuts.d.ts +0 -1
  85. package/dist/sdks/long-yield-carry/scripts/updateTokenLuts.js +0 -27
  86. package/dist/sdks/long-yield-carry/scripts/updateTokenMetadata.d.ts +0 -1
  87. package/dist/sdks/long-yield-carry/scripts/updateTokenMetadata.js +0 -194
  88. package/dist/sdks/long-yield-carry/scripts/updateYieldingBankConfig.d.ts +0 -1
  89. package/dist/sdks/long-yield-carry/scripts/updateYieldingBankConfig.js +0 -84
  90. package/dist/sdks/long-yield-carry/scripts/withdrawUnlentCollateral.d.ts +0 -1
  91. package/dist/sdks/long-yield-carry/scripts/withdrawUnlentCollateral.js +0 -140
  92. package/dist/sdks/long-yield-carry/src/client/account.d.ts +0 -152
  93. package/dist/sdks/long-yield-carry/src/client/account.js +0 -349
  94. package/dist/sdks/long-yield-carry/src/client/builders/args.d.ts +0 -299
  95. package/dist/sdks/long-yield-carry/src/client/builders/args.js +0 -2
  96. package/dist/sdks/long-yield-carry/src/client/builders/asyncBurnBuilder.d.ts +0 -20
  97. package/dist/sdks/long-yield-carry/src/client/builders/asyncBurnBuilder.js +0 -212
  98. package/dist/sdks/long-yield-carry/src/client/builders/base.d.ts +0 -77
  99. package/dist/sdks/long-yield-carry/src/client/builders/base.js +0 -191
  100. package/dist/sdks/long-yield-carry/src/client/builders/burnTokenBuilder.d.ts +0 -18
  101. package/dist/sdks/long-yield-carry/src/client/builders/burnTokenBuilder.js +0 -165
  102. package/dist/sdks/long-yield-carry/src/client/builders/claimIncentivesBuilder.d.ts +0 -9
  103. package/dist/sdks/long-yield-carry/src/client/builders/claimIncentivesBuilder.js +0 -135
  104. package/dist/sdks/long-yield-carry/src/client/builders/collectFeesBuilder.d.ts +0 -14
  105. package/dist/sdks/long-yield-carry/src/client/builders/collectFeesBuilder.js +0 -50
  106. package/dist/sdks/long-yield-carry/src/client/builders/collectInterestBuilder.d.ts +0 -8
  107. package/dist/sdks/long-yield-carry/src/client/builders/collectInterestBuilder.js +0 -86
  108. package/dist/sdks/long-yield-carry/src/client/builders/createCpiPlanBuilder.d.ts +0 -6
  109. package/dist/sdks/long-yield-carry/src/client/builders/createCpiPlanBuilder.js +0 -22
  110. package/dist/sdks/long-yield-carry/src/client/builders/createTokenBuilder.d.ts +0 -7
  111. package/dist/sdks/long-yield-carry/src/client/builders/createTokenBuilder.js +0 -64
  112. package/dist/sdks/long-yield-carry/src/client/builders/createTokenLendingPositionBuilder.d.ts +0 -10
  113. package/dist/sdks/long-yield-carry/src/client/builders/createTokenLendingPositionBuilder.js +0 -138
  114. package/dist/sdks/long-yield-carry/src/client/builders/createYieldingBankAllocationBuilder.d.ts +0 -7
  115. package/dist/sdks/long-yield-carry/src/client/builders/createYieldingBankAllocationBuilder.js +0 -29
  116. package/dist/sdks/long-yield-carry/src/client/builders/createYieldingBankBuilder.d.ts +0 -7
  117. package/dist/sdks/long-yield-carry/src/client/builders/createYieldingBankBuilder.js +0 -39
  118. package/dist/sdks/long-yield-carry/src/client/builders/decreaseCarryPositionBuilder.d.ts +0 -30
  119. package/dist/sdks/long-yield-carry/src/client/builders/decreaseCarryPositionBuilder.js +0 -99
  120. package/dist/sdks/long-yield-carry/src/client/builders/depositUnlentCollateralBuilder.d.ts +0 -8
  121. package/dist/sdks/long-yield-carry/src/client/builders/depositUnlentCollateralBuilder.js +0 -64
  122. package/dist/sdks/long-yield-carry/src/client/builders/increaseCarryPositionBuilder.d.ts +0 -8
  123. package/dist/sdks/long-yield-carry/src/client/builders/increaseCarryPositionBuilder.js +0 -73
  124. package/dist/sdks/long-yield-carry/src/client/builders/index.d.ts +0 -28
  125. package/dist/sdks/long-yield-carry/src/client/builders/index.js +0 -62
  126. package/dist/sdks/long-yield-carry/src/client/builders/mintTokenBuilder.d.ts +0 -8
  127. package/dist/sdks/long-yield-carry/src/client/builders/mintTokenBuilder.js +0 -95
  128. package/dist/sdks/long-yield-carry/src/client/builders/rebalanceTokenBuilder.d.ts +0 -11
  129. package/dist/sdks/long-yield-carry/src/client/builders/rebalanceTokenBuilder.js +0 -255
  130. package/dist/sdks/long-yield-carry/src/client/builders/rebalanceYieldingBankBuilder.d.ts +0 -8
  131. package/dist/sdks/long-yield-carry/src/client/builders/rebalanceYieldingBankBuilder.js +0 -75
  132. package/dist/sdks/long-yield-carry/src/client/builders/recollateralizeLossBuilder.d.ts +0 -12
  133. package/dist/sdks/long-yield-carry/src/client/builders/recollateralizeLossBuilder.js +0 -220
  134. package/dist/sdks/long-yield-carry/src/client/builders/refreshTokenStateBuilder.d.ts +0 -9
  135. package/dist/sdks/long-yield-carry/src/client/builders/refreshTokenStateBuilder.js +0 -112
  136. package/dist/sdks/long-yield-carry/src/client/builders/refreshTokensBuilder.d.ts +0 -9
  137. package/dist/sdks/long-yield-carry/src/client/builders/refreshTokensBuilder.js +0 -59
  138. package/dist/sdks/long-yield-carry/src/client/builders/refreshYieldingBankBuilder.d.ts +0 -8
  139. package/dist/sdks/long-yield-carry/src/client/builders/refreshYieldingBankBuilder.js +0 -29
  140. package/dist/sdks/long-yield-carry/src/client/builders/resetTokenBurnRateLimitBuilder.d.ts +0 -7
  141. package/dist/sdks/long-yield-carry/src/client/builders/resetTokenBurnRateLimitBuilder.js +0 -19
  142. package/dist/sdks/long-yield-carry/src/client/builders/setTokenCircuitBreakerBuilder.d.ts +0 -11
  143. package/dist/sdks/long-yield-carry/src/client/builders/setTokenCircuitBreakerBuilder.js +0 -31
  144. package/dist/sdks/long-yield-carry/src/client/builders/setYieldingBankCircuitBreakerBuilder.d.ts +0 -8
  145. package/dist/sdks/long-yield-carry/src/client/builders/setYieldingBankCircuitBreakerBuilder.js +0 -28
  146. package/dist/sdks/long-yield-carry/src/client/builders/updateLendingPositionConfigBuilder.d.ts +0 -10
  147. package/dist/sdks/long-yield-carry/src/client/builders/updateLendingPositionConfigBuilder.js +0 -30
  148. package/dist/sdks/long-yield-carry/src/client/builders/updateTokenConfigurationBuilder.d.ts +0 -11
  149. package/dist/sdks/long-yield-carry/src/client/builders/updateTokenConfigurationBuilder.js +0 -47
  150. package/dist/sdks/long-yield-carry/src/client/builders/updateTokenMetadataBuilder.d.ts +0 -7
  151. package/dist/sdks/long-yield-carry/src/client/builders/updateTokenMetadataBuilder.js +0 -24
  152. package/dist/sdks/long-yield-carry/src/client/builders/updateYieldingBankConfigBuilder.d.ts +0 -10
  153. package/dist/sdks/long-yield-carry/src/client/builders/updateYieldingBankConfigBuilder.js +0 -31
  154. package/dist/sdks/long-yield-carry/src/client/builders/utils.d.ts +0 -4
  155. package/dist/sdks/long-yield-carry/src/client/builders/utils.js +0 -20
  156. package/dist/sdks/long-yield-carry/src/client/client.d.ts +0 -115
  157. package/dist/sdks/long-yield-carry/src/client/client.js +0 -166
  158. package/dist/sdks/long-yield-carry/src/client/externalLiquidityResolver.d.ts +0 -13
  159. package/dist/sdks/long-yield-carry/src/client/externalLiquidityResolver.js +0 -34
  160. package/dist/sdks/long-yield-carry/src/client/index.d.ts +0 -10
  161. package/dist/sdks/long-yield-carry/src/client/index.js +0 -33
  162. package/dist/sdks/long-yield-carry/src/client/lendingPlatformClients.d.ts +0 -19
  163. package/dist/sdks/long-yield-carry/src/client/lendingPlatformClients.js +0 -33
  164. package/dist/sdks/long-yield-carry/src/client/pda.d.ts +0 -33
  165. package/dist/sdks/long-yield-carry/src/client/pda.js +0 -79
  166. package/dist/sdks/long-yield-carry/src/client/plans/collectInterest.d.ts +0 -24
  167. package/dist/sdks/long-yield-carry/src/client/plans/collectInterest.js +0 -150
  168. package/dist/sdks/long-yield-carry/src/client/plans/decreaseCarryPosition.d.ts +0 -12
  169. package/dist/sdks/long-yield-carry/src/client/plans/decreaseCarryPosition.js +0 -140
  170. package/dist/sdks/long-yield-carry/src/client/routes/collectInterest.d.ts +0 -13
  171. package/dist/sdks/long-yield-carry/src/client/routes/collectInterest.js +0 -39
  172. package/dist/sdks/long-yield-carry/src/client/transaction.d.ts +0 -41
  173. package/dist/sdks/long-yield-carry/src/client/transaction.js +0 -55
  174. package/dist/sdks/long-yield-carry/src/client/types/builders.d.ts +0 -18
  175. package/dist/sdks/long-yield-carry/src/client/types/builders.js +0 -2
  176. package/dist/sdks/long-yield-carry/src/client/types/enums.d.ts +0 -22
  177. package/dist/sdks/long-yield-carry/src/client/types/enums.js +0 -48
  178. package/dist/sdks/long-yield-carry/src/client/types/general.d.ts +0 -98
  179. package/dist/sdks/long-yield-carry/src/client/types/general.js +0 -2
  180. package/dist/sdks/long-yield-carry/src/client/types/index.d.ts +0 -6
  181. package/dist/sdks/long-yield-carry/src/client/types/index.js +0 -22
  182. package/dist/sdks/long-yield-carry/src/client/types/ix.d.ts +0 -352
  183. package/dist/sdks/long-yield-carry/src/client/types/ix.js +0 -2
  184. package/dist/sdks/long-yield-carry/src/client/types/planTypes/collectInterest.d.ts +0 -91
  185. package/dist/sdks/long-yield-carry/src/client/types/planTypes/collectInterest.js +0 -2
  186. package/dist/sdks/long-yield-carry/src/client/types/planTypes/common.d.ts +0 -28
  187. package/dist/sdks/long-yield-carry/src/client/types/planTypes/common.js +0 -2
  188. package/dist/sdks/long-yield-carry/src/client/types/planTypes/decreaseCarryPosition.d.ts +0 -128
  189. package/dist/sdks/long-yield-carry/src/client/types/planTypes/decreaseCarryPosition.js +0 -2
  190. package/dist/sdks/long-yield-carry/src/client/types/planTypes/index.d.ts +0 -3
  191. package/dist/sdks/long-yield-carry/src/client/types/planTypes/index.js +0 -19
  192. package/dist/sdks/long-yield-carry/src/client/types/tx.d.ts +0 -339
  193. package/dist/sdks/long-yield-carry/src/client/types/tx.js +0 -2
  194. package/dist/sdks/long-yield-carry/src/constants/configs/allocations.d.ts +0 -3
  195. package/dist/sdks/long-yield-carry/src/constants/configs/allocations.js +0 -23
  196. package/dist/sdks/long-yield-carry/src/constants/configs/carryTradePresets.d.ts +0 -58
  197. package/dist/sdks/long-yield-carry/src/constants/configs/carryTradePresets.js +0 -116
  198. package/dist/sdks/long-yield-carry/src/constants/configs/index.d.ts +0 -2
  199. package/dist/sdks/long-yield-carry/src/constants/configs/index.js +0 -18
  200. package/dist/sdks/long-yield-carry/src/constants/general.d.ts +0 -70
  201. package/dist/sdks/long-yield-carry/src/constants/general.js +0 -107
  202. package/dist/sdks/long-yield-carry/src/constants/index.d.ts +0 -3
  203. package/dist/sdks/long-yield-carry/src/constants/index.js +0 -19
  204. package/dist/sdks/long-yield-carry/src/constants/lycTokenMetadata.d.ts +0 -36
  205. package/dist/sdks/long-yield-carry/src/constants/lycTokenMetadata.js +0 -41
  206. package/dist/sdks/long-yield-carry/src/decoders/decodeTransaction.d.ts +0 -86
  207. package/dist/sdks/long-yield-carry/src/decoders/decodeTransaction.js +0 -230
  208. package/dist/sdks/long-yield-carry/src/decoders/discriminators.d.ts +0 -8
  209. package/dist/sdks/long-yield-carry/src/decoders/discriminators.js +0 -11
  210. package/dist/sdks/long-yield-carry/src/decoders/idlAccounts.d.ts +0 -29
  211. package/dist/sdks/long-yield-carry/src/decoders/idlAccounts.js +0 -57
  212. package/dist/sdks/long-yield-carry/src/decoders/index.d.ts +0 -6
  213. package/dist/sdks/long-yield-carry/src/decoders/index.js +0 -14
  214. package/dist/sdks/long-yield-carry/src/decoders/innerCpis.d.ts +0 -68
  215. package/dist/sdks/long-yield-carry/src/decoders/innerCpis.js +0 -225
  216. package/dist/sdks/long-yield-carry/src/decoders/lycInstructionNames.d.ts +0 -6
  217. package/dist/sdks/long-yield-carry/src/decoders/lycInstructionNames.js +0 -73
  218. package/dist/sdks/long-yield-carry/src/decoders/programIds.d.ts +0 -4
  219. package/dist/sdks/long-yield-carry/src/decoders/programIds.js +0 -11
  220. package/dist/sdks/long-yield-carry/src/decoders/solana.d.ts +0 -7
  221. package/dist/sdks/long-yield-carry/src/decoders/solana.js +0 -30
  222. package/dist/sdks/long-yield-carry/src/decoders/transactionPayload.d.ts +0 -41
  223. package/dist/sdks/long-yield-carry/src/decoders/transactionPayload.js +0 -6
  224. package/dist/sdks/long-yield-carry/src/decoders/types.d.ts +0 -58
  225. package/dist/sdks/long-yield-carry/src/decoders/types.js +0 -2
  226. package/dist/sdks/long-yield-carry/src/errors.d.ts +0 -69
  227. package/dist/sdks/long-yield-carry/src/errors.js +0 -183
  228. package/dist/sdks/long-yield-carry/src/idl/long_yield_carry.js +0 -7323
  229. package/dist/sdks/long-yield-carry/src/index.d.ts +0 -10
  230. package/dist/sdks/long-yield-carry/src/index.js +0 -25
  231. package/dist/sdks/long-yield-carry/src/metrics/index.d.ts +0 -1
  232. package/dist/sdks/long-yield-carry/src/metrics/index.js +0 -17
  233. package/dist/sdks/long-yield-carry/src/metrics/protocolMetrics.d.ts +0 -276
  234. package/dist/sdks/long-yield-carry/src/metrics/protocolMetrics.js +0 -547
  235. package/dist/sdks/long-yield-carry/src/models/index.d.ts +0 -3
  236. package/dist/sdks/long-yield-carry/src/models/index.js +0 -7
  237. package/dist/sdks/long-yield-carry/src/models/lycToken.d.ts +0 -156
  238. package/dist/sdks/long-yield-carry/src/models/lycToken.js +0 -288
  239. package/dist/sdks/long-yield-carry/src/models/yieldingBank.d.ts +0 -52
  240. package/dist/sdks/long-yield-carry/src/models/yieldingBank.js +0 -109
  241. package/dist/sdks/long-yield-carry/src/services/allocation/allocationService.d.ts +0 -106
  242. package/dist/sdks/long-yield-carry/src/services/allocation/allocationService.js +0 -589
  243. package/dist/sdks/long-yield-carry/src/services/allocation/index.d.ts +0 -2
  244. package/dist/sdks/long-yield-carry/src/services/allocation/index.js +0 -18
  245. package/dist/sdks/long-yield-carry/src/services/allocation/types.d.ts +0 -25
  246. package/dist/sdks/long-yield-carry/src/services/allocation/types.js +0 -2
  247. package/dist/sdks/long-yield-carry/src/services/carry/carryAllocationConfig.d.ts +0 -103
  248. package/dist/sdks/long-yield-carry/src/services/carry/carryAllocationConfig.js +0 -146
  249. package/dist/sdks/long-yield-carry/src/services/carry/index.d.ts +0 -2
  250. package/dist/sdks/long-yield-carry/src/services/carry/index.js +0 -18
  251. package/dist/sdks/long-yield-carry/src/services/carry/lycLendingPositionManager.d.ts +0 -39
  252. package/dist/sdks/long-yield-carry/src/services/carry/lycLendingPositionManager.js +0 -100
  253. package/dist/sdks/long-yield-carry/src/services/index.d.ts +0 -5
  254. package/dist/sdks/long-yield-carry/src/services/index.js +0 -21
  255. package/dist/sdks/long-yield-carry/src/services/lendingPosition/index.d.ts +0 -2
  256. package/dist/sdks/long-yield-carry/src/services/lendingPosition/index.js +0 -5
  257. package/dist/sdks/long-yield-carry/src/services/lendingPosition/lendingPositionService.d.ts +0 -88
  258. package/dist/sdks/long-yield-carry/src/services/lendingPosition/lendingPositionService.js +0 -229
  259. package/dist/sdks/long-yield-carry/src/services/rebalance/index.d.ts +0 -2
  260. package/dist/sdks/long-yield-carry/src/services/rebalance/index.js +0 -18
  261. package/dist/sdks/long-yield-carry/src/services/rebalance/token/index.d.ts +0 -1
  262. package/dist/sdks/long-yield-carry/src/services/rebalance/token/index.js +0 -17
  263. package/dist/sdks/long-yield-carry/src/services/rebalance/token/tokenRebalanceService.d.ts +0 -51
  264. package/dist/sdks/long-yield-carry/src/services/rebalance/token/tokenRebalanceService.js +0 -99
  265. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/index.d.ts +0 -3
  266. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/index.js +0 -21
  267. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/planner.d.ts +0 -68
  268. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/planner.js +0 -181
  269. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/strategy.d.ts +0 -26
  270. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/strategy.js +0 -26
  271. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/types.d.ts +0 -40
  272. package/dist/sdks/long-yield-carry/src/services/rebalance/yieldingBank/types.js +0 -2
  273. package/dist/sdks/long-yield-carry/src/services/redemption/index.d.ts +0 -2
  274. package/dist/sdks/long-yield-carry/src/services/redemption/index.js +0 -5
  275. package/dist/sdks/long-yield-carry/src/services/redemption/redemptionService.d.ts +0 -139
  276. package/dist/sdks/long-yield-carry/src/services/redemption/redemptionService.js +0 -532
  277. package/dist/sdks/long-yield-carry/src/types/enriched.d.ts +0 -168
  278. package/dist/sdks/long-yield-carry/src/types/enriched.js +0 -2
  279. package/dist/sdks/long-yield-carry/src/types/index.d.ts +0 -1
  280. package/dist/sdks/long-yield-carry/src/types/index.js +0 -17
  281. package/dist/sdks/long-yield-carry/src/utils/cache.d.ts +0 -4
  282. package/dist/sdks/long-yield-carry/src/utils/cache.js +0 -10
  283. package/dist/sdks/long-yield-carry/src/utils/data.d.ts +0 -12
  284. package/dist/sdks/long-yield-carry/src/utils/data.js +0 -59
  285. package/dist/sdks/long-yield-carry/src/utils/enrichment.d.ts +0 -5
  286. package/dist/sdks/long-yield-carry/src/utils/enrichment.js +0 -244
  287. package/dist/sdks/long-yield-carry/src/utils/feeDripMetrics.d.ts +0 -36
  288. package/dist/sdks/long-yield-carry/src/utils/feeDripMetrics.js +0 -93
  289. package/dist/sdks/long-yield-carry/src/utils/general.d.ts +0 -28
  290. package/dist/sdks/long-yield-carry/src/utils/general.js +0 -47
  291. package/dist/sdks/long-yield-carry/src/utils/index.d.ts +0 -13
  292. package/dist/sdks/long-yield-carry/src/utils/index.js +0 -29
  293. package/dist/sdks/long-yield-carry/src/utils/ix.d.ts +0 -83
  294. package/dist/sdks/long-yield-carry/src/utils/ix.js +0 -165
  295. package/dist/sdks/long-yield-carry/src/utils/lendingPosition.d.ts +0 -68
  296. package/dist/sdks/long-yield-carry/src/utils/lendingPosition.js +0 -105
  297. package/dist/sdks/long-yield-carry/src/utils/lookupTables.d.ts +0 -55
  298. package/dist/sdks/long-yield-carry/src/utils/lookupTables.js +0 -216
  299. package/dist/sdks/long-yield-carry/src/utils/lycData.d.ts +0 -66
  300. package/dist/sdks/long-yield-carry/src/utils/lycData.js +0 -211
  301. package/dist/sdks/long-yield-carry/src/utils/timelock.d.ts +0 -19
  302. package/dist/sdks/long-yield-carry/src/utils/timelock.js +0 -37
  303. package/dist/sdks/long-yield-carry/src/utils/tokenFeeMath.d.ts +0 -11
  304. package/dist/sdks/long-yield-carry/src/utils/tokenFeeMath.js +0 -24
  305. package/dist/sdks/long-yield-carry/src/utils/transactions.d.ts +0 -20
  306. package/dist/sdks/long-yield-carry/src/utils/transactions.js +0 -72
  307. package/dist/sdks/long-yield-carry/src/utils/yieldingBank.d.ts +0 -24
  308. package/dist/sdks/long-yield-carry/src/utils/yieldingBank.js +0 -36
  309. package/dist/shared/common/src/constants/accountMetas.d.ts +0 -3
  310. package/dist/shared/common/src/constants/accountMetas.js +0 -9
  311. package/dist/shared/common/src/constants/general.d.ts +0 -21
  312. package/dist/shared/common/src/constants/general.js +0 -30
  313. package/dist/shared/common/src/constants/generated/cpi.d.ts +0 -23
  314. package/dist/shared/common/src/constants/generated/cpi.js +0 -28
  315. package/dist/shared/common/src/constants/generated/index.d.ts +0 -1
  316. package/dist/shared/common/src/constants/generated/index.js +0 -17
  317. package/dist/shared/common/src/constants/index.d.ts +0 -3
  318. package/dist/shared/common/src/constants/index.js +0 -19
  319. package/dist/shared/common/src/index.d.ts +0 -4
  320. package/dist/shared/common/src/index.js +0 -20
  321. package/dist/shared/common/src/services/baseAccountClient.d.ts +0 -22
  322. package/dist/shared/common/src/services/baseAccountClient.js +0 -38
  323. package/dist/shared/common/src/services/baseIxBuilderService.d.ts +0 -27
  324. package/dist/shared/common/src/services/baseIxBuilderService.js +0 -48
  325. package/dist/shared/common/src/services/dataCache.d.ts +0 -41
  326. package/dist/shared/common/src/services/dataCache.js +0 -130
  327. package/dist/shared/common/src/services/index.d.ts +0 -8
  328. package/dist/shared/common/src/services/index.js +0 -24
  329. package/dist/shared/common/src/services/lutManager.d.ts +0 -31
  330. package/dist/shared/common/src/services/lutManager.js +0 -133
  331. package/dist/shared/common/src/services/mints/defaults.d.ts +0 -2
  332. package/dist/shared/common/src/services/mints/defaults.js +0 -152
  333. package/dist/shared/common/src/services/mints/index.d.ts +0 -4
  334. package/dist/shared/common/src/services/mints/index.js +0 -20
  335. package/dist/shared/common/src/services/mints/registry.d.ts +0 -70
  336. package/dist/shared/common/src/services/mints/registry.js +0 -117
  337. package/dist/shared/common/src/services/mints/symbols.d.ts +0 -6
  338. package/dist/shared/common/src/services/mints/symbols.js +0 -13
  339. package/dist/shared/common/src/services/mints/types.d.ts +0 -30
  340. package/dist/shared/common/src/services/mints/types.js +0 -2
  341. package/dist/shared/common/src/services/swap/index.d.ts +0 -4
  342. package/dist/shared/common/src/services/swap/index.js +0 -20
  343. package/dist/shared/common/src/services/swap/routableSwapClient.d.ts +0 -36
  344. package/dist/shared/common/src/services/swap/routableSwapClient.js +0 -2
  345. package/dist/shared/common/src/services/swap/swapClientBase.d.ts +0 -45
  346. package/dist/shared/common/src/services/swap/swapClientBase.js +0 -2
  347. package/dist/shared/common/src/services/swap/swapRouting.d.ts +0 -13
  348. package/dist/shared/common/src/services/swap/swapRouting.js +0 -28
  349. package/dist/shared/common/src/services/swap/types.d.ts +0 -77
  350. package/dist/shared/common/src/services/swap/types.js +0 -2
  351. package/dist/shared/common/src/services/token/index.d.ts +0 -2
  352. package/dist/shared/common/src/services/token/index.js +0 -18
  353. package/dist/shared/common/src/services/token/tokenProtocolClientBase.d.ts +0 -51
  354. package/dist/shared/common/src/services/token/tokenProtocolClientBase.js +0 -2
  355. package/dist/shared/common/src/services/token/types.d.ts +0 -19
  356. package/dist/shared/common/src/services/token/types.js +0 -2
  357. package/dist/shared/common/src/services/transactionSender.d.ts +0 -24
  358. package/dist/shared/common/src/services/transactionSender.js +0 -30
  359. package/dist/shared/common/src/types/cpi.d.ts +0 -34
  360. package/dist/shared/common/src/types/cpi.js +0 -8
  361. package/dist/shared/common/src/types/enums.d.ts +0 -59
  362. package/dist/shared/common/src/types/enums.js +0 -122
  363. package/dist/shared/common/src/types/general.d.ts +0 -38
  364. package/dist/shared/common/src/types/general.js +0 -2
  365. package/dist/shared/common/src/types/index.d.ts +0 -4
  366. package/dist/shared/common/src/types/index.js +0 -20
  367. package/dist/shared/common/src/types/solana.d.ts +0 -24
  368. package/dist/shared/common/src/types/solana.js +0 -2
  369. package/dist/shared/common/src/utils/accounts/index.d.ts +0 -5
  370. package/dist/shared/common/src/utils/accounts/index.js +0 -21
  371. package/dist/shared/common/src/utils/accounts/meta.d.ts +0 -21
  372. package/dist/shared/common/src/utils/accounts/meta.js +0 -27
  373. package/dist/shared/common/src/utils/accounts/pda.d.ts +0 -2
  374. package/dist/shared/common/src/utils/accounts/pda.js +0 -17
  375. package/dist/shared/common/src/utils/accounts/roles.d.ts +0 -26
  376. package/dist/shared/common/src/utils/accounts/roles.js +0 -54
  377. package/dist/shared/common/src/utils/accounts/rpc.d.ts +0 -8
  378. package/dist/shared/common/src/utils/accounts/rpc.js +0 -30
  379. package/dist/shared/common/src/utils/accounts/splBalances.d.ts +0 -15
  380. package/dist/shared/common/src/utils/accounts/splBalances.js +0 -52
  381. package/dist/shared/common/src/utils/anchor.d.ts +0 -17
  382. package/dist/shared/common/src/utils/anchor.js +0 -29
  383. package/dist/shared/common/src/utils/asyncConcurrency.d.ts +0 -5
  384. package/dist/shared/common/src/utils/asyncConcurrency.js +0 -28
  385. package/dist/shared/common/src/utils/compat.d.ts +0 -46
  386. package/dist/shared/common/src/utils/compat.js +0 -72
  387. package/dist/shared/common/src/utils/cpi/args.d.ts +0 -69
  388. package/dist/shared/common/src/utils/cpi/args.js +0 -100
  389. package/dist/shared/common/src/utils/cpi/index.d.ts +0 -2
  390. package/dist/shared/common/src/utils/cpi/index.js +0 -18
  391. package/dist/shared/common/src/utils/cpi/refs.d.ts +0 -122
  392. package/dist/shared/common/src/utils/cpi/refs.js +0 -234
  393. package/dist/shared/common/src/utils/data.d.ts +0 -20
  394. package/dist/shared/common/src/utils/data.js +0 -27
  395. package/dist/shared/common/src/utils/general.d.ts +0 -24
  396. package/dist/shared/common/src/utils/general.js +0 -95
  397. package/dist/shared/common/src/utils/index.d.ts +0 -22
  398. package/dist/shared/common/src/utils/index.js +0 -38
  399. package/dist/shared/common/src/utils/instruction.d.ts +0 -74
  400. package/dist/shared/common/src/utils/instruction.js +0 -147
  401. package/dist/shared/common/src/utils/jito.d.ts +0 -113
  402. package/dist/shared/common/src/utils/jito.js +0 -178
  403. package/dist/shared/common/src/utils/json.d.ts +0 -5
  404. package/dist/shared/common/src/utils/json.js +0 -25
  405. package/dist/shared/common/src/utils/jsonRpcFetch.d.ts +0 -21
  406. package/dist/shared/common/src/utils/jsonRpcFetch.js +0 -134
  407. package/dist/shared/common/src/utils/metadata.d.ts +0 -107
  408. package/dist/shared/common/src/utils/metadata.js +0 -194
  409. package/dist/shared/common/src/utils/numbers.d.ts +0 -72
  410. package/dist/shared/common/src/utils/numbers.js +0 -193
  411. package/dist/shared/common/src/utils/priorityFee.d.ts +0 -18
  412. package/dist/shared/common/src/utils/priorityFee.js +0 -63
  413. package/dist/shared/common/src/utils/retry.d.ts +0 -20
  414. package/dist/shared/common/src/utils/retry.js +0 -69
  415. package/dist/shared/common/src/utils/rpc.d.ts +0 -40
  416. package/dist/shared/common/src/utils/rpc.js +0 -130
  417. package/dist/shared/common/src/utils/solana.d.ts +0 -23
  418. package/dist/shared/common/src/utils/solana.js +0 -61
  419. package/dist/shared/common/src/utils/timeSeries.d.ts +0 -18
  420. package/dist/shared/common/src/utils/timeSeries.js +0 -40
  421. package/dist/shared/common/src/utils/token.d.ts +0 -33
  422. package/dist/shared/common/src/utils/token.js +0 -82
  423. package/dist/shared/common/src/utils/transaction.d.ts +0 -154
  424. package/dist/shared/common/src/utils/transaction.js +0 -585
  425. package/dist/shared/common/src/utils/transactionSplitter.d.ts +0 -85
  426. package/dist/shared/common/src/utils/transactionSplitter.js +0 -127
  427. package/dist/shared/common/src/utils/txAccountCoverage.d.ts +0 -49
  428. package/dist/shared/common/src/utils/txAccountCoverage.js +0 -122
  429. package/dist/shared/jupiter-helpers/src/api.d.ts +0 -59
  430. package/dist/shared/jupiter-helpers/src/api.js +0 -130
  431. package/dist/shared/jupiter-helpers/src/client.d.ts +0 -79
  432. package/dist/shared/jupiter-helpers/src/client.js +0 -173
  433. package/dist/shared/jupiter-helpers/src/constants.d.ts +0 -35
  434. package/dist/shared/jupiter-helpers/src/constants.js +0 -38
  435. package/dist/shared/jupiter-helpers/src/extract.d.ts +0 -30
  436. package/dist/shared/jupiter-helpers/src/extract.js +0 -57
  437. package/dist/shared/jupiter-helpers/src/index.d.ts +0 -5
  438. package/dist/shared/jupiter-helpers/src/index.js +0 -21
  439. package/dist/shared/jupiter-helpers/src/routePreInstructions.d.ts +0 -19
  440. package/dist/shared/jupiter-helpers/src/routePreInstructions.js +0 -61
  441. package/dist/shared/jupiter-helpers/src/sizeExactInForMinOutput.d.ts +0 -70
  442. package/dist/shared/jupiter-helpers/src/sizeExactInForMinOutput.js +0 -95
  443. package/dist/shared/jupiter-helpers/src/types.d.ts +0 -66
  444. package/dist/shared/jupiter-helpers/src/types.js +0 -2
  445. package/dist/shared/lending-platforms/src/constants/cache.d.ts +0 -8
  446. package/dist/shared/lending-platforms/src/constants/cache.js +0 -11
  447. package/dist/shared/lending-platforms/src/constants/index.d.ts +0 -3
  448. package/dist/shared/lending-platforms/src/constants/index.js +0 -19
  449. package/dist/shared/lending-platforms/src/constants/kamino.d.ts +0 -7
  450. package/dist/shared/lending-platforms/src/constants/kamino.js +0 -83
  451. package/dist/shared/lending-platforms/src/constants/lendingPosition.d.ts +0 -7
  452. package/dist/shared/lending-platforms/src/constants/lendingPosition.js +0 -10
  453. package/dist/shared/lending-platforms/src/data/accounts/index.d.ts +0 -2
  454. package/dist/shared/lending-platforms/src/data/accounts/index.js +0 -18
  455. package/dist/shared/lending-platforms/src/data/accounts/kamino.d.ts +0 -42
  456. package/dist/shared/lending-platforms/src/data/accounts/kamino.js +0 -104
  457. package/dist/shared/lending-platforms/src/data/accounts/lpAccountsBase.d.ts +0 -7
  458. package/dist/shared/lending-platforms/src/data/accounts/lpAccountsBase.js +0 -9
  459. package/dist/shared/lending-platforms/src/data/incentive/incentiveBase.d.ts +0 -35
  460. package/dist/shared/lending-platforms/src/data/incentive/incentiveBase.js +0 -26
  461. package/dist/shared/lending-platforms/src/data/incentive/index.d.ts +0 -2
  462. package/dist/shared/lending-platforms/src/data/incentive/index.js +0 -18
  463. package/dist/shared/lending-platforms/src/data/incentive/kamino.d.ts +0 -55
  464. package/dist/shared/lending-platforms/src/data/incentive/kamino.js +0 -101
  465. package/dist/shared/lending-platforms/src/data/index.d.ts +0 -6
  466. package/dist/shared/lending-platforms/src/data/index.js +0 -22
  467. package/dist/shared/lending-platforms/src/data/instructions/index.d.ts +0 -3
  468. package/dist/shared/lending-platforms/src/data/instructions/index.js +0 -19
  469. package/dist/shared/lending-platforms/src/data/instructions/kamino.d.ts +0 -55
  470. package/dist/shared/lending-platforms/src/data/instructions/kamino.js +0 -630
  471. package/dist/shared/lending-platforms/src/data/instructions/lpInstructionsBase.d.ts +0 -175
  472. package/dist/shared/lending-platforms/src/data/instructions/lpInstructionsBase.js +0 -192
  473. package/dist/shared/lending-platforms/src/data/instructions/types.d.ts +0 -7
  474. package/dist/shared/lending-platforms/src/data/instructions/types.js +0 -2
  475. package/dist/shared/lending-platforms/src/data/platform/index.d.ts +0 -2
  476. package/dist/shared/lending-platforms/src/data/platform/index.js +0 -18
  477. package/dist/shared/lending-platforms/src/data/platform/kamino.d.ts +0 -59
  478. package/dist/shared/lending-platforms/src/data/platform/kamino.js +0 -206
  479. package/dist/shared/lending-platforms/src/data/platform/lpDataBase.d.ts +0 -35
  480. package/dist/shared/lending-platforms/src/data/platform/lpDataBase.js +0 -31
  481. package/dist/shared/lending-platforms/src/data/reserve/index.d.ts +0 -2
  482. package/dist/shared/lending-platforms/src/data/reserve/index.js +0 -18
  483. package/dist/shared/lending-platforms/src/data/reserve/kamino.d.ts +0 -45
  484. package/dist/shared/lending-platforms/src/data/reserve/kamino.js +0 -141
  485. package/dist/shared/lending-platforms/src/data/reserve/reserveBase.d.ts +0 -114
  486. package/dist/shared/lending-platforms/src/data/reserve/reserveBase.js +0 -125
  487. package/dist/shared/lending-platforms/src/data/userPosition/index.d.ts +0 -2
  488. package/dist/shared/lending-platforms/src/data/userPosition/index.js +0 -18
  489. package/dist/shared/lending-platforms/src/data/userPosition/kamino.d.ts +0 -15
  490. package/dist/shared/lending-platforms/src/data/userPosition/kamino.js +0 -45
  491. package/dist/shared/lending-platforms/src/data/userPosition/userPositionBase.d.ts +0 -50
  492. package/dist/shared/lending-platforms/src/data/userPosition/userPositionBase.js +0 -63
  493. package/dist/shared/lending-platforms/src/index.d.ts +0 -5
  494. package/dist/shared/lending-platforms/src/index.js +0 -21
  495. package/dist/shared/lending-platforms/src/services/client/index.d.ts +0 -2
  496. package/dist/shared/lending-platforms/src/services/client/index.js +0 -18
  497. package/dist/shared/lending-platforms/src/services/client/kamino.d.ts +0 -53
  498. package/dist/shared/lending-platforms/src/services/client/kamino.js +0 -142
  499. package/dist/shared/lending-platforms/src/services/client/lpClientBase.d.ts +0 -66
  500. package/dist/shared/lending-platforms/src/services/client/lpClientBase.js +0 -19
  501. package/dist/shared/lending-platforms/src/services/flashLoan/flashLoanBase.d.ts +0 -49
  502. package/dist/shared/lending-platforms/src/services/flashLoan/flashLoanBase.js +0 -16
  503. package/dist/shared/lending-platforms/src/services/flashLoan/index.d.ts +0 -2
  504. package/dist/shared/lending-platforms/src/services/flashLoan/index.js +0 -18
  505. package/dist/shared/lending-platforms/src/services/flashLoan/kamino.d.ts +0 -11
  506. package/dist/shared/lending-platforms/src/services/flashLoan/kamino.js +0 -85
  507. package/dist/shared/lending-platforms/src/services/index.d.ts +0 -5
  508. package/dist/shared/lending-platforms/src/services/index.js +0 -21
  509. package/dist/shared/lending-platforms/src/services/lendingPosition/index.d.ts +0 -2
  510. package/dist/shared/lending-platforms/src/services/lendingPosition/index.js +0 -18
  511. package/dist/shared/lending-platforms/src/services/lendingPosition/lendingPositionManager.d.ts +0 -117
  512. package/dist/shared/lending-platforms/src/services/lendingPosition/lendingPositionManager.js +0 -342
  513. package/dist/shared/lending-platforms/src/services/lendingPosition/types.d.ts +0 -40
  514. package/dist/shared/lending-platforms/src/services/lendingPosition/types.js +0 -2
  515. package/dist/shared/lending-platforms/src/services/leverage/index.d.ts +0 -2
  516. package/dist/shared/lending-platforms/src/services/leverage/index.js +0 -18
  517. package/dist/shared/lending-platforms/src/services/leverage/leverageService.d.ts +0 -104
  518. package/dist/shared/lending-platforms/src/services/leverage/leverageService.js +0 -437
  519. package/dist/shared/lending-platforms/src/services/leverage/types.d.ts +0 -261
  520. package/dist/shared/lending-platforms/src/services/leverage/types.js +0 -2
  521. package/dist/shared/lending-platforms/src/services/reservesManager.d.ts +0 -53
  522. package/dist/shared/lending-platforms/src/services/reservesManager.js +0 -112
  523. package/dist/shared/lending-platforms/src/types/general.d.ts +0 -37
  524. package/dist/shared/lending-platforms/src/types/general.js +0 -8
  525. package/dist/shared/lending-platforms/src/types/index.d.ts +0 -2
  526. package/dist/shared/lending-platforms/src/types/index.js +0 -18
  527. package/dist/shared/lending-platforms/src/types/kamino.d.ts +0 -10
  528. package/dist/shared/lending-platforms/src/types/kamino.js +0 -2
  529. package/dist/shared/lending-platforms/src/utils/accounts.d.ts +0 -16
  530. package/dist/shared/lending-platforms/src/utils/accounts.js +0 -36
  531. package/dist/shared/lending-platforms/src/utils/cache.d.ts +0 -3
  532. package/dist/shared/lending-platforms/src/utils/cache.js +0 -11
  533. package/dist/shared/lending-platforms/src/utils/index.d.ts +0 -6
  534. package/dist/shared/lending-platforms/src/utils/index.js +0 -22
  535. package/dist/shared/lending-platforms/src/utils/kamino.d.ts +0 -87
  536. package/dist/shared/lending-platforms/src/utils/kamino.js +0 -190
  537. package/dist/shared/lending-platforms/src/utils/lendingPlatform.d.ts +0 -6
  538. package/dist/shared/lending-platforms/src/utils/lendingPlatform.js +0 -16
  539. package/dist/shared/lending-platforms/src/utils/math.d.ts +0 -47
  540. package/dist/shared/lending-platforms/src/utils/math.js +0 -123
  541. package/dist/shared/lending-platforms/src/utils/scope.d.ts +0 -38
  542. package/dist/shared/lending-platforms/src/utils/scope.js +0 -144
  543. package/dist/shared/oracle-service/src/constants/index.d.ts +0 -3
  544. package/dist/shared/oracle-service/src/constants/index.js +0 -19
  545. package/dist/shared/oracle-service/src/constants/pyth.d.ts +0 -7
  546. package/dist/shared/oracle-service/src/constants/pyth.js +0 -71
  547. package/dist/shared/oracle-service/src/constants/splStake.d.ts +0 -2
  548. package/dist/shared/oracle-service/src/constants/splStake.js +0 -6
  549. package/dist/shared/oracle-service/src/constants/switchboard.d.ts +0 -7
  550. package/dist/shared/oracle-service/src/constants/switchboard.js +0 -10
  551. package/dist/shared/oracle-service/src/feeds/custom.d.ts +0 -30
  552. package/dist/shared/oracle-service/src/feeds/custom.js +0 -56
  553. package/dist/shared/oracle-service/src/feeds/jupiter.d.ts +0 -7
  554. package/dist/shared/oracle-service/src/feeds/jupiter.js +0 -43
  555. package/dist/shared/oracle-service/src/feeds/priceBase.d.ts +0 -13
  556. package/dist/shared/oracle-service/src/feeds/priceBase.js +0 -25
  557. package/dist/shared/oracle-service/src/feeds/pyth.d.ts +0 -8
  558. package/dist/shared/oracle-service/src/feeds/pyth.js +0 -59
  559. package/dist/shared/oracle-service/src/feeds/splStake.d.ts +0 -26
  560. package/dist/shared/oracle-service/src/feeds/splStake.js +0 -99
  561. package/dist/shared/oracle-service/src/feeds/switchboard.d.ts +0 -6
  562. package/dist/shared/oracle-service/src/feeds/switchboard.js +0 -11
  563. package/dist/shared/oracle-service/src/index.d.ts +0 -5
  564. package/dist/shared/oracle-service/src/index.js +0 -26
  565. package/dist/shared/oracle-service/src/oracle.d.ts +0 -22
  566. package/dist/shared/oracle-service/src/oracle.js +0 -104
  567. package/dist/shared/oracle-service/src/types.d.ts +0 -4
  568. package/dist/shared/oracle-service/src/types.js +0 -2
  569. package/dist/shared/oracle-service/src/utils/general.d.ts +0 -20
  570. package/dist/shared/oracle-service/src/utils/general.js +0 -65
  571. package/dist/shared/oracle-service/src/utils/index.d.ts +0 -1
  572. package/dist/shared/oracle-service/src/utils/index.js +0 -17
  573. package/dist/shared/perena-helpers/src/accounts.d.ts +0 -7
  574. package/dist/shared/perena-helpers/src/accounts.js +0 -12
  575. package/dist/shared/perena-helpers/src/client.d.ts +0 -299
  576. package/dist/shared/perena-helpers/src/client.js +0 -680
  577. package/dist/shared/perena-helpers/src/constants.d.ts +0 -5
  578. package/dist/shared/perena-helpers/src/constants.js +0 -8
  579. package/dist/shared/perena-helpers/src/cpi/burn.d.ts +0 -27
  580. package/dist/shared/perena-helpers/src/cpi/burn.js +0 -22
  581. package/dist/shared/perena-helpers/src/cpi/index.d.ts +0 -3
  582. package/dist/shared/perena-helpers/src/cpi/index.js +0 -19
  583. package/dist/shared/perena-helpers/src/cpi/mint.d.ts +0 -27
  584. package/dist/shared/perena-helpers/src/cpi/mint.js +0 -22
  585. package/dist/shared/perena-helpers/src/cpi/requestUnstake.d.ts +0 -19
  586. package/dist/shared/perena-helpers/src/cpi/requestUnstake.js +0 -16
  587. package/dist/shared/perena-helpers/src/index.d.ts +0 -5
  588. package/dist/shared/perena-helpers/src/index.js +0 -21
  589. package/dist/shared/perena-helpers/src/utils.d.ts +0 -9
  590. package/dist/shared/perena-helpers/src/utils.js +0 -54
  591. package/dist/shared/swap-aggregator/src/aggSwapClient.d.ts +0 -71
  592. package/dist/shared/swap-aggregator/src/aggSwapClient.js +0 -103
  593. package/dist/shared/swap-aggregator/src/index.d.ts +0 -1
  594. package/dist/shared/swap-aggregator/src/index.js +0 -17
  595. package/docs/launchingToken.md +0 -57
  596. package/scripts/asyncBurn.ts +0 -155
  597. package/scripts/burnToken.ts +0 -120
  598. package/scripts/claimIncentives.ts +0 -125
  599. package/scripts/closeCpiPlans.ts +0 -113
  600. package/scripts/collectInterest.ts +0 -194
  601. package/scripts/collectProtocolFees.ts +0 -144
  602. package/scripts/computeOptimalAllocations.ts +0 -117
  603. package/scripts/createToken.ts +0 -100
  604. package/scripts/createTokenLendingPosition.ts +0 -204
  605. package/scripts/createYieldingBank.ts +0 -91
  606. package/scripts/decreaseCarryPositions.ts +0 -359
  607. package/scripts/depositUnlentCollateral.ts +0 -106
  608. package/scripts/emergency/deleverageAll.ts +0 -287
  609. package/scripts/emergency/triggerCircuitBreaker.ts +0 -87
  610. package/scripts/env.ts +0 -4
  611. package/scripts/findTxs.ts +0 -169
  612. package/scripts/increaseCarryPositions.ts +0 -134
  613. package/scripts/inspect/format.ts +0 -576
  614. package/scripts/inspect.ts +0 -147
  615. package/scripts/localUtils.ts +0 -249
  616. package/scripts/mintToken.ts +0 -126
  617. package/scripts/processAsyncBurns.ts +0 -89
  618. package/scripts/rebalanceToken.ts +0 -269
  619. package/scripts/rebalanceYieldingBank.ts +0 -183
  620. package/scripts/recollateralizeLoss.ts +0 -79
  621. package/scripts/refresh.ts +0 -156
  622. package/scripts/updateFees.ts +0 -486
  623. package/scripts/updateGeneralLut.ts +0 -36
  624. package/scripts/updateLendingPositionConfig.ts +0 -172
  625. package/scripts/updateTokenLuts.ts +0 -36
  626. package/scripts/updateTokenMetadata.ts +0 -199
  627. package/scripts/updateYieldingBankConfig.ts +0 -100
  628. package/scripts/withdrawUnlentCollateral.ts +0 -178
  629. package/src/client/account.ts +0 -503
  630. package/src/client/builders/args.ts +0 -381
  631. package/src/client/builders/asyncBurnBuilder.ts +0 -305
  632. package/src/client/builders/base.ts +0 -303
  633. package/src/client/builders/burnTokenBuilder.ts +0 -258
  634. package/src/client/builders/claimIncentivesBuilder.ts +0 -211
  635. package/src/client/builders/collectFeesBuilder.ts +0 -52
  636. package/src/client/builders/collectInterestBuilder.ts +0 -165
  637. package/src/client/builders/createCpiPlanBuilder.ts +0 -21
  638. package/src/client/builders/createTokenBuilder.ts +0 -73
  639. package/src/client/builders/createTokenLendingPositionBuilder.ts +0 -219
  640. package/src/client/builders/createYieldingBankAllocationBuilder.ts +0 -32
  641. package/src/client/builders/createYieldingBankBuilder.ts +0 -39
  642. package/src/client/builders/decreaseCarryPositionBuilder.ts +0 -162
  643. package/src/client/builders/depositUnlentCollateralBuilder.ts +0 -95
  644. package/src/client/builders/increaseCarryPositionBuilder.ts +0 -105
  645. package/src/client/builders/index.ts +0 -37
  646. package/src/client/builders/mintTokenBuilder.ts +0 -137
  647. package/src/client/builders/rebalanceTokenBuilder.ts +0 -356
  648. package/src/client/builders/rebalanceYieldingBankBuilder.ts +0 -109
  649. package/src/client/builders/recollateralizeLossBuilder.ts +0 -367
  650. package/src/client/builders/refreshTokenStateBuilder.ts +0 -153
  651. package/src/client/builders/refreshTokensBuilder.ts +0 -82
  652. package/src/client/builders/refreshYieldingBankBuilder.ts +0 -42
  653. package/src/client/builders/resetTokenBurnRateLimitBuilder.ts +0 -21
  654. package/src/client/builders/setTokenCircuitBreakerBuilder.ts +0 -40
  655. package/src/client/builders/setYieldingBankCircuitBreakerBuilder.ts +0 -37
  656. package/src/client/builders/updateLendingPositionConfigBuilder.ts +0 -33
  657. package/src/client/builders/updateTokenConfigurationBuilder.ts +0 -50
  658. package/src/client/builders/updateTokenMetadataBuilder.ts +0 -24
  659. package/src/client/builders/updateYieldingBankConfigBuilder.ts +0 -32
  660. package/src/client/builders/utils.ts +0 -26
  661. package/src/client/client.ts +0 -264
  662. package/src/client/externalLiquidityResolver.ts +0 -54
  663. package/src/client/index.ts +0 -20
  664. package/src/client/lendingPlatformClients.ts +0 -50
  665. package/src/client/pda.ts +0 -102
  666. package/src/client/plans/collectInterest.ts +0 -207
  667. package/src/client/plans/decreaseCarryPosition.ts +0 -226
  668. package/src/client/routes/collectInterest.ts +0 -56
  669. package/src/client/transaction.ts +0 -106
  670. package/src/client/types/builders.ts +0 -19
  671. package/src/client/types/enums.ts +0 -47
  672. package/src/client/types/general.ts +0 -117
  673. package/src/client/types/index.ts +0 -6
  674. package/src/client/types/ix.ts +0 -452
  675. package/src/client/types/planTypes/collectInterest.ts +0 -97
  676. package/src/client/types/planTypes/common.ts +0 -31
  677. package/src/client/types/planTypes/decreaseCarryPosition.ts +0 -134
  678. package/src/client/types/planTypes/index.ts +0 -3
  679. package/src/client/types/tx.ts +0 -409
  680. package/src/constants/configs/allocations.ts +0 -30
  681. package/src/constants/configs/carryTradePresets.ts +0 -164
  682. package/src/constants/configs/index.ts +0 -2
  683. package/src/constants/general.ts +0 -141
  684. package/src/constants/index.ts +0 -3
  685. package/src/constants/lycTokenMetadata.ts +0 -52
  686. package/src/decoders/decodeTransaction.ts +0 -319
  687. package/src/decoders/discriminators.ts +0 -10
  688. package/src/decoders/idlAccounts.ts +0 -75
  689. package/src/decoders/index.ts +0 -15
  690. package/src/decoders/innerCpis.ts +0 -262
  691. package/src/decoders/lycInstructionNames.ts +0 -73
  692. package/src/decoders/programIds.ts +0 -12
  693. package/src/decoders/solana.ts +0 -25
  694. package/src/decoders/transactionPayload.ts +0 -41
  695. package/src/decoders/types.ts +0 -60
  696. package/src/errors.ts +0 -195
  697. package/src/idl/long_yield_carry.ts +0 -14648
  698. package/src/index.ts +0 -10
  699. package/src/metrics/index.ts +0 -1
  700. package/src/metrics/protocolMetrics.ts +0 -976
  701. package/src/models/index.ts +0 -9
  702. package/src/models/lycToken.ts +0 -380
  703. package/src/models/yieldingBank.ts +0 -127
  704. package/src/services/allocation/allocationService.ts +0 -823
  705. package/src/services/allocation/index.ts +0 -2
  706. package/src/services/allocation/types.ts +0 -27
  707. package/src/services/carry/carryAllocationConfig.ts +0 -266
  708. package/src/services/carry/index.ts +0 -2
  709. package/src/services/carry/lycLendingPositionManager.ts +0 -167
  710. package/src/services/index.ts +0 -5
  711. package/src/services/lendingPosition/index.ts +0 -5
  712. package/src/services/lendingPosition/lendingPositionService.ts +0 -328
  713. package/src/services/rebalance/index.ts +0 -2
  714. package/src/services/rebalance/token/index.ts +0 -1
  715. package/src/services/rebalance/token/tokenRebalanceService.ts +0 -142
  716. package/src/services/rebalance/yieldingBank/index.ts +0 -3
  717. package/src/services/rebalance/yieldingBank/planner.ts +0 -215
  718. package/src/services/rebalance/yieldingBank/strategy.ts +0 -41
  719. package/src/services/rebalance/yieldingBank/types.ts +0 -41
  720. package/src/services/redemption/index.ts +0 -9
  721. package/src/services/redemption/redemptionService.ts +0 -758
  722. package/src/types/enriched.ts +0 -187
  723. package/src/types/index.ts +0 -1
  724. package/src/utils/cache.ts +0 -12
  725. package/src/utils/data.ts +0 -65
  726. package/src/utils/enrichment.ts +0 -330
  727. package/src/utils/feeDripMetrics.ts +0 -146
  728. package/src/utils/general.ts +0 -54
  729. package/src/utils/index.ts +0 -13
  730. package/src/utils/ix.ts +0 -227
  731. package/src/utils/lendingPosition.ts +0 -221
  732. package/src/utils/lookupTables.ts +0 -309
  733. package/src/utils/lycData.ts +0 -321
  734. package/src/utils/timelock.ts +0 -63
  735. package/src/utils/tokenFeeMath.ts +0 -25
  736. package/src/utils/transactions.ts +0 -109
  737. package/src/utils/yieldingBank.ts +0 -38
  738. package/tsconfig.json +0 -11
@@ -0,0 +1,3969 @@
1
+ import {
2
+ CpiTypes,
3
+ DAYS_PER_YEAR,
4
+ DEFAULT_PUBLIC_KEY,
5
+ DataCache,
6
+ ENVIRONMENT,
7
+ IX_SYSVAR_META,
8
+ LOCALNET_URL,
9
+ PRICE_STALENESS_SECONDS,
10
+ RENT_SYSVAR_META,
11
+ SYSTEM_PROGRAM_META,
12
+ U64_MAX_BN,
13
+ accountExists,
14
+ applyFeeCeil,
15
+ createRpcWithFailover,
16
+ createSignerFromAddress,
17
+ currentUnixSeconds,
18
+ dedupeOrderedAddresses,
19
+ fetchWithRetry,
20
+ fromUiAmount,
21
+ fromWeb3Pk,
22
+ getAtaAddress,
23
+ getCreateAtaIxIfNeeded,
24
+ getRpcUrl,
25
+ getSlot,
26
+ mints,
27
+ numToU64Bytes,
28
+ oracle,
29
+ sum,
30
+ toCustomAccountMeta,
31
+ toUiAmount
32
+ } from "./chunk-2T23QQCX.mjs";
33
+
34
+ // ../../shared/lending-platforms/src/services/client/kamino.ts
35
+ import { Obligation } from "@kamino-finance/klend-sdk";
36
+
37
+ // ../../shared/lending-platforms/src/services/client/lpClientBase.ts
38
+ var LendingPlatformClientBase = class {
39
+ constructor(rpcUrl, rpcUrls = [rpcUrl]) {
40
+ this.rpc = createRpcWithFailover(rpcUrls);
41
+ }
42
+ applyPostSuccessCacheInvalidations(invalidations) {
43
+ this.ix.applyPostSuccessCacheInvalidations(invalidations);
44
+ }
45
+ };
46
+
47
+ // ../../shared/lending-platforms/src/data/platform/kamino.ts
48
+ import {
49
+ KaminoMarket,
50
+ DEFAULT_RECENT_SLOT_DURATION_MS,
51
+ PROGRAM_ID as PROGRAM_ID2,
52
+ DEFAULT_PUBLIC_KEY as DEFAULT_PUBLIC_KEY2
53
+ } from "@kamino-finance/klend-sdk";
54
+ import { Scope as Scope2 } from "@kamino-finance/scope-sdk";
55
+ import { Farms } from "@kamino-finance/farms-sdk";
56
+
57
+ // ../../shared/lending-platforms/src/constants/cache.ts
58
+ var LENDING_PLATFORM_DATA_CACHE_CATEGORY_POOL = "pool";
59
+ var LENDING_PLATFORM_DATA_CACHE_CATEGORY_RESERVE = "reserve";
60
+ var LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT = "userAccount";
61
+
62
+ // ../../shared/lending-platforms/src/data/platform/lpDataBase.ts
63
+ var LendingPlatformData = class {
64
+ constructor(rpcUrl, cacheTtlConfig, rpcUrls = [rpcUrl]) {
65
+ this.poolCatKey = LENDING_PLATFORM_DATA_CACHE_CATEGORY_POOL;
66
+ this.reserveCatKey = LENDING_PLATFORM_DATA_CACHE_CATEGORY_RESERVE;
67
+ this.userAccountCatKey = LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT;
68
+ this.rpc = createRpcWithFailover(rpcUrls);
69
+ this.cache = new DataCache(cacheTtlConfig);
70
+ }
71
+ clearCache() {
72
+ this.cache.clearAllCache();
73
+ }
74
+ clearCacheEntry(category, id) {
75
+ this.cache.clearCacheEntry(category, id);
76
+ }
77
+ /** Returns the current slot, cached to reduce RPC calls */
78
+ async getSlot() {
79
+ const { data } = await this.cache.getDataOrThrow(
80
+ async () => await getSlot(this.rpc),
81
+ "slot",
82
+ "slot"
83
+ );
84
+ return data;
85
+ }
86
+ };
87
+
88
+ // ../../shared/lending-platforms/src/constants/kamino.ts
89
+ import { address } from "@solana/kit";
90
+ var KAMINO_FARMS_PROGRAM_ID = address("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
91
+ var KAMINO_SCOPE_PROGRAM_ID = address("HFn8GnPADiny6XqUoWE8uRPPxb29ikn4yTuPa9MF2fWJ");
92
+ var KAMINO_MAIN_MARKET = address("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF");
93
+ var SOL_RESERVE = address("d4A2prbA2whesmvHaL88BH6Ewn5N4bTSU2Ze8P6Bc4Q");
94
+ var USDC_RESERVE = address("D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59");
95
+ var KAMINO_ACCOUNTS = {
96
+ [KAMINO_MAIN_MARKET]: [
97
+ {
98
+ address: SOL_RESERVE,
99
+ mintSymbol: "SOL"
100
+ },
101
+ {
102
+ address: address("37Jk2zkz23vkAYBT66HM2gaqJuNg2nYLsCreQAVt5MWK"),
103
+ mintSymbol: "cbBTC"
104
+ },
105
+ {
106
+ address: address("febGYTnFX4GbSGoFHFeJXUHgNaK53fB23uDins9Jp1E"),
107
+ mintSymbol: "wETH"
108
+ },
109
+ {
110
+ address: address("DGQZWCY17gGtBUgdaFs1VreJWsodkjFxndPsskwFKGpp"),
111
+ mintSymbol: "JupSOL"
112
+ },
113
+ {
114
+ address: address("CkgQnPbuHHwSv2mNdAKH79TKSqC6jsyttK9yh4MPH6z3"),
115
+ mintSymbol: "dfdvSOL"
116
+ },
117
+ {
118
+ address: USDC_RESERVE,
119
+ mintSymbol: "USDC"
120
+ },
121
+ {
122
+ address: address("2gc9Dm1eB6UgVYFBUN9bWks6Kes9PbWSaPaa9DqyvEiN"),
123
+ mintSymbol: "PYUSD"
124
+ },
125
+ {
126
+ address: address("ApQkX32ULJUzszZDe986aobLDLMNDoGQK8tRm6oD6SsA"),
127
+ mintSymbol: "CASH"
128
+ },
129
+ {
130
+ address: address("ESCkPWKHmgNE7Msf77n9yzqJd5kQVWWGy3o5Mgxhvavp"),
131
+ mintSymbol: "USDG"
132
+ },
133
+ {
134
+ address: address("BHUi32TrEsfN2U821G4FprKrR4hTeK4LCWtA3BFetuqA"),
135
+ mintSymbol: "USDS"
136
+ },
137
+ {
138
+ address: address("H3t6qZ1JkguCNTi9uzVKqQ7dvt2cum4XiXWom6Gn5e5S"),
139
+ mintSymbol: "USDT"
140
+ }
141
+ ],
142
+ /// xStocks Market
143
+ [address("5wJeMrUYECGq41fxRESKALVcHnNX26TAWy4W98yULsua")]: [
144
+ {
145
+ address: address("2jerdAXR8r2B6z3P7P6VgSiePQX7wqcpbEqdDbm8mgeB"),
146
+ mintSymbol: "QQQx"
147
+ },
148
+ {
149
+ address: address("UvXjBuC7YZYaGB9Rn1PpBD1GySmjzunXgE8Zev9ua8d"),
150
+ mintSymbol: "SPYx"
151
+ },
152
+ {
153
+ address: address("97zoywd8mPZsGTg8q1wdD2Wgkdrs2tqusp1Qqcxbyj7E"),
154
+ mintSymbol: "USDC"
155
+ }
156
+ ]
157
+ // Bitcoin Market
158
+ // [address("GMqmFygF5iSm5nkckYU6tieggFcR42SyjkkhK5rswFRs")]: [
159
+ // {
160
+ // address: address("2Xd86oYAuhiKtQMVJBuWvJYxrSippreb46PmehGszpPQ"),
161
+ // mintSymbol: "wBTC"
162
+ // },
163
+ // {
164
+ // address: address("9FRZvAsjDJ6WM8BJ2S45h9PoDCLAq8DNY9zZDX7MyGzT"),
165
+ // mintSymbol: "USDC"
166
+ // }
167
+ // ]
168
+ };
169
+
170
+ // ../../shared/lending-platforms/src/constants/lendingPosition.ts
171
+ var MAX_LENDING_POSITION_UPPER_UTIL_BPS = 10500;
172
+
173
+ // ../../shared/lending-platforms/src/utils/accounts.ts
174
+ function getEligiblePools(mintSymbol) {
175
+ const needle = mintSymbol.toUpperCase();
176
+ const pools = [];
177
+ for (const pool of Object.keys(KAMINO_ACCOUNTS)) {
178
+ const reserves = KAMINO_ACCOUNTS[pool];
179
+ if (reserves.some((r) => r.mintSymbol.toUpperCase() === needle)) {
180
+ pools.push(pool);
181
+ }
182
+ }
183
+ return pools;
184
+ }
185
+
186
+ // ../../shared/lending-platforms/src/utils/cache.ts
187
+ function getLendingUserAccountCacheInvalidation(userAccount) {
188
+ return {
189
+ client: "kamino",
190
+ category: LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT,
191
+ id: userAccount
192
+ };
193
+ }
194
+
195
+ // ../../shared/lending-platforms/src/utils/kamino.ts
196
+ import {
197
+ calculateCurrentRewardPerToken,
198
+ SECONDS_IN_A_DAY
199
+ } from "@kamino-finance/farms-sdk";
200
+ import { BN } from "@anchor-lang/core";
201
+ import { LendingMarket, PROGRAM_ID } from "@kamino-finance/klend-sdk";
202
+ import Decimal from "decimal.js";
203
+ async function fetchExtraFarms() {
204
+ const cdnRes = await fetchWithRetry("https://cdn.kamino.finance/resources.json");
205
+ const allResources = await cdnRes.json();
206
+ return allResources["mainnet-beta"]["extraFarms"];
207
+ }
208
+ function calculateRewardAPY(reserveMint, rewardInfo, totalStakedRaw, stakedTokenDecimals, exchangeRate, rewardMintPrice, requiresPairReserve) {
209
+ let totalStaked = new Decimal(toUiAmount(BigInt(totalStakedRaw), stakedTokenDecimals));
210
+ if (!requiresPairReserve) {
211
+ totalStaked = totalStaked.div(exchangeRate);
212
+ }
213
+ if (totalStaked.isZero()) return 0;
214
+ const rewardPerTokenPerSecond = calculateCurrentRewardPerToken(
215
+ rewardInfo,
216
+ new Decimal(currentUnixSeconds())
217
+ );
218
+ if (!rewardPerTokenPerSecond) return 0;
219
+ const divisor = new Decimal(10).pow(new Decimal(rewardInfo.rewardsPerSecondDecimals.toString())).mul(new Decimal(10).pow(new Decimal(rewardInfo.token.decimals.toString())));
220
+ const adjustedRewardPerToken = new Decimal(rewardPerTokenPerSecond).div(divisor);
221
+ let dailyRewards = adjustedRewardPerToken.mul(SECONDS_IN_A_DAY);
222
+ if (mints.get(rewardInfo.token.mint)?.assetType !== "Stablecoin" && rewardInfo.token.mint !== reserveMint) {
223
+ dailyRewards = dailyRewards.mul(new Decimal(rewardMintPrice));
224
+ }
225
+ const dailyRate = dailyRewards.div(totalStaked);
226
+ const apy = Decimal.pow(dailyRate.plus(1), DAYS_PER_YEAR).minus(1);
227
+ return apy.toNumber();
228
+ }
229
+ function liquidityToCollateral(reserveData, liquidityBaseUnits) {
230
+ const exchangeRate = reserveData.rawData.getEstimatedCollateralExchangeRate(reserveData.slot, 0).toNumber();
231
+ return Math.floor(liquidityBaseUnits * exchangeRate);
232
+ }
233
+
234
+ // ../../shared/lending-platforms/src/utils/math.ts
235
+ function clampUnitInterval(x) {
236
+ if (x <= 0) return 0;
237
+ if (x >= 1) return 1;
238
+ return x;
239
+ }
240
+ function assertLtv(ltv) {
241
+ if (!(ltv > 0) || ltv > 1) {
242
+ throw new RangeError("ltv must be in (0, 1] (e.g. 0.8 for 80% max LTV)");
243
+ }
244
+ }
245
+ function assertLiquidationThreshold(t) {
246
+ if (!(t > 0) || t > 1) {
247
+ throw new RangeError("liquidationThreshold must be in (0, 1] (e.g. 0.85)");
248
+ }
249
+ }
250
+ function maxLtvUtilBeforeCollUsdMultiplierInternal(params) {
251
+ const {
252
+ collateralUsdMultiplier: mult,
253
+ ltv,
254
+ liquidationThreshold,
255
+ targetMaxBorrowUtilizationAfter = 1
256
+ } = params;
257
+ assertLtv(ltv);
258
+ if (!(mult > 0)) {
259
+ throw new RangeError("collateralUsdMultiplier must be positive");
260
+ }
261
+ if (liquidationThreshold !== void 0) {
262
+ assertLiquidationThreshold(liquidationThreshold);
263
+ return clampUnitInterval(mult * liquidationThreshold / ltv);
264
+ }
265
+ if (!(targetMaxBorrowUtilizationAfter > 0) || targetMaxBorrowUtilizationAfter > 1) {
266
+ throw new RangeError(
267
+ "targetMaxBorrowUtilizationAfter must be in (0, 1] (1 = 100% of borrow limit)"
268
+ );
269
+ }
270
+ return clampUnitInterval(mult * targetMaxBorrowUtilizationAfter);
271
+ }
272
+ function maxLtvUtilBeforeCollDrawdown(params) {
273
+ if (!(params.drawdownPercent >= 0)) {
274
+ throw new RangeError("drawdownPercent must be non-negative (e.g. 30 for a 30% drop)");
275
+ }
276
+ const collateralUsdMultiplier = 1 - params.drawdownPercent / 100;
277
+ if (!(collateralUsdMultiplier > 0)) {
278
+ throw new RangeError(
279
+ "drawdownPercent must be less than 100 so collateral USD remains positive"
280
+ );
281
+ }
282
+ return maxLtvUtilBeforeCollUsdMultiplierInternal({
283
+ collateralUsdMultiplier,
284
+ ltv: params.ltv,
285
+ targetMaxBorrowUtilizationAfter: params.targetMaxBorrowUtilizationAfter,
286
+ liquidationThreshold: params.liquidationThreshold
287
+ });
288
+ }
289
+ function ltvUtilAfterCollateralPricePctChg(currentLtvUtilization, collateralPricePctChg) {
290
+ if (!(currentLtvUtilization >= 0) || currentLtvUtilization > 1) {
291
+ throw new RangeError("currentLtvUtilization must be in [0, 1]");
292
+ }
293
+ const mult = 1 + collateralPricePctChg / 100;
294
+ if (!(mult > 0)) {
295
+ throw new RangeError(
296
+ "collateralPricePctChg must be greater than -100 so collateral USD stays positive"
297
+ );
298
+ }
299
+ return currentLtvUtilization / mult;
300
+ }
301
+ function ltvUtilDeltaBelowTargForRallyPct(targetLtvUtilization, rallyPercentPositive) {
302
+ if (!(targetLtvUtilization > 0) || targetLtvUtilization > 1) {
303
+ throw new RangeError("targetLtvUtilization must be in (0, 1]");
304
+ }
305
+ if (!Number.isFinite(rallyPercentPositive) || rallyPercentPositive <= 0) {
306
+ throw new RangeError("rallyPercentPositive must be finite and positive");
307
+ }
308
+ const after = ltvUtilAfterCollateralPricePctChg(targetLtvUtilization, rallyPercentPositive);
309
+ return targetLtvUtilization - after;
310
+ }
311
+
312
+ // ../../shared/lending-platforms/src/utils/scope.ts
313
+ import { Scope } from "@kamino-finance/scope-sdk";
314
+ var ORACLE_TYPE_MOST_RECENT_OF = 28;
315
+ var ORACLE_TYPE_CAPPED_FLOORED = 33;
316
+ var MOST_RECENT_OF_UNUSED = 512;
317
+ function collectTokenDependencies(token, mappings, result, depth = 0) {
318
+ if (result.has(token) || depth > 5) return;
319
+ const isValidDep = (dep2) => dep2 !== void 0 && dep2 !== token && dep2 < mappings.priceInfoAccounts.length && mappings.priceInfoAccounts[dep2] !== DEFAULT_PUBLIC_KEY;
320
+ const recurse = (dep2) => collectTokenDependencies(dep2, mappings, result, depth + 1);
321
+ if (mappings.priceTypes[token] === ORACLE_TYPE_MOST_RECENT_OF) {
322
+ const raw = mappings.generic[token];
323
+ if (raw?.length >= 8) {
324
+ for (let i = 0; i < 4; i++) {
325
+ const src = raw[i * 2] | raw[i * 2 + 1] << 8;
326
+ if (src !== MOST_RECENT_OF_UNUSED && isValidDep(src)) {
327
+ recurse(src);
328
+ }
329
+ }
330
+ }
331
+ } else if (mappings.priceTypes[token] === ORACLE_TYPE_CAPPED_FLOORED) {
332
+ const raw = mappings.generic[token];
333
+ if (raw?.length >= 7) {
334
+ const sourceEntry = raw[0] | raw[1] << 8;
335
+ if (isValidDep(sourceEntry)) recurse(sourceEntry);
336
+ if (raw[2] === 1) {
337
+ const capEntry = raw[3] | raw[4] << 8;
338
+ if (isValidDep(capEntry)) recurse(capEntry);
339
+ }
340
+ const floorOffset = raw[2] === 1 ? 5 : 3;
341
+ if (raw[floorOffset] === 1) {
342
+ const floorEntry = raw[floorOffset + 1] | raw[floorOffset + 2] << 8;
343
+ if (isValidDep(floorEntry)) recurse(floorEntry);
344
+ }
345
+ }
346
+ }
347
+ const dep = mappings.refPrice[token];
348
+ if (isValidDep(dep)) {
349
+ recurse(dep);
350
+ }
351
+ result.add(token);
352
+ }
353
+
354
+ // ../../shared/lending-platforms/src/data/platform/kamino.ts
355
+ import Decimal2 from "decimal.js";
356
+ var KaminoData = class extends LendingPlatformData {
357
+ constructor(rpcUrl, cacheConfig, rpcUrls = [rpcUrl]) {
358
+ const ttlConfig = {
359
+ defaultTtlMs: 9e4,
360
+ categoryTtlMs: {
361
+ ...cacheConfig?.categoryTtlMs,
362
+ markets: 6e4 * 5,
363
+ farms: 6e4 * 5,
364
+ extraFarms: Number.MAX_SAFE_INTEGER,
365
+ scopeOraclePrices: 3e4,
366
+ scopeConfig: 6e4 * 5
367
+ }
368
+ };
369
+ super(rpcUrl, ttlConfig, rpcUrls);
370
+ this.farms = new Farms(this.rpc, KAMINO_FARMS_PROGRAM_ID);
371
+ this.scope = new Scope2("mainnet-beta", this.rpc);
372
+ }
373
+ platform() {
374
+ return 0 /* Kamino */;
375
+ }
376
+ /**
377
+ * Warms the market cache for the requested pools. Single-pool calls reuse the
378
+ * normal lazy fetch path; multi-pool calls use Kamino's batched loader.
379
+ */
380
+ async load(pools) {
381
+ if (pools.length === 0) return;
382
+ if (pools.length === 1) {
383
+ await this.fetchMarket(pools[0]);
384
+ return;
385
+ }
386
+ const { data: markets, fromCache } = await this.cache.getDataBatch(
387
+ async () => {
388
+ const marketsData = await KaminoMarket.loadMultiple(
389
+ this.rpc,
390
+ pools,
391
+ DEFAULT_RECENT_SLOT_DURATION_MS,
392
+ PROGRAM_ID2,
393
+ true
394
+ );
395
+ return pools.map((pool) => marketsData.get(pool) ?? null);
396
+ },
397
+ this.poolCatKey,
398
+ pools
399
+ );
400
+ if (!fromCache) {
401
+ await Promise.all(markets.map(async (market) => await market.loadReserves()));
402
+ }
403
+ }
404
+ /** Fetches a market by address, loading from cache if available */
405
+ async fetchMarket(market) {
406
+ const { data, fromCache } = await this.cache.getDataOrThrow(
407
+ async () => await KaminoMarket.load(
408
+ this.rpc,
409
+ market,
410
+ DEFAULT_RECENT_SLOT_DURATION_MS,
411
+ PROGRAM_ID2,
412
+ true
413
+ ),
414
+ this.poolCatKey,
415
+ market
416
+ );
417
+ if (!fromCache) {
418
+ await data.loadReserves();
419
+ }
420
+ return data;
421
+ }
422
+ /** Fetches all oracle prices for assets in the specified market */
423
+ async fetchPrices(pool) {
424
+ const market = await this.fetchMarket(pool);
425
+ const { data } = await this.cache.getDataOrThrow(
426
+ async () => await market.getAllPrices(),
427
+ "prices",
428
+ "queryAll"
429
+ );
430
+ return data;
431
+ }
432
+ /** Fetches an obligation (user position) by address */
433
+ async fetchObligation(market, obligation) {
434
+ const { data } = await this.cache.getData(
435
+ async () => await market.getObligationByAddress(obligation),
436
+ this.userAccountCatKey,
437
+ obligation,
438
+ { cacheNull: false }
439
+ );
440
+ return data;
441
+ }
442
+ /** Batch fetches farm states by their addresses */
443
+ async fetchFarms(farms) {
444
+ const { data } = await this.cache.getDataBatch(
445
+ async () => (await this.farms.getAllFarmStatesByPubkeys(farms)).map((x) => x.farmState),
446
+ "userFarms",
447
+ farms
448
+ );
449
+ return data;
450
+ }
451
+ async fetchExtraFarms() {
452
+ const { data } = await this.cache.getDataOrThrow(
453
+ async () => await fetchExtraFarms(),
454
+ "extraFarms",
455
+ "mainnet-beta"
456
+ );
457
+ return data;
458
+ }
459
+ /**
460
+ * Collects all farm incentives for a reserve, including both standard
461
+ * collateral/debt farms and extra paired farms from Kamino CDN config.
462
+ */
463
+ async fetchFarmsForReserve(pool, reserve) {
464
+ const market = await this.fetchMarket(pool);
465
+ const reserveData = market.getReserveByAddress(reserve);
466
+ if (!reserveData) {
467
+ throw new Error(`Unable to find reserve ${reserve}`);
468
+ }
469
+ const farms = [];
470
+ const farmCollateral = reserveData.state.farmCollateral;
471
+ const farmDebt = reserveData.state.farmDebt;
472
+ if (farmCollateral && farmCollateral !== DEFAULT_PUBLIC_KEY2) {
473
+ farms.push({ address: farmCollateral, isDebtFarm: false });
474
+ }
475
+ if (farmDebt && farmDebt !== DEFAULT_PUBLIC_KEY2) {
476
+ farms.push({ address: farmDebt, isDebtFarm: true });
477
+ }
478
+ const extraFarmsData = (await this.fetchExtraFarms()).filter(
479
+ (x) => x.collReserve === reserve || x.debtReserve === reserve
480
+ );
481
+ const extraFarmEntries = extraFarmsData.map((x) => ({
482
+ address: x.farm,
483
+ isDebtFarm: x.debtReserve === reserve
484
+ }));
485
+ const allFarmEntries = [...farms, ...extraFarmEntries];
486
+ const allFarmAddresses = allFarmEntries.map((f) => f.address);
487
+ if (!allFarmAddresses.length) {
488
+ return [];
489
+ }
490
+ const farmStates = await this.fetchFarms(allFarmAddresses);
491
+ const result = [];
492
+ farmStates.forEach((farmState, i) => {
493
+ const farmEntry = allFarmEntries[i];
494
+ const isExtraFarm = i >= farms.length;
495
+ const extraFarmIndex = i - farms.length;
496
+ farmState.rewardInfos.forEach((rewardInfo, rewardIndex) => {
497
+ if (rewardInfo.rewardsVault === DEFAULT_PUBLIC_KEY2) {
498
+ return;
499
+ }
500
+ result.push({
501
+ data: {
502
+ key: farmEntry.address,
503
+ farmState
504
+ },
505
+ rewardIndex,
506
+ requiresPairReserve: isExtraFarm ? extraFarmsData[extraFarmIndex].debtReserve : void 0,
507
+ isDebtFarm: farmEntry.isDebtFarm
508
+ });
509
+ });
510
+ });
511
+ return result;
512
+ }
513
+ async fetchUserActiveIncentives(user, specificFarm) {
514
+ let { data } = await this.cache.getDataOrThrow(
515
+ async () => {
516
+ return Array.from(
517
+ (await this.farms.getAllFarmsForUserMultiState(user, new Decimal2(currentUnixSeconds()))).values()
518
+ ).flat();
519
+ },
520
+ "userFarms",
521
+ user
522
+ );
523
+ if (specificFarm) {
524
+ data = data.filter((x) => x.farm === specificFarm);
525
+ }
526
+ return data;
527
+ }
528
+ async maybeFetchUserPositionInPool(pool, userPosition) {
529
+ const market = await this.fetchMarket(pool);
530
+ const obligation = await this.fetchObligation(market, userPosition);
531
+ return obligation ? KaminoUserPositionData.loadData(obligation) : null;
532
+ }
533
+ async fetchUserPositionsInPool(pool, userPositions) {
534
+ const market = await this.fetchMarket(pool);
535
+ const { data } = await this.cache.getDataBatch(
536
+ async () => await market.getMultipleObligationsByAddress(userPositions),
537
+ this.userAccountCatKey,
538
+ userPositions
539
+ );
540
+ return data.map((obligation) => KaminoUserPositionData.loadData(obligation));
541
+ }
542
+ async fetchAllUserPositionsForUserInPool(pool, user) {
543
+ const market = await this.fetchMarket(pool);
544
+ const { data } = await this.cache.getDataOrThrow(
545
+ async () => await market.getAllUserObligations(user, "confirmed"),
546
+ "obligationsBatch",
547
+ user
548
+ );
549
+ return data.map((obligation) => KaminoUserPositionData.loadData(obligation));
550
+ }
551
+ async fetchReserve(pool, reserve) {
552
+ const market = await this.fetchMarket(pool);
553
+ const reserveData = market.getReserveByAddress(reserve);
554
+ if (!reserveData) {
555
+ throw new Error(`Unable to find reserve ${reserve}`);
556
+ }
557
+ return this.mapReserve(market, reserveData);
558
+ }
559
+ async fetchReserveByMint(pool, mint) {
560
+ const market = await this.fetchMarket(pool);
561
+ const reserveData = market.getReserveByMint(mint);
562
+ if (!reserveData) {
563
+ throw new Error(`Unable to find reserve by mint ${mint}`);
564
+ }
565
+ return this.mapReserve(market, reserveData);
566
+ }
567
+ async mapReserve(market, reserve) {
568
+ return KaminoReserveData.loadData(
569
+ market,
570
+ reserve,
571
+ await this.fetchFarmsForReserve(market.address, reserve.address),
572
+ await this.fetchPrices(market.address),
573
+ await this.getSlot()
574
+ );
575
+ }
576
+ /**
577
+ * Fetches and caches the Scope OraclePrices account for a given price feed.
578
+ * @returns The deserialized OraclePrices, or null if the account doesn't exist
579
+ */
580
+ async fetchScopeOraclePrices(priceFeed) {
581
+ const { data } = await this.cache.getData(
582
+ async () => await this.scope.getSingleOraclePrices({ prices: priceFeed }),
583
+ "scopeOraclePrices",
584
+ priceFeed
585
+ );
586
+ return data;
587
+ }
588
+ /**
589
+ * Resolves and caches the Scope Configuration account address for a given OraclePrices account.
590
+ * The first call per price feed does a getProgramAccounts lookup; subsequent calls use cache.
591
+ */
592
+ async fetchScopeConfigAddress(priceFeed) {
593
+ const { data } = await this.cache.getDataOrThrow(
594
+ async () => {
595
+ const [configAddr] = await this.scope.getSingleFeedConfiguration({
596
+ prices: priceFeed
597
+ });
598
+ return configAddr;
599
+ },
600
+ "scopeConfig",
601
+ priceFeed
602
+ );
603
+ return data;
604
+ }
605
+ };
606
+
607
+ // ../../shared/lending-platforms/src/data/reserve/kamino.ts
608
+ import {
609
+ isNotNullPubkey
610
+ } from "@kamino-finance/klend-sdk";
611
+ import Decimal4 from "decimal.js";
612
+
613
+ // ../../shared/lending-platforms/src/data/incentive/incentiveBase.ts
614
+ var TokenIncentiveBase = class {
615
+ constructor(address4, config) {
616
+ this.address = address4;
617
+ this.config = config;
618
+ }
619
+ };
620
+
621
+ // ../../shared/lending-platforms/src/data/incentive/kamino.ts
622
+ import Decimal3 from "decimal.js";
623
+ import { BN as BN2 } from "@anchor-lang/core";
624
+ import {
625
+ calculateCurrentRewardPerToken as calculateCurrentRewardPerToken2
626
+ } from "@kamino-finance/farms-sdk";
627
+ var KaminoIncentiveData = class _KaminoIncentiveData extends TokenIncentiveBase {
628
+ /**
629
+ * Creates a KaminoIncentiveData instance from farm and reserve data.
630
+ * Determines the incentive type and calculates current exchange rates.
631
+ */
632
+ static loadData(args, reserve, prices, slot) {
633
+ const {
634
+ data: { key, farmState },
635
+ rewardIndex,
636
+ requiresPairReserve,
637
+ isDebtFarm
638
+ } = args;
639
+ const rewardInfo = farmState.rewardInfos[rewardIndex];
640
+ const data = new _KaminoIncentiveData(key, {
641
+ rewardMint: rewardInfo.token.mint,
642
+ incentiveType: isDebtFarm ? "Borrowing" /* BorrowingOnly */ : requiresPairReserve ? "Pair" /* Pair */ : "Lending" /* LendingOnly */,
643
+ requiresPairReserve
644
+ });
645
+ data.rawReserve = reserve;
646
+ data.rawFarm = farmState;
647
+ data.rewardInfo = farmState.rewardInfos[rewardIndex];
648
+ data.isDebtFarm = isDebtFarm;
649
+ const collateralExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0).toNumber();
650
+ const debtExchangeRate = reserve.getEstimatedCumulativeBorrowRate(slot, 0).toNumber();
651
+ data.exchangeRate = isDebtFarm ? debtExchangeRate : collateralExchangeRate;
652
+ const rewardMint = rewardInfo.token.mint;
653
+ const scope = prices.scope.spot[rewardMint];
654
+ const pyth = prices.pyth.spot[rewardMint];
655
+ const swb = prices.switchboard.spot[rewardMint];
656
+ data.rewardMintPrice = scope ? scope.price.toNumber() : pyth ? pyth.price.toNumber() : swb ? swb.price.toNumber() : 0;
657
+ return data;
658
+ }
659
+ /**
660
+ * Checks if the incentive is currently active.
661
+ * An incentive is active if rewards are available, the schedule has started,
662
+ * and there is a non-zero emission rate.
663
+ */
664
+ active() {
665
+ const rewardsAvailable = this.rewardInfo.rewardsAvailable.gtn(0);
666
+ const hasStarted = this.rewardInfo.rewardScheduleCurve.points[0].tsStart.toNumber() < currentUnixSeconds();
667
+ const rewardPerTokenPerSecond = calculateCurrentRewardPerToken2(
668
+ this.rewardInfo,
669
+ new Decimal3(currentUnixSeconds())
670
+ );
671
+ return rewardsAvailable && hasStarted && rewardPerTokenPerSecond > 0;
672
+ }
673
+ /** Calculates the current APY based on total staked amount and reward emission rate */
674
+ apy() {
675
+ const { totalStaked, stakedTokenDecimals } = this.getStakedTokenData();
676
+ return calculateRewardAPY(
677
+ this.rawReserve.getLiquidityMint(),
678
+ this.rewardInfo,
679
+ totalStaked.toString(),
680
+ stakedTokenDecimals,
681
+ this.exchangeRate,
682
+ this.rewardMintPrice,
683
+ Boolean(this.config.requiresPairReserve)
684
+ );
685
+ }
686
+ /**
687
+ * Simulates the APY after a hypothetical position change.
688
+ * Useful for calculating expected rewards before executing a transaction.
689
+ */
690
+ simulateNewAPY(args) {
691
+ const changeInUnderlying = this.isDebtFarm ? args.debtChange ?? 0 : args.collateralChange ?? 0;
692
+ if (changeInUnderlying === 0) {
693
+ return this.apy();
694
+ }
695
+ const { totalStaked, stakedTokenDecimals } = this.getStakedTokenData();
696
+ const changeInShares = changeInUnderlying / this.exchangeRate;
697
+ const changeInSharesRaw = new BN2(
698
+ Math.round(changeInShares * Math.pow(10, stakedTokenDecimals))
699
+ );
700
+ const newTotalStakedRaw = new BN2(totalStaked.toString()).add(changeInSharesRaw);
701
+ return calculateRewardAPY(
702
+ this.rawReserve.getLiquidityMint(),
703
+ this.rewardInfo,
704
+ newTotalStakedRaw.toString(),
705
+ stakedTokenDecimals,
706
+ this.exchangeRate,
707
+ this.rewardMintPrice,
708
+ Boolean(this.config.requiresPairReserve)
709
+ );
710
+ }
711
+ /**
712
+ * Returns staking metrics for APY calculation.
713
+ * Falls back to reserve decimals if farm token decimals are not set.
714
+ */
715
+ getStakedTokenData() {
716
+ return {
717
+ totalStaked: this.rawFarm.totalStakedAmount,
718
+ stakedTokenDecimals: this.rawFarm.token.decimals.toNumber() || (this.config.requiresPairReserve ? 6 : this.rawReserve.getMintDecimals())
719
+ };
720
+ }
721
+ };
722
+
723
+ // ../../shared/lending-platforms/src/data/reserve/reserveBase.ts
724
+ var ReserveBase = class {
725
+ constructor(address4, mint, config, deposits, borrows, state, incentives) {
726
+ this.address = address4;
727
+ this.mint = mint;
728
+ this.config = config;
729
+ this.deposits = deposits;
730
+ this.borrows = borrows;
731
+ this.state = state;
732
+ this.incentives = incentives;
733
+ this.createdAt = Date.now();
734
+ }
735
+ normalizeLtvPct(ltvPct) {
736
+ return ltvPct <= 1 ? ltvPct : ltvPct / 100;
737
+ }
738
+ /** Returns the cached price, or undefined if stale */
739
+ get mintPrice() {
740
+ if (this.mint.price === void 0) {
741
+ return void 0;
742
+ }
743
+ const ageMs = Date.now() - this.createdAt;
744
+ if (ageMs > PRICE_STALENESS_SECONDS * 1e3) {
745
+ return void 0;
746
+ }
747
+ return this.mint.price;
748
+ }
749
+ /** Returns the cached EMA price, or undefined if stale/missing */
750
+ get mintEmaPrice() {
751
+ if (this.mint.emaPrice === void 0) {
752
+ return void 0;
753
+ }
754
+ const ageMs = Date.now() - this.createdAt;
755
+ if (ageMs > PRICE_STALENESS_SECONDS * 1e3) {
756
+ return void 0;
757
+ }
758
+ return this.mint.emaPrice;
759
+ }
760
+ /**
761
+ * Returns the reserve LTV in decimal form, where `0.5 = 50%`.
762
+ */
763
+ get ltvPct() {
764
+ return this.normalizeLtvPct(this.config.ltvPct);
765
+ }
766
+ /**
767
+ * Returns e-mode configs with `ltvPct` normalized to decimal form, where
768
+ * `0.5 = 50%`.
769
+ */
770
+ get emodes() {
771
+ return this.config.emodes?.map((emode) => ({
772
+ ...emode,
773
+ ltvPct: this.normalizeLtvPct(emode.ltvPct)
774
+ }));
775
+ }
776
+ utilizationRatePct() {
777
+ return this.state.utilizationRatePct;
778
+ }
779
+ /** Returns borrowable liquidity, accounting for both available balance and borrow limits, in UI amount (e.g. 1.234) */
780
+ liquidityAvailable() {
781
+ return Math.min(this.state.availableLiquidity, this.borrows.limit - this.borrows.totalAmount);
782
+ }
783
+ /**
784
+ * Returns the total supply APY including base rate and eligible supply-side
785
+ * incentives (types `LendingOnly` and `Pair`). Borrow-side incentives are
786
+ * excluded here — they reward borrowers, not lenders.
787
+ * @param usingDebtReserve - When specified, includes paired incentives requiring this debt reserve
788
+ */
789
+ supplyAPY(usingDebtReserve) {
790
+ return this.deposits.apy + this.sumEligibleIncentivesAPY("supply", usingDebtReserve);
791
+ }
792
+ /**
793
+ * Returns the effective borrow APY (base rate minus eligible borrow-side
794
+ * incentive rebates, i.e. `BorrowingOnly`). Lender-side incentives are
795
+ * excluded — they are paid to lenders and do not offset borrower cost.
796
+ * @param usingSupplyReserve - When specified, includes paired incentives requiring this collateral
797
+ */
798
+ borrowAPY(usingSupplyReserve) {
799
+ return this.borrows.apy - this.sumEligibleIncentivesAPY("borrow", usingSupplyReserve);
800
+ }
801
+ /** Sums APY from incentives eligible for the given side and paired reserve */
802
+ sumEligibleIncentivesAPY(side, usingPairReserve) {
803
+ return sum(this.getEligibleIncentives(side, usingPairReserve).map((x) => x.apy()));
804
+ }
805
+ /** Sums the new simulated APY from incentives eligible for the given side and paired reserve */
806
+ simulateNewEligbleIncentivesAPY(args, side, usingPairReserve) {
807
+ return sum(
808
+ this.getEligibleIncentives(side, usingPairReserve).map((x) => x.simulateNewAPY(args))
809
+ );
810
+ }
811
+ /**
812
+ * Filters incentives eligible for the given side (supply vs borrow) and
813
+ * paired reserve.
814
+ *
815
+ * Side filter:
816
+ * - `supply`: `LendingOnly` and `Pair` (collateral-farm incentives,
817
+ * optionally gated on a specific debt reserve).
818
+ * - `borrow`: `BorrowingOnly` (debt-farm incentives, optionally gated on a
819
+ * specific collateral reserve via `requiresPairReserve`).
820
+ *
821
+ * Pair filter: incentives with `requiresPairReserve` only apply when that
822
+ * reserve matches the caller's pair.
823
+ */
824
+ getEligibleIncentives(side, usingPairReserve) {
825
+ return (this.incentives ?? []).filter((x) => {
826
+ const sideMatches = side === "borrow" ? x.config.incentiveType === "Borrowing" /* BorrowingOnly */ : x.config.incentiveType !== "Borrowing" /* BorrowingOnly */;
827
+ if (!sideMatches) return false;
828
+ return !x.config.requiresPairReserve || x.config.requiresPairReserve === usingPairReserve;
829
+ });
830
+ }
831
+ canDeposit(amount) {
832
+ return amount <= this.deposits.limit;
833
+ }
834
+ canBorrow(amount) {
835
+ return amount <= this.borrows.limit;
836
+ }
837
+ };
838
+
839
+ // ../../shared/lending-platforms/src/data/reserve/kamino.ts
840
+ var KaminoReserveData = class _KaminoReserveData extends ReserveBase {
841
+ /**
842
+ * Creates a KaminoReserveData instance from raw SDK types.
843
+ * Extracts and normalizes configuration, rates, limits, and incentives.
844
+ */
845
+ static loadData(market, reserve, reserveFarms, prices, slot) {
846
+ const stats = reserve.stats;
847
+ const state = reserve.state;
848
+ const config = state.config;
849
+ const mintDecimals = reserve.getMintDecimals();
850
+ const price = reserve.getOracleMarketPrice().toNumber();
851
+ const allElevationGroups = config.elevationGroups.map((id) => market.getElevationGroup(id)).filter(
852
+ (group) => group !== void 0 && group.debtReserve !== reserve.address && group.maxReservesAsCollateral === 1
853
+ );
854
+ const data = new _KaminoReserveData(
855
+ reserve.address,
856
+ {
857
+ mint: reserve.getLiquidityMint(),
858
+ mintDecimals,
859
+ mintTokenProgram: reserve.getLiquidityTokenProgram(),
860
+ price
861
+ },
862
+ {
863
+ ltvPct: stats.loanToValue,
864
+ liquidationThresholdPct: stats.liquidationThreshold,
865
+ borrowFeePct: reserve.getBorrowFee().toNumber(),
866
+ flashLoanFeePct: reserve.getFlashLoanFee().toNumber(),
867
+ emodes: allElevationGroups.map((x) => ({
868
+ id: x.id,
869
+ debtReserve: x.debtReserve,
870
+ ltvPct: x.ltvPct,
871
+ liquidationThresholdPct: x.liquidationThresholdPct
872
+ }))
873
+ },
874
+ {
875
+ totalAmount: reserve.getDepositTvl().toNumber() / price,
876
+ limit: toUiAmount(config.depositLimit, mintDecimals),
877
+ apy: reserve.totalSupplyAPY(slot)
878
+ },
879
+ {
880
+ totalAmount: reserve.getBorrowTvl().toNumber() / price,
881
+ limit: toUiAmount(config.borrowLimit, mintDecimals),
882
+ apy: reserve.totalBorrowAPY(slot)
883
+ },
884
+ {
885
+ utilizationRatePct: reserve.calculateUtilizationRatio(),
886
+ availableLiquidity: toUiAmount(
887
+ BigInt(reserve.getLiquidityAvailableAmount().toFixed(0)),
888
+ mintDecimals
889
+ )
890
+ },
891
+ reserveFarms.map((x) => KaminoIncentiveData.loadData(x, reserve, prices, slot)).filter((x) => x.active() || [state.farmCollateral, state.farmDebt].includes(x.address))
892
+ );
893
+ data.rawData = reserve;
894
+ data.slot = slot;
895
+ return data;
896
+ }
897
+ /** Checks if TWAP price validation is enabled for this reserve */
898
+ isTwapEnabled() {
899
+ return this.rawData.state.config.tokenInfo.maxTwapDivergenceBps.toNumber() > 0;
900
+ }
901
+ /**
902
+ * Determines if the reserve's on-chain price data is stale and needs refreshing.
903
+ */
904
+ requiresRefresh() {
905
+ return true;
906
+ }
907
+ /**
908
+ * Returns all configured oracle account addresses for this reserve.
909
+ * Only includes accounts that are actually enabled.
910
+ */
911
+ getOracleAccounts() {
912
+ const tokenInfo = this.rawData.state.config.tokenInfo;
913
+ const pythAccount = tokenInfo.pythConfiguration.price;
914
+ const switchboardPrice = tokenInfo.switchboardConfiguration.priceAggregator;
915
+ const switchboardTwap = tokenInfo.switchboardConfiguration.twapAggregator;
916
+ const scope = tokenInfo.scopeConfiguration.priceFeed;
917
+ const pythEnabled = isNotNullPubkey(pythAccount);
918
+ const switchboardEnabled = isNotNullPubkey(switchboardPrice);
919
+ const switchboardTwapEnabled = switchboardEnabled && this.isTwapEnabled() && isNotNullPubkey(switchboardTwap);
920
+ const scopeEnabled = isNotNullPubkey(scope);
921
+ return {
922
+ pythPrice: pythEnabled ? pythAccount : void 0,
923
+ switchboardPrice: switchboardEnabled ? switchboardPrice : void 0,
924
+ switchboardTwap: switchboardTwapEnabled ? switchboardTwap : void 0,
925
+ scope: scopeEnabled ? scope : void 0
926
+ };
927
+ }
928
+ /**
929
+ * Simulates the supply APY after a position balance change.
930
+ * Uses the SDK's calcSimulatedSupplyAPR which accounts for utilization changes.
931
+ */
932
+ simulateNewSupplyAPY(args, usingDebtReserve) {
933
+ const collateralChange = args.collateralChange ?? 0;
934
+ if (!collateralChange) {
935
+ return this.supplyAPY(usingDebtReserve);
936
+ }
937
+ const simulatedAPR = this.rawData.calcSimulatedSupplyAPR(
938
+ new Decimal4(fromUiAmount(collateralChange, this.mint.mintDecimals).toNumber()),
939
+ collateralChange > 0 ? "deposit" : "withdraw",
940
+ this.slot,
941
+ 0
942
+ );
943
+ return simulatedAPR + this.simulateNewEligbleIncentivesAPY(args, "supply", usingDebtReserve);
944
+ }
945
+ /**
946
+ * Simulates the borrow APY after a position balance change.
947
+ * Uses the SDK's calcSimulatedBorrowAPR which accounts for utilization changes.
948
+ */
949
+ simulateNewBorrowAPY(args, usingSupplyReserve) {
950
+ const debtChange = args.debtChange ?? 0;
951
+ if (!debtChange) {
952
+ return this.borrowAPY(usingSupplyReserve);
953
+ }
954
+ const simulatedAPR = this.rawData.calcSimulatedBorrowAPR(
955
+ new Decimal4(fromUiAmount(debtChange, this.mint.mintDecimals).toNumber()),
956
+ debtChange > 0 ? "borrow" : "repay",
957
+ this.slot,
958
+ 0
959
+ );
960
+ return simulatedAPR - this.simulateNewEligbleIncentivesAPY(args, "borrow", usingSupplyReserve);
961
+ }
962
+ canWithdraw(amount) {
963
+ const capCapacity = this.rawData.getDepositWithdrawalCapCapacity();
964
+ const capCurrent = this.rawData.getDepositWithdrawalCapCurrent(this.slot);
965
+ return this.hasCapacity(amount, capCapacity, capCurrent);
966
+ }
967
+ canBorrow(amount) {
968
+ const capCapacity = this.rawData.getDebtWithdrawalCapCapacity();
969
+ const capCurrent = this.rawData.getDebtWithdrawalCapCurrent(this.slot);
970
+ return amount <= this.borrows.limit && this.hasCapacity(amount, capCapacity, capCurrent);
971
+ }
972
+ hasCapacity(amount, capCapacity, capCurrent) {
973
+ if (!capCapacity.isZero()) {
974
+ const remainingCap = toUiAmount(
975
+ BigInt(capCapacity.minus(capCurrent).toFixed(0)),
976
+ this.mint.mintDecimals
977
+ );
978
+ if (amount > remainingCap) {
979
+ return false;
980
+ }
981
+ }
982
+ return true;
983
+ }
984
+ };
985
+
986
+ // ../../shared/lending-platforms/src/data/userPosition/kamino.ts
987
+ import { BN as BN4 } from "@anchor-lang/core";
988
+
989
+ // ../../shared/lending-platforms/src/data/userPosition/userPositionBase.ts
990
+ import { BN as BN3 } from "@anchor-lang/core";
991
+ var UserPositionBase = class {
992
+ constructor(address4, utilizationRate, deposits, borrows, ltv, liquidationThreshold, borrowLimitUsd) {
993
+ this.address = address4;
994
+ this.utilizationRate = utilizationRate;
995
+ this.deposits = deposits;
996
+ this.borrows = borrows;
997
+ this.ltv = ltv;
998
+ this.liquidationThreshold = liquidationThreshold;
999
+ this.borrowLimitUsd = borrowLimitUsd;
1000
+ }
1001
+ /** Aggregate borrowed USD for headroom; prefers per-borrow breakdown when present. */
1002
+ userPositionBorrowedValueUsd() {
1003
+ const fromBorrows = this.borrows.reduce((sum2, borrow) => sum2 + borrow.valueUsd, 0);
1004
+ if (fromBorrows > 0) {
1005
+ return fromBorrows;
1006
+ }
1007
+ if (this.borrowLimitUsd !== void 0 && this.utilizationRate > 0) {
1008
+ return this.borrowLimitUsd * this.utilizationRate;
1009
+ }
1010
+ return 0;
1011
+ }
1012
+ /**
1013
+ * Max additional debt UI amount before the platform rejects the borrow.
1014
+ * Uses obligation `borrowLimitUsd − borrowedUsd`, floored to base units with a
1015
+ * one-unit buffer so simulation-time refresh cannot overshoot. Returns `undefined`
1016
+ * when `borrowLimitUsd` was not set by the platform loader.
1017
+ */
1018
+ getMaxAdditionalBorrowUiAmount(debtPriceUsd, debtDecimals) {
1019
+ if (this.borrowLimitUsd === void 0) {
1020
+ return void 0;
1021
+ }
1022
+ const borrowedValueUsd = this.userPositionBorrowedValueUsd();
1023
+ const headroomUsd = Math.max(0, this.borrowLimitUsd - borrowedValueUsd);
1024
+ if (headroomUsd <= 0 || !(debtPriceUsd > 0)) {
1025
+ return 0;
1026
+ }
1027
+ const headroomUi = headroomUsd / debtPriceUsd;
1028
+ const maxBaseUnits = fromUiAmount(headroomUi, debtDecimals);
1029
+ const safeBaseUnits = BN3.max(maxBaseUnits.subn(1), new BN3(0));
1030
+ return toUiAmount(safeBaseUnits, debtDecimals);
1031
+ }
1032
+ };
1033
+
1034
+ // ../../shared/lending-platforms/src/data/userPosition/kamino.ts
1035
+ var KaminoUserPositionData = class _KaminoUserPositionData extends UserPositionBase {
1036
+ /** Creates a KaminoUserPositionData from a raw KaminoObligation */
1037
+ static loadData(obligation) {
1038
+ const deposits = [];
1039
+ obligation.deposits.forEach((deposit, mint) => {
1040
+ deposits.push({
1041
+ reserve: deposit.reserveAddress,
1042
+ mint,
1043
+ amount: new BN4(deposit.amount.toFixed(0)),
1044
+ valueUsd: deposit.marketValueRefreshed.toNumber()
1045
+ });
1046
+ });
1047
+ const borrows = [];
1048
+ obligation.borrows.forEach((borrow, mint) => {
1049
+ borrows.push({
1050
+ reserve: borrow.reserveAddress,
1051
+ mint,
1052
+ amount: new BN4(borrow.amount.toFixed(0)),
1053
+ valueUsd: borrow.marketValueRefreshed.toNumber()
1054
+ });
1055
+ });
1056
+ const borrowedValueUsd = obligation.refreshedStats.userTotalBorrow.toNumber();
1057
+ const borrowLimitUsd = obligation.refreshedStats.borrowLimit.toNumber();
1058
+ const utilizationRate = borrowLimitUsd > 0 ? borrowedValueUsd / borrowLimitUsd : 0;
1059
+ const data = new _KaminoUserPositionData(
1060
+ obligation.obligationAddress,
1061
+ utilizationRate,
1062
+ deposits,
1063
+ borrows,
1064
+ void 0,
1065
+ void 0,
1066
+ borrowLimitUsd
1067
+ );
1068
+ data.rawData = obligation;
1069
+ return data;
1070
+ }
1071
+ /**
1072
+ * Determines if the obligation needs a refresh_obligation instruction.
1073
+ */
1074
+ requiresRefresh() {
1075
+ return true;
1076
+ }
1077
+ };
1078
+
1079
+ // ../../shared/lending-platforms/src/data/instructions/kamino.ts
1080
+ import { BN as BN5 } from "@anchor-lang/core";
1081
+ import { address as address2, getAddressEncoder } from "@solana/kit";
1082
+ import { Scope as Scope3 } from "@kamino-finance/scope-sdk";
1083
+ import {
1084
+ DEFAULT_PUBLIC_KEY as DEFAULT_PUBLIC_KEY3,
1085
+ lendingMarketAuthPda,
1086
+ PROGRAM_ID as PROGRAM_ID3,
1087
+ userMetadataPda as userMetadataPda2,
1088
+ VanillaObligation as VanillaObligation2
1089
+ } from "@kamino-finance/klend-sdk";
1090
+
1091
+ // ../../shared/lending-platforms/src/data/instructions/lpInstructionsBase.ts
1092
+ var LpInstructionsBase = class {
1093
+ constructor(rpc, rpcUrl, data, accounts) {
1094
+ /** Tracks which reserves (and their pools/roles) are involved in each transaction */
1095
+ this.txReserves = /* @__PURE__ */ new Map();
1096
+ /**
1097
+ * Per-txId per-obligation set of debt reserves that the caller has flagged
1098
+ * as being fully repaid earlier in the same transaction. Subsequent
1099
+ * `RefreshObligation` builds for that obligation must NOT include these
1100
+ * reserves in the borrow accounts list — by execution time the borrow row
1101
+ * has been removed from the obligation, and Kamino's `handler_refresh_obligation`
1102
+ * checks the passed account count against the live obligation state and
1103
+ * fails with `InvalidAccountInput` (klend error 6006) on a mismatch.
1104
+ *
1105
+ * Set via {@link markObligationDebtCleared}, read via {@link getTxObligationClearedDebt}.
1106
+ */
1107
+ this.txClearedDebt = /* @__PURE__ */ new Map();
1108
+ this.rpc = rpc;
1109
+ this.rpcUrl = rpcUrl;
1110
+ this.data = data;
1111
+ this.accounts = accounts;
1112
+ }
1113
+ emptyAccountMeta() {
1114
+ return toCustomAccountMeta(this.programId);
1115
+ }
1116
+ clearCacheEntry(category, id) {
1117
+ this.data.clearCacheEntry(category, id);
1118
+ }
1119
+ getCacheInvalidation(invalidation) {
1120
+ return {
1121
+ client: "kamino",
1122
+ ...invalidation
1123
+ };
1124
+ }
1125
+ applyPostSuccessCacheInvalidations(invalidations) {
1126
+ for (const invalidation of invalidations) {
1127
+ if (invalidation.client !== "kamino") {
1128
+ continue;
1129
+ }
1130
+ this.clearCacheEntry(invalidation.category, invalidation.id);
1131
+ }
1132
+ }
1133
+ getCpiData(cpiType, accounts, data, programId, postSuccessCacheInvalidations) {
1134
+ return {
1135
+ programId: programId ?? this.programId,
1136
+ cpiType,
1137
+ data,
1138
+ accounts,
1139
+ lookupTables: [this.lookupTable],
1140
+ postSuccessCacheInvalidations
1141
+ };
1142
+ }
1143
+ createSplitOperationCpiData(prerequisiteCpis, cpis) {
1144
+ return {
1145
+ prerequisiteCpis,
1146
+ cpis,
1147
+ allCpis: [...prerequisiteCpis, ...cpis]
1148
+ };
1149
+ }
1150
+ buildLendingOperationCpiBundle(cpiData) {
1151
+ return {
1152
+ prerequisiteCpis: cpiData.prerequisiteCpis,
1153
+ cpis: cpiData.cpis,
1154
+ allCpis: [...cpiData.prerequisiteCpis, ...cpiData.cpis],
1155
+ postSuccessCacheInvalidations: [...cpiData.prerequisiteCpis, ...cpiData.cpis].flatMap(
1156
+ (cpi) => cpi.postSuccessCacheInvalidations ?? []
1157
+ )
1158
+ };
1159
+ }
1160
+ async getInitAndDepositCpiBundle(params, userAccountId) {
1161
+ return this.buildLendingOperationCpiBundle(
1162
+ await this.getInitAndDepositCpiData(params, userAccountId)
1163
+ );
1164
+ }
1165
+ async getInitBorrowPositionCpiBundle(params, collReserve) {
1166
+ return this.buildLendingOperationCpiBundle(
1167
+ await this.getInitBorrowPositionCpiData(params, collReserve)
1168
+ );
1169
+ }
1170
+ async getDepositCpiBundle(params) {
1171
+ return this.buildLendingOperationCpiBundle(await this.getDepositCpiData(params));
1172
+ }
1173
+ async getWithdrawCpiBundle(params) {
1174
+ return this.buildLendingOperationCpiBundle(await this.getWithdrawCpiData(params));
1175
+ }
1176
+ async getBorrowCpiBundle(params) {
1177
+ return this.buildLendingOperationCpiBundle(await this.getBorrowCpiData(params));
1178
+ }
1179
+ async getRepayCpiBundle(params) {
1180
+ return this.buildLendingOperationCpiBundle(await this.getRepayCpiData(params));
1181
+ }
1182
+ /**
1183
+ * Registers a reserve as being used in a transaction.
1184
+ * When userAccount and role are provided, also tracks the collateral/debt role
1185
+ * for that specific user account.
1186
+ */
1187
+ registerTxReserve(txId, pool, reserve, userAccount, role) {
1188
+ if (!this.txReserves.has(txId)) {
1189
+ this.txReserves.set(txId, /* @__PURE__ */ new Map());
1190
+ }
1191
+ const txMap = this.txReserves.get(txId);
1192
+ if (!txMap.has(reserve)) {
1193
+ txMap.set(reserve, { pool, userAccounts: /* @__PURE__ */ new Map() });
1194
+ }
1195
+ if (userAccount && role) {
1196
+ const entry = txMap.get(reserve);
1197
+ if (!entry.userAccounts.has(userAccount)) {
1198
+ entry.userAccounts.set(userAccount, /* @__PURE__ */ new Set());
1199
+ }
1200
+ entry.userAccounts.get(userAccount).add(role);
1201
+ }
1202
+ }
1203
+ /**
1204
+ * Returns the collateral and debt reserves registered in the tx cache
1205
+ * for a specific user account (obligation).
1206
+ */
1207
+ getTxUserAccountReserves(txId, userAccount) {
1208
+ const collateral = [];
1209
+ const debt = [];
1210
+ const txMap = this.txReserves.get(txId);
1211
+ if (!txMap) return { collateral, debt };
1212
+ for (const [reserve, info] of txMap) {
1213
+ const roles = info.userAccounts.get(userAccount);
1214
+ if (roles?.has("collateral")) collateral.push(reserve);
1215
+ if (roles?.has("debt")) debt.push(reserve);
1216
+ }
1217
+ return { collateral, debt };
1218
+ }
1219
+ /**
1220
+ * Mark that `reserve` will be fully repaid for `userAccount` earlier in the
1221
+ * `txId` flow, so subsequent obligation-refresh builders drop it from the
1222
+ * borrow accounts they emit. Call after building a "repay all" CPI; it has
1223
+ * no effect on the repay itself.
1224
+ */
1225
+ markObligationDebtCleared(txId, userAccount, reserve) {
1226
+ if (!this.txClearedDebt.has(txId)) {
1227
+ this.txClearedDebt.set(txId, /* @__PURE__ */ new Map());
1228
+ }
1229
+ const obligationMap = this.txClearedDebt.get(txId);
1230
+ if (!obligationMap.has(userAccount)) {
1231
+ obligationMap.set(userAccount, /* @__PURE__ */ new Set());
1232
+ }
1233
+ obligationMap.get(userAccount).add(reserve);
1234
+ }
1235
+ /** Returns the set of debt reserves marked cleared for `(txId, userAccount)`. */
1236
+ getTxObligationClearedDebt(txId, userAccount) {
1237
+ return this.txClearedDebt.get(txId)?.get(userAccount) ?? /* @__PURE__ */ new Set();
1238
+ }
1239
+ /**
1240
+ * Clears the transaction cache for a given transaction or all transactions.
1241
+ * Call after finishing building a transaction to free memory.
1242
+ */
1243
+ clearTransactionCache(txId) {
1244
+ if (txId) {
1245
+ this.txReserves.delete(txId);
1246
+ this.txClearedDebt.delete(txId);
1247
+ } else {
1248
+ this.txReserves.clear();
1249
+ this.txClearedDebt.clear();
1250
+ }
1251
+ }
1252
+ /**
1253
+ * Returns prerequisite CPIs needed before reading refreshed account state for
1254
+ * a batch of lending positions outside a normal deposit/withdraw/borrow/repay
1255
+ * flow.
1256
+ */
1257
+ async getPrerequisiteCpisForRefresh(_targets) {
1258
+ return [];
1259
+ }
1260
+ /**
1261
+ * Returns CPI data for initializing a lending position end-to-end: the user
1262
+ * account itself plus any per-reserve accessory accounts (e.g. Kamino
1263
+ * obligation farm user states for the collateral and debt reserves). Called
1264
+ * at position-creation time so subsequent deposit/borrow flows don't need
1265
+ * to init these inline.
1266
+ *
1267
+ * Default: delegates to {@link getInitUserAccountCpiData}. Platforms with
1268
+ * per-reserve accessory accounts override this to add their inits.
1269
+ */
1270
+ async getInitLendingPositionCpiData(params) {
1271
+ return this.getInitUserAccountCpiData(
1272
+ params.pool,
1273
+ params.user,
1274
+ params.payer,
1275
+ params.userAccountId
1276
+ );
1277
+ }
1278
+ };
1279
+
1280
+ // ../../shared/lending-platforms/src/data/instructions/kamino.ts
1281
+ import { TOKEN_PROGRAM_ADDRESS } from "@solana-program/token";
1282
+ import { getTreasuryVaultPDA } from "@kamino-finance/farms-sdk";
1283
+ var KaminoInstructions = class extends LpInstructionsBase {
1284
+ constructor(rpc, rpcUrl, data, accounts) {
1285
+ super(rpc, rpcUrl, data, accounts);
1286
+ this.programId = PROGRAM_ID3;
1287
+ this.lookupTable = address2("bzdjSeDDPEdsGpK73oevQ87x4Sm6QRsnzupPLQEaFFN");
1288
+ }
1289
+ clearTransactionCache(txId) {
1290
+ super.clearTransactionCache(txId);
1291
+ }
1292
+ // ================ CPI Data ================
1293
+ getUserAccountCacheInvalidations(userAccount) {
1294
+ return [
1295
+ this.getCacheInvalidation({
1296
+ category: this.data.userAccountCatKey,
1297
+ id: userAccount
1298
+ })
1299
+ ];
1300
+ }
1301
+ async getInitUserMetadataCpiData(user, payer, userLookupTable) {
1302
+ const [userMetadataAddress] = await userMetadataPda2(user, this.programId);
1303
+ if (await accountExists(this.rpc, userMetadataAddress)) return;
1304
+ return this.getCpiData(
1305
+ CpiTypes.K_INIT_USER_METADATA,
1306
+ [
1307
+ toCustomAccountMeta(user, false, void 0, true),
1308
+ toCustomAccountMeta(payer, true, void 0, true),
1309
+ toCustomAccountMeta(userMetadataAddress, true),
1310
+ this.emptyAccountMeta(),
1311
+ RENT_SYSVAR_META,
1312
+ SYSTEM_PROGRAM_META
1313
+ ],
1314
+ new Uint8Array(getAddressEncoder().encode(userLookupTable ?? DEFAULT_PUBLIC_KEY3))
1315
+ );
1316
+ }
1317
+ async getInitLendingPositionCpiData(params) {
1318
+ const userInit = await this.getInitUserAccountCpiData(
1319
+ params.pool,
1320
+ params.user,
1321
+ params.payer,
1322
+ params.userAccountId
1323
+ );
1324
+ const obligation = await this.accounts.getUserAccountAddress(
1325
+ params.pool,
1326
+ params.user,
1327
+ params.userAccountId
1328
+ );
1329
+ const farmCpis = [];
1330
+ const farmTargets = [
1331
+ [params.collateralReserve, "collateral"],
1332
+ [params.debtReserve, "debt"]
1333
+ ];
1334
+ for (const [reserve, mode] of farmTargets) {
1335
+ const reserveData = await this.data.fetchReserve(params.pool, reserve);
1336
+ const reserveFarm = mode === "collateral" ? reserveData.rawData.state.farmCollateral : reserveData.rawData.state.farmDebt;
1337
+ if (!reserveFarm || reserveFarm === DEFAULT_PUBLIC_KEY3) continue;
1338
+ const farmAccounts = await this.accounts.getFarmAccounts(
1339
+ params.pool,
1340
+ reserve,
1341
+ obligation,
1342
+ mode
1343
+ );
1344
+ if (await accountExists(this.rpc, farmAccounts.userFarm.address)) continue;
1345
+ farmCpis.push(
1346
+ await this.getInitObligationFarmsForReserveCpiData(
1347
+ params.user,
1348
+ params.payer,
1349
+ obligation,
1350
+ params.pool,
1351
+ reserve,
1352
+ mode
1353
+ )
1354
+ );
1355
+ }
1356
+ return this.createSplitOperationCpiData(userInit.prerequisiteCpis, [
1357
+ ...userInit.cpis,
1358
+ ...farmCpis
1359
+ ]);
1360
+ }
1361
+ async getInitUserAccountCpiData(pool, user, payer, id, userLookupTable) {
1362
+ const market = await this.data.fetchMarket(pool);
1363
+ const obligationPda = await this.accounts.getUserAccountAddress(pool, user, id);
1364
+ const userMetadataAddress = await this.accounts.getUserMetadataAddress(user);
1365
+ const tag = VanillaObligation2.tag;
1366
+ const initMetadataCpi = await this.getInitUserMetadataCpiData(user, payer, userLookupTable);
1367
+ const obligationAlreadyInit = await accountExists(this.rpc, obligationPda);
1368
+ return this.createSplitOperationCpiData(
1369
+ [],
1370
+ [
1371
+ ...initMetadataCpi ? [initMetadataCpi] : [],
1372
+ ...obligationAlreadyInit ? [] : [
1373
+ this.getCpiData(
1374
+ CpiTypes.K_INIT_OBLIGATION,
1375
+ [
1376
+ toCustomAccountMeta(user),
1377
+ toCustomAccountMeta(payer, true),
1378
+ toCustomAccountMeta(obligationPda, true),
1379
+ toCustomAccountMeta(market.address),
1380
+ toCustomAccountMeta(DEFAULT_PUBLIC_KEY3),
1381
+ toCustomAccountMeta(DEFAULT_PUBLIC_KEY3),
1382
+ toCustomAccountMeta(userMetadataAddress),
1383
+ RENT_SYSVAR_META,
1384
+ SYSTEM_PROGRAM_META
1385
+ ],
1386
+ new Uint8Array([tag, id])
1387
+ )
1388
+ ]
1389
+ ]
1390
+ );
1391
+ }
1392
+ async getInitObligationFarmsForReserveCpiData(user, payer, obligation, pool, reserve, farmMode) {
1393
+ const farmAccounts = await this.accounts.getFarmAccounts(pool, reserve, obligation, farmMode);
1394
+ return this.getCpiData(
1395
+ CpiTypes.K_INIT_USER_FARM,
1396
+ [
1397
+ toCustomAccountMeta(payer, true),
1398
+ toCustomAccountMeta(user),
1399
+ toCustomAccountMeta(obligation, true),
1400
+ toCustomAccountMeta((await lendingMarketAuthPda(pool))[0]),
1401
+ toCustomAccountMeta(reserve, true),
1402
+ farmAccounts.farm,
1403
+ farmAccounts.userFarm,
1404
+ toCustomAccountMeta(pool),
1405
+ toCustomAccountMeta(KAMINO_FARMS_PROGRAM_ID),
1406
+ RENT_SYSVAR_META,
1407
+ SYSTEM_PROGRAM_META
1408
+ ],
1409
+ new Uint8Array([farmMode === "collateral" ? 0 : 1])
1410
+ );
1411
+ }
1412
+ /**
1413
+ * Returns CPI accounts for refreshing a reserve's state.
1414
+ * Includes the market, reserve, and all configured oracle accounts.
1415
+ */
1416
+ async getRefreshReserveCpiData(pool, reserve) {
1417
+ const reserveData = await this.data.fetchReserve(pool, reserve);
1418
+ const oracleAccounts = reserveData.getOracleAccounts();
1419
+ return this.getCpiData(
1420
+ CpiTypes.K_REFRESH_RESERVE,
1421
+ [
1422
+ toCustomAccountMeta(reserve, true),
1423
+ toCustomAccountMeta(pool),
1424
+ ...Object.values(oracleAccounts).map(
1425
+ (x) => x === void 0 ? this.emptyAccountMeta() : toCustomAccountMeta(x)
1426
+ )
1427
+ ],
1428
+ new Uint8Array()
1429
+ );
1430
+ }
1431
+ async getRefreshObligationCpiData(txId, pool, obligation) {
1432
+ const obligationData = await this.data.maybeFetchUserPositionInPool(pool, obligation);
1433
+ const cached = this.getTxUserAccountReserves(txId, obligation);
1434
+ const cleared = this.getTxObligationClearedDebt(txId, obligation);
1435
+ const collateralReserves = [
1436
+ .../* @__PURE__ */ new Set([...obligationData?.deposits.map((x) => x.reserve) ?? [], ...cached.collateral])
1437
+ ];
1438
+ const debtReserves = [
1439
+ .../* @__PURE__ */ new Set([...obligationData?.borrows.map((x) => x.reserve) ?? [], ...cached.debt])
1440
+ ].filter((r) => !cleared.has(r));
1441
+ return this.getCpiData(
1442
+ CpiTypes.K_REFRESH_OBLIGATION,
1443
+ [
1444
+ toCustomAccountMeta(pool),
1445
+ toCustomAccountMeta(obligation, true),
1446
+ ...collateralReserves.map((x) => toCustomAccountMeta(x)),
1447
+ ...debtReserves.map((x) => toCustomAccountMeta(x))
1448
+ ],
1449
+ new Uint8Array()
1450
+ );
1451
+ }
1452
+ getRefreshObligationCpiDataFromReserves({
1453
+ pool,
1454
+ userAccount,
1455
+ collateralReserves,
1456
+ debtReserves
1457
+ }) {
1458
+ return this.getCpiData(
1459
+ CpiTypes.K_REFRESH_OBLIGATION,
1460
+ [
1461
+ toCustomAccountMeta(pool),
1462
+ toCustomAccountMeta(userAccount, true),
1463
+ ...dedupeOrderedAddresses(collateralReserves).map((x) => toCustomAccountMeta(x)),
1464
+ ...dedupeOrderedAddresses(debtReserves).map((x) => toCustomAccountMeta(x))
1465
+ ],
1466
+ new Uint8Array()
1467
+ );
1468
+ }
1469
+ async getPrerequisiteCpisForRefresh(targets) {
1470
+ const reserveRefreshes = [];
1471
+ const seenReserveRefreshes = /* @__PURE__ */ new Set();
1472
+ const obligationRefreshes = /* @__PURE__ */ new Map();
1473
+ for (const target of targets) {
1474
+ for (const reserve of dedupeOrderedAddresses([
1475
+ ...target.collateralReserves,
1476
+ ...target.debtReserves
1477
+ ])) {
1478
+ const reserveRefreshKey = `${target.pool}:${reserve}`;
1479
+ if (seenReserveRefreshes.has(reserveRefreshKey)) {
1480
+ continue;
1481
+ }
1482
+ seenReserveRefreshes.add(reserveRefreshKey);
1483
+ reserveRefreshes.push({ pool: target.pool, reserve });
1484
+ }
1485
+ if (target.userAccount === DEFAULT_PUBLIC_KEY3) {
1486
+ continue;
1487
+ }
1488
+ const obligationKey = `${target.pool}:${target.userAccount}`;
1489
+ if (obligationRefreshes.has(obligationKey)) {
1490
+ continue;
1491
+ }
1492
+ obligationRefreshes.set(obligationKey, {
1493
+ pool: target.pool,
1494
+ userAccount: target.userAccount,
1495
+ collateralReserves: dedupeOrderedAddresses(target.collateralReserves),
1496
+ debtReserves: dedupeOrderedAddresses(target.debtReserves)
1497
+ });
1498
+ }
1499
+ const prerequisiteCpis = [];
1500
+ for (const { pool, reserve } of reserveRefreshes) {
1501
+ prerequisiteCpis.push(await this.getRefreshReserveCpiData(pool, reserve));
1502
+ }
1503
+ for (const obligationRefresh of obligationRefreshes.values()) {
1504
+ let obligationData = null;
1505
+ try {
1506
+ obligationData = await this.data.maybeFetchUserPositionInPool(
1507
+ obligationRefresh.pool,
1508
+ obligationRefresh.userAccount
1509
+ );
1510
+ } catch {
1511
+ obligationData = null;
1512
+ }
1513
+ if (!obligationData) {
1514
+ continue;
1515
+ }
1516
+ prerequisiteCpis.push(
1517
+ this.getRefreshObligationCpiDataFromReserves({
1518
+ pool: obligationRefresh.pool,
1519
+ userAccount: obligationRefresh.userAccount,
1520
+ collateralReserves: obligationData.deposits.map((deposit) => deposit.reserve),
1521
+ debtReserves: obligationData.borrows.map((borrow) => borrow.reserve)
1522
+ })
1523
+ );
1524
+ }
1525
+ return prerequisiteCpis;
1526
+ }
1527
+ async getRefreshUserFarmCpiData(signer, pool, reserve, obligation, userFarm, farm, mode) {
1528
+ const details = await this.accounts.reserveInteractionDetails(
1529
+ signer,
1530
+ pool,
1531
+ reserve,
1532
+ obligation
1533
+ );
1534
+ return this.getCpiData(
1535
+ CpiTypes.K_REFRESH_USER_FARM,
1536
+ [
1537
+ details.signer,
1538
+ details.obligation,
1539
+ details.lendingMarketAuthority,
1540
+ details.reserve,
1541
+ toCustomAccountMeta(farm, true),
1542
+ toCustomAccountMeta(userFarm, true),
1543
+ details.lendingMarket,
1544
+ details.farmsProgram,
1545
+ RENT_SYSVAR_META,
1546
+ SYSTEM_PROGRAM_META
1547
+ ],
1548
+ new Uint8Array([mode === "collateral" ? 0 : 1])
1549
+ );
1550
+ }
1551
+ /**
1552
+ * Checks if refresh CPIs are needed for the given reserve and obligation.
1553
+ * Also registers all involved reserves in the txReserves cache for getPreInstructions.
1554
+ *
1555
+ * The instruction `reserve` (collateral vs debt) is also listed on the obligation;
1556
+ * `dedupeOrderedAddresses` ensures one RefreshReserve CPI per reserve pubkey.
1557
+ */
1558
+ async getRefreshCpisIfNeeded(txId, pool, reserve, obligation) {
1559
+ const cpis = [];
1560
+ const cached = this.getTxUserAccountReserves(txId, obligation);
1561
+ const refreshReserve = async (reserveAddr) => {
1562
+ cpis.push(await this.getRefreshReserveCpiData(pool, reserveAddr));
1563
+ this.registerTxReserve(txId, pool, reserveAddr);
1564
+ };
1565
+ const obligationData = await this.data.maybeFetchUserPositionInPool(pool, obligation);
1566
+ if (obligationData) {
1567
+ const needsFullObligationRefresh = obligationData.requiresRefresh() || cached.collateral.length > 0 || cached.debt.length > 0;
1568
+ if (needsFullObligationRefresh) {
1569
+ const additional = [
1570
+ ...obligationData.deposits.map((d) => d.reserve),
1571
+ ...obligationData.borrows.map((b) => b.reserve),
1572
+ ...cached.collateral,
1573
+ ...cached.debt
1574
+ ];
1575
+ for (const addr of dedupeOrderedAddresses([reserve, ...additional])) {
1576
+ await refreshReserve(addr);
1577
+ }
1578
+ cpis.push(await this.getRefreshObligationCpiData(txId, pool, obligation));
1579
+ } else {
1580
+ await refreshReserve(reserve);
1581
+ }
1582
+ } else {
1583
+ const additional = [.../* @__PURE__ */ new Set([...cached.collateral, ...cached.debt])];
1584
+ for (const addr of dedupeOrderedAddresses([reserve, ...additional])) {
1585
+ await refreshReserve(addr);
1586
+ }
1587
+ cpis.push(await this.getRefreshObligationCpiData(txId, pool, obligation));
1588
+ }
1589
+ return cpis;
1590
+ }
1591
+ async getPreInstructions(txId) {
1592
+ const reserveEntries = this.txReserves.get(txId);
1593
+ if (!reserveEntries) return [];
1594
+ const SCOPE_CHAIN_END = 65535;
1595
+ const scopeFeeds = /* @__PURE__ */ new Map();
1596
+ if (reserveEntries) {
1597
+ for (const [reserve, { pool }] of reserveEntries) {
1598
+ const reserveData = await this.data.fetchReserve(pool, reserve);
1599
+ if (!reserveData.requiresRefresh()) continue;
1600
+ const scopeFeed = reserveData.getOracleAccounts().scope;
1601
+ if (!scopeFeed) continue;
1602
+ if (!scopeFeeds.has(scopeFeed)) {
1603
+ scopeFeeds.set(scopeFeed, /* @__PURE__ */ new Set());
1604
+ }
1605
+ const tokens2 = scopeFeeds.get(scopeFeed);
1606
+ const { priceChain, twapChain } = reserveData.rawData.state.config.tokenInfo.scopeConfiguration;
1607
+ for (const chain of [priceChain, twapChain]) {
1608
+ for (const index of chain) {
1609
+ if (index === SCOPE_CHAIN_END) break;
1610
+ tokens2.add(index);
1611
+ }
1612
+ }
1613
+ }
1614
+ }
1615
+ const configTokens = /* @__PURE__ */ new Map();
1616
+ for (const [feed, chainTokens2] of scopeFeeds) {
1617
+ const configAddr2 = await this.data.fetchScopeConfigAddress(feed);
1618
+ if (!configTokens.has(configAddr2)) {
1619
+ configTokens.set(configAddr2, /* @__PURE__ */ new Set());
1620
+ }
1621
+ const merged = configTokens.get(configAddr2);
1622
+ for (const t of chainTokens2) merged.add(t);
1623
+ }
1624
+ const scope = new Scope3("mainnet-beta", this.rpc);
1625
+ const isLocalnet = this.rpcUrl === LOCALNET_URL;
1626
+ const [firstEntry] = configTokens;
1627
+ if (!firstEntry) return [];
1628
+ const [configAddr, chainTokens] = firstEntry;
1629
+ let tokens;
1630
+ if (isLocalnet) {
1631
+ const mappings = await scope.getOracleMappings({ config: address2(configAddr) });
1632
+ const allTokens = /* @__PURE__ */ new Set();
1633
+ for (const token of chainTokens) {
1634
+ collectTokenDependencies(token, mappings, allTokens);
1635
+ }
1636
+ tokens = [...allTokens];
1637
+ } else {
1638
+ tokens = [...chainTokens];
1639
+ }
1640
+ const ix = await scope.refreshPriceListIx({ config: address2(configAddr) }, tokens);
1641
+ return ix ? [ix] : [];
1642
+ }
1643
+ async getClaimIncentiveCpiData(user, payer, pool, reserve, obligation, farm, userFarm, mint) {
1644
+ const tokenProgram = mints.get(mint)?.tokenProgram ?? TOKEN_PROGRAM_ADDRESS;
1645
+ const reserveData = await this.data.fetchReserve(pool, reserve);
1646
+ const [farmState] = await this.data.fetchFarms([farm]);
1647
+ const rewardIndex = farmState.rewardInfos.findIndex((r) => r.token.mint === mint);
1648
+ if (rewardIndex === -1) {
1649
+ throw new Error(`Reward mint ${mint} not found on farm ${farm}`);
1650
+ }
1651
+ const rewardInfo = farmState.rewardInfos[rewardIndex];
1652
+ const treasuryVault = await getTreasuryVaultPDA(
1653
+ KAMINO_FARMS_PROGRAM_ID,
1654
+ farmState.globalConfig,
1655
+ mint
1656
+ );
1657
+ const scopePrices = farmState.scopePrices === DEFAULT_PUBLIC_KEY3 ? KAMINO_FARMS_PROGRAM_ID : farmState.scopePrices;
1658
+ const mode = reserveData.rawData.state.farmCollateral === farm ? "collateral" : reserveData.rawData.state.farmDebt === farm ? "debt" : void 0;
1659
+ const refreshIx = mode ? await this.getRefreshUserFarmCpiData(user, pool, reserve, obligation, userFarm, farm, mode) : void 0;
1660
+ return [
1661
+ ...refreshIx ? [refreshIx] : [],
1662
+ this.getCpiData(
1663
+ CpiTypes.K_HARVEST_REWARD,
1664
+ [
1665
+ toCustomAccountMeta(user, true),
1666
+ toCustomAccountMeta(userFarm, true),
1667
+ toCustomAccountMeta(farm, true),
1668
+ toCustomAccountMeta(farmState.globalConfig),
1669
+ toCustomAccountMeta(mint),
1670
+ toCustomAccountMeta(await getAtaAddress(mint, user, tokenProgram), true, {
1671
+ owner: user,
1672
+ mint,
1673
+ tokenProgram
1674
+ }),
1675
+ toCustomAccountMeta(rewardInfo.rewardsVault, true),
1676
+ toCustomAccountMeta(treasuryVault, true),
1677
+ toCustomAccountMeta(farmState.farmVaultsAuthority),
1678
+ toCustomAccountMeta(scopePrices),
1679
+ toCustomAccountMeta(tokenProgram)
1680
+ ],
1681
+ numToU64Bytes(rewardIndex),
1682
+ KAMINO_FARMS_PROGRAM_ID
1683
+ )
1684
+ ];
1685
+ }
1686
+ async getRequestElevationGroupCpiData(elevationGroup, user, obligation, pool, txId) {
1687
+ const obligationData = await this.data.maybeFetchUserPositionInPool(pool, obligation);
1688
+ const cached = this.getTxUserAccountReserves(txId, obligation);
1689
+ const cleared = this.getTxObligationClearedDebt(txId, obligation);
1690
+ const collateralReserves = [
1691
+ .../* @__PURE__ */ new Set([...obligationData?.deposits.map((x) => x.reserve) ?? [], ...cached.collateral])
1692
+ ];
1693
+ const debtReserves = [
1694
+ .../* @__PURE__ */ new Set([...obligationData?.borrows.map((x) => x.reserve) ?? [], ...cached.debt])
1695
+ ].filter((r) => !cleared.has(r));
1696
+ return this.getCpiData(
1697
+ CpiTypes.K_REQUEST_ELEVATION_GROUP,
1698
+ [
1699
+ toCustomAccountMeta(user),
1700
+ toCustomAccountMeta(obligation, true),
1701
+ toCustomAccountMeta(pool),
1702
+ ...collateralReserves.map((x) => toCustomAccountMeta(x, true)),
1703
+ ...debtReserves.map((x) => toCustomAccountMeta(x, true))
1704
+ ],
1705
+ new Uint8Array([elevationGroup])
1706
+ );
1707
+ }
1708
+ async getInitAndDepositCpiData(params, userAccountId) {
1709
+ const initCpis = [];
1710
+ if (!await accountExists(this.rpc, params.userAccount)) {
1711
+ initCpis.push(
1712
+ ...(await this.getInitUserAccountCpiData(
1713
+ params.pool,
1714
+ params.user,
1715
+ params.payer,
1716
+ userAccountId
1717
+ )).allCpis,
1718
+ await this.getRefreshObligationCpiData(params.txId, params.pool, params.userAccount)
1719
+ );
1720
+ }
1721
+ const reserveData = await this.data.fetchReserve(params.pool, params.reserve);
1722
+ const farmCollateral = reserveData.rawData.state.farmCollateral;
1723
+ if (farmCollateral && farmCollateral !== DEFAULT_PUBLIC_KEY3) {
1724
+ const farmAccounts = await this.accounts.getFarmAccounts(
1725
+ params.pool,
1726
+ params.reserve,
1727
+ params.userAccount,
1728
+ "collateral"
1729
+ );
1730
+ if (!await accountExists(this.rpc, farmAccounts.userFarm.address)) {
1731
+ initCpis.push(
1732
+ await this.getInitObligationFarmsForReserveCpiData(
1733
+ params.user,
1734
+ params.payer,
1735
+ params.userAccount,
1736
+ params.pool,
1737
+ params.reserve,
1738
+ "collateral"
1739
+ )
1740
+ );
1741
+ }
1742
+ }
1743
+ const depositCpis = await this.getDepositCpiData(params);
1744
+ return this.createSplitOperationCpiData(
1745
+ [...initCpis, ...depositCpis.prerequisiteCpis],
1746
+ depositCpis.cpis
1747
+ );
1748
+ }
1749
+ async getInitBorrowPositionCpiData(params, collReserve) {
1750
+ const initCpis = [];
1751
+ const reserveData = await this.data.fetchReserve(params.pool, params.reserve);
1752
+ const farmDebt = reserveData.rawData.state.farmDebt;
1753
+ if (farmDebt && farmDebt !== DEFAULT_PUBLIC_KEY3) {
1754
+ const farmAccounts = await this.accounts.getFarmAccounts(
1755
+ params.pool,
1756
+ params.reserve,
1757
+ params.userAccount,
1758
+ "debt"
1759
+ );
1760
+ if (!await accountExists(this.rpc, farmAccounts.userFarm.address)) {
1761
+ initCpis.push(
1762
+ await this.getInitObligationFarmsForReserveCpiData(
1763
+ params.user,
1764
+ params.payer,
1765
+ params.userAccount,
1766
+ params.pool,
1767
+ params.reserve,
1768
+ "debt"
1769
+ )
1770
+ );
1771
+ }
1772
+ }
1773
+ const debtReserveData = await this.data.fetchReserve(params.pool, params.reserve);
1774
+ const market = await this.data.fetchMarket(params.pool);
1775
+ const requestedBorrowBaseUnits = params.baseUnitAmount && params.baseUnitAmount !== "all" ? params.baseUnitAmount : typeof params.uiAmount === "number" ? new BN5(Math.floor(params.uiAmount * Math.pow(10, debtReserveData.mint.mintDecimals))) : void 0;
1776
+ const collReserveData = await this.data.fetchReserve(params.pool, collReserve);
1777
+ const availableElevationGroups = collReserveData.config.emodes?.filter(
1778
+ (x) => x.debtReserve === params.reserve
1779
+ );
1780
+ if (availableElevationGroups?.length) {
1781
+ const sortedGroups = [...availableElevationGroups].filter((g) => g.id !== void 0).sort((a, b) => b.ltvPct - a.ltvPct);
1782
+ let selectedGroup;
1783
+ for (const group of sortedGroups) {
1784
+ const [available] = debtReserveData.rawData.getLiquidityAvailableForDebtReserveGivenCaps(
1785
+ market,
1786
+ [group.id],
1787
+ [collReserve]
1788
+ );
1789
+ const hasCapacity = requestedBorrowBaseUnits ? available.gte(requestedBorrowBaseUnits.toString()) : available.gt(0);
1790
+ if (hasCapacity) {
1791
+ selectedGroup = group.id;
1792
+ break;
1793
+ }
1794
+ }
1795
+ if (selectedGroup !== void 0) {
1796
+ initCpis.push(
1797
+ ...await this.getRefreshCpisIfNeeded(
1798
+ params.txId,
1799
+ params.pool,
1800
+ collReserve,
1801
+ params.userAccount
1802
+ )
1803
+ );
1804
+ initCpis.push(
1805
+ await this.getRequestElevationGroupCpiData(
1806
+ selectedGroup,
1807
+ params.user,
1808
+ params.userAccount,
1809
+ params.pool,
1810
+ params.txId
1811
+ )
1812
+ );
1813
+ }
1814
+ }
1815
+ const borrowCpis = await this.getBorrowCpiData(params);
1816
+ return this.createSplitOperationCpiData(
1817
+ [...initCpis, ...borrowCpis.prerequisiteCpis],
1818
+ borrowCpis.cpis
1819
+ );
1820
+ }
1821
+ async getDepositCpiData(params) {
1822
+ const refreshCpis = await this.getRefreshCpisIfNeeded(
1823
+ params.txId,
1824
+ params.pool,
1825
+ params.reserve,
1826
+ params.userAccount
1827
+ );
1828
+ const details = await this.accounts.reserveInteractionDetails(
1829
+ params.user,
1830
+ params.pool,
1831
+ params.reserve,
1832
+ params.userAccount,
1833
+ typeof params.uiAmount === "number" ? params.uiAmount : void 0,
1834
+ params.baseUnitAmount instanceof BN5 ? params.baseUnitAmount : void 0
1835
+ );
1836
+ const farms = await this.accounts.getFarmAccounts(
1837
+ params.pool,
1838
+ params.reserve,
1839
+ params.userAccount,
1840
+ "collateral"
1841
+ );
1842
+ this.registerTxReserve(
1843
+ params.txId,
1844
+ params.pool,
1845
+ params.reserve,
1846
+ params.userAccount,
1847
+ "collateral"
1848
+ );
1849
+ return this.createSplitOperationCpiData(refreshCpis, [
1850
+ this.getCpiData(
1851
+ CpiTypes.K_DEPOSIT,
1852
+ [
1853
+ details.signer,
1854
+ details.obligation,
1855
+ details.lendingMarket,
1856
+ details.lendingMarketAuthority,
1857
+ details.reserve,
1858
+ details.reserveLiquidityMint,
1859
+ details.reserveLiquiditySupply,
1860
+ details.reserveCollateralMint,
1861
+ details.reserveCollateralSupply,
1862
+ details.userLiquidityTa,
1863
+ this.emptyAccountMeta(),
1864
+ details.collateralMintTokenProgram,
1865
+ details.liquidityMintTokenProgram,
1866
+ IX_SYSVAR_META,
1867
+ farms.userFarm,
1868
+ farms.farm,
1869
+ details.farmsProgram
1870
+ ],
1871
+ details.baseUnitAmount ? numToU64Bytes(details.baseUnitAmount) : void 0,
1872
+ void 0,
1873
+ this.getUserAccountCacheInvalidations(params.userAccount)
1874
+ )
1875
+ ]);
1876
+ }
1877
+ async getWithdrawCpiData(params) {
1878
+ const refreshCpis = await this.getRefreshCpisIfNeeded(
1879
+ params.txId,
1880
+ params.pool,
1881
+ params.reserve,
1882
+ params.userAccount
1883
+ );
1884
+ const withdrawAll = params.uiAmount === "all" || params.baseUnitAmount === "all";
1885
+ const details = await this.accounts.reserveInteractionDetails(
1886
+ params.user,
1887
+ params.pool,
1888
+ params.reserve,
1889
+ params.userAccount,
1890
+ typeof params.uiAmount === "number" ? params.uiAmount : void 0,
1891
+ params.baseUnitAmount instanceof BN5 ? params.baseUnitAmount : void 0
1892
+ );
1893
+ const farms = await this.accounts.getFarmAccounts(
1894
+ params.pool,
1895
+ params.reserve,
1896
+ params.userAccount,
1897
+ "collateral"
1898
+ );
1899
+ let collateralBytes;
1900
+ if (withdrawAll) {
1901
+ collateralBytes = numToU64Bytes(U64_MAX_BN);
1902
+ } else if (details.baseUnitAmount) {
1903
+ const reserveData = await this.data.fetchReserve(params.pool, params.reserve);
1904
+ const collateralAmount = liquidityToCollateral(reserveData, details.baseUnitAmount.toNumber()) + 1;
1905
+ collateralBytes = numToU64Bytes(collateralAmount);
1906
+ }
1907
+ this.registerTxReserve(
1908
+ params.txId,
1909
+ params.pool,
1910
+ params.reserve,
1911
+ params.userAccount,
1912
+ "collateral"
1913
+ );
1914
+ return this.createSplitOperationCpiData(refreshCpis, [
1915
+ this.getCpiData(
1916
+ CpiTypes.K_WITHDRAW,
1917
+ [
1918
+ details.signer,
1919
+ details.obligation,
1920
+ details.lendingMarket,
1921
+ details.lendingMarketAuthority,
1922
+ details.reserve,
1923
+ details.reserveLiquidityMint,
1924
+ details.reserveCollateralSupply,
1925
+ details.reserveCollateralMint,
1926
+ details.reserveLiquiditySupply,
1927
+ details.userLiquidityTa,
1928
+ this.emptyAccountMeta(),
1929
+ details.collateralMintTokenProgram,
1930
+ details.liquidityMintTokenProgram,
1931
+ IX_SYSVAR_META,
1932
+ farms.userFarm,
1933
+ farms.farm,
1934
+ details.farmsProgram
1935
+ ],
1936
+ collateralBytes,
1937
+ void 0,
1938
+ this.getUserAccountCacheInvalidations(params.userAccount)
1939
+ )
1940
+ ]);
1941
+ }
1942
+ async getBorrowCpiData(params) {
1943
+ const refreshCpis = await this.getRefreshCpisIfNeeded(
1944
+ params.txId,
1945
+ params.pool,
1946
+ params.reserve,
1947
+ params.userAccount
1948
+ );
1949
+ const details = await this.accounts.reserveInteractionDetails(
1950
+ params.user,
1951
+ params.pool,
1952
+ params.reserve,
1953
+ params.userAccount,
1954
+ typeof params.uiAmount === "number" ? params.uiAmount : void 0
1955
+ );
1956
+ const farms = await this.accounts.getFarmAccounts(
1957
+ params.pool,
1958
+ params.reserve,
1959
+ params.userAccount,
1960
+ "debt"
1961
+ );
1962
+ this.registerTxReserve(params.txId, params.pool, params.reserve, params.userAccount, "debt");
1963
+ return this.createSplitOperationCpiData(refreshCpis, [
1964
+ this.getCpiData(
1965
+ CpiTypes.K_BORROW,
1966
+ [
1967
+ details.signer,
1968
+ details.obligation,
1969
+ details.lendingMarket,
1970
+ details.lendingMarketAuthority,
1971
+ details.reserve,
1972
+ details.reserveLiquidityMint,
1973
+ details.reserveLiquiditySupply,
1974
+ details.reserveFeeVault,
1975
+ details.userLiquidityTa,
1976
+ this.emptyAccountMeta(),
1977
+ details.liquidityMintTokenProgram,
1978
+ IX_SYSVAR_META,
1979
+ farms.userFarm,
1980
+ farms.farm,
1981
+ details.farmsProgram
1982
+ ],
1983
+ details.baseUnitAmount ? numToU64Bytes(details.baseUnitAmount) : void 0,
1984
+ void 0,
1985
+ this.getUserAccountCacheInvalidations(params.userAccount)
1986
+ )
1987
+ ]);
1988
+ }
1989
+ async getRepayCpiData(params) {
1990
+ this.registerTxReserve(params.txId, params.pool, params.reserve, params.userAccount, "debt");
1991
+ const refreshCpis = await this.getRefreshCpisIfNeeded(
1992
+ params.txId,
1993
+ params.pool,
1994
+ params.reserve,
1995
+ params.userAccount
1996
+ );
1997
+ const details = await this.accounts.reserveInteractionDetails(
1998
+ params.user,
1999
+ params.pool,
2000
+ params.reserve,
2001
+ params.userAccount,
2002
+ typeof params.uiAmount === "number" ? params.uiAmount : void 0
2003
+ );
2004
+ const farms = await this.accounts.getFarmAccounts(
2005
+ params.pool,
2006
+ params.reserve,
2007
+ params.userAccount,
2008
+ "debt"
2009
+ );
2010
+ const repayAmountBytes = params.full ? numToU64Bytes(U64_MAX_BN) : params.baseUnitAmount instanceof BN5 ? numToU64Bytes(params.baseUnitAmount) : details.baseUnitAmount ? numToU64Bytes(details.baseUnitAmount) : void 0;
2011
+ return this.createSplitOperationCpiData(refreshCpis, [
2012
+ this.getCpiData(
2013
+ CpiTypes.K_REPAY,
2014
+ [
2015
+ details.signer,
2016
+ details.obligation,
2017
+ details.lendingMarket,
2018
+ details.reserve,
2019
+ details.reserveLiquidityMint,
2020
+ details.reserveLiquiditySupply,
2021
+ details.userLiquidityTa,
2022
+ details.liquidityMintTokenProgram,
2023
+ IX_SYSVAR_META,
2024
+ farms.userFarm,
2025
+ farms.farm,
2026
+ details.lendingMarketAuthority,
2027
+ details.farmsProgram
2028
+ ],
2029
+ repayAmountBytes,
2030
+ void 0,
2031
+ this.getUserAccountCacheInvalidations(params.userAccount)
2032
+ )
2033
+ ]);
2034
+ }
2035
+ };
2036
+
2037
+ // ../../shared/lending-platforms/src/data/accounts/kamino.ts
2038
+ import {
2039
+ DEFAULT_PUBLIC_KEY as DEFAULT_PUBLIC_KEY4,
2040
+ lendingMarketAuthPda as lendingMarketAuthPda2,
2041
+ obligationFarmStatePda,
2042
+ PROGRAM_ID as PROGRAM_ID4,
2043
+ userMetadataPda as userMetadataPda3,
2044
+ VanillaObligation as VanillaObligation3
2045
+ } from "@kamino-finance/klend-sdk";
2046
+ import { TOKEN_PROGRAM_ADDRESS as TOKEN_PROGRAM_ADDRESS2 } from "@solana-program/token";
2047
+
2048
+ // ../../shared/lending-platforms/src/data/accounts/lpAccountsBase.ts
2049
+ var LpAccountsBase = class {
2050
+ constructor(data) {
2051
+ this.data = data;
2052
+ }
2053
+ };
2054
+
2055
+ // ../../shared/lending-platforms/src/data/accounts/kamino.ts
2056
+ var KaminoAccounts = class extends LpAccountsBase {
2057
+ async getUserAccountAddress(pool, user, id) {
2058
+ const market = await this.data.fetchMarket(pool);
2059
+ const obligationType = new VanillaObligation3(market.programId, id);
2060
+ return await obligationType.toPda(pool, user);
2061
+ }
2062
+ async getUserMetadataAddress(user) {
2063
+ return (await userMetadataPda3(user, PROGRAM_ID4))[0];
2064
+ }
2065
+ /**
2066
+ * Gets the obligation farm accounts for a reserve.
2067
+ */
2068
+ async getFarmAccounts(pool, reserve, obligation, farmMode) {
2069
+ const emptyFarms = {
2070
+ userFarm: toCustomAccountMeta(PROGRAM_ID4),
2071
+ farm: toCustomAccountMeta(PROGRAM_ID4)
2072
+ };
2073
+ const reserveData = await this.data.fetchReserve(pool, reserve);
2074
+ if (!reserveData) {
2075
+ return emptyFarms;
2076
+ }
2077
+ const farmAddress = farmMode === "collateral" ? reserveData.rawData.state.farmCollateral : reserveData.rawData.state.farmDebt;
2078
+ if (!farmAddress || farmAddress === DEFAULT_PUBLIC_KEY4) {
2079
+ return emptyFarms;
2080
+ }
2081
+ const obligationFarmUserState = await obligationFarmStatePda(farmAddress, obligation);
2082
+ return {
2083
+ userFarm: toCustomAccountMeta(obligationFarmUserState, true),
2084
+ farm: toCustomAccountMeta(farmAddress, true)
2085
+ };
2086
+ }
2087
+ /**
2088
+ * Returns the obligationFarmUserState PDA addresses for all active farms
2089
+ * (collateral and debt) on a reserve. The farm addresses themselves live on
2090
+ * the Kamino LUTs; only the user-specific state needs the per-token LUT.
2091
+ */
2092
+ async getUserFarmAddresses(pool, reserve, obligation) {
2093
+ const addresses = [];
2094
+ for (const mode of ["collateral", "debt"]) {
2095
+ const { farm, userFarm } = await this.getFarmAccounts(pool, reserve, obligation, mode);
2096
+ if (farm.address !== PROGRAM_ID4) {
2097
+ addresses.push(userFarm.address);
2098
+ }
2099
+ }
2100
+ return addresses;
2101
+ }
2102
+ /**
2103
+ * Get all relevant account metas needed for interacting with the Kamino lending market.
2104
+ */
2105
+ async reserveInteractionDetails(user, pool, reserve, obligation, amount, baseUnitAmountOverride) {
2106
+ const reserveData = await this.data.fetchReserve(pool, reserve);
2107
+ const liquidityMint = reserveData.mint.mint;
2108
+ const liquidityMintTokenProgram = reserveData.mint.mintTokenProgram;
2109
+ const collateralMint = reserveData.rawData.state.collateral.mintPubkey;
2110
+ const collateralMintTokenProgram = TOKEN_PROGRAM_ADDRESS2;
2111
+ const userLiquidityTaSeeds = {
2112
+ mint: liquidityMint,
2113
+ owner: user,
2114
+ tokenProgram: liquidityMintTokenProgram
2115
+ };
2116
+ const userLiquidityTa = await getAtaAddress(liquidityMint, user, liquidityMintTokenProgram);
2117
+ const userCollateralTaSeeds = {
2118
+ mint: collateralMint,
2119
+ owner: user,
2120
+ tokenProgram: collateralMintTokenProgram
2121
+ };
2122
+ const userCollateralTa = await getAtaAddress(collateralMint, user, collateralMintTokenProgram);
2123
+ const reserveLiquiditySupply = reserveData.rawData.state.liquidity.supplyVault;
2124
+ const reserveCollateralSupply = reserveData.rawData.state.collateral.supplyVault;
2125
+ return {
2126
+ baseUnitAmount: baseUnitAmountOverride !== void 0 ? baseUnitAmountOverride : amount !== void 0 ? fromUiAmount(amount, reserveData.mint.mintDecimals) : void 0,
2127
+ signer: toCustomAccountMeta(user, true),
2128
+ obligation: obligation ? toCustomAccountMeta(obligation, true) : void 0,
2129
+ reserve: toCustomAccountMeta(reserve, true),
2130
+ reserveFeeVault: toCustomAccountMeta(reserveData.rawData.state.liquidity.feeVault, true),
2131
+ reserveLiquidityMint: toCustomAccountMeta(liquidityMint),
2132
+ reserveLiquiditySupply: toCustomAccountMeta(reserveLiquiditySupply, true),
2133
+ reserveCollateralMint: toCustomAccountMeta(collateralMint, true),
2134
+ reserveCollateralSupply: toCustomAccountMeta(reserveCollateralSupply, true),
2135
+ lendingMarket: toCustomAccountMeta(pool),
2136
+ lendingMarketAuthority: toCustomAccountMeta((await lendingMarketAuthPda2(pool))[0]),
2137
+ userLiquidityTa: toCustomAccountMeta(userLiquidityTa, true, userLiquidityTaSeeds),
2138
+ userCollateralTa: toCustomAccountMeta(userCollateralTa, true, userCollateralTaSeeds),
2139
+ liquidityMintTokenProgram: toCustomAccountMeta(liquidityMintTokenProgram),
2140
+ collateralMintTokenProgram: toCustomAccountMeta(collateralMintTokenProgram),
2141
+ farmsProgram: toCustomAccountMeta(KAMINO_FARMS_PROGRAM_ID)
2142
+ };
2143
+ }
2144
+ };
2145
+
2146
+ // ../../shared/lending-platforms/src/services/flashLoan/kamino.ts
2147
+ import { BN as BN6 } from "@anchor-lang/core";
2148
+ import Decimal5 from "decimal.js";
2149
+ import { none } from "@solana/kit";
2150
+ import {
2151
+ getBorrowFlashLoanInstruction,
2152
+ getRepayFlashLoanInstruction,
2153
+ lendingMarketAuthPda as lendingMarketAuthPda3,
2154
+ PROGRAM_ID as PROGRAM_ID5
2155
+ } from "@kamino-finance/klend-sdk";
2156
+
2157
+ // ../../shared/lending-platforms/src/services/flashLoan/flashLoanBase.ts
2158
+ var FlashLoanBase = class {
2159
+ constructor(data) {
2160
+ this.data = data;
2161
+ }
2162
+ };
2163
+
2164
+ // ../../shared/lending-platforms/src/services/flashLoan/kamino.ts
2165
+ function stripAccountSigners(ix) {
2166
+ if (!ix.accounts) return ix;
2167
+ return {
2168
+ ...ix,
2169
+ accounts: ix.accounts.map((account) => {
2170
+ if (!("signer" in account)) return account;
2171
+ const { signer: _signer, ...rest } = account;
2172
+ return rest;
2173
+ })
2174
+ };
2175
+ }
2176
+ var KaminoFlashLoan = class extends FlashLoanBase {
2177
+ async getFlashBorrowIx(params) {
2178
+ const { reserve, lendingMarketAuthority, destinationAta } = await this.resolveSharedAccounts(params);
2179
+ return stripAccountSigners(
2180
+ getBorrowFlashLoanInstruction({
2181
+ userTransferAuthority: createSignerFromAddress(params.user),
2182
+ lendingMarketAuthority,
2183
+ lendingMarketAddress: params.pool,
2184
+ reserve: reserve.rawData,
2185
+ amountLamports: new Decimal5(params.amountBaseUnits.toString()),
2186
+ destinationAta,
2187
+ referrerAccount: none(),
2188
+ referrerTokenState: none(),
2189
+ programId: PROGRAM_ID5
2190
+ })
2191
+ );
2192
+ }
2193
+ async getAvailableFlashBorrowAmount(pool, reserve) {
2194
+ const reserveData = await this.data.fetchReserve(pool, reserve);
2195
+ return new BN6(reserveData.rawData.getLiquidityAvailableAmount().toFixed(0));
2196
+ }
2197
+ async getFlashLoanFeeRate(pool, reserve) {
2198
+ const reserveData = await this.data.fetchReserve(pool, reserve);
2199
+ return reserveData.config.flashLoanFeePct;
2200
+ }
2201
+ async getFlashRepayIx(params) {
2202
+ const { reserve, lendingMarketAuthority, destinationAta } = await this.resolveSharedAccounts(params);
2203
+ return stripAccountSigners(
2204
+ getRepayFlashLoanInstruction({
2205
+ borrowIxIndex: params.borrowIxIndex,
2206
+ userTransferAuthority: createSignerFromAddress(params.user),
2207
+ lendingMarketAuthority,
2208
+ lendingMarketAddress: params.pool,
2209
+ reserve: reserve.rawData,
2210
+ amountLamports: new Decimal5(params.amountBaseUnits.toString()),
2211
+ userSourceLiquidity: params.userSourceLiquidity ?? destinationAta,
2212
+ referrerAccount: none(),
2213
+ referrerTokenState: none(),
2214
+ programId: PROGRAM_ID5
2215
+ })
2216
+ );
2217
+ }
2218
+ async resolveSharedAccounts(params) {
2219
+ const reserve = await this.data.fetchReserve(params.pool, params.reserve);
2220
+ const [lendingMarketAuthority] = await lendingMarketAuthPda3(params.pool);
2221
+ const liquidityMint = reserve.mint.mint;
2222
+ const tokenProgram = mints.get(liquidityMint)?.tokenProgram;
2223
+ if (!tokenProgram) {
2224
+ throw new Error(`Unsupported liquidity mint for flash loan: ${liquidityMint}`);
2225
+ }
2226
+ const destinationAta = params.destinationAta ?? await getAtaAddress(liquidityMint, params.user, tokenProgram);
2227
+ return { reserve, lendingMarketAuthority, destinationAta };
2228
+ }
2229
+ };
2230
+
2231
+ // ../../shared/lending-platforms/src/services/client/kamino.ts
2232
+ var KaminoClient = class extends LendingPlatformClientBase {
2233
+ constructor(rpcUrl = getRpcUrl(ENVIRONMENT), rpcUrls = [rpcUrl]) {
2234
+ super(rpcUrl, rpcUrls);
2235
+ this.data = new KaminoData(rpcUrl, void 0, rpcUrls);
2236
+ this.accounts = new KaminoAccounts(this.data);
2237
+ this.ix = new KaminoInstructions(this.rpc, rpcUrl, this.data, this.accounts);
2238
+ }
2239
+ async refreshData(pools) {
2240
+ this.data.clearCache();
2241
+ await this.data.load(pools);
2242
+ }
2243
+ getFlashLoan() {
2244
+ return new KaminoFlashLoan(this.data);
2245
+ }
2246
+ /**
2247
+ * Kamino's `RepayObligationLiquidityV2` interprets `u64::MAX` as "repay
2248
+ * the obligation's full debt for this reserve" — letting the on-chain
2249
+ * handler clear interest-accrual dust between the off-chain quote and
2250
+ * settlement. The flash-borrow over-borrows by a slippage buffer to fund
2251
+ * this; the post-repay surplus is swept into the yielding bank.
2252
+ */
2253
+ getRepayAllSentinel() {
2254
+ return U64_MAX_BN;
2255
+ }
2256
+ async getAvailableUserAccountId(pool, user, excludeUserAccounts = []) {
2257
+ const positions = await this.data.fetchAllUserPositionsForUserInPool(pool, user);
2258
+ const positionsByAddress = new Map(positions.map((position) => [position.address, position]));
2259
+ const excludeSet = new Set(excludeUserAccounts);
2260
+ for (let userAccountId = 0; ; userAccountId++) {
2261
+ const userAccount = await this.accounts.getUserAccountAddress(pool, user, userAccountId);
2262
+ if (excludeSet.has(userAccount)) {
2263
+ continue;
2264
+ }
2265
+ const existingPosition = positionsByAddress.get(userAccount);
2266
+ if (!existingPosition || this.isInactiveUserAccount(existingPosition)) {
2267
+ return userAccountId;
2268
+ }
2269
+ }
2270
+ }
2271
+ /**
2272
+ * Returns claimable rewards across all kamino farms tied to this obligation:
2273
+ *
2274
+ * - **Obligation farms** (klend reserve `farmCollateral`/`farmDebt`):
2275
+ * UserState.owner = obligation owner (the lyc-token PDA),
2276
+ * UserState.delegatee = the obligation itself.
2277
+ * - **Direct/extra farms** (e.g. paired-reserve incentives): the lyc-token
2278
+ * PDA stakes directly in the farms program.
2279
+ * UserState.owner = UserState.delegatee = lyc-token PDA.
2280
+ *
2281
+ * The farms SDK filters UserStates by memcmp against `owner` (offset 48),
2282
+ * so we query by the obligation's owner and then accept any UserState whose
2283
+ * `delegatee` is either the obligation or the owner itself. In both cases
2284
+ * `userFarm.userStateAddress` is the correct UserState account for the
2285
+ * `HarvestReward` CPI; deriving via `obligationFarmStatePda` would be wrong
2286
+ * for direct farms (different seed scheme).
2287
+ */
2288
+ async getOutstandingIncentives(userAccount, minUiAmount = 0, log) {
2289
+ const obligationOwner = await this.fetchObligationOwner(userAccount);
2290
+ if (!obligationOwner) {
2291
+ log?.(` [getOutstandingIncentives] no obligation owner found for ${userAccount}`);
2292
+ return [];
2293
+ }
2294
+ const allOwnerFarms = await this.data.fetchUserActiveIncentives(obligationOwner);
2295
+ log?.(
2296
+ ` [getOutstandingIncentives] found ${allOwnerFarms.length} farm(s) owned by ${obligationOwner.slice(0, 6)}\u2026`
2297
+ );
2298
+ const userFarms = allOwnerFarms.filter(
2299
+ (uf) => uf.userState.delegatee === userAccount || uf.userState.delegatee === obligationOwner
2300
+ );
2301
+ const filteredOut = allOwnerFarms.length - userFarms.length;
2302
+ if (filteredOut > 0) {
2303
+ log?.(
2304
+ ` [getOutstandingIncentives] ${filteredOut} farm(s) skipped \u2014 delegatee matched neither userAccount (${userAccount.slice(0, 6)}\u2026) nor owner`
2305
+ );
2306
+ }
2307
+ if (userFarms.length === 0) {
2308
+ log?.(` [getOutstandingIncentives] no matching farms for userAccount`);
2309
+ return [];
2310
+ }
2311
+ const farmStates = await this.data.fetchFarms(userFarms.map((uf) => uf.farm));
2312
+ const decimalsByFarmAndMint = /* @__PURE__ */ new Map();
2313
+ farmStates.forEach((farmState, i) => {
2314
+ const farm = userFarms[i].farm;
2315
+ for (const rewardInfo of farmState.rewardInfos) {
2316
+ decimalsByFarmAndMint.set(
2317
+ `${farm}:${rewardInfo.token.mint}`,
2318
+ rewardInfo.token.decimals.toNumber()
2319
+ );
2320
+ }
2321
+ });
2322
+ const incentives = [];
2323
+ for (const userFarm of userFarms) {
2324
+ log?.(
2325
+ ` [getOutstandingIncentives] farm ${userFarm.farm.slice(0, 6)}\u2026 userFarm ${userFarm.userStateAddress.slice(0, 6)}\u2026 delegatee ${userFarm.userState.delegatee.slice(0, 6)}\u2026 ${userFarm.pendingRewards.length} pending reward(s)`
2326
+ );
2327
+ for (const reward of userFarm.pendingRewards) {
2328
+ const amount = reward.cumulatedPendingRewards.toNumber();
2329
+ const decimals = decimalsByFarmAndMint.get(`${userFarm.farm}:${reward.rewardTokenMint}`) ?? 0;
2330
+ const uiAmount = amount / 10 ** decimals;
2331
+ if (amount <= 0) {
2332
+ log?.(` reward ${reward.rewardTokenMint.slice(0, 6)}\u2026 \u2014 skipped (amount=0)`);
2333
+ continue;
2334
+ }
2335
+ if (uiAmount < minUiAmount) {
2336
+ log?.(
2337
+ ` reward ${reward.rewardTokenMint.slice(0, 6)}\u2026 \u2014 skipped (uiAmount=${uiAmount.toFixed(4)} < minUiAmount=${minUiAmount})`
2338
+ );
2339
+ continue;
2340
+ }
2341
+ log?.(
2342
+ ` reward ${reward.rewardTokenMint.slice(0, 6)}\u2026 \u2014 claimable uiAmount=${uiAmount.toFixed(4)}`
2343
+ );
2344
+ incentives.push({
2345
+ mint: reward.rewardTokenMint,
2346
+ amount,
2347
+ decimals,
2348
+ uiAmount,
2349
+ claimAccounts: {
2350
+ farm: userFarm.farm,
2351
+ userFarm: userFarm.userStateAddress
2352
+ }
2353
+ });
2354
+ }
2355
+ }
2356
+ return incentives;
2357
+ }
2358
+ /**
2359
+ * Reads the klend obligation account and returns its `owner` field (the
2360
+ * authority that opened the obligation — for LYC this is the lyc-token PDA).
2361
+ * Returns null when the account doesn't exist on-chain (stale protocolUserAcc).
2362
+ */
2363
+ async fetchObligationOwner(userAccount) {
2364
+ const obligation = await Obligation.fetch(this.rpc, userAccount);
2365
+ return obligation ? obligation.owner : null;
2366
+ }
2367
+ isInactiveUserAccount(position) {
2368
+ return [...position.deposits, ...position.borrows].every((entry) => entry.amount.isZero());
2369
+ }
2370
+ };
2371
+
2372
+ // ../../shared/lending-platforms/src/services/leverage/leverageService.ts
2373
+ import { BN as BN8 } from "@anchor-lang/core";
2374
+
2375
+ // ../../shared/jupiter-helpers/src/constants.ts
2376
+ import { address as address3 } from "@solana/kit";
2377
+ var JUPITER_V6_PROGRAM_ID = address3(
2378
+ "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
2379
+ );
2380
+ var JUPITER_API_URL = "https://lite-api.jup.ag";
2381
+ var DEFAULT_SLIPPAGE_BPS = 500;
2382
+ var LOCAL_TEST_MAX_ACCOUNTS = 20;
2383
+ var LOCAL_TEST_EXCLUDED_DEXES = ["GoonFi", "HumidiFi", "TesseraV", "1DEX", "Aquifer"];
2384
+ var ALWAYS_EXCLUDED_DEXES = ["Riptide"];
2385
+
2386
+ // ../../shared/jupiter-helpers/src/api.ts
2387
+ import { getBase64Encoder, getTransactionDecoder } from "@solana/kit";
2388
+ import { createJupiterApiClient } from "@jup-ag/api";
2389
+ async function getJupiterQuote(params) {
2390
+ const jupiterApi = createJupiterApiClient({ basePath: JUPITER_API_URL });
2391
+ const amount = typeof params.amount === "bigint" ? Number(params.amount) : params.amount;
2392
+ const request = {
2393
+ inputMint: params.inputMint,
2394
+ outputMint: params.outputMint,
2395
+ amount,
2396
+ slippageBps: params.slippageBps ?? DEFAULT_SLIPPAGE_BPS,
2397
+ swapMode: params.swapMode,
2398
+ maxAccounts: params.maxAccounts,
2399
+ dexes: params.dexes,
2400
+ // When `dexes` is set it acts as a whitelist and `excludeDexes` is irrelevant.
2401
+ // Otherwise the caller's exclusions are merged with the global list.
2402
+ excludeDexes: params.dexes ? void 0 : [.../* @__PURE__ */ new Set([...ALWAYS_EXCLUDED_DEXES, ...params.excludeDexes ?? []])],
2403
+ onlyDirectRoutes: params.onlyDirectRoutes
2404
+ };
2405
+ try {
2406
+ return await jupiterApi.quoteGet(request);
2407
+ } catch (err) {
2408
+ throw await enrichJupiterHttpError(err, request);
2409
+ }
2410
+ }
2411
+ async function enrichJupiterHttpError(err, request) {
2412
+ if (!(err instanceof Error) || !("response" in err)) {
2413
+ return err instanceof Error ? err : new Error(String(err));
2414
+ }
2415
+ const res = err.response;
2416
+ if (!res || res.ok || typeof res.text !== "function") {
2417
+ return err;
2418
+ }
2419
+ let body = "";
2420
+ try {
2421
+ body = (await res.text()).slice(0, 2e3);
2422
+ } catch {
2423
+ body = "<failed to read response body>";
2424
+ }
2425
+ return new Error(
2426
+ `Jupiter quoteGet http=${res.status} ${res.statusText} request=${JSON.stringify(request)} body=${body} (was: ${err.message})`
2427
+ );
2428
+ }
2429
+ async function buildJupiterSwapTransaction(params) {
2430
+ const jupiterApi = createJupiterApiClient({ basePath: JUPITER_API_URL });
2431
+ const swapResult = await jupiterApi.swapPost({
2432
+ swapRequest: {
2433
+ quoteResponse: params.quote,
2434
+ userPublicKey: params.userPublicKey,
2435
+ wrapAndUnwrapSol: params.wrapAndUnwrapSol ?? false,
2436
+ // Default false for CPI
2437
+ dynamicComputeUnitLimit: params.dynamicComputeUnitLimit ?? true
2438
+ }
2439
+ });
2440
+ const base64Encoder = getBase64Encoder();
2441
+ const transactionBytes = base64Encoder.encode(swapResult.swapTransaction);
2442
+ const transactionDecoder = getTransactionDecoder();
2443
+ return transactionDecoder.decode(transactionBytes);
2444
+ }
2445
+
2446
+ // ../../shared/jupiter-helpers/src/extract.ts
2447
+ import {
2448
+ decompileTransactionMessageFetchingLookupTables,
2449
+ getCompiledTransactionMessageDecoder
2450
+ } from "@solana/kit";
2451
+ async function extractJupiterInstruction(transaction, rpc, jupiterProgramId = JUPITER_V6_PROGRAM_ID) {
2452
+ const messageDecoder = getCompiledTransactionMessageDecoder();
2453
+ const compiledMessage = messageDecoder.decode(transaction.messageBytes);
2454
+ const lookupTables = ("addressTableLookups" in compiledMessage ? compiledMessage.addressTableLookups ?? [] : []).map((lookup) => lookup.lookupTableAddress);
2455
+ const decompiledMessage = await decompileTransactionMessageFetchingLookupTables(
2456
+ compiledMessage,
2457
+ rpc
2458
+ );
2459
+ const jupiterIx = decompiledMessage.instructions.find(
2460
+ (ix) => ix.programAddress === jupiterProgramId
2461
+ );
2462
+ if (!jupiterIx) {
2463
+ throw new Error("Jupiter instruction not found in transaction");
2464
+ }
2465
+ const accounts = (jupiterIx.accounts ?? []).map(
2466
+ (account) => ({
2467
+ address: account.address,
2468
+ role: account.role
2469
+ })
2470
+ );
2471
+ return {
2472
+ data: new Uint8Array(jupiterIx.data ?? []),
2473
+ accounts,
2474
+ lookupTables
2475
+ };
2476
+ }
2477
+
2478
+ // ../../shared/jupiter-helpers/src/routePreInstructions.ts
2479
+ async function getJupiterRoutePreInstructions(rpc, quote, user, payer) {
2480
+ const intermediate = /* @__PURE__ */ new Set();
2481
+ for (const step of quote.routePlan ?? []) {
2482
+ intermediate.add(step.swapInfo.inputMint);
2483
+ intermediate.add(step.swapInfo.outputMint);
2484
+ }
2485
+ intermediate.delete(quote.inputMint);
2486
+ intermediate.delete(quote.outputMint);
2487
+ if (!intermediate.size) {
2488
+ return { instructions: [], postSuccessCacheInvalidations: [] };
2489
+ }
2490
+ const tokenProgramByMint = /* @__PURE__ */ new Map();
2491
+ const unknown = [];
2492
+ for (const mint of intermediate) {
2493
+ const info = mints.get(mint);
2494
+ if (info) {
2495
+ tokenProgramByMint.set(mint, info.tokenProgram);
2496
+ } else {
2497
+ unknown.push(mint);
2498
+ }
2499
+ }
2500
+ if (unknown.length) {
2501
+ const resp = await rpc.getMultipleAccounts(unknown, { encoding: "base64" }).send();
2502
+ for (let i = 0; i < unknown.length; i += 1) {
2503
+ const acct = resp.value[i];
2504
+ if (!acct) {
2505
+ throw new Error(
2506
+ `getJupiterRoutePreInstructions: route mint ${unknown[i]} not found on-chain`
2507
+ );
2508
+ }
2509
+ tokenProgramByMint.set(unknown[i], acct.owner);
2510
+ }
2511
+ }
2512
+ const instructions = [];
2513
+ const postSuccessCacheInvalidations = [];
2514
+ for (const mint of intermediate) {
2515
+ const tokenProgram = tokenProgramByMint.get(mint);
2516
+ const result = await getCreateAtaIxIfNeeded(rpc, payer, mint, user, tokenProgram);
2517
+ if (result.instruction) {
2518
+ instructions.push(result.instruction);
2519
+ postSuccessCacheInvalidations.push(...result.postSuccessCacheInvalidations);
2520
+ }
2521
+ }
2522
+ return { instructions, postSuccessCacheInvalidations };
2523
+ }
2524
+
2525
+ // ../../shared/jupiter-helpers/src/client.ts
2526
+ var JupiterSwapClient = class {
2527
+ /**
2528
+ * Creates a new Jupiter swap client.
2529
+ *
2530
+ * @param rpc - Solana RPC client for resolving address lookup tables
2531
+ * @param config - Optional default quote policy applied to every Jupiter quote
2532
+ */
2533
+ constructor(rpc, config = {}) {
2534
+ this.rpc = rpc;
2535
+ this.config = config;
2536
+ /**
2537
+ * Empty lists mean any route for aggregate routing (Jupiter quotes arbitrary
2538
+ * pairs via the API).
2539
+ */
2540
+ this.inputMints = [];
2541
+ this.outputMints = [];
2542
+ this.routeAnchorMints = [];
2543
+ }
2544
+ /**
2545
+ * Get a swap quote from Jupiter.
2546
+ *
2547
+ * @param params - Quote parameters
2548
+ * @returns Normalized swap quote with Jupiter's QuoteResponse as rawQuote
2549
+ */
2550
+ async getQuote(params) {
2551
+ const excludeDexes = params.excludeDexes?.length ? [.../* @__PURE__ */ new Set([...this.config.quoteDefaults?.excludeDexes ?? [], ...params.excludeDexes])] : void 0;
2552
+ const rawQuote = await getJupiterQuote({
2553
+ ...this.config.quoteDefaults ?? {},
2554
+ inputMint: params.inputMint,
2555
+ outputMint: params.outputMint,
2556
+ amount: params.amount,
2557
+ slippageBps: params.slippageBps,
2558
+ ...params.maxAccounts !== void 0 ? { maxAccounts: params.maxAccounts } : {},
2559
+ ...params.onlyDirectRoutes !== void 0 ? { onlyDirectRoutes: params.onlyDirectRoutes } : {},
2560
+ ...excludeDexes ? { excludeDexes } : {}
2561
+ });
2562
+ return {
2563
+ inputMint: params.inputMint,
2564
+ outputMint: params.outputMint,
2565
+ inputAmount: BigInt(rawQuote.inAmount),
2566
+ outputAmount: BigInt(rawQuote.outAmount),
2567
+ priceImpactPct: Number(rawQuote.priceImpactPct ?? 0),
2568
+ rawQuote
2569
+ };
2570
+ }
2571
+ /**
2572
+ * Use Jupiter `ExactOut` quoting: desired output is `minOutputAmount`; reject if implied
2573
+ * input exceeds `maxInputAmount`.
2574
+ */
2575
+ async getQuoteCoveringMinOutput(params) {
2576
+ const need = params.minOutputAmount;
2577
+ if (need <= BigInt(0)) {
2578
+ throw new Error("getQuoteCoveringMinOutput: minOutputAmount must be positive");
2579
+ }
2580
+ const maxIn = params.maxInputAmount;
2581
+ if (maxIn <= BigInt(0)) {
2582
+ throw new Error("getQuoteCoveringMinOutput: maxInputAmount must be positive");
2583
+ }
2584
+ if (need > BigInt(Number.MAX_SAFE_INTEGER)) {
2585
+ throw new Error("getQuoteCoveringMinOutput: minOutputAmount exceeds Number.MAX_SAFE_INTEGER");
2586
+ }
2587
+ const rawQuote = await getJupiterQuote({
2588
+ ...this.config.quoteDefaults ?? {},
2589
+ inputMint: params.inputMint,
2590
+ outputMint: params.outputMint,
2591
+ amount: Number(need),
2592
+ slippageBps: params.slippageBps,
2593
+ swapMode: "ExactOut"
2594
+ });
2595
+ const inAmt = BigInt(rawQuote.inAmount);
2596
+ const outAmt = BigInt(rawQuote.outAmount);
2597
+ if (inAmt > maxIn) {
2598
+ throw new Error(
2599
+ "Jupiter getQuoteCoveringMinOutput: exact-out route needs more input than maxInputAmount"
2600
+ );
2601
+ }
2602
+ if (outAmt < need) {
2603
+ throw new Error("Jupiter getQuoteCoveringMinOutput: quoted output is below minOutputAmount");
2604
+ }
2605
+ return {
2606
+ inputMint: params.inputMint,
2607
+ outputMint: params.outputMint,
2608
+ inputAmount: inAmt,
2609
+ outputAmount: outAmt,
2610
+ priceImpactPct: Number(rawQuote.priceImpactPct ?? 0),
2611
+ rawQuote
2612
+ };
2613
+ }
2614
+ /**
2615
+ * Build Jupiter swap instruction for CPI.
2616
+ *
2617
+ * This fetches a swap transaction from Jupiter API, decompiles it,
2618
+ * and extracts the instruction data and accounts needed for CPI.
2619
+ *
2620
+ * @param quote - Quote from getQuote()
2621
+ * @param userPublicKey - Address executing the swap (typically a PDA)
2622
+ * @param options - Swap options
2623
+ * @returns Instruction data, accounts, and Jupiter program ID
2624
+ */
2625
+ async getSwapCpiData(quote, userPublicKey, options) {
2626
+ const transaction = await buildJupiterSwapTransaction({
2627
+ quote: quote.rawQuote,
2628
+ userPublicKey,
2629
+ wrapAndUnwrapSol: options?.wrapAndUnwrapSol ?? false
2630
+ });
2631
+ const { data, accounts, lookupTables } = await extractJupiterInstruction(transaction, this.rpc);
2632
+ let preInstructions;
2633
+ let preInvalidations;
2634
+ if (options?.payer) {
2635
+ const result = await getJupiterRoutePreInstructions(
2636
+ this.rpc,
2637
+ quote.rawQuote,
2638
+ userPublicKey,
2639
+ options.payer
2640
+ );
2641
+ if (result.instructions.length) {
2642
+ preInstructions = result.instructions;
2643
+ preInvalidations = result.postSuccessCacheInvalidations;
2644
+ }
2645
+ }
2646
+ return {
2647
+ cpiType: CpiTypes.JUPITER_SWAP,
2648
+ data,
2649
+ accounts,
2650
+ programId: JUPITER_V6_PROGRAM_ID,
2651
+ lookupTables,
2652
+ ...preInstructions ? { preInstructions } : {},
2653
+ ...preInvalidations ? { postSuccessCacheInvalidations: preInvalidations } : {}
2654
+ };
2655
+ }
2656
+ };
2657
+
2658
+ // ../../shared/jupiter-helpers/src/sizeExactInForMinOutput.ts
2659
+ var ExactInQuoteExceedsMaxInputError = class extends Error {
2660
+ constructor(inputAmount, maxInputAmount) {
2661
+ super(
2662
+ `sizeExactInForMinOutput: sized input (${inputAmount}) exceeds maxInputAmount (${maxInputAmount})`
2663
+ );
2664
+ this.inputAmount = inputAmount;
2665
+ this.maxInputAmount = maxInputAmount;
2666
+ this.name = "ExactInQuoteExceedsMaxInputError";
2667
+ }
2668
+ };
2669
+ async function sizeExactInForMinOutput(swap, params) {
2670
+ const {
2671
+ inputMint,
2672
+ outputMint,
2673
+ minOutputAmount,
2674
+ maxInputAmount,
2675
+ slippageBps,
2676
+ safetyBufferBps = 0,
2677
+ onlyDirectRoutes,
2678
+ maxAccounts,
2679
+ excludeDexes
2680
+ } = params;
2681
+ if (minOutputAmount <= 0n) {
2682
+ throw new Error("sizeExactInForMinOutput: minOutputAmount must be positive");
2683
+ }
2684
+ if (maxInputAmount <= 0n) {
2685
+ throw new Error("sizeExactInForMinOutput: maxInputAmount must be positive");
2686
+ }
2687
+ if (slippageBps < 0 || slippageBps >= 1e4) {
2688
+ throw new Error("sizeExactInForMinOutput: slippageBps must be in [0, 10000)");
2689
+ }
2690
+ if (safetyBufferBps < 0) {
2691
+ throw new Error("sizeExactInForMinOutput: safetyBufferBps must be non-negative");
2692
+ }
2693
+ if (minOutputAmount > BigInt(Number.MAX_SAFE_INTEGER)) {
2694
+ throw new Error("sizeExactInForMinOutput: minOutputAmount exceeds Number.MAX_SAFE_INTEGER");
2695
+ }
2696
+ const probeQuote = await swap.getQuote({
2697
+ inputMint,
2698
+ outputMint,
2699
+ amount: Number(minOutputAmount),
2700
+ slippageBps,
2701
+ onlyDirectRoutes,
2702
+ maxAccounts,
2703
+ excludeDexes
2704
+ });
2705
+ if (probeQuote.outputAmount <= 0n || probeQuote.inputAmount <= 0n) {
2706
+ throw new Error("sizeExactInForMinOutput: probe quote returned non-positive amounts");
2707
+ }
2708
+ const slippageBpsBig = BigInt(slippageBps);
2709
+ const safetyBpsBig = BigInt(safetyBufferBps);
2710
+ const sizingNumer = minOutputAmount * probeQuote.inputAmount * (10000n + safetyBpsBig);
2711
+ const sizingDenom = probeQuote.outputAmount * (10000n - slippageBpsBig);
2712
+ const inputAmount = (sizingNumer + sizingDenom - 1n) / sizingDenom;
2713
+ if (inputAmount > maxInputAmount) {
2714
+ throw new ExactInQuoteExceedsMaxInputError(inputAmount, maxInputAmount);
2715
+ }
2716
+ if (inputAmount > BigInt(Number.MAX_SAFE_INTEGER)) {
2717
+ throw new Error("sizeExactInForMinOutput: sized input exceeds Number.MAX_SAFE_INTEGER");
2718
+ }
2719
+ const quote = await swap.getQuote({
2720
+ inputMint,
2721
+ outputMint,
2722
+ amount: Number(inputAmount),
2723
+ slippageBps,
2724
+ onlyDirectRoutes,
2725
+ maxAccounts,
2726
+ excludeDexes
2727
+ });
2728
+ const worstCaseOutputAmount = quote.outputAmount * (10000n - slippageBpsBig) / 10000n;
2729
+ if (worstCaseOutputAmount < minOutputAmount) {
2730
+ throw new Error(
2731
+ `sizeExactInForMinOutput: real-quote worst-case output (${worstCaseOutputAmount}) does not cover minOutputAmount (${minOutputAmount}) \u2014 likely price impact at sized input diverged from probe spot rate; raise safetyBufferBps`
2732
+ );
2733
+ }
2734
+ return { quote, inputAmount, worstCaseOutputAmount };
2735
+ }
2736
+
2737
+ // ../../shared/lending-platforms/src/services/lendingPosition/lendingPositionManager.ts
2738
+ import { BN as BN7 } from "@anchor-lang/core";
2739
+
2740
+ // ../../shared/lending-platforms/src/services/reservesManager.ts
2741
+ var ReservesManager = class {
2742
+ constructor(supplyReserve, debtReserve, environment) {
2743
+ this.supplyReserve = supplyReserve;
2744
+ this.debtReserve = debtReserve;
2745
+ this.environment = environment;
2746
+ this.cache = new DataCache();
2747
+ }
2748
+ /** Max LTV ratio (0-1), using e-mode override when the pair qualifies */
2749
+ get maxLtv() {
2750
+ const emode = this.supplyReserve.emodes?.find(
2751
+ (e) => e.debtReserve === this.debtReserve.address
2752
+ );
2753
+ return emode?.ltvPct ?? this.supplyReserve.ltvPct;
2754
+ }
2755
+ /**
2756
+ * Returns supply and debt token prices.
2757
+ * Uses reserve-embedded prices when available, otherwise fetches from oracle and caches the result.
2758
+ */
2759
+ async prices() {
2760
+ const { data } = await this.cache.getDataOrThrow(
2761
+ async () => {
2762
+ const supplyRealtimePrice = this.supplyReserve.mintPrice;
2763
+ const debtRealtimePrice = this.debtReserve.mintPrice;
2764
+ const supplyEmaPrice = this.supplyReserve.mintEmaPrice;
2765
+ const debtEmaPrice = this.debtReserve.mintEmaPrice;
2766
+ const realtimeMintsToFetch = [
2767
+ ...supplyRealtimePrice === void 0 ? [this.supplyReserve.mint.mint] : [],
2768
+ ...debtRealtimePrice === void 0 ? [this.debtReserve.mint.mint] : []
2769
+ ];
2770
+ const emaMintsToFetch = [
2771
+ ...supplyEmaPrice === void 0 ? [this.supplyReserve.mint.mint] : [],
2772
+ ...debtEmaPrice === void 0 ? [this.debtReserve.mint.mint] : []
2773
+ ];
2774
+ const [realtime, ema] = await Promise.all([
2775
+ realtimeMintsToFetch.length ? oracle.fetchPrices(realtimeMintsToFetch, "realtime", void 0, this.environment) : {},
2776
+ emaMintsToFetch.length ? oracle.fetchPrices(emaMintsToFetch, "ema", void 0, this.environment) : {}
2777
+ ]);
2778
+ return {
2779
+ supply: {
2780
+ realtimePrice: supplyRealtimePrice ?? realtime[this.supplyReserve.mint.mint],
2781
+ emaPrice: supplyEmaPrice ?? ema[this.supplyReserve.mint.mint]
2782
+ },
2783
+ debt: {
2784
+ realtimePrice: debtRealtimePrice ?? realtime[this.debtReserve.mint.mint],
2785
+ emaPrice: debtEmaPrice ?? ema[this.debtReserve.mint.mint]
2786
+ }
2787
+ };
2788
+ },
2789
+ "prices",
2790
+ `${this.supplyReserve.mint.mint}:${this.debtReserve.mint.mint}`
2791
+ );
2792
+ return data;
2793
+ }
2794
+ /**
2795
+ * Net APY for the lending & borrowing position.
2796
+ * Accounts for eligible incentives based on the paired reserve relationship.
2797
+ */
2798
+ get netAPY() {
2799
+ return this.supplyReserve.supplyAPY(this.debtReserve.address) - this.debtReserve.borrowAPY();
2800
+ }
2801
+ /**
2802
+ * Simulates net APY after hypothetical position changes.
2803
+ * Accounts for eligible incentives based on the paired reserve relationship.
2804
+ */
2805
+ simulateNetAPY(args) {
2806
+ return this.supplyReserve.simulateNewSupplyAPY(
2807
+ args.find((x) => Boolean(x.collateralChange)) ?? { collateralChange: 0 },
2808
+ this.debtReserve.address
2809
+ ) - this.debtReserve.simulateNewBorrowAPY(
2810
+ args.find((x) => Boolean(x.debtChange)) ?? { debtChange: 0 }
2811
+ );
2812
+ }
2813
+ /** Current LTV utilization rate in basis points (0-10000) given USD position values */
2814
+ calcLtvUtilizationRateBps(supplyUsd, debtUsd) {
2815
+ if (supplyUsd <= 0) return 0;
2816
+ return debtUsd / (supplyUsd * this.maxLtv) * 1e4;
2817
+ }
2818
+ /**
2819
+ * Calculates the USD debt adjustment needed to reach a target LTV utilization rate.
2820
+ * Positive result = boost (increase leverage), negative = deleverage.
2821
+ */
2822
+ async calcDebtAdjustmentUsd(uiSupplyAmount, uiDebtAmount, targetLtvUtilizationRateBps, options = {}) {
2823
+ const { supply: supplyPrice, debt: debtPrice } = await this.prices();
2824
+ let supplyUsd = uiSupplyAmount * supplyPrice.realtimePrice;
2825
+ let debtUsd = uiDebtAmount * debtPrice.realtimePrice;
2826
+ const maxLtv = this.maxLtv;
2827
+ const targetUtilizationRate = targetLtvUtilizationRateBps / 1e4;
2828
+ const flFee = this.debtReserve.config.flashLoanFeePct / 100;
2829
+ const lpBorrowFee = this.debtReserve.config.borrowFeePct / 100;
2830
+ const positionChangeMode = options.positionChangeMode ?? "levered";
2831
+ const currentLtvUtilizationRate = supplyUsd > 0 ? debtUsd / (supplyUsd * maxLtv) : 0;
2832
+ const isBoost = currentLtvUtilizationRate < targetUtilizationRate;
2833
+ if (isBoost) {
2834
+ supplyUsd = uiSupplyAmount * (supplyPrice.emaPrice ?? supplyPrice.realtimePrice);
2835
+ debtUsd = uiDebtAmount * (debtPrice.emaPrice ?? debtPrice.realtimePrice);
2836
+ }
2837
+ if (positionChangeMode === "debtOnly") {
2838
+ const targetDebtDeltaUsd = targetUtilizationRate * maxLtv * supplyUsd - debtUsd;
2839
+ return isBoost ? targetDebtDeltaUsd / (1 + lpBorrowFee) : targetDebtDeltaUsd;
2840
+ }
2841
+ return isBoost ? (targetUtilizationRate * maxLtv * supplyUsd - debtUsd) / (1 + lpBorrowFee + flFee - targetUtilizationRate * maxLtv) : (targetUtilizationRate * maxLtv * supplyUsd - debtUsd) / (1 - targetUtilizationRate * maxLtv * (1 + flFee));
2842
+ }
2843
+ };
2844
+
2845
+ // ../../shared/lending-platforms/src/services/lendingPosition/lendingPositionManager.ts
2846
+ var LendingPositionManager = class {
2847
+ constructor(lpData, pool, userAccount, collateralReserve, debtReserve, environment) {
2848
+ this.lpData = lpData;
2849
+ this.pool = pool;
2850
+ this.userAccount = userAccount;
2851
+ this.reservesManager = new ReservesManager(collateralReserve, debtReserve, environment);
2852
+ }
2853
+ /**
2854
+ * Calculates the UI debt amount change needed to reach the target LTV utilization
2855
+ * rate. Positive values indicate borrowing; negative values indicate repaying.
2856
+ */
2857
+ async calcDebtChangeAmount(targetUtilizationRateBps) {
2858
+ const state = await this.getPositionState("realtime");
2859
+ if (!state) return 0;
2860
+ return this.calcDebtChangeAmountFromState(state, targetUtilizationRateBps);
2861
+ }
2862
+ /**
2863
+ * Fetch current supply and debt position amounts in UI units.
2864
+ */
2865
+ async getLendingPositionAmounts() {
2866
+ const state = await this.getPositionState("realtime");
2867
+ if (!state) return { supplyUiAmount: 0, debtUiAmount: 0 };
2868
+ const supplyPrice = state.prices.supply.realtimePrice;
2869
+ const debtPrice = state.prices.debt.realtimePrice;
2870
+ return {
2871
+ supplyUiAmount: supplyPrice > 0 ? state.supplyUsd / supplyPrice : 0,
2872
+ debtUiAmount: debtPrice > 0 ? state.debtUsd / debtPrice : 0
2873
+ };
2874
+ }
2875
+ /**
2876
+ * Calculates the utilization rate the source position must reach before a
2877
+ * collateral withdrawal so that, after the withdrawal, the position lands at
2878
+ * the desired target utilization rate.
2879
+ *
2880
+ * Units:
2881
+ * - current supply USD = supplied collateral before withdrawal
2882
+ * - withdrawn USD = collateral requested for the rebalance move
2883
+ * - post-withdraw target = desired utilization after collateral leaves the LP
2884
+ *
2885
+ * Formula:
2886
+ * pre_withdraw_target = post_withdraw_target * (current_supply - withdrawn) / current_supply
2887
+ *
2888
+ * The result is floored to stay conservatively at or below the requested
2889
+ * post-withdraw target once integer basis-point rounding is applied.
2890
+ */
2891
+ async calcPreWithdrawalTargetUtilizationRateBps(withdrawUiCollateralAmount, postWithdrawalTargetUtilizationRateBps) {
2892
+ const state = await this.getPositionState("realtime");
2893
+ if (!state) return 0;
2894
+ return this.calcPreWithdrawalTargetUtilizationRateBpsFromState(
2895
+ state,
2896
+ withdrawUiCollateralAmount,
2897
+ postWithdrawalTargetUtilizationRateBps
2898
+ );
2899
+ }
2900
+ /**
2901
+ * Calculates the UI debt amount change needed before a collateral withdrawal
2902
+ * so that the position lands at the desired utilization rate after the
2903
+ * withdrawal completes.
2904
+ */
2905
+ async calcDebtChangeAmountForCollateralWithdrawal(withdrawUiCollateralAmount, postWithdrawalTargetUtilizationRateBps) {
2906
+ const state = await this.getPositionState("realtime");
2907
+ if (!state) return 0;
2908
+ const preWithdrawalTargetUtilizationRateBps = this.calcPreWithdrawalTargetUtilizationRateBpsFromState(
2909
+ state,
2910
+ withdrawUiCollateralAmount,
2911
+ postWithdrawalTargetUtilizationRateBps
2912
+ );
2913
+ return this.calcDebtChangeAmountFromState(state, preWithdrawalTargetUtilizationRateBps);
2914
+ }
2915
+ /**
2916
+ * Calculates the utilization rate after withdrawing collateral while leaving
2917
+ * debt unchanged.
2918
+ */
2919
+ async calcPostWithdrawalUtilizationRateBps(withdrawUiCollateralAmount) {
2920
+ const state = await this.getPositionState("realtime");
2921
+ if (!state) return 0;
2922
+ return this.calcPostWithdrawalUtilizationRateBpsFromState(state, withdrawUiCollateralAmount);
2923
+ }
2924
+ /**
2925
+ * For burn-token liquidity management: checks that a withdrawal of
2926
+ * `collateralWithdrawalUiAmount` (collateral mint UI units) leaves strictly
2927
+ * positive supplied collateral, matching the pre-withdraw math used in
2928
+ * {@link calcPreWithdrawalTargetUtilizationRateBps}.
2929
+ *
2930
+ * Returns realtime LTV utilization in basis points when eligible; null when the
2931
+ * obligation is missing, has no supply, prices are invalid, or the withdrawal
2932
+ * would consume the full (or more than the full) collateral position.
2933
+ */
2934
+ async getBurnUnwindEligibility(collateralWithdrawalUiAmount) {
2935
+ if (!(collateralWithdrawalUiAmount > 0)) {
2936
+ return null;
2937
+ }
2938
+ const state = await this.getPositionState("realtime");
2939
+ if (!state) {
2940
+ return null;
2941
+ }
2942
+ const collateralPrice = state.prices.supply.realtimePrice;
2943
+ if (!(collateralPrice > 0)) {
2944
+ return null;
2945
+ }
2946
+ const withdrawnCollateralUsd = collateralWithdrawalUiAmount * collateralPrice;
2947
+ if (!(withdrawnCollateralUsd < state.supplyUsd)) {
2948
+ return null;
2949
+ }
2950
+ const utilizationRateBps = this.reservesManager.calcLtvUtilizationRateBps(
2951
+ state.supplyUsd,
2952
+ state.debtUsd
2953
+ );
2954
+ return { utilizationRateBps };
2955
+ }
2956
+ /**
2957
+ * Returns the collateral price levels that would place the position exactly on
2958
+ * its lower and upper utilization trigger bands.
2959
+ *
2960
+ * The lower-band trigger uses EMA pricing (to mirror boost-trigger semantics),
2961
+ * while the upper-band trigger uses realtime pricing (to mirror unwind-trigger
2962
+ * semantics).
2963
+ */
2964
+ async getCollateralPriceTriggerBand(params) {
2965
+ const [lower, upper] = await Promise.all([
2966
+ this.getCollateralPriceTriggerLevel("ema", params.lowerTargetUtilizationRateBps),
2967
+ this.getCollateralPriceTriggerLevel("realtime", params.upperTargetUtilizationRateBps)
2968
+ ]);
2969
+ return { lower, upper };
2970
+ }
2971
+ async getUtilizationRatesBps() {
2972
+ const [realtimeState, emaState] = await Promise.all([
2973
+ this.getPositionState("realtime"),
2974
+ this.getPositionState("ema")
2975
+ ]);
2976
+ if (!realtimeState || !emaState) {
2977
+ return null;
2978
+ }
2979
+ return {
2980
+ realtime: this.reservesManager.calcLtvUtilizationRateBps(
2981
+ realtimeState.supplyUsd,
2982
+ realtimeState.debtUsd
2983
+ ),
2984
+ ema: this.reservesManager.calcLtvUtilizationRateBps(emaState.supplyUsd, emaState.debtUsd)
2985
+ };
2986
+ }
2987
+ async getUtilizationPrices() {
2988
+ const [realtimeState, emaState] = await Promise.all([
2989
+ this.getPositionState("realtime"),
2990
+ this.getPositionState("ema")
2991
+ ]);
2992
+ if (!realtimeState || !emaState) {
2993
+ return null;
2994
+ }
2995
+ return {
2996
+ realtime: {
2997
+ collateral: this.selectPrice(realtimeState.prices.supply, "realtime"),
2998
+ debt: this.selectPrice(realtimeState.prices.debt, "realtime")
2999
+ },
3000
+ ema: {
3001
+ collateral: this.selectPrice(emaState.prices.supply, "ema"),
3002
+ debt: this.selectPrice(emaState.prices.debt, "ema")
3003
+ }
3004
+ };
3005
+ }
3006
+ async getInspectMetrics(params) {
3007
+ const [utilizationRateBps, utilizationPrices, triggerBand] = await Promise.all([
3008
+ this.getUtilizationRatesBps(),
3009
+ this.getUtilizationPrices(),
3010
+ this.getCollateralPriceTriggerBand(params)
3011
+ ]);
3012
+ if (!utilizationRateBps || !utilizationPrices) {
3013
+ return null;
3014
+ }
3015
+ return { utilizationRateBps, utilizationPrices, triggerBand };
3016
+ }
3017
+ async getPositionState(mode) {
3018
+ const position = await this.lpData.maybeFetchUserPositionInPool(this.pool, this.userAccount);
3019
+ if (!position) return null;
3020
+ const prices = await this.reservesManager.prices();
3021
+ const { supplyUsd, debtUsd } = this.calcPositionSupplyDebtUsd(position, prices, mode);
3022
+ return { prices, supplyUsd, debtUsd };
3023
+ }
3024
+ calcPositionSupplyDebtUsd(position, prices, mode) {
3025
+ const { supplyReserve, debtReserve } = this.reservesManager;
3026
+ const deposit = position.deposits.find((d) => d.reserve === supplyReserve.address);
3027
+ const borrow = position.borrows.find((b) => b.reserve === debtReserve.address);
3028
+ const supplyAmount = deposit ? toUiAmount(deposit.amount, supplyReserve.mint.mintDecimals) : 0;
3029
+ const debtAmount = borrow ? toUiAmount(borrow.amount, debtReserve.mint.mintDecimals) : 0;
3030
+ return {
3031
+ supplyUsd: supplyAmount * this.selectPrice(prices.supply, mode).value,
3032
+ debtUsd: debtAmount * this.selectPrice(prices.debt, mode).value
3033
+ };
3034
+ }
3035
+ selectPrice(price, mode) {
3036
+ if (mode === "realtime") {
3037
+ return { value: price.realtimePrice, source: "realtime" };
3038
+ }
3039
+ if (price.emaPrice != null) {
3040
+ return { value: price.emaPrice, source: "ema" };
3041
+ }
3042
+ return { value: price.realtimePrice, source: "ema_fallback_realtime" };
3043
+ }
3044
+ async getCollateralPriceTriggerLevel(mode, targetUtilizationRateBps) {
3045
+ this.assertValidTriggerBandUtilizationRateBps(
3046
+ targetUtilizationRateBps,
3047
+ "targetUtilizationRateBps"
3048
+ );
3049
+ if (targetUtilizationRateBps === 0) {
3050
+ return void 0;
3051
+ }
3052
+ const state = await this.getPositionState(mode);
3053
+ if (!state) {
3054
+ return void 0;
3055
+ }
3056
+ const currentCollateralPrice = mode === "ema" ? state.prices.supply.emaPrice ?? state.prices.supply.realtimePrice : state.prices.supply.realtimePrice;
3057
+ if (currentCollateralPrice <= 0 || state.debtUsd < 0 || this.reservesManager.maxLtv <= 0) {
3058
+ return void 0;
3059
+ }
3060
+ const uiSupplyAmount = state.supplyUsd / currentCollateralPrice;
3061
+ if (uiSupplyAmount <= 0) {
3062
+ return void 0;
3063
+ }
3064
+ const triggerCollateralPrice = this.calcCollateralPriceForTargetUtilization(
3065
+ state.debtUsd,
3066
+ uiSupplyAmount,
3067
+ targetUtilizationRateBps
3068
+ );
3069
+ if (!Number.isFinite(triggerCollateralPrice) || triggerCollateralPrice < 0) {
3070
+ return void 0;
3071
+ }
3072
+ return {
3073
+ currentCollateralPrice,
3074
+ triggerCollateralPrice,
3075
+ targetUtilizationRateBps,
3076
+ priceMode: mode,
3077
+ priceChangePct: (triggerCollateralPrice - currentCollateralPrice) / currentCollateralPrice * 100
3078
+ };
3079
+ }
3080
+ /**
3081
+ * Solve for collateral price at a target utilization:
3082
+ * utilization = debtUsd / (collateralAmount * collateralPrice * maxLtv).
3083
+ */
3084
+ calcCollateralPriceForTargetUtilization(debtUsd, uiSupplyAmount, targetUtilizationRateBps) {
3085
+ const targetUtilizationRate = targetUtilizationRateBps / 1e4;
3086
+ return debtUsd / (uiSupplyAmount * this.reservesManager.maxLtv * targetUtilizationRate);
3087
+ }
3088
+ async calcDebtChangeAmountFromState(state, targetUtilizationRateBps) {
3089
+ this.assertValidUtilizationRateBps(targetUtilizationRateBps, "targetUtilizationRateBps");
3090
+ if (state.prices.debt.realtimePrice <= 0) {
3091
+ throw new Error("Debt reserve realtime price must be positive");
3092
+ }
3093
+ if (state.prices.supply.realtimePrice <= 0) {
3094
+ throw new Error("Collateral reserve realtime price must be positive");
3095
+ }
3096
+ const debtAdjustmentUsd = await this.reservesManager.calcDebtAdjustmentUsd(
3097
+ state.supplyUsd / state.prices.supply.realtimePrice,
3098
+ state.debtUsd / state.prices.debt.realtimePrice,
3099
+ targetUtilizationRateBps,
3100
+ { positionChangeMode: "debtOnly" }
3101
+ );
3102
+ const debtChangeUiAmount = debtAdjustmentUsd / state.prices.debt.realtimePrice;
3103
+ const debtDecimals = this.reservesManager.debtReserve.mint.mintDecimals;
3104
+ let quantizedUiAmount = this.quantizeDebtChangeUiAmount(debtChangeUiAmount, debtDecimals);
3105
+ if (quantizedUiAmount > 0) {
3106
+ quantizedUiAmount = await this.capPositiveBorrowToProtocolHeadroom(quantizedUiAmount, state);
3107
+ }
3108
+ return debtChangeUiAmount < 0 ? -quantizedUiAmount : quantizedUiAmount;
3109
+ }
3110
+ /**
3111
+ * Quantize to the debt mint's base-unit precision. Borrows floor; repays round
3112
+ * away from zero so deleveraging does not undershoot.
3113
+ */
3114
+ quantizeDebtChangeUiAmount(debtChangeUiAmount, debtDecimals) {
3115
+ if (debtChangeUiAmount === 0) return 0;
3116
+ const absUi = Math.abs(debtChangeUiAmount);
3117
+ if (debtChangeUiAmount > 0) {
3118
+ if (!(absUi > 0)) return 0;
3119
+ const flooredBaseUnits = new BN7(Math.floor(absUi * Math.pow(10, debtDecimals)));
3120
+ return toUiAmount(flooredBaseUnits, debtDecimals);
3121
+ }
3122
+ const roundedAmount = fromUiAmount(absUi, debtDecimals);
3123
+ let repayUi = toUiAmount(roundedAmount, debtDecimals);
3124
+ if (repayUi < absUi) {
3125
+ repayUi = toUiAmount(roundedAmount.addn(1), debtDecimals);
3126
+ }
3127
+ return repayUi;
3128
+ }
3129
+ /** Cap positive borrows to obligation headroom when the platform exposes it. */
3130
+ async capPositiveBorrowToProtocolHeadroom(requestedUiAmount, state) {
3131
+ const debtDecimals = this.reservesManager.debtReserve.mint.mintDecimals;
3132
+ const position = await this.lpData.maybeFetchUserPositionInPool(this.pool, this.userAccount);
3133
+ if (!position) {
3134
+ return requestedUiAmount;
3135
+ }
3136
+ const maxUi = position.getMaxAdditionalBorrowUiAmount(
3137
+ state.prices.debt.realtimePrice,
3138
+ debtDecimals
3139
+ );
3140
+ if (maxUi === void 0) {
3141
+ return requestedUiAmount;
3142
+ }
3143
+ return Math.min(requestedUiAmount, maxUi);
3144
+ }
3145
+ calcPreWithdrawalTargetUtilizationRateBpsFromState(state, withdrawUiCollateralAmount, postWithdrawalTargetUtilizationRateBps) {
3146
+ if (withdrawUiCollateralAmount <= 0) {
3147
+ throw new Error("withdrawUiCollateralAmount must be greater than zero");
3148
+ }
3149
+ this.assertValidUtilizationRateBps(
3150
+ postWithdrawalTargetUtilizationRateBps,
3151
+ "postWithdrawalTargetUtilizationRateBps"
3152
+ );
3153
+ const collateralPrice = state.prices.supply.realtimePrice;
3154
+ if (collateralPrice <= 0) {
3155
+ throw new Error("Collateral reserve realtime price must be positive");
3156
+ }
3157
+ const withdrawnCollateralUsd = withdrawUiCollateralAmount * collateralPrice;
3158
+ if (withdrawnCollateralUsd >= state.supplyUsd) {
3159
+ throw new Error("withdrawUiCollateralAmount exceeds the current supplied collateral");
3160
+ }
3161
+ const preWithdrawalTargetUtilizationRateBps = Math.floor(
3162
+ postWithdrawalTargetUtilizationRateBps * (state.supplyUsd - withdrawnCollateralUsd) / state.supplyUsd
3163
+ );
3164
+ return Math.max(
3165
+ 0,
3166
+ Math.min(postWithdrawalTargetUtilizationRateBps, preWithdrawalTargetUtilizationRateBps)
3167
+ );
3168
+ }
3169
+ calcPostWithdrawalUtilizationRateBpsFromState(state, withdrawUiCollateralAmount) {
3170
+ if (withdrawUiCollateralAmount <= 0) {
3171
+ throw new Error("withdrawUiCollateralAmount must be greater than zero");
3172
+ }
3173
+ const collateralPrice = state.prices.supply.realtimePrice;
3174
+ if (collateralPrice <= 0) {
3175
+ throw new Error("Collateral reserve realtime price must be positive");
3176
+ }
3177
+ const withdrawnCollateralUsd = withdrawUiCollateralAmount * collateralPrice;
3178
+ if (withdrawnCollateralUsd >= state.supplyUsd) {
3179
+ throw new Error("withdrawUiCollateralAmount exceeds the current supplied collateral");
3180
+ }
3181
+ return this.reservesManager.calcLtvUtilizationRateBps(
3182
+ state.supplyUsd - withdrawnCollateralUsd,
3183
+ state.debtUsd
3184
+ );
3185
+ }
3186
+ assertValidUtilizationRateBps(value, field) {
3187
+ if (!Number.isFinite(value) || value < 0 || value > 1e4) {
3188
+ throw new Error(`${field} must be between 0 and 10000`);
3189
+ }
3190
+ }
3191
+ /**
3192
+ * Unwind/boost trigger bands may exceed 100% LTV utilization (up to 10_500 bps
3193
+ * on-chain). Debt-sizing paths still use {@link assertValidUtilizationRateBps}.
3194
+ */
3195
+ assertValidTriggerBandUtilizationRateBps(value, field) {
3196
+ if (!Number.isFinite(value) || value < 0 || value > MAX_LENDING_POSITION_UPPER_UTIL_BPS) {
3197
+ throw new Error(`${field} must be between 0 and ${MAX_LENDING_POSITION_UPPER_UTIL_BPS}`);
3198
+ }
3199
+ }
3200
+ };
3201
+
3202
+ // ../../shared/lending-platforms/src/services/leverage/leverageService.ts
3203
+ var DECREASE_LEVERAGE_SWAP_BUFFER_BPS = 5;
3204
+ var DECREASE_LEVERAGE_SWAP_SLIPPAGE_BPS = 40;
3205
+ var DECREASE_LEVERAGE_SWAP_MAX_ACCOUNTS = 30;
3206
+ var FLASH_REBALANCE_SWAP_MAX_ACCOUNTS = 25;
3207
+ var FlashRebalanceSwapCostExceededError = class extends Error {
3208
+ constructor(reason, executionCostBps, marketBasisBps, limitBps, inputAmount, outputAmount) {
3209
+ super(
3210
+ `LeverageService.buildFlashRebalance: swap ${reason} exceeds ${limitBps} bps (execution cost ${executionCostBps.toFixed(2)} bps, market basis ${marketBasisBps.toFixed(2)} bps, in=${inputAmount} out=${outputAmount})`
3211
+ );
3212
+ this.reason = reason;
3213
+ this.executionCostBps = executionCostBps;
3214
+ this.marketBasisBps = marketBasisBps;
3215
+ this.limitBps = limitBps;
3216
+ this.inputAmount = inputAmount;
3217
+ this.outputAmount = outputAmount;
3218
+ this.name = "FlashRebalanceSwapCostExceededError";
3219
+ }
3220
+ };
3221
+ var LeverageService = class {
3222
+ /**
3223
+ * Calculate the borrow amount needed to reach the target utilization rate,
3224
+ * then build the borrow CPIs.
3225
+ */
3226
+ static async buildIncreaseLeverage(ctx, params) {
3227
+ const reserves = new ReservesManager(ctx.supplyReserve, ctx.debtReserve, ctx.environment);
3228
+ const mode = params.mode ?? "debtOnly";
3229
+ const debtAdjustmentUsd = await reserves.calcDebtAdjustmentUsd(
3230
+ params.currentSupplyUiAmount,
3231
+ params.currentDebtUiAmount,
3232
+ params.targetUtilizationRateBps,
3233
+ { positionChangeMode: mode }
3234
+ );
3235
+ const prices = await reserves.prices();
3236
+ const borrowUiAmount = Math.abs(debtAdjustmentUsd / prices.debt.realtimePrice);
3237
+ const borrowBaseUnits = fromUiAmount(borrowUiAmount, ctx.debtReserve.mint.mintDecimals);
3238
+ const { prerequisiteCpis, cpis, postSuccessCacheInvalidations } = await ctx.lendingIx.getBorrowCpiBundle({
3239
+ user: ctx.user,
3240
+ payer: ctx.payer,
3241
+ pool: ctx.pool,
3242
+ reserve: ctx.debtReserve.address,
3243
+ userAccount: ctx.userAccount,
3244
+ uiAmount: borrowUiAmount,
3245
+ txId: ctx.txId
3246
+ });
3247
+ const preInstructions = await ctx.lendingIx.getPreInstructions(ctx.txId);
3248
+ return {
3249
+ borrowUiAmount,
3250
+ borrowBaseUnits,
3251
+ prerequisiteCpis,
3252
+ borrowCpis: cpis,
3253
+ preInstructions,
3254
+ postSuccessCacheInvalidations
3255
+ };
3256
+ }
3257
+ /**
3258
+ * Calculate the repay amount needed to reach the target utilization rate,
3259
+ * build the repay CPIs, and assemble CPI groups with an optional swap
3260
+ * prepended when the caller's debt-token balance is insufficient.
3261
+ *
3262
+ * The returned `repayUiAmount` is always non-negative. When the position is
3263
+ * already at or below the target, the amount is zero and the CPI list is
3264
+ * sized for a zero repay.
3265
+ */
3266
+ static async buildDecreaseLeverage(ctx, params) {
3267
+ const reserves = new ReservesManager(ctx.supplyReserve, ctx.debtReserve, ctx.environment);
3268
+ const mode = params.mode ?? "debtOnly";
3269
+ const debtAdjustmentUsd = await reserves.calcDebtAdjustmentUsd(
3270
+ params.currentSupplyUiAmount,
3271
+ params.currentDebtUiAmount,
3272
+ params.targetUtilizationRateBps,
3273
+ { positionChangeMode: mode }
3274
+ );
3275
+ const prices = await reserves.prices();
3276
+ const debtDecimals = ctx.debtReserve.mint.mintDecimals;
3277
+ const repayUiAmount = Math.abs(debtAdjustmentUsd / prices.debt.realtimePrice);
3278
+ const calculatedRepayBaseUnits = fromUiAmount(repayUiAmount, debtDecimals);
3279
+ const repayBaseUnits = params.repayBaseUnitsOverride ?? calculatedRepayBaseUnits;
3280
+ const { prerequisiteCpis, cpis } = await ctx.lendingIx.getRepayCpiData({
3281
+ user: ctx.user,
3282
+ payer: ctx.payer,
3283
+ pool: ctx.pool,
3284
+ reserve: ctx.debtReserve.address,
3285
+ userAccount: ctx.userAccount,
3286
+ txId: ctx.txId,
3287
+ ...params.repayBaseUnitsOverride ? { baseUnitAmount: repayBaseUnits } : {}
3288
+ });
3289
+ const preInstructions = await ctx.lendingIx.getPreInstructions(ctx.txId);
3290
+ const swapRequired = params.swapContext !== void 0;
3291
+ const assembledCpis = await this.assembleDecreaseLeverageCpis(
3292
+ repayBaseUnits,
3293
+ cpis,
3294
+ params.swapContext
3295
+ );
3296
+ return {
3297
+ repayUiAmount,
3298
+ repayBaseUnits,
3299
+ prerequisiteCpis,
3300
+ repayCpis: cpis,
3301
+ cpiDataGroups: assembledCpis.cpiDataGroups,
3302
+ swapRequired,
3303
+ preInstructions: [...preInstructions, ...assembledCpis.preInstructions]
3304
+ };
3305
+ }
3306
+ /**
3307
+ * Assemble repay CPI groups, prepending a swap group whenever the bank is
3308
+ * configured to source the debt mint via a swap. The on-chain handler
3309
+ * decides whether to actually invoke the swap (via `perform_swap`) based on
3310
+ * runtime balances; building it unconditionally keeps the tx resilient when
3311
+ * the bank's debt-token balance changes between build and send.
3312
+ */
3313
+ static async assembleDecreaseLeverageCpis(repayBaseUnits, repayCpis, swapContext) {
3314
+ if (!swapContext) {
3315
+ return { cpiDataGroups: [repayCpis], preInstructions: [] };
3316
+ }
3317
+ const swapCpiData = await this.quoteDebtTopUpSwap(swapContext, repayBaseUnits);
3318
+ return {
3319
+ cpiDataGroups: [[swapCpiData], repayCpis],
3320
+ preInstructions: swapCpiData.preInstructions ?? []
3321
+ };
3322
+ }
3323
+ /**
3324
+ * Quote a swap that converts a source asset into the debt mint,
3325
+ * covering at least `shortfall` base units.
3326
+ */
3327
+ static async quoteDebtTopUpSwap(ctx, shortfall) {
3328
+ const need = BigInt(shortfall.toString());
3329
+ if (need <= 0n) {
3330
+ throw new Error("LeverageService.quoteDebtTopUpSwap: shortfall must be positive");
3331
+ }
3332
+ if (ctx.sourceBalanceBaseUnits <= 0n) {
3333
+ throw new Error("LeverageService.quoteDebtTopUpSwap: source balance is zero");
3334
+ }
3335
+ const { quote } = await sizeExactInForMinOutput(ctx.swap, {
3336
+ inputMint: ctx.sourceMint,
3337
+ outputMint: ctx.debtMint,
3338
+ minOutputAmount: need,
3339
+ maxInputAmount: ctx.sourceBalanceBaseUnits,
3340
+ slippageBps: ctx.slippageBps ?? DECREASE_LEVERAGE_SWAP_SLIPPAGE_BPS,
3341
+ safetyBufferBps: DECREASE_LEVERAGE_SWAP_BUFFER_BPS,
3342
+ maxAccounts: DECREASE_LEVERAGE_SWAP_MAX_ACCOUNTS,
3343
+ excludeDexes: ctx.excludeDexes
3344
+ });
3345
+ return ctx.swap.getSwapCpiData(quote, ctx.swapTarget, { payer: ctx.payer });
3346
+ }
3347
+ /**
3348
+ * Build a flash-loan-wrapped rebalance that moves collateral between two
3349
+ * lending positions without decreasing any carry positions.
3350
+ *
3351
+ * The flow assembled here (inside a single transaction):
3352
+ * 1. Top-level: flash-borrow source debt mint into the user's ATA.
3353
+ * 2. CPI: repay flash-borrowed amount on source → frees collateral.
3354
+ * 3. CPI: withdraw `collateralUiAmount` from source.
3355
+ * 4. CPI: deposit that collateral on destination.
3356
+ * 5. CPI: borrow destination debt mint (sized slightly above the swap
3357
+ * input needed to produce the flash repay, so post-slippage output
3358
+ * still covers it).
3359
+ * 6. CPI: exact-in swap destination debt → source debt; the entire borrow
3360
+ * is consumed and worst-case output is at least the flash repay amount.
3361
+ * 7. Top-level: flash-repay source debt mint.
3362
+ *
3363
+ * The exact-in over-borrow leaves a small **source-debt** excess in the
3364
+ * token PDA's ATA after the swap; the on-chain handler sweeps this excess
3365
+ * into the yielding bank before the top-level flash repay so exactly
3366
+ * `flashRepayAmountBaseUnits` remains for the repay.
3367
+ */
3368
+ static async buildFlashRebalance(ctx, params) {
3369
+ if (ctx.source.debtReserve.mint.mint === ctx.destination.debtReserve.mint.mint) {
3370
+ throw new Error(
3371
+ "LeverageService.buildFlashRebalance: source and destination debt mints must differ"
3372
+ );
3373
+ }
3374
+ const sourceDebtMint = ctx.source.debtReserve.address;
3375
+ const sourceDebtLiqMint = ctx.source.debtReserve.mint.mint;
3376
+ const sourceDebtDecimals = ctx.source.debtReserve.mint.mintDecimals;
3377
+ const destDebtLiqMint = ctx.destination.debtReserve.mint.mint;
3378
+ const destDebtDecimals = ctx.destination.debtReserve.mint.mintDecimals;
3379
+ const sourceRepayBaseUnits = await this.calcSourceRepayForWithdraw(ctx, params);
3380
+ if (sourceRepayBaseUnits.lten(0)) {
3381
+ throw new Error(
3382
+ "LeverageService.buildFlashRebalance: source repay amount must be positive \u2014 use the simple rebalance path when no flash loan is needed"
3383
+ );
3384
+ }
3385
+ const sourceRepayUiAmount = toUiAmount(sourceRepayBaseUnits, sourceDebtDecimals);
3386
+ const flashFeeRate = await ctx.flashLoan.getFlashLoanFeeRate(ctx.source.pool, sourceDebtMint);
3387
+ const SOURCE_REPAY_OVERBORROW_BPS = 5n;
3388
+ const sourceRepayBigInt = BigInt(sourceRepayBaseUnits.toString());
3389
+ const flashBorrowBigInt = params.withdrawAll ? sourceRepayBigInt + sourceRepayBigInt * SOURCE_REPAY_OVERBORROW_BPS / 10000n : sourceRepayBigInt;
3390
+ const flashFeeBigInt = applyFeeCeil(flashBorrowBigInt, flashFeeRate);
3391
+ const flashRepayBigInt = flashBorrowBigInt + flashFeeBigInt;
3392
+ const flashBorrowAmountBaseUnits = new BN8(flashBorrowBigInt.toString());
3393
+ const flashFeeBaseUnits = new BN8(flashFeeBigInt.toString());
3394
+ const flashRepayAmountBaseUnits = new BN8(flashRepayBigInt.toString());
3395
+ const reserveBorrowCapacityBaseUnits = BigInt(
3396
+ fromUiAmount(
3397
+ ctx.destination.debtReserve.borrows.limit - ctx.destination.debtReserve.borrows.totalAmount,
3398
+ destDebtDecimals
3399
+ ).toString()
3400
+ );
3401
+ const utilizationBorrowCapacityBaseUnits = await this.calcDestinationBorrowCapacityForDeposit(
3402
+ ctx,
3403
+ { ...params, collateralUiAmount: 0 }
3404
+ );
3405
+ const maxDestinationBorrowBaseUnits = [
3406
+ params.maxDestinationBorrowBaseUnits,
3407
+ reserveBorrowCapacityBaseUnits,
3408
+ utilizationBorrowCapacityBaseUnits
3409
+ ].filter((amount) => amount !== void 0).reduce((min, amount) => amount < min ? amount : min);
3410
+ if (maxDestinationBorrowBaseUnits <= 0n) {
3411
+ throw new Error(
3412
+ "LeverageService.buildFlashRebalance: destination reserve has no available borrow capacity"
3413
+ );
3414
+ }
3415
+ const { quote: swapQuote } = await sizeExactInForMinOutput(ctx.swap, {
3416
+ inputMint: destDebtLiqMint,
3417
+ outputMint: sourceDebtLiqMint,
3418
+ minOutputAmount: flashRepayBigInt,
3419
+ maxInputAmount: maxDestinationBorrowBaseUnits,
3420
+ slippageBps: params.swapSlippageBps ?? 15,
3421
+ safetyBufferBps: params.swapBufferBps ?? 5,
3422
+ maxAccounts: FLASH_REBALANCE_SWAP_MAX_ACCOUNTS
3423
+ });
3424
+ if (params.maxSwapCostBps !== void 0 || params.maxMarketBasisBps !== void 0) {
3425
+ const [sourcePrices, destPrices] = await Promise.all([
3426
+ new ReservesManager(
3427
+ ctx.source.supplyReserve,
3428
+ ctx.source.debtReserve,
3429
+ ctx.environment
3430
+ ).prices(),
3431
+ new ReservesManager(
3432
+ ctx.destination.supplyReserve,
3433
+ ctx.destination.debtReserve,
3434
+ ctx.environment
3435
+ ).prices()
3436
+ ]);
3437
+ const fairOutPerIn = destPrices.debt.realtimePrice / sourcePrices.debt.realtimePrice;
3438
+ if (!Number.isFinite(fairOutPerIn) || fairOutPerIn <= 0) {
3439
+ throw new Error(
3440
+ `LeverageService.buildFlashRebalance: invalid oracle prices for swap cost check (source=${sourcePrices.debt.realtimePrice} dest=${destPrices.debt.realtimePrice})`
3441
+ );
3442
+ }
3443
+ const inUi = Number(swapQuote.inputAmount) / Math.pow(10, destDebtDecimals);
3444
+ const outUi = Number(swapQuote.outputAmount) / Math.pow(10, sourceDebtDecimals);
3445
+ const executionCostBps = (1 - outUi / inUi / fairOutPerIn) * 1e4;
3446
+ const marketBasisBps = (1 - fairOutPerIn) * 1e4;
3447
+ if (params.maxSwapCostBps !== void 0 && executionCostBps > params.maxSwapCostBps) {
3448
+ throw new FlashRebalanceSwapCostExceededError(
3449
+ "execution-cost",
3450
+ executionCostBps,
3451
+ marketBasisBps,
3452
+ params.maxSwapCostBps,
3453
+ swapQuote.inputAmount,
3454
+ swapQuote.outputAmount
3455
+ );
3456
+ }
3457
+ if (params.maxMarketBasisBps !== void 0 && Math.abs(marketBasisBps) > params.maxMarketBasisBps) {
3458
+ throw new FlashRebalanceSwapCostExceededError(
3459
+ "market-basis",
3460
+ executionCostBps,
3461
+ marketBasisBps,
3462
+ params.maxMarketBasisBps,
3463
+ swapQuote.inputAmount,
3464
+ swapQuote.outputAmount
3465
+ );
3466
+ }
3467
+ }
3468
+ const swapCpi = await ctx.swap.getSwapCpiData(swapQuote, ctx.user, { payer: ctx.payer });
3469
+ const destinationBorrowBaseUnits = new BN8(swapQuote.inputAmount.toString());
3470
+ const destinationBorrowUiAmount = toUiAmount(destinationBorrowBaseUnits, destDebtDecimals);
3471
+ const sourceRepay = await ctx.source.lendingIx.getRepayCpiData({
3472
+ user: ctx.user,
3473
+ payer: ctx.payer,
3474
+ pool: ctx.source.pool,
3475
+ reserve: sourceDebtMint,
3476
+ userAccount: ctx.source.userAccount,
3477
+ txId: ctx.txId
3478
+ });
3479
+ if (params.withdrawAll) {
3480
+ ctx.source.lendingIx.markObligationDebtCleared(
3481
+ ctx.txId,
3482
+ ctx.source.userAccount,
3483
+ sourceDebtMint
3484
+ );
3485
+ }
3486
+ const destBorrow = await ctx.destination.lendingIx.getInitBorrowPositionCpiBundle(
3487
+ {
3488
+ user: ctx.user,
3489
+ payer: ctx.payer,
3490
+ pool: ctx.destination.pool,
3491
+ reserve: ctx.destination.debtReserve.address,
3492
+ userAccount: ctx.destination.userAccount,
3493
+ uiAmount: destinationBorrowUiAmount,
3494
+ txId: ctx.txId
3495
+ },
3496
+ ctx.destination.supplyReserve.address
3497
+ );
3498
+ const userSourceDebtAta = await getAtaAddress(
3499
+ sourceDebtLiqMint,
3500
+ ctx.user,
3501
+ ctx.source.debtReserve.mint.mintTokenProgram
3502
+ );
3503
+ const flashBorrowIx = await ctx.flashLoan.getFlashBorrowIx({
3504
+ user: ctx.payer,
3505
+ pool: ctx.source.pool,
3506
+ reserve: sourceDebtMint,
3507
+ amountBaseUnits: flashBorrowAmountBaseUnits,
3508
+ destinationAta: userSourceDebtAta
3509
+ });
3510
+ const sourceIx = ctx.source.lendingIx;
3511
+ const destIx = ctx.destination.lendingIx;
3512
+ const sourcePreInstructions = await sourceIx.getPreInstructions(ctx.txId);
3513
+ const lendingPreInstructions = sourceIx === destIx ? sourcePreInstructions : [...sourcePreInstructions, ...await destIx.getPreInstructions(ctx.txId)];
3514
+ const swapPreInstructions = swapCpi.preInstructions ?? [];
3515
+ const preInstructions = [...lendingPreInstructions, ...swapPreInstructions];
3516
+ const postSuccessCacheInvalidations = [
3517
+ ...destBorrow.postSuccessCacheInvalidations,
3518
+ ...swapCpi.postSuccessCacheInvalidations ?? []
3519
+ ];
3520
+ return {
3521
+ flashBorrowAmountBaseUnits,
3522
+ flashRepayAmountBaseUnits,
3523
+ flashFeeBaseUnits,
3524
+ sourceRepayUiAmount,
3525
+ destinationBorrowUiAmount,
3526
+ flashBorrowIx,
3527
+ sourceRepayCpis: [...sourceRepay.prerequisiteCpis, ...sourceRepay.cpis],
3528
+ destinationBorrowCpis: [...destBorrow.prerequisiteCpis, ...destBorrow.cpis],
3529
+ swapCpis: [swapCpi],
3530
+ preInstructions,
3531
+ postSuccessCacheInvalidations
3532
+ };
3533
+ }
3534
+ /**
3535
+ * Build the top-level flash-repay instruction for a previously-built flash
3536
+ * rebalance, given the final transaction index of its `flashBorrowIx`.
3537
+ *
3538
+ * Split from {@link buildFlashRebalance} because `borrowIxIndex` depends on
3539
+ * the caller's full tx layout (pre-instructions + heap frame + ATA creations
3540
+ * + flash-borrow position), which in turn depends on the ATA list derived
3541
+ * from the plan's `remainingAccounts` — a chicken-and-egg the caller resolves
3542
+ * by assembling the preamble before calling this.
3543
+ */
3544
+ static async buildFlashRepayIx(ctx, plan, borrowIxIndex) {
3545
+ const userSourceDebtAta = await getAtaAddress(
3546
+ ctx.source.debtReserve.mint.mint,
3547
+ ctx.user,
3548
+ ctx.source.debtReserve.mint.mintTokenProgram
3549
+ );
3550
+ return ctx.flashLoan.getFlashRepayIx({
3551
+ user: ctx.payer,
3552
+ pool: ctx.source.pool,
3553
+ reserve: ctx.source.debtReserve.address,
3554
+ amountBaseUnits: plan.flashBorrowAmountBaseUnits,
3555
+ borrowIxIndex,
3556
+ userSourceLiquidity: userSourceDebtAta
3557
+ });
3558
+ }
3559
+ static async calcSourceRepayForWithdraw(ctx, params) {
3560
+ const manager = new LendingPositionManager(
3561
+ ctx.source.lendingIx.data,
3562
+ ctx.source.pool,
3563
+ ctx.source.userAccount,
3564
+ ctx.source.supplyReserve,
3565
+ ctx.source.debtReserve,
3566
+ ctx.environment
3567
+ );
3568
+ if (params.withdrawAll) {
3569
+ const { debtUiAmount } = await manager.getLendingPositionAmounts();
3570
+ return fromUiAmount(debtUiAmount, ctx.source.debtReserve.mint.mintDecimals);
3571
+ }
3572
+ const debtChangeUi = await manager.calcDebtChangeAmountForCollateralWithdrawal(
3573
+ params.collateralUiAmount,
3574
+ params.sourceTargetUtilizationRateBps
3575
+ );
3576
+ const repayUi = Math.max(0, -debtChangeUi);
3577
+ return fromUiAmount(repayUi, ctx.source.debtReserve.mint.mintDecimals);
3578
+ }
3579
+ static async calcDestinationBorrowCapacityForDeposit(ctx, params) {
3580
+ if (params.destinationMaxUtilizationRateBps === void 0) {
3581
+ return void 0;
3582
+ }
3583
+ const manager = new LendingPositionManager(
3584
+ ctx.destination.lendingIx.data,
3585
+ ctx.destination.pool,
3586
+ ctx.destination.userAccount,
3587
+ ctx.destination.supplyReserve,
3588
+ ctx.destination.debtReserve,
3589
+ ctx.environment
3590
+ );
3591
+ const current = await manager.getLendingPositionAmounts();
3592
+ const reserves = new ReservesManager(
3593
+ ctx.destination.supplyReserve,
3594
+ ctx.destination.debtReserve,
3595
+ ctx.environment
3596
+ );
3597
+ const debtAdjustmentUsd = await reserves.calcDebtAdjustmentUsd(
3598
+ current.supplyUiAmount + params.collateralUiAmount,
3599
+ current.debtUiAmount,
3600
+ params.destinationMaxUtilizationRateBps,
3601
+ { positionChangeMode: "debtOnly" }
3602
+ );
3603
+ const prices = await reserves.prices();
3604
+ if (debtAdjustmentUsd <= 0) {
3605
+ return 0n;
3606
+ }
3607
+ const debtUiAmount = debtAdjustmentUsd / prices.debt.realtimePrice;
3608
+ return BigInt(
3609
+ fromUiAmount(debtUiAmount, ctx.destination.debtReserve.mint.mintDecimals).toString()
3610
+ );
3611
+ }
3612
+ };
3613
+
3614
+ // src/constants/configs/carryTradePresets.ts
3615
+ var VOLATILITY_REGIMES = ["lowVol", "highVol"];
3616
+ function isVolatilityRegime(s) {
3617
+ return VOLATILITY_REGIMES.includes(s);
3618
+ }
3619
+ var STOCK_INDEX_PRESETS = {
3620
+ lowVol: {
3621
+ drawdownPctFromTargetToLiq: 8,
3622
+ drawdownPctFromUnwindToLiq: 5,
3623
+ maxPriceChangeUpPercent: 2
3624
+ },
3625
+ highVol: {
3626
+ drawdownPctFromTargetToLiq: 11,
3627
+ drawdownPctFromUnwindToLiq: 7,
3628
+ maxPriceChangeUpPercent: 3
3629
+ }
3630
+ };
3631
+ var BTC_CARRY_PRESETS = {
3632
+ lowVol: {
3633
+ drawdownPctFromTargetToLiq: 12,
3634
+ drawdownPctFromUnwindToLiq: 8,
3635
+ maxPriceChangeUpPercent: 6
3636
+ },
3637
+ highVol: {
3638
+ drawdownPctFromTargetToLiq: 14,
3639
+ drawdownPctFromUnwindToLiq: 10,
3640
+ maxPriceChangeUpPercent: 8
3641
+ }
3642
+ };
3643
+ var ETH_CARRY_PRESETS = {
3644
+ lowVol: {
3645
+ drawdownPctFromTargetToLiq: 14,
3646
+ drawdownPctFromUnwindToLiq: 10,
3647
+ maxPriceChangeUpPercent: 7
3648
+ },
3649
+ highVol: {
3650
+ drawdownPctFromTargetToLiq: 17,
3651
+ drawdownPctFromUnwindToLiq: 12,
3652
+ maxPriceChangeUpPercent: 10
3653
+ }
3654
+ };
3655
+ var SOL_CARRY_PRESETS = {
3656
+ lowVol: {
3657
+ drawdownPctFromTargetToLiq: 16,
3658
+ drawdownPctFromUnwindToLiq: 12,
3659
+ maxPriceChangeUpPercent: 8
3660
+ },
3661
+ highVol: {
3662
+ drawdownPctFromTargetToLiq: 19,
3663
+ drawdownPctFromUnwindToLiq: 14,
3664
+ maxPriceChangeUpPercent: 11
3665
+ }
3666
+ };
3667
+ var LST_CARRY_PRESETS = {
3668
+ lowVol: {
3669
+ drawdownPctFromTargetToLiq: 19,
3670
+ drawdownPctFromUnwindToLiq: 10,
3671
+ maxPriceChangeUpPercent: 8
3672
+ },
3673
+ highVol: {
3674
+ drawdownPctFromTargetToLiq: 22,
3675
+ drawdownPctFromUnwindToLiq: 12,
3676
+ maxPriceChangeUpPercent: 11
3677
+ }
3678
+ };
3679
+ var LARGE_CAP_ALT_CARRY_PRESETS = {
3680
+ lowVol: {
3681
+ drawdownPctFromTargetToLiq: 22,
3682
+ drawdownPctFromUnwindToLiq: 16,
3683
+ maxPriceChangeUpPercent: 8
3684
+ },
3685
+ highVol: {
3686
+ drawdownPctFromTargetToLiq: 25,
3687
+ drawdownPctFromUnwindToLiq: 18,
3688
+ maxPriceChangeUpPercent: 10
3689
+ }
3690
+ };
3691
+ var SMALL_CAP_ALT_CARRY_PRESETS = {
3692
+ lowVol: {
3693
+ drawdownPctFromTargetToLiq: 26,
3694
+ drawdownPctFromUnwindToLiq: 22,
3695
+ maxPriceChangeUpPercent: 10
3696
+ },
3697
+ highVol: {
3698
+ drawdownPctFromTargetToLiq: 29,
3699
+ drawdownPctFromUnwindToLiq: 24,
3700
+ maxPriceChangeUpPercent: 12
3701
+ }
3702
+ };
3703
+ var ASSET_PRESETS = {
3704
+ WBTC: { presets: BTC_CARRY_PRESETS, defaultRegime: "lowVol" },
3705
+ CBBTC: { presets: BTC_CARRY_PRESETS, defaultRegime: "lowVol" },
3706
+ WETH: { presets: ETH_CARRY_PRESETS, defaultRegime: "lowVol" },
3707
+ SOL: { presets: SOL_CARRY_PRESETS, defaultRegime: "lowVol" },
3708
+ JUPSOL: { presets: LST_CARRY_PRESETS, defaultRegime: "lowVol" },
3709
+ JITOSOL: { presets: LST_CARRY_PRESETS, defaultRegime: "lowVol" },
3710
+ DFDVSOL: { presets: LST_CARRY_PRESETS, defaultRegime: "lowVol" },
3711
+ SPYX: { presets: STOCK_INDEX_PRESETS, defaultRegime: "lowVol" },
3712
+ QQQX: { presets: STOCK_INDEX_PRESETS, defaultRegime: "lowVol" },
3713
+ LARGE_CAP: { presets: LARGE_CAP_ALT_CARRY_PRESETS, defaultRegime: "lowVol" },
3714
+ SMALL_CAP: { presets: SMALL_CAP_ALT_CARRY_PRESETS, defaultRegime: "highVol" }
3715
+ };
3716
+ function resolvePresets(collateralSymbol) {
3717
+ return ASSET_PRESETS[collateralSymbol.toUpperCase()];
3718
+ }
3719
+
3720
+ // src/services/carry/carryAllocationConfig.ts
3721
+ var MAX_TARGET_UTILIZATION_RATE_BPS = 1e4;
3722
+ var MAX_LENDING_POSITION_UPPER_UTIL_BPS2 = 10500;
3723
+ var MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS = 200;
3724
+ function clampLendingPositionConfigBps(config) {
3725
+ let { targetUtilizationRateBps, maxDeviationAboveTargetUtilBps, maxDeviationBelowTargetUtilBps } = config;
3726
+ if (!Number.isInteger(targetUtilizationRateBps) || targetUtilizationRateBps <= 0) {
3727
+ throw new Error("targetUtilizationRateBps must be a positive integer");
3728
+ }
3729
+ for (const [name, v] of [
3730
+ ["maxDeviationAboveTargetUtilBps", maxDeviationAboveTargetUtilBps],
3731
+ ["maxDeviationBelowTargetUtilBps", maxDeviationBelowTargetUtilBps]
3732
+ ]) {
3733
+ if (!Number.isInteger(v) || v < 0) {
3734
+ throw new Error(`${name} must be a non-negative integer`);
3735
+ }
3736
+ }
3737
+ targetUtilizationRateBps = Math.min(targetUtilizationRateBps, MAX_TARGET_UTILIZATION_RATE_BPS);
3738
+ maxDeviationAboveTargetUtilBps = Math.min(
3739
+ maxDeviationAboveTargetUtilBps,
3740
+ MAX_LENDING_POSITION_UPPER_UTIL_BPS2 - targetUtilizationRateBps
3741
+ );
3742
+ if (targetUtilizationRateBps <= maxDeviationBelowTargetUtilBps) {
3743
+ throw new Error("targetUtilizationRateBps must be greater than maxDeviationBelowTargetUtilBps");
3744
+ }
3745
+ return {
3746
+ targetUtilizationRateBps,
3747
+ maxDeviationAboveTargetUtilBps,
3748
+ maxDeviationBelowTargetUtilBps
3749
+ };
3750
+ }
3751
+ function computeCarryLendingAllocationConfig(params) {
3752
+ const {
3753
+ drawdownPctFromTargetToLiq,
3754
+ drawdownPctFromUnwindToLiq,
3755
+ maxPriceChangeUpPercent,
3756
+ maxLtv,
3757
+ liquidationThreshold
3758
+ } = params;
3759
+ if (!Number.isFinite(drawdownPctFromTargetToLiq) || drawdownPctFromTargetToLiq <= 0 || drawdownPctFromTargetToLiq >= 100) {
3760
+ throw new RangeError("drawdownPctFromTargetToLiq must be in (0, 100)");
3761
+ }
3762
+ if (!Number.isFinite(drawdownPctFromUnwindToLiq) || drawdownPctFromUnwindToLiq < 0 || drawdownPctFromUnwindToLiq >= 100) {
3763
+ throw new RangeError("drawdownPctFromUnwindToLiq must be in [0, 100)");
3764
+ }
3765
+ if (drawdownPctFromUnwindToLiq >= drawdownPctFromTargetToLiq) {
3766
+ throw new RangeError(
3767
+ "drawdownPctFromUnwindToLiq must be less than drawdownPctFromTargetToLiq (unwind trigger is closer to liquidation than target)"
3768
+ );
3769
+ }
3770
+ if (!Number.isFinite(maxPriceChangeUpPercent) || maxPriceChangeUpPercent <= 0) {
3771
+ throw new RangeError("maxPriceChangeUpPercent must be finite and positive");
3772
+ }
3773
+ const targetDecimal = maxLtvUtilBeforeCollDrawdown({
3774
+ drawdownPercent: drawdownPctFromTargetToLiq,
3775
+ ltv: maxLtv,
3776
+ liquidationThreshold
3777
+ });
3778
+ let targetUtilizationRateBps = Math.min(
3779
+ Math.floor(targetDecimal * 1e4),
3780
+ MAX_TARGET_UTILIZATION_RATE_BPS
3781
+ );
3782
+ if (targetUtilizationRateBps <= 0) {
3783
+ throw new RangeError(
3784
+ "Computed target utilization rounds to zero; reduce drawdownPctFromTargetToLiq or check maxLtv / liquidationThreshold"
3785
+ );
3786
+ }
3787
+ const unwindTriggerDecimal = maxLtvUtilBeforeCollDrawdown({
3788
+ drawdownPercent: drawdownPctFromUnwindToLiq,
3789
+ ltv: maxLtv,
3790
+ liquidationThreshold
3791
+ });
3792
+ const unwindTriggerBps = Math.floor(unwindTriggerDecimal * 1e4);
3793
+ let maxDeviationAboveTargetUtilBps = Math.min(
3794
+ unwindTriggerBps - targetUtilizationRateBps,
3795
+ MAX_LENDING_POSITION_UPPER_UTIL_BPS2 - targetUtilizationRateBps
3796
+ );
3797
+ if (maxDeviationAboveTargetUtilBps < MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS) {
3798
+ maxDeviationAboveTargetUtilBps = MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS;
3799
+ targetUtilizationRateBps = Math.min(
3800
+ targetUtilizationRateBps,
3801
+ MAX_LENDING_POSITION_UPPER_UTIL_BPS2 - MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS
3802
+ );
3803
+ }
3804
+ const t = targetUtilizationRateBps / 1e4;
3805
+ const maxBelowDecimal = ltvUtilDeltaBelowTargForRallyPct(t, maxPriceChangeUpPercent);
3806
+ const maxDeviationBelowTargetUtilBps = Math.floor(maxBelowDecimal * 1e4);
3807
+ return clampLendingPositionConfigBps({
3808
+ targetUtilizationRateBps,
3809
+ maxDeviationAboveTargetUtilBps,
3810
+ maxDeviationBelowTargetUtilBps
3811
+ });
3812
+ }
3813
+ function computeConfigForCollateral(args) {
3814
+ const { collateralMint, collateralReserve, debtReserve } = args;
3815
+ const mintInfo = mints.get(collateralMint);
3816
+ const symbol = mintInfo?.symbol ?? String(collateralMint);
3817
+ const entry = resolvePresets(symbol);
3818
+ if (!entry) {
3819
+ throw new Error(
3820
+ `computeConfigForCollateral: no carry preset found for collateral "${symbol}" (${collateralMint})`
3821
+ );
3822
+ }
3823
+ const regime = args.regime ?? entry.defaultRegime;
3824
+ const preset = entry.presets[regime];
3825
+ const rm = new ReservesManager(collateralReserve, debtReserve);
3826
+ const pct = collateralReserve.config.liquidationThresholdPct;
3827
+ const liquidationThreshold = pct <= 1 ? pct : pct / 100;
3828
+ return computeCarryLendingAllocationConfig({
3829
+ ...preset,
3830
+ maxLtv: rm.maxLtv,
3831
+ liquidationThreshold
3832
+ });
3833
+ }
3834
+
3835
+ // src/services/carry/lycLendingPositionManager.ts
3836
+ var LycLendingPositionManager = class _LycLendingPositionManager extends LendingPositionManager {
3837
+ constructor(lpData, lendingPosition, collateralReserve, debtReserve, environment) {
3838
+ super(
3839
+ lpData,
3840
+ fromWeb3Pk(lendingPosition.pool),
3841
+ fromWeb3Pk(lendingPosition.protocolUserAcc),
3842
+ collateralReserve,
3843
+ debtReserve,
3844
+ environment
3845
+ );
3846
+ this.lendingPosition = lendingPosition;
3847
+ }
3848
+ static async create(lpData, lendingPosition, environment) {
3849
+ const pool = fromWeb3Pk(lendingPosition.pool);
3850
+ const [collateralReserve, debtReserve] = await Promise.all([
3851
+ lpData.fetchReserve(pool, fromWeb3Pk(lendingPosition.collateralReserve)),
3852
+ lpData.fetchReserve(pool, fromWeb3Pk(lendingPosition.debtReserve))
3853
+ ]);
3854
+ if (!collateralReserve || !debtReserve) {
3855
+ throw new Error("Failed to fetch reserves");
3856
+ }
3857
+ return new _LycLendingPositionManager(
3858
+ lpData,
3859
+ lendingPosition,
3860
+ collateralReserve,
3861
+ debtReserve,
3862
+ environment
3863
+ );
3864
+ }
3865
+ /**
3866
+ * Derives `targetUtilizationRateBps` and carry trigger deviations from drawdown-to-liquidation
3867
+ * buffers and a rally percentage, using this pair's {@link ReservesManager.maxLtv} and the
3868
+ * collateral reserve's **base** `liquidationThresholdPct` (normalized to a decimal).
3869
+ *
3870
+ * For custom `maxLtv` / `liquidationThreshold` (e.g. e-mode liquidation threshold), call
3871
+ * {@link computeCarryLendingAllocationConfig} directly.
3872
+ */
3873
+ getLendingAllocationConfigFromPriceBands(params) {
3874
+ const pct = this.reservesManager.supplyReserve.config.liquidationThresholdPct;
3875
+ const liquidationThreshold = pct <= 1 ? pct : pct / 100;
3876
+ return computeCarryLendingAllocationConfig({
3877
+ ...params,
3878
+ maxLtv: this.reservesManager.maxLtv,
3879
+ liquidationThreshold
3880
+ });
3881
+ }
3882
+ /**
3883
+ * Returns true when the current LTV utilization (valued at EMA prices) has
3884
+ * fallen far enough below the target that the position should be boosted.
3885
+ */
3886
+ async shouldIncreaseCarryPosition() {
3887
+ const state = await this.getPositionState("ema");
3888
+ if (!state) return false;
3889
+ const { supplyUsd, debtUsd } = state;
3890
+ if (supplyUsd <= 0) return false;
3891
+ const currentUtilBps = this.reservesManager.calcLtvUtilizationRateBps(supplyUsd, debtUsd);
3892
+ return currentUtilBps <= this.lendingPosition.config.targetUtilizationRateBps - this.lendingPosition.config.maxDeviationBelowTargetUtilBps;
3893
+ }
3894
+ /**
3895
+ * Returns true when the current LTV utilization (valued at realtime prices) has
3896
+ * risen far enough above the target that the position should be unwound.
3897
+ */
3898
+ async shouldDecreaseCarryPosition() {
3899
+ const state = await this.getPositionState("realtime");
3900
+ if (!state) return false;
3901
+ const { supplyUsd, debtUsd } = state;
3902
+ const currentUtilBps = this.reservesManager.calcLtvUtilizationRateBps(supplyUsd, debtUsd);
3903
+ return currentUtilBps >= this.lendingPosition.config.targetUtilizationRateBps + this.lendingPosition.config.maxDeviationAboveTargetUtilBps;
3904
+ }
3905
+ async calcDebtChangeAmount(targetUtilizationRateBps = this.lendingPosition.config.targetUtilizationRateBps) {
3906
+ return super.calcDebtChangeAmount(targetUtilizationRateBps);
3907
+ }
3908
+ async calcPreWithdrawalTargetUtilizationRateBps(withdrawUiCollateralAmount, postWithdrawalTargetUtilizationRateBps = this.lendingPosition.config.targetUtilizationRateBps) {
3909
+ return super.calcPreWithdrawalTargetUtilizationRateBps(
3910
+ withdrawUiCollateralAmount,
3911
+ postWithdrawalTargetUtilizationRateBps
3912
+ );
3913
+ }
3914
+ async calcDebtChangeAmountForCollateralWithdrawal(withdrawUiCollateralAmount, postWithdrawalTargetUtilizationRateBps = this.lendingPosition.config.targetUtilizationRateBps) {
3915
+ return super.calcDebtChangeAmountForCollateralWithdrawal(
3916
+ withdrawUiCollateralAmount,
3917
+ postWithdrawalTargetUtilizationRateBps
3918
+ );
3919
+ }
3920
+ async getCollateralPriceTriggerBand() {
3921
+ return super.getCollateralPriceTriggerBand(this.configTriggerBandBps());
3922
+ }
3923
+ async getInspectMetrics() {
3924
+ return super.getInspectMetrics(this.configTriggerBandBps());
3925
+ }
3926
+ configTriggerBandBps() {
3927
+ const {
3928
+ targetUtilizationRateBps,
3929
+ maxDeviationBelowTargetUtilBps,
3930
+ maxDeviationAboveTargetUtilBps
3931
+ } = this.lendingPosition.config;
3932
+ return {
3933
+ lowerTargetUtilizationRateBps: targetUtilizationRateBps - maxDeviationBelowTargetUtilBps,
3934
+ upperTargetUtilizationRateBps: targetUtilizationRateBps + maxDeviationAboveTargetUtilBps
3935
+ };
3936
+ }
3937
+ };
3938
+
3939
+ export {
3940
+ KAMINO_MAIN_MARKET,
3941
+ getEligiblePools,
3942
+ getLendingUserAccountCacheInvalidation,
3943
+ KaminoClient,
3944
+ LOCAL_TEST_MAX_ACCOUNTS,
3945
+ LOCAL_TEST_EXCLUDED_DEXES,
3946
+ JupiterSwapClient,
3947
+ ExactInQuoteExceedsMaxInputError,
3948
+ FlashRebalanceSwapCostExceededError,
3949
+ LeverageService,
3950
+ VOLATILITY_REGIMES,
3951
+ isVolatilityRegime,
3952
+ STOCK_INDEX_PRESETS,
3953
+ BTC_CARRY_PRESETS,
3954
+ ETH_CARRY_PRESETS,
3955
+ SOL_CARRY_PRESETS,
3956
+ LST_CARRY_PRESETS,
3957
+ LARGE_CAP_ALT_CARRY_PRESETS,
3958
+ SMALL_CAP_ALT_CARRY_PRESETS,
3959
+ ASSET_PRESETS,
3960
+ resolvePresets,
3961
+ MAX_TARGET_UTILIZATION_RATE_BPS,
3962
+ MAX_LENDING_POSITION_UPPER_UTIL_BPS2 as MAX_LENDING_POSITION_UPPER_UTIL_BPS,
3963
+ MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS,
3964
+ clampLendingPositionConfigBps,
3965
+ computeCarryLendingAllocationConfig,
3966
+ computeConfigForCollateral,
3967
+ LycLendingPositionManager
3968
+ };
3969
+ //# sourceMappingURL=chunk-GOW6CARW.mjs.map