@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 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/utils/enrichment.ts","../src/utils/feeDripMetrics.ts","../src/utils/timelock.ts","../src/utils/lycData.ts","../src/constants/configs/allocations.ts","../src/utils/data.ts","../src/utils/transactions.ts","../src/utils/lendingPosition.ts","../src/utils/yieldingBank.ts","../src/client/client.ts","../../../shared/swap-aggregator/src/aggSwapClient.ts","../src/client/lendingPlatformClients.ts","../src/client/externalLiquidityResolver.ts","../src/client/builders/asyncBurnBuilder.ts","../src/client/builders/claimIncentivesBuilder.ts","../src/client/builders/collectFeesBuilder.ts","../src/client/plans/collectInterest.ts","../src/client/routes/collectInterest.ts","../src/client/builders/collectInterestBuilder.ts","../src/client/builders/createCpiPlanBuilder.ts","../src/client/builders/createTokenBuilder.ts","../src/client/builders/createTokenLendingPositionBuilder.ts","../src/client/builders/createYieldingBankAllocationBuilder.ts","../src/client/builders/createYieldingBankBuilder.ts","../src/client/plans/decreaseCarryPosition.ts","../src/client/builders/decreaseCarryPositionBuilder.ts","../src/client/builders/depositUnlentCollateralBuilder.ts","../src/client/builders/increaseCarryPositionBuilder.ts","../src/client/builders/rebalanceTokenBuilder.ts","../src/client/builders/rebalanceYieldingBankBuilder.ts","../src/client/builders/recollateralizeLossBuilder.ts","../src/client/builders/resetTokenBurnRateLimitBuilder.ts","../src/client/builders/setTokenCircuitBreakerBuilder.ts","../src/client/builders/setYieldingBankCircuitBreakerBuilder.ts","../src/client/builders/updateLendingPositionConfigBuilder.ts","../src/client/builders/updateTokenConfigurationBuilder.ts","../src/client/builders/updateTokenMetadataBuilder.ts","../src/client/builders/updateYieldingBankConfigBuilder.ts","../src/client/transaction.ts","../src/client/types/enums.ts","../src/services/allocation/allocationService.ts","../src/services/lendingPosition/lendingPositionService.ts","../src/services/rebalance/token/tokenRebalanceService.ts","../src/services/rebalance/yieldingBank/strategy.ts","../src/services/rebalance/yieldingBank/planner.ts","../src/services/redemption/redemptionService.ts","../src/metrics/protocolMetrics.ts","../src/decoders/discriminators.ts","../src/decoders/idlAccounts.ts","../src/decoders/innerCpis.ts","../src/decoders/solana.ts","../src/decoders/decodeTransaction.ts","../src/decoders/lycInstructionNames.ts"],"sourcesContent":["import { TransactionError } from \"common\";\nimport { IDL } from \"./idl/long_yield_carry\";\n\n/** LYC program error when on-chain utilization guards block a carry update. */\nexport const INVALID_UTILIZATION_RATE_CONDITION_CODE = 8020;\n\n/** LYC on-chain errors that represent expected no-ops, not operator failures. */\nconst SKIPPABLE_LYC_ERROR_CODES = new Set<number>([INVALID_UTILIZATION_RATE_CONDITION_CODE]);\n\n/**\n * Thrown when a tx builder receives inputs that make the operation a no-op\n * (e.g. zero borrow amount, no yield to collect). Callers can catch this\n * to distinguish \"nothing to do\" from genuine failures.\n */\nexport class NoOpTransactionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NoOpTransactionError\";\n }\n}\n\n/**\n * Thrown when `collect_interest` has nothing meaningful to redeem or swap\n * (no net carry yield, no matching carry slot, redeem rounds to zero, etc.).\n *\n * Extends {@link NoOpTransactionError} so batch jobs that skip no-ops via\n * `instanceof NoOpTransactionError` continue to treat this as a skip.\n */\nexport class NoInterestToCollectError extends NoOpTransactionError {\n constructor(message: string) {\n super(message);\n this.name = \"NoInterestToCollectError\";\n }\n}\n\n/**\n * Thrown when an initial lending position cannot be created because of a\n * permanent configuration gap rather than a transient failure — e.g. the\n * collateral mint is not listed in any lending pool, has no carry preset, or\n * has no viable debt mint / reserve.\n *\n * Callers running on a tight schedule (e.g. the unlent-buffer worker) should\n * catch this to **skip** the token instead of failing the task, which would\n * otherwise retry every cycle and churn the DLQ until the config is fixed.\n */\nexport class LendingPositionBootstrapError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"LendingPositionBootstrapError\";\n }\n}\n\nconst LYC_ERROR_MAP = new Map<number, { name: string; msg: string }>();\nfor (const entry of IDL.errors) {\n LYC_ERROR_MAP.set(entry.code, { name: entry.name, msg: entry.msg });\n}\n\n/**\n * Looks up an Anchor custom error code against the LYC program IDL.\n * Returns the error name and message if found, or `undefined` for codes\n * belonging to other programs (e.g. Kamino, SPL Token).\n */\nexport function lookupLycError(code: number): { name: string; msg: string } | undefined {\n return LYC_ERROR_MAP.get(code);\n}\n\n/**\n * Parses a logged Anchor error from a simulation failure message or program log line.\n */\nexport function parseLoggedLycAnchorError(\n text: string\n): { name: string; code: number; msg: string } | undefined {\n const match = text.match(\n /Error Code:\\s*([A-Za-z0-9_]+)\\.\\s*Error Number:\\s*(\\d+)\\.\\s*Error Message:\\s*([^\\n\\r]*)/\n );\n if (!match) return undefined;\n\n const code = parseInt(match[2], 10);\n if (Number.isNaN(code) || !LYC_ERROR_MAP.has(code)) return undefined;\n\n return {\n name: match[1],\n code,\n msg: match[3].trim().replace(/\\.$/, \"\"),\n };\n}\n\n/**\n * Extracts an LYC program error code from a failed transaction, when present.\n */\nexport function extractLycErrorCode(err: unknown): number | undefined {\n if (err instanceof TransactionError) {\n for (const line of err.programLogs) {\n const parsed = parseLoggedLycAnchorError(line);\n if (parsed) return parsed.code;\n }\n }\n\n const message = err instanceof Error ? err.message : String(err);\n const parsedFromMessage = parseLoggedLycAnchorError(message);\n if (parsedFromMessage) return parsedFromMessage.code;\n\n const jsonMatch = message.match(/\\{.*\"InstructionError\".*\\}/s);\n if (!jsonMatch) return undefined;\n\n try {\n const parsed = JSON.parse(jsonMatch[0]);\n const [, detail] = parsed.InstructionError;\n if (detail?.Custom === undefined) return undefined;\n\n const code = typeof detail.Custom === \"string\" ? parseInt(detail.Custom, 10) : detail.Custom;\n return typeof code === \"number\" && !Number.isNaN(code) && LYC_ERROR_MAP.has(code)\n ? code\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** True when a failed tx was rejected by an expected LYC guard (not an incident). */\nexport function isSkippableLycTransactionError(err: unknown): boolean {\n const code = extractLycErrorCode(err);\n return code !== undefined && SKIPPABLE_LYC_ERROR_CODES.has(code);\n}\n\n/**\n * Attempts to parse a Solana `InstructionError` from a transaction simulation\n * failure message and returns a human-readable string.\n *\n * Handles formats like:\n * - `Transaction simulation failed: {\"InstructionError\":[\"0\",{\"Custom\":\"6121\"}]}`\n * - `Transaction simulation failed: {\"InstructionError\":[\"1\",\"ProgramFailedToComplete\"]}`\n *\n * If the error contains a `Custom` code in the LYC IDL range, it's decoded to\n * the program error name and message. Otherwise, the raw code or variant is\n * included with a note that it may be from a CPI target program.\n */\nexport function formatTransactionError(errMessage: string): string {\n const loggedAnchorError = parseLoggedAnchorError(errMessage);\n const jsonMatch = errMessage.match(/\\{.*\"InstructionError\".*\\}/s);\n if (!jsonMatch) {\n return loggedAnchorError\n ? `${loggedAnchorError.name} (${loggedAnchorError.code}) — ${loggedAnchorError.msg}`\n : errMessage;\n }\n\n try {\n const parsed = JSON.parse(jsonMatch[0]);\n const [ixIndexRaw, detail] = parsed.InstructionError;\n const ixIndex = typeof ixIndexRaw === \"string\" ? parseInt(ixIndexRaw, 10) : ixIndexRaw;\n\n if (typeof detail === \"string\") {\n return `ix[${ixIndex}]: ${detail}`;\n }\n\n if (detail?.Custom !== undefined) {\n const code = typeof detail.Custom === \"string\" ? parseInt(detail.Custom, 10) : detail.Custom;\n const matchingLoggedAnchorError =\n loggedAnchorError?.code === code ? loggedAnchorError : undefined;\n if (matchingLoggedAnchorError) {\n return `ix[${ixIndex}]: ${matchingLoggedAnchorError.name} (${code}) — ${matchingLoggedAnchorError.msg}`;\n }\n const lycErr = lookupLycError(code);\n if (lycErr) {\n return `ix[${ixIndex}]: ${lycErr.name} (${code}) — ${lycErr.msg}`;\n }\n return `ix[${ixIndex}]: Custom error ${code} (from CPI target program)`;\n }\n\n return `ix[${ixIndex}]: ${JSON.stringify(detail)}`;\n } catch {\n return errMessage;\n }\n}\n\nfunction parseLoggedAnchorError(\n errMessage: string\n): { name: string; code: number; msg: string } | undefined {\n const parsed = parseLoggedLycAnchorError(errMessage);\n if (parsed) return parsed;\n\n const match = errMessage.match(\n /Error Code:\\s*([A-Za-z0-9_]+)\\.\\s*Error Number:\\s*(\\d+)\\.\\s*Error Message:\\s*([^\\n\\r]*)/\n );\n if (!match) return undefined;\n\n const code = parseInt(match[2], 10);\n if (Number.isNaN(code)) return undefined;\n\n return {\n name: match[1],\n code,\n msg: match[3].trim().replace(/\\.$/, \"\"),\n };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport {\n fromWeb3Pk,\n LendingPlatform,\n lendingPlatformToEnum,\n type MintRegistry,\n mintSymbol,\n toBigInt,\n toUiAmount,\n TVL_USD_DECIMAL_PLACES,\n} from \"common\";\nimport type { LendingPlatformData } from \"lending-platforms\";\nimport { oracle } from \"oracle\";\nimport type { LYCToken, TokenLendingPositionData } from \"../models/lycToken\";\nimport type { LYCYieldingBank } from \"../models/yieldingBank\";\nimport { LycLendingPositionManager } from \"../services/carry\";\nimport { calculateFeeDripMetrics } from \"./feeDripMetrics\";\nimport { podBoolToNumber } from \"./general\";\nimport { collectableNetYieldUsd } from \"./tokenFeeMath\";\nimport { getTimelockStatus } from \"./timelock\";\nimport type {\n EnrichedTokenCarryPosition,\n EnrichedTokenLendingPosition,\n EnrichedTokenSnapshot,\n EnrichedYieldingBankHolding,\n EnrichedYieldingBankSnapshot,\n TokenInspectSnapshotArgs,\n YieldingBankInspectSnapshotArgs,\n} from \"../types/enriched\";\n\nexport function buildYieldingBankInspectSnapshot(\n bank: LYCYieldingBank,\n args: YieldingBankInspectSnapshotArgs\n): EnrichedYieldingBankSnapshot {\n const { environment, mintRegistry, timelocksEnabledInLocal } = args;\n const timelockOptions = { enableLocalTimelocks: timelocksEnabledInLocal };\n const baseSymbol = mintSymbol(bank.baseMint, mintRegistry);\n const defaultRedemptionMint =\n bank.defaultRedemptionMint !== PublicKey.default.toBase58()\n ? bank.defaultRedemptionMint\n : undefined;\n\n const holdings: EnrichedYieldingBankHolding[] = [\n {\n kind: \"base\",\n mint: bank.baseMint,\n symbol: baseSymbol,\n amountRaw: toBigInt(bank.data.baseAsset.amount),\n amountUi: toUiAmount(bank.data.baseAsset.amount, bank.data.baseAsset.decimals),\n decimals: bank.data.baseAsset.decimals,\n priceRaw: toBigInt(bank.data.baseAsset.price),\n priceUi: toUiAmount(bank.data.baseAsset.price, bank.data.baseAsset.decimals),\n isTimelocked: getTimelockStatus(\n environment,\n bank.data.baseAsset.timeCreated,\n \"touch\",\n timelockOptions\n ).isTimelocked,\n },\n ...bank.data.assets\n .filter((asset) => !asset.mint.equals(PublicKey.default))\n .map((asset) => {\n const mint = fromWeb3Pk(asset.mint);\n return {\n kind: \"asset\" as const,\n mint,\n symbol: mintSymbol(mint, mintRegistry),\n amountRaw: toBigInt(asset.amount),\n amountUi: toUiAmount(asset.amount, asset.decimals),\n decimals: asset.decimals,\n priceRaw: toBigInt(asset.price),\n priceUi: toUiAmount(asset.price, asset.decimals),\n isTimelocked: getTimelockStatus(environment, asset.timeCreated, \"touch\", timelockOptions)\n .isTimelocked,\n };\n }),\n ];\n\n const externalYieldingPositions = bank.data.externalYieldingPositions\n .map((position) => ({\n platform: lendingPlatformToEnum(position.lendingPlatform),\n pool: fromWeb3Pk(position.pool),\n tvlRaw: toBigInt(position.tvl),\n tvlUsd: toUiAmount(position.tvl, TVL_USD_DECIMAL_PLACES),\n isTimelocked: getTimelockStatus(environment, position.timeCreated, \"touch\", timelockOptions)\n .isTimelocked,\n }))\n .filter((position) => position.platform !== LendingPlatform.None);\n\n return {\n address: bank.address,\n id: bank.id,\n curator: fromWeb3Pk(bank.data.roles.curator),\n baseMint: bank.baseMint,\n baseSymbol,\n isActive: bank.isActive,\n circuitBreaker: bank.circuitBreaker,\n decimals: bank.decimals,\n tvlRaw: toBigInt(bank.data.accounting.tvl),\n tvlUsd: toUiAmount(bank.data.accounting.tvl, TVL_USD_DECIMAL_PLACES),\n sharePrice: bank.sharePrice,\n totalShares: bank.totalShares,\n lastRefreshedTs: toBigInt(bank.data.accounting.lastRefreshedTs),\n lastRebalancedTs: toBigInt(bank.data.accounting.lastRebalancedTs),\n isTimelocked: getTimelockStatus(\n environment,\n bank.data.config.timeCreatedTs,\n \"touch\",\n timelockOptions\n ).isTimelocked,\n defaultRedemptionMint,\n defaultRedemptionSymbol: defaultRedemptionMint\n ? mintSymbol(defaultRedemptionMint, mintRegistry)\n : undefined,\n holdings,\n externalYieldingPositions,\n };\n}\n\nexport async function buildTokenInspectSnapshot(\n token: LYCToken,\n args: TokenInspectSnapshotArgs\n): Promise<EnrichedTokenSnapshot> {\n const { environment, mintRegistry, yieldingBanks, kaminoData } = args;\n const collateralSymbol = mintSymbol(token.collateralMint, mintRegistry);\n const [collateralRealtimePrices, collateralEmaPrices] = await Promise.all([\n oracle.fetchPrices([token.collateralMint], \"realtime\", undefined, environment),\n oracle.fetchPrices([token.collateralMint], \"ema\", undefined, environment),\n ]);\n const collateralRealtimePriceUi = collateralRealtimePrices[token.collateralMint];\n const collateralEmaPriceUi = collateralEmaPrices[token.collateralMint];\n\n const lendingPositions = (\n await Promise.all(\n token.data.lendingPositions.map((position, index) =>\n buildLendingPositionInspectSnapshot(\n position,\n index,\n collateralSymbol,\n token.data.collateral.decimals,\n kaminoData,\n mintRegistry\n )\n )\n )\n ).filter((position): position is EnrichedTokenLendingPosition => position !== undefined);\n\n const carryPositions = token.data.debtCarry\n .map((carry, index) => {\n if (carry.yieldingBaseMint.equals(PublicKey.default) || toBigInt(carry.shares) <= BigInt(0)) {\n return undefined;\n }\n\n const baseMint = fromWeb3Pk(carry.yieldingBaseMint);\n const resolvedBank = yieldingBanks.find(\n (bank) => bank.id === carry.yieldingBankId && bank.baseMint === baseMint\n );\n\n const position: EnrichedTokenCarryPosition = {\n index,\n yieldingBankId: carry.yieldingBankId,\n yieldingBankAddress: resolvedBank?.address,\n baseMint,\n baseSymbol: mintSymbol(baseMint, mintRegistry),\n sharesRaw: toBigInt(carry.shares),\n sharesUi: resolvedBank ? toUiAmount(carry.shares, resolvedBank.decimals) : undefined,\n shareDecimals: resolvedBank?.decimals,\n tvlUsdRaw: toBigInt(carry.tvlUsd),\n tvlUsd: toUiAmount(carry.tvlUsd, TVL_USD_DECIMAL_PLACES),\n };\n\n return position;\n })\n .filter((position): position is EnrichedTokenCarryPosition => position !== undefined);\n\n const totalCarryTvlUsdRaw = carryPositions.reduce(\n (sum, position) => sum + position.tvlUsdRaw,\n 0n\n );\n const totalDebtUsdRaw = lendingPositions.reduce(\n (sum, position) => sum + position.debtTvlUsdRaw,\n 0n\n );\n // Net yield is the full active-carry surplus above active debt.\n const netYieldUsdRaw = collectableNetYieldUsd(totalCarryTvlUsdRaw, totalDebtUsdRaw);\n const apyReferencePriceRaw = toBigInt(token.data.feeDrip.apyReferencePrice);\n const feeDripMetrics = calculateFeeDripMetrics({\n currentPriceRaw: toBigInt(token.data.accounting.price),\n apyReferencePriceRaw,\n apyReferenceTs: toBigInt(token.data.feeDrip.apyReferenceTs),\n currentPriceTs: toBigInt(token.data.accounting.lastRefreshedTs),\n totalSupplyRaw: toBigInt(token.data.accounting.totalSupply),\n tokenDecimals: token.decimals,\n undrippedFeeCollateralRaw: toBigInt(token.data.feeDrip.undrippedFeeCollateral),\n feeDripMaxApyBps: token.data.fees.feeDripMaxApyBps,\n nowTs: BigInt(args.nowTs ?? Math.floor(Date.now() / 1000)),\n });\n\n return {\n address: token.address,\n id: token.id,\n curator: fromWeb3Pk(token.data.roles.curator),\n mint: token.mint,\n decimals: token.decimals,\n isActive: token.isActive,\n price: token.price,\n totalSupply: token.totalSupply,\n tvlUsdRaw: toBigInt(token.data.accounting.tvlUsd),\n tvlUsd: toUiAmount(token.data.accounting.tvlUsd, TVL_USD_DECIMAL_PLACES),\n lastRefreshedTs: toBigInt(token.data.accounting.lastRefreshedTs),\n firstMintTs: toBigInt(token.data.accounting.firstMintTs),\n collateral: {\n mint: token.collateralMint,\n symbol: collateralSymbol,\n decimals: token.data.collateral.decimals,\n unlentAmountRaw: toBigInt(token.data.collateral.unlentAmount),\n unlentAmountUi: toUiAmount(\n token.data.collateral.unlentAmount,\n token.data.collateral.decimals\n ),\n pendingUnwindResidualRaw: toBigInt(token.data.accounting.pendingUnwindResidual),\n pendingUnwindResidualUi: toUiAmount(\n token.data.accounting.pendingUnwindResidual,\n token.data.collateral.decimals\n ),\n oraclePriceRaw: toBigInt(token.data.collateral.price),\n oraclePriceOnChainUi: toUiAmount(token.data.collateral.price, token.data.collateral.decimals),\n oraclePriceRealtimeUi: collateralRealtimePriceUi,\n oraclePriceEmaUi: collateralEmaPriceUi,\n oracle: fromWeb3Pk(token.data.collateral.oracle),\n secondaryOracle: token.data.collateral.secondaryOracle.equals(PublicKey.default)\n ? undefined\n : fromWeb3Pk(token.data.collateral.secondaryOracle),\n lastRefreshedTs: toBigInt(token.data.collateral.lastRefreshedTs),\n },\n lendingPositions,\n carryPositions,\n carrySummary: {\n totalCarryTvlUsdRaw,\n totalCarryTvlUsd: toUiAmount(totalCarryTvlUsdRaw, TVL_USD_DECIMAL_PLACES),\n totalDebtUsdRaw,\n totalDebtUsd: toUiAmount(totalDebtUsdRaw, TVL_USD_DECIMAL_PLACES),\n netYieldUsdRaw,\n netYieldUsd: toUiAmount(netYieldUsdRaw, TVL_USD_DECIMAL_PLACES),\n },\n hasInterestToCollect: token.hasInterestToCollect(),\n fees: {\n mintingFeeBps: token.data.fees.mintingFeeBps,\n burningFeeBps: token.data.fees.burningFeeBps,\n performanceFeeBps: token.data.fees.performanceFeeBps,\n protocolMintBurnPctBps: token.data.fees.protocolMintBurnPctBps,\n curatorMintBurnPctBps: token.data.fees.curatorMintBurnPctBps,\n holderMintBurnPctBps:\n 10_000 - token.data.fees.protocolMintBurnPctBps - token.data.fees.curatorMintBurnPctBps,\n curatorPerfPctBps: token.data.fees.curatorPerfPctBps,\n feeDripMaxApyBps: token.data.fees.feeDripMaxApyBps,\n undrippedFeeCollateralRaw: toBigInt(token.data.feeDrip.undrippedFeeCollateral),\n undrippedFeeCollateralUi: toUiAmount(\n token.data.feeDrip.undrippedFeeCollateral,\n token.data.collateral.decimals\n ),\n apyReferencePriceRaw,\n apyReferencePrice: toUiAmount(apyReferencePriceRaw, token.decimals),\n apyReferenceTs: toBigInt(token.data.feeDrip.apyReferenceTs),\n currentApyBps: feeDripMetrics.currentApyBps,\n absorptionEtaSeconds: feeDripMetrics.absorptionEtaSeconds,\n absorptionStatus: feeDripMetrics.absorptionStatus,\n pendingProtocolFeesRaw: toBigInt(token.data.accounting.pendingProtocolFees),\n pendingProtocolFeesUi: toUiAmount(token.data.accounting.pendingProtocolFees, token.decimals),\n pendingCuratorFeesRaw: toBigInt(token.data.accounting.pendingCuratorFees),\n pendingCuratorFeesUi: toUiAmount(token.data.accounting.pendingCuratorFees, token.decimals),\n },\n };\n}\n\nasync function buildLendingPositionInspectSnapshot(\n position: TokenLendingPositionData,\n index: number,\n collateralSymbol: string,\n collateralDecimals: number,\n kaminoData: LendingPlatformData,\n mintRegistry: MintRegistry\n): Promise<EnrichedTokenLendingPosition | undefined> {\n const platform = lendingPlatformToEnum(position.platform);\n if (platform === LendingPlatform.None) {\n return undefined;\n }\n\n let inspectMetrics;\n if (platform === LendingPlatform.Kamino) {\n try {\n const manager = await LycLendingPositionManager.create(kaminoData, position);\n inspectMetrics = (await manager.getInspectMetrics()) ?? undefined;\n } catch {\n inspectMetrics = undefined;\n }\n }\n\n const debtMint = fromWeb3Pk(position.accounting.debt.mint);\n return {\n index,\n platform,\n withdrawPending: podBoolToNumber(position.withdrawPending) !== 0,\n pool: fromWeb3Pk(position.pool),\n userAccount: fromWeb3Pk(position.protocolUserAcc),\n collateralAmountRaw: toBigInt(position.accounting.collateral),\n collateralAmountUi: toUiAmount(position.accounting.collateral, collateralDecimals),\n collateralDecimals,\n collateralSymbol,\n debtAmountRaw: toBigInt(position.accounting.debt.amount),\n debtAmountUi: toUiAmount(position.accounting.debt.amount, position.accounting.debt.decimals),\n debtTvlUsdRaw: toBigInt(position.accounting.debt.tvlUsd),\n debtTvlUsd: toUiAmount(position.accounting.debt.tvlUsd, TVL_USD_DECIMAL_PLACES),\n debtMint,\n debtSymbol: mintSymbol(debtMint, mintRegistry),\n debtDecimals: position.accounting.debt.decimals,\n debtPriceRaw: toBigInt(position.accounting.debt.price),\n debtPriceUi: toUiAmount(position.accounting.debt.price, position.accounting.debt.decimals),\n onChainUtilizationRateBps: position.accounting.ltvUtilizationRateBps,\n targetUtilizationRateBps: position.config.targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps: position.config.maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps: position.config.maxDeviationBelowTargetUtilBps,\n lastRebalancedTs: toBigInt(position.lastUpdatedTs),\n inspectMetrics,\n };\n}\n","const BASIS_POINTS = 10_000;\nconst SECONDS_PER_YEAR = 365 * 24 * 60 * 60;\n\nexport type FeeDripAbsorptionStatus = \"estimated\" | \"no_fees\" | \"parked\" | \"unavailable\";\n\nexport interface FeeDripMetricsInput {\n currentPriceRaw: bigint;\n apyReferencePriceRaw: bigint;\n apyReferenceTs: bigint;\n /** Timestamp at which `currentPriceRaw` was last written on-chain. */\n currentPriceTs: bigint;\n totalSupplyRaw: bigint;\n tokenDecimals: number;\n undrippedFeeCollateralRaw: bigint;\n feeDripMaxApyBps: number;\n nowTs: bigint;\n}\n\nexport interface FeeDripMetrics {\n /** Simple annualized price return from the on-chain APY reference, in basis points. */\n currentApyBps: number | null;\n /** Estimated seconds until the current fee buffer is fully released. */\n absorptionEtaSeconds: number | null;\n absorptionStatus: FeeDripAbsorptionStatus;\n}\n\n/**\n * Derives the current fee-window APY and a simple absorption ETA.\n *\n * ETA assumes fees release at the configured target APY:\n * remaining_price_return = buffer * 10^decimals / (supply * price)\n * eta_seconds = remaining_price_return / (target_apy_bps / 10_000) * seconds_per_year\n *\n * A zero target parks the buffer. Current-window APY is reported separately and\n * does not change the ETA.\n */\nexport function calculateFeeDripMetrics(input: FeeDripMetricsInput): FeeDripMetrics {\n const currentApyBps = calculateCurrentApyBps(input);\n\n if (input.undrippedFeeCollateralRaw <= BigInt(0)) {\n return {\n currentApyBps,\n absorptionEtaSeconds: 0,\n absorptionStatus: \"no_fees\",\n };\n }\n\n if (input.feeDripMaxApyBps === 0) {\n return {\n currentApyBps,\n absorptionEtaSeconds: null,\n absorptionStatus: \"parked\",\n };\n }\n\n if (\n input.currentPriceRaw <= BigInt(0) ||\n input.totalSupplyRaw <= BigInt(0) ||\n input.tokenDecimals < 0\n ) {\n return {\n currentApyBps,\n absorptionEtaSeconds: null,\n absorptionStatus: \"unavailable\",\n };\n }\n\n let scale = BigInt(1);\n for (let decimal = 0; decimal < input.tokenDecimals; decimal += 1) {\n scale *= BigInt(10);\n }\n\n // eta = buffer * scale * 10_000 * year / (supply * price * target_apy_bps)\n const numerator =\n input.undrippedFeeCollateralRaw * scale * BigInt(BASIS_POINTS) * BigInt(SECONDS_PER_YEAR);\n const denominator = input.totalSupplyRaw * input.currentPriceRaw * BigInt(input.feeDripMaxApyBps);\n const apyEtaSeconds = Number((numerator + denominator - BigInt(1)) / denominator);\n\n return finiteEstimate(currentApyBps, apyEtaSeconds);\n}\n\nfunction calculateCurrentApyBps(input: FeeDripMetricsInput): number | null {\n if (\n input.currentPriceRaw <= BigInt(0) ||\n input.apyReferencePriceRaw <= BigInt(0) ||\n input.apyReferenceTs <= BigInt(0) ||\n input.currentPriceTs <= input.apyReferenceTs\n ) {\n return null;\n }\n\n const elapsedSeconds = Number(input.currentPriceTs - input.apyReferenceTs);\n const priceReturn = Number(input.currentPriceRaw) / Number(input.apyReferencePriceRaw) - 1;\n const currentApyBps = priceReturn * (SECONDS_PER_YEAR / elapsedSeconds) * BASIS_POINTS;\n\n return Number.isFinite(currentApyBps) ? currentApyBps : null;\n}\n\nfunction finiteEstimate(\n currentApyBps: number | null,\n absorptionEtaSeconds: number\n): FeeDripMetrics {\n if (!Number.isFinite(absorptionEtaSeconds) || absorptionEtaSeconds < 0) {\n return {\n currentApyBps,\n absorptionEtaSeconds: null,\n absorptionStatus: \"unavailable\",\n };\n }\n\n return {\n currentApyBps,\n absorptionEtaSeconds: Math.ceil(absorptionEtaSeconds),\n absorptionStatus: \"estimated\",\n };\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { type Environment, toBigInt } from \"common\";\n\nexport type TimelockKind = \"touch\" | \"cleanup\";\n\nexport interface TimelockStatus {\n enabled: boolean;\n isTimelocked: boolean;\n timeCreated: bigint;\n unlockAt?: bigint;\n remainingSecs: bigint;\n}\n\nexport interface TimelockOptions {\n enableLocalTimelocks?: boolean;\n}\n\nconst TIMELOCK_COOLDOWN_SECS: Record<TimelockKind, bigint> = {\n touch: 12n * 60n * 60n,\n cleanup: 24n * 60n * 60n,\n};\n\nexport function timelocksEnabled(environment: Environment, options: TimelockOptions = {}): boolean {\n return (\n environment === \"prod\" || (environment === \"local\" && options.enableLocalTimelocks === true)\n );\n}\n\nexport function getTimelockStatus(\n environment: Environment,\n timeCreated: bigint | number | BN,\n kind: TimelockKind,\n options: TimelockOptions = {}\n): TimelockStatus {\n const createdAt = toBigInt(timeCreated);\n const enabled = timelocksEnabled(environment, options);\n\n if (!enabled || createdAt === 0n) {\n return {\n enabled,\n isTimelocked: false,\n timeCreated: createdAt,\n remainingSecs: 0n,\n };\n }\n\n const unlockAt = createdAt + TIMELOCK_COOLDOWN_SECS[kind];\n const now = BigInt(Math.floor(Date.now() / 1000));\n const remainingSecs = unlockAt > now ? unlockAt - now : 0n;\n\n return {\n enabled,\n isTimelocked: remainingSecs > 0n,\n timeCreated: createdAt,\n unlockAt,\n remainingSecs,\n };\n}\n\nexport type AllocationTimelockKind = TimelockKind;\nexport type AllocationTimelockStatus = TimelockStatus;\nexport const allocationTimelocksEnabled = timelocksEnabled;\nexport const getAllocationTimelockStatus = getTimelockStatus;\n","/**\n * Pure helpers over decoded long_yield_carry account data (`Token`, `YieldingBank`, etc.):\n * selection logic, liquidity / holding analysis, and other algorithms that do not belong on\n * `AccountClient` or transaction composers.\n */\n\nimport type { Address } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport {\n fromWeb3Pk,\n LendingPlatform,\n lendingPlatformToEnum,\n maxByNumber,\n toUiAmount,\n} from \"common\";\nimport type { AccountClient } from \"../client/account\";\nimport type { LYCToken, TokenLendingPositionData } from \"../models/lycToken\";\nimport type { BurnAmounts } from \"../client/types/general\";\nimport { LYCYieldingBank } from \"../models/yieldingBank\";\nimport type { LendingPlatformClientBase, LendingPlatformData } from \"lending-platforms\";\nimport { LycLendingPositionManager } from \"../services/carry\";\n\n/** Any object that can resolve a lending-platform client for a given position. */\nexport interface LendingPlatformResolver {\n getForPosition(\n position: TokenLendingPositionData\n ): LendingPlatformClientBase<LendingPlatformData>;\n}\n\ntype BurnUnwindCandidate = {\n lendingPositionIndex: number;\n position: TokenLendingPositionData;\n collateralAmount: bigint;\n};\n\nexport function getBurnCollateralWithdrawalAmount(tokenData: LYCToken, burnAmount: BN | number) {\n const { collateralToUser } = tokenData.computeBurnAmounts(burnAmount);\n const unlentAmount = BigInt(tokenData.data.collateral.unlentAmount.toString());\n const reserved = BigInt(tokenData.data.accounting.pendingAsyncRedemptionLiability.toString());\n const available = unlentAmount > reserved ? unlentAmount - reserved : BigInt(0);\n return collateralToUser > available ? collateralToUser - available : BigInt(0);\n}\n\nexport function getBurnCollateralWithdrawalUiAmount(\n tokenData: LYCToken,\n burnAmount: BN | number,\n includeOneUnitTolerance = false\n) {\n const withdrawalAmount = getBurnCollateralWithdrawalAmount(tokenData, burnAmount);\n const adjustedWithdrawalAmount =\n includeOneUnitTolerance && withdrawalAmount > BigInt(0)\n ? withdrawalAmount + BigInt(1)\n : withdrawalAmount;\n return toUiAmount(adjustedWithdrawalAmount, tokenData.data.collateral.decimals);\n}\n\nexport async function computeBurnAmountsForFrontendEstimate(\n _account: AccountClient,\n tokenData: LYCToken,\n burnAmount: BN | number,\n _resolver: LendingPlatformResolver\n): Promise<BurnAmounts> {\n // TODO: For frontend redemption estimates, account for expected\n // default-redemption swap slippage/fee.\n return tokenData.computeBurnAmounts(burnAmount);\n}\n\nasync function collectBurnUnwindCandidates(\n tokenData: LYCToken,\n collateralWithdrawalUiAmount: number,\n resolver: LendingPlatformResolver\n): Promise<BurnUnwindCandidate[]> {\n const candidates: BurnUnwindCandidate[] = [];\n\n for (let i = 0; i < tokenData.data.lendingPositions.length; i++) {\n const position = tokenData.data.lendingPositions[i];\n if (lendingPlatformToEnum(position.platform) === LendingPlatform.None) {\n continue;\n }\n\n const lpClient = resolver.getForPosition(position);\n const manager = await LycLendingPositionManager.create(lpClient.data, position);\n const eligibility = await manager.getBurnUnwindEligibility(collateralWithdrawalUiAmount);\n if (!eligibility) {\n continue;\n }\n\n candidates.push({\n lendingPositionIndex: i,\n position,\n collateralAmount: BigInt(position.accounting.collateral.toString()),\n });\n }\n\n return candidates;\n}\n\n/**\n * True when at least one active lending position can supply the collateral implied by `burnAmount`\n * for a liquidity-managed burn (same eligibility filter as {@link findPositionToUnwindForBurn}).\n */\nexport async function hasLendingPositionCoveringBurn(\n tokenData: LYCToken,\n burnAmount: BN | number,\n resolver: LendingPlatformResolver\n): Promise<boolean> {\n const collateralWithdrawalUiAmount = getBurnCollateralWithdrawalUiAmount(\n tokenData,\n burnAmount,\n true\n );\n const candidates = await collectBurnUnwindCandidates(\n tokenData,\n collateralWithdrawalUiAmount,\n resolver\n );\n return candidates.length > 0;\n}\n\n/**\n * True when the best burn-candidate lending position can absorb a collateral\n * withdrawal for `burnAmount` without pushing the LTV utilization rate above\n * the position's upper deviation band — meaning no `decrease_carry_position`\n * (debt repayment) is required.\n *\n * Should only be called after {@link hasLendingPositionCoveringBurn} returns\n * `true`; uses the same candidate selection logic as\n * {@link findPositionToUnwindForBurn}.\n */\nexport async function isWithdrawOnlyBurnFeasible(\n tokenData: LYCToken,\n burnAmount: BN | number,\n resolver: LendingPlatformResolver\n): Promise<boolean> {\n const collateralWithdrawalUiAmount = getBurnCollateralWithdrawalUiAmount(\n tokenData,\n burnAmount,\n true\n );\n\n let position: TokenLendingPositionData;\n try {\n ({ position } = await findPositionToUnwindForBurn(\n tokenData,\n collateralWithdrawalUiAmount,\n resolver\n ));\n } catch {\n return false;\n }\n\n const lpClient = resolver.getForPosition(position);\n const manager = await LycLendingPositionManager.create(lpClient.data, position);\n const postWithdrawalUtilBps = await manager.calcPostWithdrawalUtilizationRateBps(\n collateralWithdrawalUiAmount\n );\n\n const upperBound =\n position.config.targetUtilizationRateBps + position.config.maxDeviationAboveTargetUtilBps;\n return postWithdrawalUtilBps <= upperBound;\n}\n\n/**\n * Chooses which `lendingPositions` slot to unwind for a burn liquidity-managed tx.\n *\n * Considers only active positions with a supported platform and collateral mint\n * matching the token. Filters to positions that can cover `collateralWithdrawalUiAmount`\n * (same strict less-than full-supply rule as pre-withdraw repay sizing). Among those,\n * picks the position with the most deposited collateral (tie → lower index) so the\n * burn unwind comes out of the deepest slot and small positions are left intact.\n *\n * @param getLendingPlatformClient - Resolves the Kamino (etc.) client for a position;\n * kept injectable so callers are not tied to transaction wiring.\n */\nexport async function findPositionToUnwindForBurn(\n tokenData: LYCToken,\n collateralWithdrawalUiAmount: number,\n resolver: LendingPlatformResolver\n): Promise<{ lendingPositionIndex: number; position: TokenLendingPositionData }> {\n const candidates = await collectBurnUnwindCandidates(\n tokenData,\n collateralWithdrawalUiAmount,\n resolver\n );\n\n if (!candidates.length) {\n // Fallback: the withdrawal would fully drain the position (supply <=\n // withdrawal amount), so the eligibility filter excluded it. Pick the\n // largest active position instead — the SDK will pass the \"all\" sentinel.\n const fallback = findLargestActiveLendingPosition(tokenData);\n if (fallback) {\n return fallback;\n }\n throw new Error(\n \"No lending position can cover this burn collateral withdrawal with the token collateral mint (or platform is unsupported)\"\n );\n }\n\n candidates.sort((a, b) => {\n if (a.collateralAmount === b.collateralAmount) {\n return a.lendingPositionIndex - b.lendingPositionIndex;\n }\n return b.collateralAmount > a.collateralAmount ? 1 : -1;\n });\n\n const best = candidates[0]!;\n return { lendingPositionIndex: best.lendingPositionIndex, position: best.position };\n}\n\n/**\n * Finds the largest active (non-None platform) lending position by collateral\n * amount. Used as a fallback when the standard eligibility filter excludes all\n * positions (e.g. when the withdrawal fully drains the position).\n */\nfunction findLargestActiveLendingPosition(\n tokenData: LYCToken\n): { lendingPositionIndex: number; position: TokenLendingPositionData } | null {\n let best: { lendingPositionIndex: number; position: TokenLendingPositionData } | null = null;\n let bestCollateral = BigInt(0);\n\n for (let i = 0; i < tokenData.data.lendingPositions.length; i++) {\n const position = tokenData.data.lendingPositions[i];\n if (lendingPlatformToEnum(position.platform) === LendingPlatform.None) {\n continue;\n }\n const collateral = BigInt(position.accounting.collateral.toString());\n if (collateral > bestCollateral) {\n bestCollateral = collateral;\n best = { lendingPositionIndex: i, position };\n }\n }\n\n return best;\n}\n\n/**\n * Picks the yielding bank to fund repay/swap during a burn liquidity-managed tx.\n *\n * Enumerates banks derived from active `debtCarry` entries on the token, fetches\n * each account via `account.fetchYieldingBanks`, then:\n * 1. Prefer a bank whose **debt mint** holding is at least `requiredDebtUiAmount` (debt token UI)\n * and is largest among those sufficient balances (headroom for the unwind repay).\n * 2. Otherwise prefer the bank whose **default redemption mint** holding has the largest\n * balance in UI units (`toUiAmount` with the holding's on-chain `decimals`).\n *\n * Permissionless burn planning does not pass `sourceMint`; the default-redemption fallback\n * assumes that path is viable for the chosen bank's holdings.\n */\nexport async function findBestYieldingBankForBurn(\n account: AccountClient,\n tokenData: LYCToken,\n position: TokenLendingPositionData,\n requiredDebtUiAmount: number\n): Promise<{ yieldingBank: Address }> {\n const bankAddresses: Address[] = [];\n const seen = new Set<string>();\n\n for (let i = 0; i < tokenData.data.debtCarry.length; i++) {\n const carry = tokenData.data.debtCarry[i];\n if (carry.yieldingBaseMint.equals(PublicKey.default)) {\n continue;\n }\n const bankPda = await tokenData.deriveYieldingBankAddressForDebtCarryIndex(i, account.pda);\n const key = String(bankPda);\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n bankAddresses.push(bankPda);\n }\n\n if (bankAddresses.length === 0) {\n throw new Error(\n \"Token has no active yielding carry positions; cannot select a yielding bank for burn liquidity management\"\n );\n }\n\n const banks = await account.fetchYieldingBanks(bankAddresses);\n const debtMint = fromWeb3Pk(position.accounting.debt.mint);\n\n type SufficientDebt = { bank: LYCYieldingBank; debtHeldUi: number };\n const sufficientDebt: SufficientDebt[] = [];\n for (const bank of banks) {\n const holding = bank.findAssetHolding(debtMint);\n if (!holding) {\n continue;\n }\n const debtHeldUi = toUiAmount(holding.amount, holding.decimals);\n if (debtHeldUi >= requiredDebtUiAmount) {\n sufficientDebt.push({ bank, debtHeldUi });\n }\n }\n\n if (sufficientDebt.length > 0) {\n const best = maxByNumber(sufficientDebt, (x) => x.debtHeldUi);\n return { yieldingBank: best.bank.address };\n }\n\n type DefaultMintUi = { bank: LYCYieldingBank; defaultMintUiAmount: number };\n const defaultMintUi: DefaultMintUi[] = [];\n for (const bank of banks) {\n const holding = bank.findAssetHolding(bank.defaultRedemptionMint);\n if (!holding) {\n continue;\n }\n defaultMintUi.push({\n bank,\n defaultMintUiAmount: toUiAmount(holding.amount, holding.decimals),\n });\n }\n\n if (defaultMintUi.length > 0) {\n const best = maxByNumber(defaultMintUi, (x) => x.defaultMintUiAmount);\n return { yieldingBank: best.bank.address };\n }\n\n throw new Error(\n \"No yielding bank linked to this token has sufficient debt liquidity for unwind or an active default redemption holding\"\n );\n}\n","import {\n enumToExternalLiquidityType,\n enumToOracleType,\n ExternalLiquidityType,\n mints,\n OracleType,\n} from \"common\";\nimport { YieldingBankAllocationConfig } from \"../../client\";\nimport { oracle } from \"oracle\";\n\nconst USD_STAR = mints.get(\"USD*\")!;\nconst USD_STAR_JUNIOR = mints.get(\"USD*-J\")!;\n\nexport const usdStarAllocationConfig: YieldingBankAllocationConfig = {\n assetHolding: {\n mint: USD_STAR.address,\n oracle: oracle.getOracleData(\"USD*\").oracle,\n oracleType: enumToOracleType(OracleType.PerenaBank),\n externalLiquidityType: enumToExternalLiquidityType(ExternalLiquidityType.None),\n },\n};\n\nexport const usdStarJuniorAllocationConfig: YieldingBankAllocationConfig = {\n assetHolding: {\n mint: USD_STAR_JUNIOR.address,\n oracle: oracle.getOracleData(\"USD*-J\").oracle,\n oracleType: enumToOracleType(OracleType.PerenaTranche),\n externalLiquidityType: enumToExternalLiquidityType(ExternalLiquidityType.PerenaWithdrawalQueue),\n },\n};\n","import { type Address } from \"@solana/kit\";\nimport { accountExists } from \"common\";\nimport type { LongYieldCarryClient } from \"../client/client\";\n\n/**\n * First token ID (0–255) not yet used for the given yToken mint address.\n *\n * Tries `fetchAllTokens` first, then scans PDAs if RPC program accounts are unavailable.\n */\nexport async function findFreeTokenId(\n client: LongYieldCarryClient,\n mint: Address\n): Promise<number> {\n try {\n client.account.dataCache.clearAllCache();\n const tokens = await client.account.fetchAllTokens();\n\n if (tokens.length > 0) {\n const usedIds = new Set(tokens.filter((t) => t.mint === mint).map((t) => t.id));\n\n for (let id = 0; id <= 255; id++) {\n if (!usedIds.has(id)) return id;\n }\n throw new Error(`No free token ID found for mint ${mint}`);\n }\n } catch {\n // getProgramAccounts may not be supported / reliable on some RPCs\n }\n\n for (let id = 0; id <= 255; id++) {\n const [pda] = await client.pda.deriveTokenPda(mint, id);\n if (!(await accountExists(client.rpc, pda))) return id;\n }\n throw new Error(`No free token ID found for mint ${mint}`);\n}\n\n/**\n * First yielding-bank ID (0–255) not yet used for the given base mint.\n */\nexport async function findFreeYieldingBankId(\n client: LongYieldCarryClient,\n baseMint: Address\n): Promise<number> {\n try {\n client.account.dataCache.clearAllCache();\n const banks = await client.account.fetchAllYieldingBanks();\n\n if (banks.length > 0) {\n const usedIds = new Set(banks.filter((b) => b.baseMint === baseMint).map((b) => b.id));\n\n for (let id = 0; id <= 255; id++) {\n if (!usedIds.has(id)) return id;\n }\n throw new Error(`No free yielding bank ID found for mint ${baseMint}`);\n }\n } catch {\n // getProgramAccounts may not be supported / reliable on some RPCs\n }\n\n for (let id = 0; id <= 255; id++) {\n const [pda] = await client.pda.deriveYieldingBankPda(baseMint, id);\n if (!(await accountExists(client.rpc, pda))) return id;\n }\n throw new Error(`No free yielding bank ID found for mint ${baseMint}`);\n}\n","import {\n type Address,\n type KeyPairSigner,\n type Signature,\n generateKeyPairSigner,\n} from \"@solana/kit\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { accountExists, createMint, sleep } from \"common\";\nimport type { LongYieldCarryClient } from \"../client/client\";\nimport type { LongYieldCarryTransactionPlan } from \"../client/types\";\nimport { findFreeTokenId } from \"./data\";\n\n/**\n * Compose ordered phases into one bundle-ready plan without making an entire\n * phase indivisible. Existing atomic segments are preserved, and each phase\n * after the first is forced to start in a new transaction.\n */\nexport function composePhasedTransactionPlan(\n phases: LongYieldCarryTransactionPlan[]\n): LongYieldCarryTransactionPlan {\n if (phases.length === 0) {\n throw new Error(\"Cannot compose an empty transaction phase list.\");\n }\n if (phases.length === 1) {\n return phases[0];\n }\n\n const segmentLengths: number[] = [];\n const freshBinSegments = new Set<number>();\n let segmentOffset = 0;\n\n for (const [phaseIndex, phase] of phases.entries()) {\n const phaseSegmentLengths =\n phase.segmentLengths?.length === 0 || phase.segmentLengths === undefined\n ? phase.instructions.map(() => 1)\n : phase.segmentLengths;\n\n if (phaseIndex > 0) {\n freshBinSegments.add(segmentOffset);\n }\n for (const segmentIndex of phase.freshBinSegments ?? []) {\n freshBinSegments.add(segmentOffset + segmentIndex);\n }\n\n segmentLengths.push(...phaseSegmentLengths);\n segmentOffset += phaseSegmentLengths.length;\n }\n\n return {\n instructions: phases.flatMap((phase) => phase.instructions),\n lookupTables: [...new Set(phases.flatMap((phase) => phase.lookupTables ?? []))],\n segmentLengths,\n freshBinSegments: [...freshBinSegments].sort((a, b) => a - b),\n postSuccessCacheInvalidations: phases.flatMap(\n (phase) => phase.postSuccessCacheInvalidations ?? []\n ),\n };\n}\n\nexport async function setTokenCircuitBreaker(\n client: LongYieldCarryClient,\n signer: KeyPairSigner,\n token: Address,\n active: boolean\n): Promise<Signature> {\n const plan = await client.tx.setTokenCircuitBreaker.getTx({\n authority: signer.address,\n token,\n active,\n });\n return client.sendTransaction(signer, plan);\n}\n\nexport async function setYieldingBankCircuitBreaker(\n client: LongYieldCarryClient,\n signer: KeyPairSigner,\n yieldingBank: Address,\n active: boolean\n): Promise<Signature> {\n const plan = await client.tx.setYieldingBankCircuitBreaker.getTx({\n authority: signer.address,\n yieldingBank,\n active,\n });\n return client.sendTransaction(signer, plan);\n}\n\n/**\n * Creates a new yToken SPL mint with mint authority = token PDA, using the next free token ID.\n */\nexport async function createYTokenMint(\n client: LongYieldCarryClient,\n payer: KeyPairSigner,\n decimals: number = 6,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS\n): Promise<{\n mintSigner: KeyPairSigner;\n tokenPda: Address;\n tokenPdaBump: number;\n id: number;\n}> {\n const mintSigner = await generateKeyPairSigner();\n const id = await findFreeTokenId(client, mintSigner.address);\n const [tokenPda, tokenPdaBump] = await client.pda.deriveTokenPda(mintSigner.address, id);\n\n await createMint(client.rpc, payer, mintSigner, tokenPda, decimals, tokenProgram);\n\n // Multi-RPC failover can confirm the mint on one provider while a later\n // create_token simulation hits another that has not indexed it yet.\n const mintVisibleDeadline = Date.now() + 30_000;\n while (!(await accountExists(client.rpc, mintSigner.address))) {\n if (Date.now() >= mintVisibleDeadline) {\n throw new Error(\n `Mint ${mintSigner.address} was created but is not yet visible on the configured RPC endpoints.`\n );\n }\n await sleep(500);\n }\n\n return { mintSigner, tokenPda, tokenPdaBump, id };\n}\n","import { type Address } from \"@solana/kit\";\nimport {\n enumToLendingPlatform,\n enumToOracleType,\n enumToTokenProgram,\n LendingPlatform,\n lendingPlatformToEnum,\n TokenProgram,\n fromWeb3Pk,\n mints,\n} from \"common\";\nimport {\n getEligiblePools,\n type LendingPlatformClientBase,\n type LendingPlatformData,\n} from \"lending-platforms\";\nimport { oracle } from \"oracle\";\nimport type { LYCToken } from \"../models/lycToken\";\nimport type {\n CreateTokenLendingPositionAccounts,\n CreateTokenLendingPositionParams,\n} from \"../client/types\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface BuildLendingPositionAllocationArgs {\n /** Lending platform client used to resolve reserves and user accounts. */\n lendingClient: LendingPlatformClientBase<LendingPlatformData>;\n /** Token PDA that will own the lending position. */\n tokenPda: Address;\n /** Collateral mint address. Used to resolve the collateral reserve in the pool. */\n collateralMint: Address;\n /** Debt mint address. Decimals and token program are resolved from the mint registry. */\n debtMint: Address;\n /** Debt reserve address. If omitted, looked up from the pool by `debtMint`. */\n debtReserve?: Address;\n /** Obligation / user-account ID within the lending pool. */\n userAccountId: number;\n /**\n * Lending pool address. When omitted, resolved automatically from the\n * collateral mint via {@link getEligiblePools}. Throws if the mint is\n * listed in zero or multiple pools (caller must disambiguate).\n */\n pool?: Address;\n /** @default LendingPlatform.Kamino */\n lendingPlatform?: LendingPlatform;\n /** @default 9000 */\n targetUtilizationRateBps?: number;\n /** @default 150 */\n maxDeviationAboveTargetUtilBps?: number;\n /** @default 300 */\n maxDeviationBelowTargetUtilBps?: number;\n}\n\nexport interface LendingPositionAllocation {\n params: CreateTokenLendingPositionParams;\n accounts: CreateTokenLendingPositionAccounts;\n pool: Address;\n collateralReserve: Address;\n debtReserve: Address;\n protocolUserAccount: Address;\n userAccountId: number;\n}\n\nconst DEFAULT_TARGET_UTILIZATION_RATE_BPS = 9000;\n\nexport interface GetAvailableTokenLendingUserAccountIdArgs {\n lendingClient: LendingPlatformClientBase<LendingPlatformData>;\n token: LYCToken;\n pool: Address;\n lendingPlatform?: LendingPlatform;\n}\n\n// =============================================================================\n// Pool resolution\n// =============================================================================\n\n/**\n * Resolves the lending pool for a collateral mint when the caller didn't\n * supply one explicitly. Uses the static `KAMINO_ACCOUNTS` registry to\n * find which pool(s) list the mint.\n *\n * - Exactly one pool → returns it.\n * - Zero pools → throws (mint not listed anywhere).\n * - Multiple pools → throws (caller must pass `pool` to disambiguate).\n */\nexport function resolveDefaultPool(collateralMint: Address): Address {\n const mintInfo = mints.get(collateralMint);\n const symbol = mintInfo?.symbol ?? String(collateralMint);\n\n const eligible = getEligiblePools(symbol);\n\n if (eligible.length === 0) {\n throw new Error(\n `resolveDefaultPool: collateral mint ${symbol} (${collateralMint}) is not listed in any known lending pool`\n );\n }\n\n if (eligible.length > 1) {\n throw new Error(\n `resolveDefaultPool: collateral mint ${symbol} is listed in multiple pools — ` +\n `pass \\`pool\\` explicitly. Eligible pools:\\n` +\n eligible.map((m) => ` ${m}`).join(\"\\n\")\n );\n }\n\n return eligible[0];\n}\n\nexport async function getAvailableTokenLendingUserAccountId({\n lendingClient,\n token,\n pool,\n lendingPlatform = LendingPlatform.Kamino,\n}: GetAvailableTokenLendingUserAccountIdArgs): Promise<number> {\n const activeProtocolUserAccounts = token.activeLendingPositions\n .filter(({ data }) => lendingPlatformToEnum(data.platform) === lendingPlatform)\n .map(({ data }) => fromWeb3Pk(data.protocolUserAcc));\n\n return lendingClient.getAvailableUserAccountId(pool, token.address, activeProtocolUserAccounts);\n}\n\n// =============================================================================\n// Builder\n// =============================================================================\n\n/**\n * Resolves reserves, oracle data, and user-account PDA, then assembles a\n * `CreateTokenLendingPositionParams` ready for `ix.createTokenLendingPosition`.\n *\n * The collateral reserve is resolved from the collateral mint against the pool.\n * Debt metadata (decimals, token program) is resolved from the mint registry;\n * the debt reserve address is either provided directly or looked up by mint.\n */\nexport async function buildLendingPositionAllocation(\n args: BuildLendingPositionAllocationArgs\n): Promise<LendingPositionAllocation> {\n const {\n lendingClient,\n tokenPda,\n collateralMint,\n debtMint,\n userAccountId,\n lendingPlatform = LendingPlatform.Kamino,\n targetUtilizationRateBps = DEFAULT_TARGET_UTILIZATION_RATE_BPS,\n maxDeviationAboveTargetUtilBps = 150,\n maxDeviationBelowTargetUtilBps = 300,\n } = args;\n\n const debtMintInfo = mints.get(debtMint);\n if (!debtMintInfo) {\n throw new Error(\n `buildLendingPositionAllocation: debt mint ${debtMint} not found in mint registry`\n );\n }\n\n const pool = args.pool ?? resolveDefaultPool(collateralMint);\n\n const collateralReserve = await lendingClient.data.fetchReserveByMint(pool, collateralMint);\n if (!collateralReserve) {\n throw new Error(\n `buildLendingPositionAllocation: no reserve found for collateral mint ${collateralMint} in pool ${pool}`\n );\n }\n const collateralReserveAddress = collateralReserve.address;\n\n let debtReserveAddress: Address;\n if (args.debtReserve) {\n debtReserveAddress = args.debtReserve;\n } else {\n const reserve = await lendingClient.data.fetchReserveByMint(pool, debtMint);\n if (!reserve) {\n throw new Error(\n `buildLendingPositionAllocation: no reserve found for debt mint ${debtMint} in pool ${pool}`\n );\n }\n debtReserveAddress = reserve.address;\n }\n\n const protocolUserAccount = await lendingClient.accounts.getUserAccountAddress(\n pool,\n tokenPda,\n userAccountId\n );\n\n const debtOracleData = oracle.getOracleData(debtMint);\n const debtTokenProgram = enumToTokenProgram(\n debtMintInfo.isToken2022 ? TokenProgram.Token2022 : TokenProgram.Spl\n );\n\n const params: CreateTokenLendingPositionParams = {\n lendingPlatform: enumToLendingPlatform(lendingPlatform),\n pool,\n debtReserve: debtReserveAddress,\n targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps,\n debtMint,\n debtDecimals: debtMintInfo.decimals,\n debtTokenProgram,\n debtOracleType: enumToOracleType(debtOracleData.oracleType),\n };\n\n const accounts: CreateTokenLendingPositionAccounts = {\n protocolUserAcc: protocolUserAccount,\n collateralReserve: collateralReserveAddress,\n debtOracle: debtOracleData.oracle,\n };\n\n return {\n params,\n accounts,\n pool,\n collateralReserve: collateralReserveAddress,\n debtReserve: debtReserveAddress,\n protocolUserAccount,\n userAccountId,\n };\n}\n","import type { Address } from \"@solana/kit\";\nimport { lendingPlatformToEnum, type LendingPlatform } from \"common\";\nimport type { LYCToken } from \"../models/lycToken\";\nimport type { LYCYieldingBank } from \"../models/yieldingBank\";\n\n/**\n * Returns the first active yielding bank (circuit breaker off, lowest id).\n *\n * TODO: This naively returns the first active bank regardless of what the\n * lending position actually borrows. It works today because there is one\n * yielding bank (USDC) and all debt is denominated in USDC. When a second\n * yielding bank exists (e.g. SOL-denominated) or a lending position borrows\n * a non-USDC asset, the carry-manager would route that debt into the wrong\n * bank. At that point this function needs to accept the lending position's\n * debt mint and match it to the correct bank — either via the token's\n * existing `debtCarry` entries or an explicit per-token bank configuration.\n *\n * @returns The yielding bank address, or `null` if no active bank exists.\n */\nexport function resolveYieldingBankForPosition(allBanks: LYCYieldingBank[]): Address | null {\n const candidates = allBanks.filter((b) => b.circuitBreaker === 0).sort((a, b) => a.id - b.id);\n\n return candidates[0]?.address ?? null;\n}\n\n/**\n * Returns the index of the first active lending position for the given\n * platform, or `null` if the token has no positions on that platform.\n */\nexport function firstActiveLendingIndex(token: LYCToken, platform: LendingPlatform): number | null {\n const positions = token.data.lendingPositions;\n for (let i = 0; i < positions.length; i++) {\n if (lendingPlatformToEnum(positions[i].platform) === platform) {\n return i;\n }\n }\n return null;\n}\n","/**\n * Long Yield Carry program client.\n *\n * Composes PDA derivation, account fetching, instruction building, and\n * transaction composition behind a single entry point.\n *\n * The Anchor program ID flows through to all sub-clients — no global state\n * required.\n *\n * Usage:\n * const client = new LongYieldCarryClient(provider, \"local\");\n * const [pda, bump] = client.pda.token(mintAddress);\n * const ix = await client.tx.createToken.getIx({\n * mint,\n * collateralMint,\n * params,\n * });\n * const data = await client.account.token(pda);\n * const tx = await client.tx.collectInterest.getTx({ manager: manager, token: token, params: { yieldingBank } });\n */\n\nimport { Program, AnchorProvider } from \"@anchor-lang/core\";\nimport {\n address,\n type Instruction,\n type Rpc,\n type Signature,\n type SolanaRpcApi,\n type TransactionSigner,\n} from \"@solana/kit\";\nimport {\n LendingPlatform,\n type Environment,\n createRpc,\n getRpcUrl,\n getRpcUrls,\n applyDataCacheTransactionInvalidations,\n fromWeb3Pk,\n mints,\n signSendAndConfirmTransaction,\n type SendTransactionOptionsWithPostSuccess,\n type SwapClient,\n type TransactionPlan,\n createReadOnlyAnchorProvider,\n} from \"common\";\nimport {\n KaminoClient,\n type LendingPlatformClientBase,\n type LendingPlatformData,\n type OutstandingIncentive,\n} from \"lending-platforms\";\nimport { createAggSwapClient } from \"swap-aggregator\";\nimport { LongYieldCarry, IDL } from \"../idl/long_yield_carry\";\nimport { DEFAULT_MIN_INCENTIVE_UI_AMOUNT, PROGRAM_ID } from \"../constants/general\";\nimport { PdaClient } from \"./pda\";\nimport { AccountClient, LYC_TOKEN_CACHE_CATEGORY, YIELDING_BANK_CACHE_CATEGORY } from \"./account\";\nimport type { LongYieldCarryTransactionPlan } from \"./types\";\nimport type { LYCToken, TokenLendingPositionData } from \"../models/lycToken\";\nimport {\n LendingPlatformClientRegistry,\n type SupportedLendingPlatformClients,\n} from \"./lendingPlatformClients\";\nimport { LongYieldCarryExternalLiquidityResolver } from \"./externalLiquidityResolver\";\nimport { TransactionClient } from \"./transaction\";\n\nexport interface LongYieldCarryClientOptions {\n /**\n * Swap client override. Replaces the default `AggSwapClient` for all swaps\n * (including collect_interest). Useful in tests that need a restricted routing\n * client (e.g. Surfpool direct-route-only client).\n */\n swapClient?: SwapClient;\n /**\n * Optional overrides for internally managed lending platform clients.\n * These are primarily useful in tests.\n */\n lendingPlatformClients?: Partial<SupportedLendingPlatformClients>;\n}\n\n/** Claimable incentives keyed by the token's lending position index. */\nexport type OutstandingIncentivesByPosition = Map<number, OutstandingIncentive[]>;\n\nexport class LongYieldCarryClient {\n /**\n * Deployment tier for this client (`local`, `test`, `prod`) — drives program ID,\n * RPC URL, and authority constants passed into transaction builders.\n */\n readonly environment: Environment;\n /** Shared RPC client used by SDK send helpers */\n readonly rpc: Rpc<SolanaRpcApi>;\n /** PDA derivation utilities */\n readonly pda: PdaClient;\n /** On-chain account fetchers */\n readonly account: AccountClient;\n /** Transaction/instruction builders */\n readonly tx: TransactionClient;\n /** Aggregated swap client (Perena for USD* pairs, Jupiter fallback) */\n readonly swap: SwapClient;\n /** Shared registry of protocol-specific lending clients */\n readonly lendingPlatformClients: LendingPlatformClientRegistry;\n\n /**\n * @param provider - Anchor provider (connection + wallet)\n * @param environment - Optional environment override (\"local\", \"test\", \"prod\").\n * Determines which program ID and RPC URL to use. Defaults to the IDL address.\n * @param options - Optional configuration overrides (e.g. custom swap client for tests).\n */\n /**\n * Create a read-only client with a throwaway keypair.\n *\n * Use this for services that only need to read on-chain state (e.g. the\n * price ingestion Lambda) and never sign transactions.\n */\n static readOnly(env: Environment): LongYieldCarryClient {\n return new LongYieldCarryClient(createReadOnlyAnchorProvider(env), env);\n }\n\n constructor(\n provider: AnchorProvider,\n environment?: Environment,\n options?: LongYieldCarryClientOptions\n ) {\n const env = environment ?? \"local\";\n this.environment = env;\n const rpcUrl = getRpcUrl(env);\n const rpcUrls = getRpcUrls(env);\n const idl = environment ? { ...IDL, address: PROGRAM_ID[environment] } : IDL;\n const program: Program<LongYieldCarry> = new Program(idl as LongYieldCarry, provider);\n this.rpc = createRpc(env);\n this.pda = new PdaClient(address(program.programId.toBase58()));\n this.account = new AccountClient(program, this.pda, this.rpc);\n const kaminoClient =\n options?.lendingPlatformClients?.kamino ?? new KaminoClient(rpcUrl, rpcUrls);\n this.lendingPlatformClients = new LendingPlatformClientRegistry({\n kamino: kaminoClient,\n });\n this.swap = options?.swapClient ?? createAggSwapClient(rpcUrl, env);\n const externalLiquidityResolver = new LongYieldCarryExternalLiquidityResolver(rpcUrl);\n this.tx = new TransactionClient({\n rpc: this.rpc,\n program,\n account: this.account,\n pda: this.pda,\n swap: this.swap,\n externalLiquidityResolver,\n environment: environment ?? \"local\",\n lendingPlatformClients: this.lendingPlatformClients,\n });\n }\n\n /**\n * Sign, send, and confirm a transaction, then apply any post-success cache\n * invalidations embedded in the transaction plan.\n */\n async sendTransaction(\n payer: TransactionSigner,\n instructionsOrPlan: Instruction[] | TransactionPlan,\n options?: SendTransactionOptionsWithPostSuccess\n ): Promise<Signature> {\n const plan = Array.isArray(instructionsOrPlan)\n ? undefined\n : (instructionsOrPlan as LongYieldCarryTransactionPlan);\n\n return signSendAndConfirmTransaction(this.rpc, payer, instructionsOrPlan, {\n ...options,\n onSuccess: () => {\n if (plan) this.applyCacheInvalidations(plan);\n options?.onSuccess?.();\n },\n });\n }\n\n /**\n * Returns currently claimable lending incentives keyed by lending position\n * index. Each value contains that position's claimable incentive entries as\n * reported by the underlying lending-platform client.\n *\n * `minUiAmount` filters out dust rewards (UI-denominated, per reward token);\n * defaults to {@link DEFAULT_MIN_INCENTIVE_UI_AMOUNT} so harvesting never pays\n * a transaction fee for an economically negligible balance.\n */\n async getOutstandingIncentives(\n token: LYCToken,\n minUiAmount: number = DEFAULT_MIN_INCENTIVE_UI_AMOUNT,\n log?: (msg: string) => void\n ): Promise<OutstandingIncentivesByPosition> {\n const positionIncentives = await Promise.all(\n token.activeLendingPositions.map(async ({ index, data: position }) => {\n log?.(\n `\\n[getOutstandingIncentives] position #${index} userAcc=${fromWeb3Pk(position.protocolUserAcc).slice(0, 6)}…`\n );\n const incentives = await this.lendingPlatformClients\n .getForPosition(position)\n .getOutstandingIncentives(fromWeb3Pk(position.protocolUserAcc), minUiAmount, log);\n return { index, incentives };\n })\n );\n\n const incentivesByPosition: OutstandingIncentivesByPosition = new Map();\n for (const { index, incentives } of positionIncentives) {\n const known = incentives.filter((i) => mints.get(i.mint) !== undefined);\n const unknown = incentives.filter((i) => mints.get(i.mint) === undefined);\n if (unknown.length > 0) {\n log?.(\n ` position #${index}: ${unknown.length} incentive(s) skipped — mint not in registry: ${unknown.map((i) => i.mint.slice(0, 6) + \"…\").join(\", \")}`\n );\n }\n if (known.length > 0) {\n incentivesByPosition.set(index, known);\n }\n }\n\n return incentivesByPosition;\n }\n\n /**\n * Drops every cached entry across all sub-clients (account data, Kamino\n * lending data, swap quotes). The next read through any sub-client will\n * hit the RPC / API fresh.\n *\n * Use this between sequential phases that mutate on-chain state so that\n * the later phase doesn't operate on stale snapshots.\n */\n clearAllCache(): void {\n this.account.dataCache.clearAllCache();\n for (const lpClient of this.lendingPlatformClients.getAll()) {\n lpClient.data.clearCache();\n }\n }\n\n /**\n * Clears cached data that a confirmed transaction has made stale.\n *\n * Call this after a transaction built from a `LongYieldCarryTransactionPlan`\n * has been confirmed by an external sender (e.g. the backend\n * `TransactionService`). The built-in `sendTransaction` applies these\n * automatically; this method exists for callers that sign/send through a\n * different path.\n */\n applyCacheInvalidations(plan: LongYieldCarryTransactionPlan): void {\n const invalidations = plan.postSuccessCacheInvalidations ?? [];\n for (const lpClient of this.lendingPlatformClients.getAll()) {\n lpClient.applyPostSuccessCacheInvalidations(invalidations);\n }\n applyDataCacheTransactionInvalidations(this.account.dataCache, invalidations, {\n tokenPdaCategory: LYC_TOKEN_CACHE_CATEGORY,\n yieldingBankPdaCategory: YIELDING_BANK_CACHE_CATEGORY,\n });\n }\n\n getLendingPlatformClient(position: TokenLendingPositionData) {\n return this.lendingPlatformClients.getForPosition(position);\n }\n\n getLendingPlatformClientByPlatform(platform: LendingPlatform.Kamino): KaminoClient;\n getLendingPlatformClientByPlatform(\n platform: LendingPlatform\n ): LendingPlatformClientBase<LendingPlatformData>;\n getLendingPlatformClientByPlatform(\n platform: LendingPlatform\n ): LendingPlatformClientBase<LendingPlatformData> {\n return this.lendingPlatformClients.getByPlatform(platform);\n }\n}\n","import { type Address } from \"@solana/kit\";\nimport {\n type CpiData,\n type SwapClient,\n type RoutableSwapClient,\n type SwapQuoteParams,\n type SwapQuoteCoveringMinOutputParams,\n type SwapQuote,\n type SwapInstructionOptions,\n swapClientCanRoute,\n createRpcWithRetry,\n type Environment,\n} from \"common\";\nimport {\n JupiterSwapClient,\n LOCAL_TEST_EXCLUDED_DEXES,\n LOCAL_TEST_MAX_ACCOUNTS,\n type JupiterSwapClientConfig,\n} from \"jupiter-helpers\";\nimport { PerenaClient } from \"perena-helpers\";\n\n/**\n * Internal wrapper around a sub-client's quote so we can route\n * `getSwapCpiData` back to the correct client.\n */\ninterface AggRawQuote {\n routeKey: string;\n innerQuote: SwapQuote<any>;\n}\n\nexport type AggSwapQuote = SwapQuote<AggRawQuote>;\n\n/**\n * Optional routing-policy overrides for the aggregate swap client.\n */\nexport interface AggSwapClientConfig {\n /** Optional default quote policy passed through to the Jupiter fallback client. */\n jupiter?: JupiterSwapClientConfig;\n}\n\nexport function createAggSwapClient(rpcUrl: string, environment: Environment): AggSwapClient {\n return new AggSwapClient(rpcUrl, {\n jupiter:\n environment === \"local\"\n ? {\n quoteDefaults: {\n excludeDexes: LOCAL_TEST_EXCLUDED_DEXES,\n maxAccounts: LOCAL_TEST_MAX_ACCOUNTS,\n },\n }\n : undefined,\n });\n}\n\n/**\n * Aggregating swap client that routes to the best available swap\n * implementation based on {@link swapClientCanRoute} over an ordered list\n * of {@link RoutableSwapClient}s (Perena first, then Jupiter).\n *\n * Routing priority:\n * 1. **Perena** — when the pair is routable per Perena’s mint lists and anchors\n * 2. **Jupiter** — fallback (wildcard routing metadata)\n *\n * @example\n * ```typescript\n * const swapClient = new AggSwapClient(rpcUrl);\n *\n * // USD* <-> USDC goes through Perena\n * const quote = await swapClient.getQuote({\n * inputMint: USD_STAR_MINT,\n * outputMint: USDC_MINT,\n * amount: 10_000_000,\n * });\n *\n * // USD*-J -> USD* goes through Perena\n * const quote2 = await swapClient.getQuote({\n * inputMint: USD_STAR_J_MINT,\n * outputMint: USD_STAR_MINT,\n * amount: 10_000_000,\n * });\n *\n * // SOL -> USDC goes through Jupiter\n * const quote3 = await swapClient.getQuote({\n * inputMint: SOL_MINT,\n * outputMint: USDC_MINT,\n * amount: 1_000_000_000,\n * });\n * ```\n */\nexport class AggSwapClient implements SwapClient<AggRawQuote> {\n private readonly perena: PerenaClient;\n private readonly jupiter: JupiterSwapClient;\n\n /** Priority order: first routable client wins. */\n private readonly routeClients: readonly { key: string; client: RoutableSwapClient }[];\n\n constructor(rpcUrl: string, config: AggSwapClientConfig = {}) {\n this.perena = new PerenaClient(rpcUrl);\n this.jupiter = new JupiterSwapClient(createRpcWithRetry(rpcUrl), config.jupiter);\n this.routeClients = [\n { key: \"perena\", client: this.perena },\n { key: \"jupiter\", client: this.jupiter },\n ];\n }\n\n async getQuote(params: SwapQuoteParams): Promise<AggSwapQuote> {\n const match = this.routeClients.find(({ client }) =>\n swapClientCanRoute(client, params.inputMint, params.outputMint)\n );\n if (!match) {\n throw new Error(\"AggSwapClient: no backend can route this mint pair\");\n }\n const innerQuote = await match.client.getQuote(params);\n return this.wrapQuote(match.key, innerQuote);\n }\n\n async getSwapCpiData(\n quote: AggSwapQuote,\n userPublicKey: Address,\n options?: SwapInstructionOptions\n ): Promise<CpiData> {\n const { routeKey, innerQuote } = quote.rawQuote;\n const entry = this.routeClients.find((r) => r.key === routeKey);\n if (!entry) {\n throw new Error(`AggSwapClient: unknown routeKey ${routeKey}`);\n }\n return entry.client.getSwapCpiData(innerQuote as any, userPublicKey, options);\n }\n\n /**\n * Route {@link SwapClient.getQuoteCoveringMinOutput} to the first backend that can\n * handle the mint pair (Perena before Jupiter).\n */\n async getQuoteCoveringMinOutput(params: SwapQuoteCoveringMinOutputParams): Promise<AggSwapQuote> {\n const match = this.routeClients.find(({ client }) =>\n swapClientCanRoute(client, params.inputMint, params.outputMint)\n );\n if (!match) {\n throw new Error(\"AggSwapClient: no backend can route this mint pair\");\n }\n const innerQuote = await match.client.getQuoteCoveringMinOutput(params);\n return this.wrapQuote(match.key, innerQuote);\n }\n\n private wrapQuote(routeKey: string, innerQuote: SwapQuote<any>): AggSwapQuote {\n return {\n inputMint: innerQuote.inputMint,\n outputMint: innerQuote.outputMint,\n inputAmount: innerQuote.inputAmount,\n outputAmount: innerQuote.outputAmount,\n priceImpactPct: innerQuote.priceImpactPct,\n rawQuote: { routeKey, innerQuote },\n };\n }\n}\n","import { LendingPlatform, lendingPlatformToEnum } from \"common\";\nimport type {\n KaminoClient,\n LendingPlatformClientBase,\n LendingPlatformData,\n} from \"lending-platforms\";\nimport type { TokenLendingPositionData } from \"../models/lycToken\";\n\nexport interface SupportedLendingPlatformClients {\n kamino: KaminoClient;\n}\n\n/**\n * Central registry for protocol-specific lending clients used throughout the\n * long-yield-carry SDK.\n */\nexport class LendingPlatformClientRegistry {\n private readonly kaminoClient: KaminoClient;\n\n constructor(clients: SupportedLendingPlatformClients) {\n this.kaminoClient = clients.kamino;\n }\n\n getAll(): LendingPlatformClientBase<LendingPlatformData>[] {\n return [this.kaminoClient];\n }\n\n getPlatformForPosition(position: TokenLendingPositionData): LendingPlatform {\n return lendingPlatformToEnum(position.platform);\n }\n\n getForPosition(\n position: TokenLendingPositionData\n ): LendingPlatformClientBase<LendingPlatformData> {\n return this.getByPlatform(this.getPlatformForPosition(position));\n }\n\n getByPlatform(platform: LendingPlatform.Kamino): KaminoClient;\n getByPlatform(platform: LendingPlatform): LendingPlatformClientBase<LendingPlatformData>;\n getByPlatform(platform: LendingPlatform): LendingPlatformClientBase<LendingPlatformData> {\n switch (platform) {\n case LendingPlatform.None:\n throw new Error(\"Lending position does not have an active lending platform\");\n case LendingPlatform.Kamino:\n return this.kaminoClient;\n default:\n throw new Error(`Unsupported lending platform client: ${platform}`);\n }\n }\n}\n","import type { Address } from \"@solana/kit\";\nimport {\n dedupeOrderedAddresses,\n mints,\n type CpiData,\n type TransactionCacheInvalidation,\n} from \"common\";\nimport { getPerenaWithdrawalQueueAddressesFromCpiData, PerenaClient } from \"perena-helpers\";\nimport type { YieldingBankExternalLiquiditySource } from \"./types\";\nimport type { AccountClient } from \"./account\";\n\nexport interface YieldingBankRefreshExternalLiquidity {\n externalLiquiditySources: YieldingBankExternalLiquiditySource[];\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\nexport class LongYieldCarryExternalLiquidityResolver {\n private readonly perena: PerenaClient;\n\n constructor(rpcUrl: string) {\n this.perena = new PerenaClient(rpcUrl);\n }\n\n async resolveYieldingBankRefreshExternalLiquidity(\n accountClient: AccountClient,\n yieldingBank: Address,\n cpiData: readonly CpiData[] = []\n ): Promise<YieldingBankRefreshExternalLiquidity> {\n const usdStarJuniorMint = mints.get(\"USD*-J\");\n if (!usdStarJuniorMint) {\n return { externalLiquiditySources: [], postSuccessCacheInvalidations: [] };\n }\n\n const bank = await accountClient.fetchYieldingBank(yieldingBank);\n if (!bank.findAssetHolding(usdStarJuniorMint.address)) {\n return { externalLiquiditySources: [], postSuccessCacheInvalidations: [] };\n }\n\n const withdrawalQueues = dedupeOrderedAddresses([\n ...(await this.perena.getActiveWithdrawalQueues(yieldingBank)),\n ...getPerenaWithdrawalQueueAddressesFromCpiData(cpiData),\n ]);\n\n return {\n externalLiquiditySources: withdrawalQueues.map((account) => ({\n mint: usdStarJuniorMint.address,\n account,\n })),\n postSuccessCacheInvalidations: withdrawalQueues.length\n ? [this.perena.getActiveWithdrawalQueuesCacheInvalidation(yieldingBank)]\n : [],\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport {\n createCpiRefs,\n fromWeb3Pk,\n getAtaAddress,\n getCreateAtaInstructions,\n getCreateAtaIxIfNeeded,\n mints,\n resolveTokenProgram,\n toKitInstruction,\n toWeb3AccountMeta,\n type TransactionCacheInvalidation,\n} from \"common\";\nimport type {\n CreditUnlentToRedemptionEpochIxArgs,\n ProcessAsyncBurnIxArgs,\n ProcessAsyncBurnTxArgs,\n SetRedemptionEpochStatusIxArgs,\n TopUpUnlentReservesIxArgs,\n TopUpUnlentReservesTxArgs,\n} from \"./args\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\n\nexport class SetRedemptionEpochStatusBuilder extends LongYieldCarryBuilderBase<\n SetRedemptionEpochStatusIxArgs,\n SetRedemptionEpochStatusIxArgs\n> {\n async getTx(args: SetRedemptionEpochStatusIxArgs): Promise<LongYieldCarryTransactionPlan> {\n return { instructions: [await this.getIx(args)], lookupTables: [] };\n }\n\n async getIx(args: SetRedemptionEpochStatusIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const manager = this.resolveTokenManager(tokenData.data);\n const epochData = await this.program.account.redemptionEpoch.fetch(args.redemptionEpoch);\n const epochRentRecipient = epochData.header.payer.equals(PublicKey.default)\n ? manager\n : (epochData.header.payer.toBase58() as Address);\n\n return this.program.methods\n .setRedemptionEpochStatus({ status: args.params.status })\n .accountsPartial({\n manager,\n token: args.token,\n redemptionEpoch: args.redemptionEpoch,\n epochRentRecipient,\n })\n .instruction()\n .then(toKitInstruction);\n }\n}\n\nexport class TopUpUnlentReservesBuilder extends LongYieldCarryBuilderBase<\n TopUpUnlentReservesIxArgs,\n TopUpUnlentReservesTxArgs\n> {\n async getTx(args: TopUpUnlentReservesTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const tokenData = await this.account.fetchToken(args.token, { fresh: true });\n const position = tokenData.data.lendingPositions[args.params.lendingPositionIndex];\n const manager = this.resolveTokenManager(tokenData.data);\n\n const txId =\n args.params.txId ??\n `top-up-unlent-reserves-${Date.now()}-${position.protocolUserAcc.toBase58()}`;\n\n const cpiBundle = await this.getLendingOperationCpiData(\n args.token,\n manager,\n position,\n txId,\n \"withdraw\",\n args.params.uiAmount\n );\n const prerequisiteCpiRefs = createCpiRefs(cpiBundle.prerequisiteCpis);\n const {\n accounts: remainingAccounts,\n refs: ixRefs,\n lookupTables,\n } = createCpiRefs(cpiBundle.cpis, { initialAccounts: prerequisiteCpiRefs.accounts });\n\n const lpClient = this.getLendingPlatformClient(position);\n const preInstructions = await lpClient.ix.getPreInstructions(txId);\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations } =\n await getCreateAtaInstructions(this.rpc, manager, remainingAccounts);\n\n const redemptionEpoch = args.params.redemptionEpoch ?? undefined;\n const topUpIx = await this.getIx({\n token: args.token,\n params: {\n prerequisiteCpis: prerequisiteCpiRefs.refs,\n ixRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n remainingAccounts,\n redemptionEpoch,\n },\n });\n\n return {\n instructions: [...preInstructions, ...ataCreationIxs, topUpIx],\n lookupTables: this.getTxLookupTables(args.token, [\n ...(lookupTables ?? []),\n ...(prerequisiteCpiRefs.lookupTables ?? []),\n ]),\n postSuccessCacheInvalidations: [\n ...cpiBundle.postSuccessCacheInvalidations,\n ...postSuccessCacheInvalidations,\n ],\n txId,\n };\n }\n\n async getIx(args: TopUpUnlentReservesIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const position = tokenData.data.lendingPositions[args.params.lendingPositionIndex];\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n return this.program.methods\n .topUpUnlentReserves({\n prerequisiteCpis: args.params.prerequisiteCpis,\n ixRefs: args.params.ixRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n })\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n redemptionEpoch: args.params.redemptionEpoch ?? null,\n collateralMint: tokenData.collateralMint,\n collateralTokenProgram,\n lendingPositionUserAccount: fromWeb3Pk(position.protocolUserAcc),\n lendingPositionCollateralReserve: fromWeb3Pk(position.collateralReserve),\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n}\n\nexport class CreditUnlentToRedemptionEpochBuilder extends LongYieldCarryBuilderBase<\n CreditUnlentToRedemptionEpochIxArgs,\n CreditUnlentToRedemptionEpochIxArgs\n> {\n async getTx(args: CreditUnlentToRedemptionEpochIxArgs): Promise<LongYieldCarryTransactionPlan> {\n return { instructions: [await this.getIx(args)], lookupTables: [] };\n }\n\n async getIx(args: CreditUnlentToRedemptionEpochIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const collateralTokenAccount = await getAtaAddress(\n tokenData.collateralMint,\n args.token,\n collateralTokenProgram\n );\n\n return this.program.methods\n .creditUnlentToRedemptionEpoch()\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n redemptionEpoch: args.redemptionEpoch,\n collateralMint: tokenData.collateralMint,\n collateralTokenAccount,\n collateralTokenProgram,\n })\n .instruction()\n .then(toKitInstruction);\n }\n}\n\nexport class ProcessAsyncBurnBuilder extends LongYieldCarryBuilderBase<\n ProcessAsyncBurnIxArgs,\n ProcessAsyncBurnTxArgs\n> {\n async getTx(args: ProcessAsyncBurnTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const epochId = BigInt(args.params.epochId.toString());\n const sequence = BigInt(args.params.sequence.toString());\n\n const [redemptionEpoch] = await this.pda.deriveRedemptionEpochPda(args.token, epochId);\n const [request] = await this.pda.deriveAsyncBurnRequestPda(args.token, epochId, sequence);\n const tokenData = await this.account.fetchToken(args.token);\n const manager = this.resolveTokenManager(tokenData.data);\n const requestData = await this.program.account.asyncBurnRequest.fetch(request);\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const user = requestData.header.user.toBase58() as Address;\n const isNativeSolCollateral = tokenData.collateralMint === mints.get(\"SOL\")?.address;\n\n const instructions: Instruction[] = [];\n const postSuccessCacheInvalidations: TransactionCacheInvalidation[] = [];\n\n if (isNativeSolCollateral) {\n const requestCollateralAccount = await getAtaAddress(\n tokenData.collateralMint,\n request,\n collateralTokenProgram\n );\n const createRequestCollateralAta = await getCreateAtaIxIfNeeded(\n this.rpc,\n manager,\n tokenData.collateralMint,\n request,\n collateralTokenProgram,\n { accountClient: this.account }\n );\n if (createRequestCollateralAta.instruction) {\n instructions.push(createRequestCollateralAta.instruction);\n postSuccessCacheInvalidations.push(\n ...(createRequestCollateralAta.postSuccessCacheInvalidations ?? [])\n );\n }\n } else {\n const userCollateralAccount = await getAtaAddress(\n tokenData.collateralMint,\n user,\n collateralTokenProgram\n );\n const createUserCollateralAta = await getCreateAtaIxIfNeeded(\n this.rpc,\n manager,\n tokenData.collateralMint,\n user,\n collateralTokenProgram,\n { accountClient: this.account }\n );\n if (createUserCollateralAta.instruction) {\n instructions.push(createUserCollateralAta.instruction);\n postSuccessCacheInvalidations.push(\n ...(createUserCollateralAta.postSuccessCacheInvalidations ?? [])\n );\n }\n }\n\n instructions.push(await this.getIx({ token: args.token, redemptionEpoch, request }));\n\n return {\n instructions,\n lookupTables: this.getTxLookupTables(args.token),\n postSuccessCacheInvalidations,\n debug: {\n processAsyncBurn: {\n epochId,\n sequence,\n request,\n user,\n collateralDelivery: isNativeSolCollateral ? \"nativeSol\" : \"tokenAta\",\n userCollateralAccount: isNativeSolCollateral\n ? undefined\n : await getAtaAddress(tokenData.collateralMint, user, collateralTokenProgram),\n requestCollateralAccount: isNativeSolCollateral\n ? await getAtaAddress(tokenData.collateralMint, request, collateralTokenProgram)\n : undefined,\n },\n },\n };\n }\n\n async getIx(args: ProcessAsyncBurnIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const manager = this.resolveTokenManager(tokenData.data);\n const tokenProgram = resolveTokenProgram(tokenData.data.config.tokenProgram);\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const requestData = await this.program.account.asyncBurnRequest.fetch(args.request);\n const user = requestData.header.user.toBase58() as Address;\n const payer = requestData.header.payer.toBase58() as Address;\n const epochData = await this.program.account.redemptionEpoch.fetch(args.redemptionEpoch);\n const epochRentRecipient = epochData.header.payer.equals(PublicKey.default)\n ? manager\n : (epochData.header.payer.toBase58() as Address);\n const isNativeSolCollateral = tokenData.collateralMint === mints.get(\"SOL\")?.address;\n const requestTokenAccount = await getAtaAddress(tokenData.mint, args.request, tokenProgram);\n const userCollateralAccount = isNativeSolCollateral\n ? null\n : await getAtaAddress(tokenData.collateralMint, user, collateralTokenProgram);\n const requestCollateralAccount = isNativeSolCollateral\n ? await getAtaAddress(tokenData.collateralMint, args.request, collateralTokenProgram)\n : null;\n const collateralTokenAccount = await getAtaAddress(\n tokenData.collateralMint,\n args.token,\n collateralTokenProgram\n );\n\n return this.program.methods\n .processAsyncBurn()\n .accountsPartial({\n manager,\n payer,\n token: args.token,\n redemptionEpoch: args.redemptionEpoch,\n request: args.request,\n user,\n mint: tokenData.mint,\n requestTokenAccount,\n collateralMint: tokenData.collateralMint,\n userCollateralAccount,\n requestCollateralAccount,\n collateralTokenAccount,\n epochRentRecipient,\n tokenProgram,\n collateralTokenProgram,\n })\n .instruction()\n .then(toKitInstruction);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { ClaimIncentivesIxArgs, ClaimIncentivesTxArgs } from \"./args\";\nimport {\n type AnchorOracleType,\n LendingPlatform,\n createMultiCpiRefs,\n fromWeb3Pk,\n getAtaAddress,\n getCreateAtaInstructions,\n getCreateAtaIxIfNeeded,\n mints,\n resolveTokenProgram,\n toKitInstruction,\n toWeb3AccountMeta,\n} from \"common\";\nimport { PYTH_FEEDS } from \"oracle\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { getTokenCacheInvalidation, getYieldingBankCacheInvalidation } from \"../../utils\";\nimport { RefreshYieldingBankBuilder } from \"./refreshYieldingBankBuilder\";\nimport type { TokenAccountData } from \"../../models/lycToken\";\n\nexport class ClaimIncentivesBuilder extends LongYieldCarryBuilderBase<\n ClaimIncentivesIxArgs,\n ClaimIncentivesTxArgs\n> {\n async getIx(args: ClaimIncentivesIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const tokenIncentiveAta = await getAtaAddress(\n args.params.expectedIncentiveMint,\n args.token,\n args.params.incentiveTokenProgram\n );\n const yieldingBankIncentiveAta = args.params.yieldingBank\n ? await getAtaAddress(\n args.params.expectedIncentiveMint,\n args.params.yieldingBank,\n args.params.incentiveTokenProgram\n )\n : null;\n const feeWallet = args.params.feeWallet ?? this.resolveTokenCuratorFeeWallet(tokenData.data);\n const feeWalletIncentiveAta = await getAtaAddress(\n args.params.expectedIncentiveMint,\n feeWallet,\n args.params.incentiveTokenProgram\n );\n\n return this.program.methods\n .claimIncentives({\n prerequisiteCpis: args.params.prerequisiteCpis ?? null,\n tokenIxRefs: args.params.tokenIxRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n incentiveOracleType: args.params.incentiveOracleType,\n })\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n yieldingBank: args.params.yieldingBank ?? null,\n expectedIncentiveMint: args.params.expectedIncentiveMint,\n tokenIncentiveAta,\n yieldingBankIncentiveAta: yieldingBankIncentiveAta ?? null,\n incentiveOracle: args.params.incentiveOracle ?? null,\n feeWallet,\n feeWalletIncentiveAta,\n incentiveTokenProgram: args.params.incentiveTokenProgram,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: ClaimIncentivesTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const tokenData = await this.account.fetchToken(args.token, { fresh: true });\n const manager = this.resolveTokenManager(tokenData.data);\n const position = tokenData.data.lendingPositions[args.params.lendingPositionIndex];\n const lpClients = this.lendingPlatformClients;\n const lpClient = this.getLendingPlatformClient(position);\n const positionPlatform = lpClients.getPlatformForPosition(position);\n if (positionPlatform !== LendingPlatform.Kamino) {\n throw new Error(`Unsupported lending platform for claim_incentives: ${positionPlatform}`);\n }\n\n const yieldingBank =\n args.params.yieldingBank ?? (await tokenData.resolveFirstYieldingBankAddress(this.pda));\n\n const debtMint = fromWeb3Pk(position.accounting.debt.mint);\n const isDebtMintIncentive = args.params.incentiveMint === debtMint;\n const incentiveTokenProgram = isDebtMintIncentive\n ? resolveTokenProgram(position.accounting.debt.tokenProgram)\n : (mints.get(args.params.incentiveMint)?.tokenProgram ?? TOKEN_PROGRAM_ADDRESS);\n\n const { incentiveOracle, incentiveOracleType } = this.resolveIncentiveOracle(\n tokenData.data,\n args.params\n );\n\n let claimAccounts = args.params.claimAccounts;\n if (!claimAccounts) {\n const matchingIncentives = (\n await lpClient.getOutstandingIncentives(fromWeb3Pk(position.protocolUserAcc))\n ).filter((incentive) => incentive.mint === args.params.incentiveMint);\n if (matchingIncentives.length !== 1 || !matchingIncentives[0].claimAccounts) {\n throw new Error(\n `Unable to resolve claim accounts for incentive mint ${args.params.incentiveMint}` +\n ` (found ${matchingIncentives.length} matching farm(s));` +\n ` pass claimAccounts explicitly to disambiguate`\n );\n }\n claimAccounts = matchingIncentives[0].claimAccounts;\n }\n\n const kaminoClient = lpClients.getByPlatform(LendingPlatform.Kamino);\n const claimCpiData = await kaminoClient.ix.getClaimIncentiveCpiData(\n args.token,\n manager,\n fromWeb3Pk(position.pool),\n fromWeb3Pk(position.collateralReserve),\n fromWeb3Pk(position.protocolUserAcc),\n claimAccounts.farm,\n claimAccounts.userFarm,\n args.params.incentiveMint\n );\n\n const {\n accounts: remainingAccounts,\n refsGroups,\n lookupTables,\n } = createMultiCpiRefs([claimCpiData]);\n const tokenIxRefs = refsGroups[0];\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations } =\n await getCreateAtaInstructions(this.rpc, manager, remainingAccounts);\n\n const { instruction: createYbAtaIx, postSuccessCacheInvalidations: ybAtaCacheInv } =\n await getCreateAtaIxIfNeeded(\n this.rpc,\n manager,\n args.params.incentiveMint,\n yieldingBank,\n incentiveTokenProgram\n );\n\n const refreshYieldingBankPlan = await new RefreshYieldingBankBuilder(this.context).getTx({\n signer: manager,\n yieldingBank,\n });\n\n return {\n instructions: [\n ...ataCreationIxs,\n ...(createYbAtaIx ? [createYbAtaIx] : []),\n ...refreshYieldingBankPlan.instructions,\n await this.getIx({\n token: args.token,\n params: {\n tokenIxRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n yieldingBank,\n expectedIncentiveMint: args.params.incentiveMint,\n incentiveTokenProgram,\n incentiveOracle,\n incentiveOracleType,\n feeWallet: this.resolveTokenCuratorFeeWallet(tokenData.data),\n remainingAccounts,\n },\n }),\n ],\n lookupTables: this.getTxLookupTables(args.token, lookupTables ?? []),\n postSuccessCacheInvalidations: [\n ...postSuccessCacheInvalidations,\n ...ybAtaCacheInv,\n getTokenCacheInvalidation(args.token),\n getYieldingBankCacheInvalidation(yieldingBank),\n ],\n };\n }\n\n private resolveIncentiveOracle(\n tokenData: TokenAccountData,\n params: ClaimIncentivesTxArgs[\"params\"]\n ): { incentiveOracle: Address; incentiveOracleType: AnchorOracleType } {\n for (const lp of tokenData.lendingPositions) {\n const debtMint = fromWeb3Pk(lp.accounting.debt.mint);\n if (debtMint !== params.incentiveMint) continue;\n return {\n incentiveOracle: fromWeb3Pk(lp.accounting.debt.oracle),\n incentiveOracleType: lp.accounting.debt.oracleType,\n };\n }\n\n if (params.incentiveOracle && params.incentiveOracleType) {\n return {\n incentiveOracle: params.incentiveOracle,\n incentiveOracleType: params.incentiveOracleType,\n };\n }\n\n const symbol = mints.get(params.incentiveMint)?.symbol;\n const pythFeed = symbol ? PYTH_FEEDS[symbol as keyof typeof PYTH_FEEDS] : undefined;\n if (pythFeed) {\n return {\n incentiveOracle: pythFeed.account,\n incentiveOracleType: { pyth: {} },\n };\n }\n\n throw new Error(\n `claim_incentives: cannot auto-resolve oracle for incentive mint ${params.incentiveMint}; pass incentiveOracle and incentiveOracleType explicitly`\n );\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { fromWeb3Pk, getAtaAddress, resolveTokenProgram, toKitInstruction } from \"common\";\nimport { PROTOCOL_ADMIN } from \"../../constants/general\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { CollectFeesIxArgs } from \"./args\";\n\n/**\n * Collects pending fees for either the curator or the protocol. The caller\n * passes the `authority` signer. If it is `PROTOCOL_ADMIN`, the protocol bucket and\n * protocol fee wallet are used (even when that address is also the token curator).\n * Otherwise, if it is the curator only, the curator bucket and curator fee wallet are used.\n * Throws client-side if the signer matches neither role (mirroring the on-chain check).\n */\nexport class CollectFeesBuilder extends LongYieldCarrySingleInstructionBuilderService<CollectFeesIxArgs> {\n async getIx(args: CollectFeesIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const mint = tokenData.mint;\n const tokenProgram = resolveTokenProgram(tokenData.data.config.tokenProgram);\n\n const curator = fromWeb3Pk(tokenData.data.roles.curator);\n const protocolAdmin = PROTOCOL_ADMIN[this.environment];\n let feeWallet: Address;\n if (args.authority === curator) {\n feeWallet = this.resolveTokenCuratorFeeWallet(tokenData.data);\n } else if (args.authority === protocolAdmin) {\n feeWallet = this.protocolFeeWallet;\n } else {\n throw new Error(\n `collectFees: authority ${args.authority} is neither the token's curator ` +\n `(${curator}) nor PROTOCOL_ADMIN (${protocolAdmin})`\n );\n }\n const feeWalletTokenAccount = await getAtaAddress(mint, feeWallet, tokenProgram);\n\n return this.program.methods\n .collectFees()\n .accountsPartial({\n authority: args.authority,\n token: args.token,\n mint,\n feeWallet,\n feeWalletTokenAccount,\n tokenProgram,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(args: CollectFeesIxArgs): Promise<readonly Address[]> {\n return this.getTxLookupTables(args.token);\n }\n}\n","import { BN } from \"@anchor-lang/core\";\nimport type { Address } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport {\n bnFromBigInt,\n calculateTvlUsd,\n fromUiAmount,\n fromWeb3Pk,\n resolveTokenProgram,\n toBigInt,\n tvlUsdToBaseUnits,\n} from \"common\";\nimport type { AccountClient } from \"../account\";\nimport type { CollectInterestPlan, CollectInterestPlanParams } from \"../types\";\nimport { NoInterestToCollectError } from \"../../errors\";\nimport { collectableNetYieldUsd } from \"../../utils/tokenFeeMath\";\n\n/**\n * Ensures the planner produced at least one positive redemption leg. Without this,\n * routing would fail or build an empty CPI list even though share math passed.\n */\nexport function assertCollectInterestPlanHasPositiveRedemptions(plan: CollectInterestPlan): void {\n const hasPositive = plan.holdingsToRedeem.some((h) => h.amount.gt(new BN(0)));\n if (!hasPositive) {\n throw new NoInterestToCollectError(\"No redeemable yielding bank assets — nothing to collect\");\n }\n}\n\n/**\n * Derive deterministic collect-interest values from fresh token and bank state.\n * This intentionally excludes route / venue selection.\n *\n * @param account - Account client used to fetch fresh token and yielding-bank state.\n * @param token - Token PDA whose carry position should collect accrued interest.\n * @param params - Yielding bank to redeem from.\n * @returns Deterministic collect-interest plan without swap routing attached.\n *\n * @throws {NoInterestToCollectError} When carry/debt math rules out collection.\n *\n * Before swap routing, run `assertCollectInterestPlanHasPositiveRedemptions` on the\n * returned plan (the `getCollectInterestTx` transaction builder does this) so rounding\n * cannot yield an empty redemption list.\n */\nexport async function buildCollectInterestPlan(\n account: AccountClient,\n token: Address,\n params: CollectInterestPlanParams\n): Promise<CollectInterestPlan> {\n const [tokenData, bank] = await Promise.all([\n account.fetchToken(token),\n account.fetchYieldingBank(params.yieldingBank),\n ]);\n\n const carryIndex = tokenData.data.debtCarry.findIndex(\n (carry) =>\n !carry.yieldingBaseMint.equals(PublicKey.default) &&\n fromWeb3Pk(carry.yieldingBaseMint) === bank.baseMint &&\n carry.yieldingBankId === bank.id &&\n toBigInt(carry.shares) > BigInt(0)\n );\n\n if (carryIndex === -1) {\n throw new NoInterestToCollectError(\n `No active carry position found for yielding bank ${params.yieldingBank}`\n );\n }\n\n const carry = tokenData.data.debtCarry[carryIndex];\n const totalCarryTvl = tokenData.totalCarryTvlUsd;\n const totalDebtUsd = tokenData.totalLendingDebtTvlUsd;\n const totalShares = toBigInt(bank.data.accounting.totalShares);\n const tvlBefore = toBigInt(bank.data.accounting.tvl);\n const carryShares = toBigInt(carry.shares);\n\n if (!tokenData.hasInterestToCollect()) {\n throw new NoInterestToCollectError(\n \"Token is inactive, carry surplus is absent, or surplus exceeds the 1 bp collection limit\"\n );\n }\n if (totalShares <= BigInt(0)) {\n throw new NoInterestToCollectError(\"Yielding bank has no outstanding shares\");\n }\n if (tvlBefore <= BigInt(0)) {\n throw new NoInterestToCollectError(\"Yielding bank has zero TVL — nothing to collect\");\n }\n\n // Only redeem from the default redemption mint — the on-chain instruction\n // enforces this by validating the yb_redemption_token_account ATA.\n const redemptionMint = bank.defaultRedemptionMint;\n const redemptionHolding = bank.findAssetHolding(redemptionMint);\n if (!redemptionHolding) {\n throw new NoInterestToCollectError(\n `Default redemption mint ${redemptionMint} has no active asset holding on the yielding bank`\n );\n }\n const redemptionOracle = fromWeb3Pk(redemptionHolding.oracle);\n const redemptionTokenProgram = resolveTokenProgram(redemptionHolding.tokenProgram);\n\n // Use the redemption holding's cached on-chain price rather than a freshly\n // fetched live price. The handler re-reads the same on-chain oracle account\n // we cached from the previous refresh_yielding_bank, so using the cached\n // value here lets the SDK predict the handler's `redemption_sold_tvl`\n // exactly. (An independently-fetched Hermes/live price drifts by a few\n // fixed-point units from the on-chain account, which previously caused\n // strict-equality test assertions and the share_price invariant check to\n // fail on rebalanced banks.)\n const redemptionPrice = toBigInt(redemptionHolding.price);\n const redemptionDecimals = redemptionHolding.decimals;\n const redemptionHoldingAmount = toBigInt(redemptionHolding.amount);\n if (redemptionPrice <= BigInt(0)) {\n throw new NoInterestToCollectError(\n `Redemption mint ${redemptionMint} has no cached price — refresh the yielding bank first`\n );\n }\n\n // Collectable yield is the full carry surplus above debt — must match the on-chain cap.\n const netYieldUsd = collectableNetYieldUsd(totalCarryTvl, totalDebtUsd);\n\n if (params.minYieldUsd !== undefined && params.minYieldUsd > 0) {\n const minYield8Dec = toBigInt(fromUiAmount(params.minYieldUsd, 8));\n if (netYieldUsd < minYield8Dec) {\n throw new NoInterestToCollectError(\n `Net yield $${(Number(netYieldUsd) / 1e8).toFixed(4)} is below minimum $${\n params.minYieldUsd\n }`\n );\n }\n }\n\n // Target shares to burn: capped at this carry position's balance because a\n // single call cannot drain more than this bank's own carry (the handler\n // enforces the same cap against `carry.shares`).\n //\n // Use the same `totalShares / tvl` ratio as the handler's final derivation\n // to keep a single truncation across all share-math steps.\n const unboundedSharesToBurn = (netYieldUsd * totalShares) / tvlBefore;\n const targetSharesToBurn =\n unboundedSharesToBurn < carryShares ? unboundedSharesToBurn : carryShares;\n if (targetSharesToBurn <= BigInt(0)) {\n throw new NoInterestToCollectError(\n \"Computed shares to burn is zero — yield too small to collect\"\n );\n }\n\n // USD value we want the swap to liquidate from the redemption mint. Convert\n // to raw token units at the cached redemption price to size the swap input.\n const targetRedemptionTvlUsd = (targetSharesToBurn * tvlBefore) / totalShares;\n const redemptionAmount = tvlUsdToBaseUnits(\n targetRedemptionTvlUsd,\n redemptionPrice,\n redemptionDecimals\n );\n\n if (redemptionAmount > redemptionHoldingAmount) {\n throw new NoInterestToCollectError(\n `Redemption mint ${redemptionMint} holding (${redemptionHoldingAmount}) is insufficient ` +\n `to cover yield redemption (${redemptionAmount}) — rebalance the yielding bank first`\n );\n }\n\n // Predict the handler's phase 6 derivation exactly (same integer-truncation\n // order): first recompute the *actual* USD value the handler will see from\n // the sized `redemptionAmount`, then apply the invariant formula\n // `shares_to_burn = redemption_sold_tvl × total_shares_before / tvl_before`.\n // The handler uses `total_shares / tvl` rather than `bank_scale /\n // share_price` to avoid double truncation — mirror that here.\n const sharesBurnedValueUsd = calculateTvlUsd(\n redemptionAmount,\n redemptionPrice,\n redemptionDecimals\n );\n const sharesToBurn = (sharesBurnedValueUsd * totalShares) / tvlBefore;\n if (sharesToBurn <= BigInt(0)) {\n throw new NoInterestToCollectError(\n \"Predicted shares to burn is zero — redemption amount rounds down below one share\"\n );\n }\n\n const holdingsToRedeem: CollectInterestPlan[\"holdingsToRedeem\"] = [];\n if (redemptionAmount > BigInt(0)) {\n holdingsToRedeem.push({\n mint: redemptionMint,\n amount: bnFromBigInt(redemptionAmount),\n isBaseAsset: redemptionMint === bank.baseMint,\n });\n }\n\n return {\n token,\n yieldingBank: params.yieldingBank,\n baseMint: bank.baseMint,\n redemption: {\n mint: redemptionMint,\n tokenProgram: redemptionTokenProgram,\n oracle: redemptionOracle,\n },\n collateral: {\n mint: fromWeb3Pk(tokenData.data.collateral.mint),\n tokenProgram: resolveTokenProgram(tokenData.data.collateral.tokenProgram),\n oracle: fromWeb3Pk(tokenData.data.collateral.oracle),\n },\n carryIndex,\n sharesToBurn: bnFromBigInt(sharesToBurn),\n sharesBurnedValueUsd: bnFromBigInt(sharesBurnedValueUsd),\n holdingsToRedeem,\n };\n}\n","import { BN } from \"@anchor-lang/core\";\nimport type { Address } from \"@solana/kit\";\nimport type { CpiData, SwapClient } from \"common\";\nimport { toSafeNumber } from \"common\";\nimport type {\n CollectInterestExecutionPlan,\n CollectInterestPlan,\n CollectInterestRouteBuilderParams,\n} from \"../types\";\nimport { NoInterestToCollectError } from \"../../errors\";\n\n/**\n * Convert a deterministic collect-interest plan into ordered CPI data.\n * Venue selection and slippage policy live here.\n *\n * @param swapClient - Swap client used for all intermediate and final swaps.\n * @param plan - Deterministic collect-interest plan returned by the planner layer.\n * @param params - Optional routing policy such as output mint and slippage.\n * @returns Executable collect-interest plan with ordered CPI data.\n */\nexport async function buildCollectInterestRoutePlan(\n swapClient: SwapClient,\n plan: CollectInterestPlan,\n params: CollectInterestRouteBuilderParams = {},\n payer?: Address\n): Promise<CollectInterestExecutionPlan> {\n const outputMint = params.outputMint ?? plan.collateral.mint;\n const slippageBps = params.slippageBps ?? 100;\n const cpiData: CpiData[] = [];\n\n const holding = plan.holdingsToRedeem[0];\n if (!holding || holding.amount.lte(new BN(0))) {\n throw new NoInterestToCollectError(\"Expected positive redeemable yielding bank assets\");\n }\n\n // Single swap: redemption mint → output mint (collateral or caller override).\n const quote = await swapClient.getQuote({\n inputMint: holding.mint,\n outputMint,\n amount: toSafeNumber(holding.amount, \"collect_interest swap amount\"),\n slippageBps,\n });\n const swapCpi = await swapClient.getSwapCpiData(\n quote,\n plan.yieldingBank,\n payer ? { payer } : undefined\n );\n cpiData.push(swapCpi);\n\n return {\n ...plan,\n preInstructions: swapCpi.preInstructions ?? [],\n initialAccounts: [],\n cpiData,\n };\n}\n","import type { Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { CollectInterestIxArgs, CollectInterestTxArgs } from \"./args\";\nimport {\n assertCollectInterestPlanHasPositiveRedemptions,\n buildCollectInterestPlan,\n} from \"../plans/collectInterest\";\nimport { buildCollectInterestRoutePlan } from \"../routes/collectInterest\";\nimport {\n createCpiRefs,\n fromWeb3Pk,\n getAtaAddress,\n getCreateAtaInstructions,\n getCreateAtaIxIfNeeded,\n resolveTokenProgram,\n toKitInstruction,\n toWeb3AccountMeta,\n} from \"common\";\nexport class CollectInterestBuilder extends LongYieldCarryBuilderBase<\n CollectInterestIxArgs,\n CollectInterestTxArgs\n> {\n async getIx(args: CollectInterestIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const collateralMint = fromWeb3Pk(tokenData.data.collateral.mint);\n const collateralOracle = fromWeb3Pk(tokenData.data.collateral.oracle);\n const secondaryCollateralOracle = this.resolveOptionalSecondaryCollateralOracle(\n tokenData.data.collateral\n );\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const { redemption } = args.params;\n const collateralTokenAccount = await getAtaAddress(\n collateralMint,\n args.token,\n collateralTokenProgram\n );\n const ybCollateralTokenAccount = await getAtaAddress(\n collateralMint,\n args.yieldingBank,\n collateralTokenProgram\n );\n const ybRedemptionTokenAccount = await getAtaAddress(\n redemption.mint,\n args.yieldingBank,\n redemption.tokenProgram\n );\n const curatorFeeWallet = this.resolveTokenCuratorFeeWallet(tokenData.data);\n const protocolFeeWallet = this.protocolFeeWallet;\n const curatorFeeWalletCollateralAccount = await getAtaAddress(\n collateralMint,\n curatorFeeWallet,\n collateralTokenProgram\n );\n const protocolFeeWalletCollateralAccount = await getAtaAddress(\n collateralMint,\n protocolFeeWallet,\n collateralTokenProgram\n );\n\n return this.program.methods\n .collectInterest(args.params.refs)\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n yieldingBank: args.yieldingBank,\n collateralMint,\n collateralOracle,\n secondaryCollateralOracle,\n redemptionOracle: redemption.oracle,\n collateralTokenAccount,\n ybCollateralTokenAccount,\n ybRedemptionTokenAccount,\n curatorFeeWalletCollateralAccount,\n protocolFeeWalletCollateralAccount,\n collateralTokenProgram,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: CollectInterestTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const plan = await buildCollectInterestPlan(this.account, args.token, args.params);\n assertCollectInterestPlanHasPositiveRedemptions(plan);\n const executionPlan = await buildCollectInterestRoutePlan(\n this.swap,\n plan,\n args.params,\n args.manager\n );\n const { collateral, redemption, cpiData } = executionPlan;\n const {\n accounts: remainingAccounts,\n refs,\n lookupTables,\n } = createCpiRefs(cpiData, {\n initialAccounts: [],\n });\n const tokenData = await this.account.fetchToken(args.token);\n const {\n instruction: ybCollateralAtaIx,\n postSuccessCacheInvalidations: ybCollateralAtaCacheInv,\n } = await getCreateAtaIxIfNeeded(\n this.rpc,\n args.manager,\n collateral.mint,\n args.params.yieldingBank,\n collateral.tokenProgram\n );\n const curatorFeeWallet = this.resolveTokenCuratorFeeWallet(tokenData.data);\n const protocolFeeWallet = this.protocolFeeWallet;\n const {\n instruction: curatorPerfFeeAtaIx,\n postSuccessCacheInvalidations: curatorPerfFeeAtaCacheInv,\n } = await getCreateAtaIxIfNeeded(\n this.rpc,\n args.manager,\n collateral.mint,\n curatorFeeWallet,\n collateral.tokenProgram\n );\n const {\n instruction: protocolPerfFeeAtaIx,\n postSuccessCacheInvalidations: protocolPerfFeeAtaCacheInv,\n } = await getCreateAtaIxIfNeeded(\n this.rpc,\n args.manager,\n collateral.mint,\n protocolFeeWallet,\n collateral.tokenProgram\n );\n const { instructions, postSuccessCacheInvalidations } = await getCreateAtaInstructions(\n this.rpc,\n args.manager,\n remainingAccounts\n );\n\n return {\n instructions: [\n ...executionPlan.preInstructions,\n ...(ybCollateralAtaIx ? [ybCollateralAtaIx] : []),\n ...(curatorPerfFeeAtaIx ? [curatorPerfFeeAtaIx] : []),\n ...(protocolPerfFeeAtaIx ? [protocolPerfFeeAtaIx] : []),\n ...instructions,\n await this.getIx({\n token: args.token,\n yieldingBank: args.params.yieldingBank,\n params: {\n redemption,\n refs,\n remainingAccounts,\n },\n }),\n ],\n lookupTables: this.getTxLookupTables(args.token, lookupTables ?? []),\n postSuccessCacheInvalidations: [\n ...ybCollateralAtaCacheInv,\n ...curatorPerfFeeAtaCacheInv,\n ...protocolPerfFeeAtaCacheInv,\n ...postSuccessCacheInvalidations,\n ],\n };\n }\n}\n","import type { Instruction } from \"@solana/kit\";\nimport { toKitInstruction, toWeb3Pk } from \"common\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { CreateCpiPlanIxArgs } from \"./args\";\n\nexport class CreateCpiPlanBuilder extends LongYieldCarrySingleInstructionBuilderService<CreateCpiPlanIxArgs> {\n async getIx(args: CreateCpiPlanIxArgs): Promise<Instruction> {\n return this.program.methods\n .createCpiPlan({\n uniqueId: toWeb3Pk(args.params.uniqueId),\n createdTs: args.params.createdTs,\n refs: args.params.refs,\n })\n .accountsPartial({\n manager: args.manager,\n cpiPlan: args.cpiPlan,\n })\n .instruction()\n .then(toKitInstruction);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { getAtaAddress, toKitInstruction, toWeb3Pk } from \"common\";\nimport { PROTOCOL_ADMIN } from \"../../constants/general\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { CreateTokenIxArgs } from \"./args\";\n\nconst DEFAULT_FEE_DRIP_MAX_APY_BPS = 200;\n\nexport class CreateTokenBuilder extends LongYieldCarrySingleInstructionBuilderService<CreateTokenIxArgs> {\n async getIx(args: CreateTokenIxArgs): Promise<Instruction> {\n const [tokenPda] = await this.pda.deriveTokenPda(args.mint, args.params.id);\n const tokenProgram = args.tokenProgram ?? TOKEN_PROGRAM_ADDRESS;\n const collateralTokenProgram = args.collateralTokenProgram ?? TOKEN_PROGRAM_ADDRESS;\n // Keep local omission behavior unchanged for existing tests. Deployed\n // environments default to a 200 bps APY target and hard cap.\n const defaultFeeDripMaxApyBps = this.environment === \"local\" ? 0 : DEFAULT_FEE_DRIP_MAX_APY_BPS;\n const collateralTokenAccount = await getAtaAddress(\n args.collateralMint,\n tokenPda,\n collateralTokenProgram\n );\n\n const curator = args.curator ?? PROTOCOL_ADMIN[this.environment];\n\n return this.program.methods\n .createToken({\n id: args.params.id,\n interestDistribution: args.params.interestDistribution,\n oracleConfig: {\n oracle: toWeb3Pk(args.params.oracleConfig.oracle),\n oracleType: args.params.oracleConfig.oracleType,\n secondaryOracle: args.params.oracleConfig.secondaryOracle\n ? toWeb3Pk(args.params.oracleConfig.secondaryOracle)\n : null,\n },\n feeConfig: {\n performanceFeeBps: args.params.feeConfig.performanceFeeBps,\n mintingFeeBps: args.params.feeConfig.mintingFeeBps,\n burningFeeBps: args.params.feeConfig.burningFeeBps,\n protocolMintBurnPctBps: args.params.feeConfig.protocolMintBurnPctBps,\n curatorMintBurnPctBps: args.params.feeConfig.curatorMintBurnPctBps,\n curatorPerfPctBps: args.params.feeConfig.curatorPerfPctBps,\n feeDripMaxApyBps: args.params.feeConfig.feeDripMaxApyBps ?? defaultFeeDripMaxApyBps,\n },\n })\n .accountsPartial({\n curator,\n adminRole: args.adminRole ?? null,\n managerRole: args.managerRole ?? null,\n curatorFeeWallet: args.curatorFeeWallet ?? null,\n cbControllerRole: args.cbControllerRole ?? null,\n token: tokenPda,\n mint: args.mint,\n collateralMint: args.collateralMint,\n collateralTokenAccount,\n tokenProgram,\n collateralTokenProgram,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(): Promise<readonly Address[]> {\n return this.getTxLookupTables();\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport {\n type CpiData,\n createCpiRefs,\n fromWeb3Pk,\n getCreateAtaInstructions,\n getCreateAtaIxIfNeeded,\n LendingPlatform,\n lendingPlatformToEnum,\n mints,\n toKitInstruction,\n toWeb3AccountMeta,\n toWeb3Pk,\n} from \"common\";\nimport type { AnyLendingPlatformClient } from \"lending-platforms\";\nimport {\n buildLendingPositionAllocation,\n getAvailableTokenLendingUserAccountId,\n getTokenCacheInvalidation,\n resolveDefaultPool,\n} from \"../../utils\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { CreateTokenLendingPositionIxArgs, CreateTokenLendingPositionTxArgs } from \"./args\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\n\nexport class CreateTokenLendingPositionBuilder extends LongYieldCarryBuilderBase<\n CreateTokenLendingPositionIxArgs,\n CreateTokenLendingPositionTxArgs\n> {\n async getIx(args: CreateTokenLendingPositionIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n return this.program.methods\n .createTokenLendingPosition({\n lendingPlatform: args.params.lendingPlatform,\n pool: toWeb3Pk(args.params.pool),\n debtReserve: toWeb3Pk(args.params.debtReserve),\n targetUtilizationRateBps: args.params.targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps: args.params.maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps: args.params.maxDeviationBelowTargetUtilBps,\n debtMint: toWeb3Pk(args.params.debtMint),\n debtDecimals: args.params.debtDecimals,\n debtTokenProgram: args.params.debtTokenProgram,\n debtOracleType: args.params.debtOracleType,\n tokenCpis: args.params.tokenCpis ?? null,\n })\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n lpPosition: {\n userAccount: args.accounts.protocolUserAcc,\n collateralReserve: args.accounts.collateralReserve,\n debtOracle: args.accounts.debtOracle,\n },\n })\n .remainingAccounts((args.params.remainingAccounts ?? []).map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(txArgs: CreateTokenLendingPositionTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const tokenData = await this.account.fetchToken(txArgs.token);\n const manager = this.resolveTokenManager(tokenData.data);\n const lendingPlatform = txArgs.lendingPlatform ?? LendingPlatform.Kamino;\n const lpClient = this.lendingPlatformClients.getByPlatform(lendingPlatform);\n const pool = txArgs.pool ?? resolveDefaultPool(tokenData.collateralMint);\n\n const duplicatePosition = tokenData.data.lendingPositions.find(\n (p) =>\n lendingPlatformToEnum(p.platform) !== LendingPlatform.None &&\n fromWeb3Pk(p.pool) === pool &&\n fromWeb3Pk(p.accounting.debt.mint) === txArgs.debtMint\n );\n if (duplicatePosition) {\n throw new Error(\n `Token ${txArgs.token} already has a lending position on pool ${pool} ` +\n `with debt mint ${txArgs.debtMint}. Use updateLendingPositionConfig to ` +\n `modify the existing position instead of creating a duplicate.`\n );\n }\n\n const userAccountId =\n txArgs.userAccountId ??\n (await getAvailableTokenLendingUserAccountId({\n lendingClient: lpClient,\n token: tokenData,\n pool,\n lendingPlatform,\n }));\n const txId = txArgs.txId ?? `create-token-lending-position-${Date.now()}`;\n\n const allocation = await buildLendingPositionAllocation({\n lendingClient: lpClient,\n tokenPda: txArgs.token,\n collateralMint: tokenData.collateralMint,\n debtMint: txArgs.debtMint,\n debtReserve: txArgs.debtReserve,\n userAccountId,\n pool,\n lendingPlatform,\n targetUtilizationRateBps: txArgs.targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps: txArgs.maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps: txArgs.maxDeviationBelowTargetUtilBps,\n });\n\n const tokenCpisData = await this.buildSetupCpis(\n lpClient,\n allocation,\n txArgs.token,\n manager,\n userAccountId\n );\n\n const {\n accounts: remainingAccounts,\n refs: tokenCpis,\n lookupTables,\n } = tokenCpisData.length\n ? createCpiRefs(tokenCpisData)\n : { accounts: [], refs: undefined, lookupTables: [] as readonly Address[] };\n\n const preInstructions = tokenCpisData.length ? await lpClient.ix.getPreInstructions(txId) : [];\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations: ataCacheInvalidations } =\n tokenCpisData.length\n ? await getCreateAtaInstructions(this.rpc, manager, remainingAccounts)\n : { instructions: [] as Instruction[], postSuccessCacheInvalidations: [] };\n\n // Pre-create the token PDA's debt-mint ATA. Kamino's borrow CPI uses\n // this ATA as `user_destination_liquidity` and fails with\n // `AccountNotInitialized` (Anchor 3012) if the token has never held\n // this mint. Creating it at LP setup means future rebalances/borrows\n // against this LP don't have to reason about whether the ATA exists.\n // The dedup-pool ATA pass above can drop the `isRequiredAta` flag if\n // the same address appears in an earlier CPI without seeds, so we add\n // an explicit idempotent create here.\n const debtMintInfo = mints.get(txArgs.debtMint);\n if (!debtMintInfo) {\n throw new Error(\n `CreateTokenLendingPositionBuilder: debt mint ${txArgs.debtMint} not found in mint registry`\n );\n }\n const { instruction: debtAtaIx, postSuccessCacheInvalidations: debtAtaCacheInvalidations } =\n await getCreateAtaIxIfNeeded(\n this.rpc,\n manager,\n txArgs.debtMint,\n txArgs.token,\n debtMintInfo.tokenProgram\n );\n\n const ix = await this.getIx({\n token: txArgs.token,\n accounts: allocation.accounts,\n params: {\n ...allocation.params,\n tokenCpis,\n remainingAccounts,\n },\n });\n\n const cpiCacheInvalidations = tokenCpisData.flatMap(\n (cpi) => cpi.postSuccessCacheInvalidations ?? []\n );\n\n return {\n instructions: [...preInstructions, ...ataCreationIxs, ...(debtAtaIx ? [debtAtaIx] : []), ix],\n lookupTables: this.getTxLookupTables(txArgs.token, lookupTables ?? []),\n postSuccessCacheInvalidations: [\n getTokenCacheInvalidation(txArgs.token),\n ...cpiCacheInvalidations,\n ...ataCacheInvalidations,\n ...debtAtaCacheInvalidations,\n ],\n txId,\n };\n }\n\n private async buildSetupCpis(\n lpClient: AnyLendingPlatformClient,\n allocation: {\n pool: Address;\n protocolUserAccount: Address;\n collateralReserve: Address;\n debtReserve: Address;\n },\n token: Address,\n manager: Address,\n userAccountId: number\n ): Promise<CpiData[]> {\n const initBundle = await lpClient.ix.getInitLendingPositionCpiData({\n pool: allocation.pool,\n user: token,\n payer: manager,\n userAccountId,\n collateralReserve: allocation.collateralReserve,\n debtReserve: allocation.debtReserve,\n });\n const refreshCpis = await this.buildRefreshCpis(lpClient, allocation);\n return [...initBundle.allCpis, ...refreshCpis];\n }\n\n private async buildRefreshCpis(\n lpClient: AnyLendingPlatformClient,\n allocation: {\n pool: Address;\n protocolUserAccount: Address;\n collateralReserve: Address;\n debtReserve: Address;\n }\n ): Promise<CpiData[]> {\n return lpClient.ix.getPrerequisiteCpisForRefresh([\n {\n pool: allocation.pool,\n userAccount: allocation.protocolUserAccount,\n collateralReserves: [allocation.collateralReserve],\n debtReserves: [allocation.debtReserve],\n },\n ]);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { toAnchorAllocationConfig } from \"../../utils/ix\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { CreateYieldingBankAllocationIxArgs } from \"./args\";\n\nexport class CreateYieldingBankAllocationBuilder extends LongYieldCarrySingleInstructionBuilderService<CreateYieldingBankAllocationIxArgs> {\n async getIx(args: CreateYieldingBankAllocationIxArgs): Promise<Instruction> {\n const allocationMint = args.config.assetHolding?.mint;\n if (!allocationMint) {\n throw new Error(\n \"createYieldingBankAllocation requires config.assetHolding.mint \" +\n \"to populate the allocation_mint account\"\n );\n }\n\n const bankData = await this.account.fetchYieldingBank(args.yieldingBank);\n return this.program.methods\n .createYieldingBankAllocation(toAnchorAllocationConfig(args.config))\n .accountsPartial({\n manager: this.resolveYieldingBankManager(bankData.data),\n yieldingBank: args.yieldingBank,\n allocationMint,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(): Promise<readonly Address[]> {\n return this.getTxLookupTables();\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { toKitInstruction, toWeb3Pk } from \"common\";\nimport { PROTOCOL_ADMIN } from \"../../constants/general\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { CreateYieldingBankIxArgs } from \"./args\";\n\nexport class CreateYieldingBankBuilder extends LongYieldCarrySingleInstructionBuilderService<CreateYieldingBankIxArgs> {\n async getIx(args: CreateYieldingBankIxArgs): Promise<Instruction> {\n const [yieldingBankPda] = await this.pda.deriveYieldingBankPda(args.baseMint, args.params.id);\n return this.program.methods\n .createYieldingBank({\n id: args.params.id,\n oracleConfig: {\n oracle: toWeb3Pk(args.params.oracleConfig.oracle),\n oracleType: args.params.oracleConfig.oracleType,\n secondaryOracle: args.params.oracleConfig.secondaryOracle\n ? toWeb3Pk(args.params.oracleConfig.secondaryOracle)\n : null,\n },\n })\n .accountsPartial({\n curator: args.curator ?? PROTOCOL_ADMIN[this.environment],\n adminRole: args.adminRole ?? null,\n managerRole: args.managerRole ?? null,\n cbControllerRole: args.cbControllerRole ?? null,\n baseMint: args.baseMint,\n defaultRedemptionMint: args.params.defaultRedemptionMint,\n yieldingBank: yieldingBankPda,\n baseMintTokenProgram: args.baseMintTokenProgram ?? TOKEN_PROGRAM_ADDRESS,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(): Promise<readonly Address[]> {\n return this.getTxLookupTables();\n }\n}\n","import type { Address } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport { fromUiAmount, fromWeb3Pk, type SwapClient } from \"common\";\nimport type { LendingPlatformData, ReserveBase } from \"lending-platforms\";\nimport { LeverageService, type LeverageSwapContext } from \"lending-platforms\";\nimport type { TokenLendingPositionData } from \"../../models/lycToken\";\nimport type { LYCYieldingBank } from \"../../models/yieldingBank\";\nimport { LycLendingPositionManager } from \"../../services/carry\";\nimport type { AccountClient } from \"../account\";\nimport type {\n DecreaseCarryPositionBuilderParams,\n DecreaseCarryPositionPlan,\n DecreaseCarryRepaySteering,\n} from \"../types\";\n\n/**\n * Build the execution plan for `decrease_carry_position`.\n *\n * LYC-specific concerns (permissionless operation handling, steering-based target\n * resolution) live here. Sizing, repay CPI construction, and swap assembly are\n * delegated to the generic {@link LeverageService} from `lending-platforms`.\n */\nexport async function buildDecreaseCarryPositionPlan(\n account: AccountClient,\n swap: SwapClient,\n signer: Address,\n token: Address,\n params: DecreaseCarryPositionBuilderParams\n): Promise<DecreaseCarryPositionPlan> {\n const tokenData = await account.fetchToken(token);\n const position = tokenData.data.lendingPositions[params.lendingPositionIndex];\n const debtMint = fromWeb3Pk(position.accounting.debt.mint);\n\n const initialAccounts = await account.getCarryTradeAccounts(\n token,\n params.yieldingBank,\n params.lendingPositionIndex\n );\n\n if (params.permissionlessOperation && params.sourceMint !== undefined) {\n throw new Error(\n \"DecreaseCarryPositionBuilderParams: sourceMint must not be set when permissionlessOperation is true\"\n );\n }\n\n params.lendingIx.clearCacheEntry(\n params.lendingIx.data.userAccountCatKey,\n fromWeb3Pk(position.protocolUserAcc)\n );\n const manager = await LycLendingPositionManager.create(\n params.lendingIx.data,\n position,\n params.environment\n );\n\n const { targetUtilizationBps, passTargetUtilizationOnChain } =\n await resolveRepaySteeringUtilization(manager, position, params.repaySteering);\n\n const bank = await account.fetchYieldingBank(params.yieldingBank);\n const { swapContext, sourceAssetHoldingIndex, needsSwapPath } = resolveSwapContext(\n swap,\n signer,\n params,\n bank,\n debtMint\n );\n\n const { supplyReserve, debtReserve } = manager.reservesManager;\n const positionState = await manager.getLendingPositionAmounts();\n const txId = params.txId ?? `decrease-carry-${Date.now()}-${position.protocolUserAcc.toBase58()}`;\n\n const isFullDeleverage =\n params.repaySteering?.mode === \"explicitTargetUtilization\" &&\n params.repaySteering.targetUtilizationRateBps === 0;\n\n const repayBaseUnitsOverride = isFullDeleverage\n ? await resolveFullDeleverageRepayBaseUnits(\n params.lendingIx.data,\n position,\n debtReserve,\n manager\n )\n : undefined;\n\n const leverageResult = await LeverageService.buildDecreaseLeverage(\n {\n lendingIx: params.lendingIx,\n supplyReserve,\n debtReserve,\n user: token,\n payer: signer,\n pool: fromWeb3Pk(position.pool),\n userAccount: fromWeb3Pk(position.protocolUserAcc),\n txId,\n environment: params.environment,\n },\n {\n currentSupplyUiAmount: positionState.supplyUiAmount,\n currentDebtUiAmount: positionState.debtUiAmount,\n targetUtilizationRateBps: targetUtilizationBps,\n swapContext,\n repayBaseUnitsOverride,\n }\n );\n\n return {\n lendingPositionIndex: params.lendingPositionIndex,\n repayAmount: leverageResult.repayBaseUnits,\n preInstructions: leverageResult.preInstructions,\n initialAccounts,\n cpiDataGroups: leverageResult.cpiDataGroups,\n ...(leverageResult.prerequisiteCpis.length\n ? { tokenPrerequisiteCpis: leverageResult.prerequisiteCpis }\n : {}),\n ...(passTargetUtilizationOnChain ? { targetUtilizationRateBps: targetUtilizationBps } : {}),\n yieldingBank: params.yieldingBank,\n ...(needsSwapPath && sourceAssetHoldingIndex != null ? { sourceAssetHoldingIndex } : {}),\n };\n}\n\n/**\n * Sizes a full repay from the refreshed Kamino obligation borrow (+ buffer), not\n * stale token accounting, so the SPL transfer and repay CPI stay in sync.\n */\nasync function resolveFullDeleverageRepayBaseUnits(\n lpData: LendingPlatformData,\n position: TokenLendingPositionData,\n debtReserve: ReserveBase,\n manager: LycLendingPositionManager\n): Promise<BN> {\n const pool = fromWeb3Pk(position.pool);\n const userAccount = fromWeb3Pk(position.protocolUserAcc);\n const obligation = await lpData.maybeFetchUserPositionInPool(pool, userAccount);\n const borrow = obligation?.borrows.find((entry) => entry.reserve === debtReserve.address);\n\n const fallbackUi = (await manager.getLendingPositionAmounts()).debtUiAmount;\n const fallbackBaseUnits = fromUiAmount(fallbackUi, debtReserve.mint.mintDecimals);\n if (!borrow) {\n return fallbackBaseUnits;\n }\n\n // Kamino obligation debt can exceed stale token accounting by accrued interest\n // (often 1 base unit on tiny positions). Size the SPL transfer and repay CPI\n // from the refreshed obligation borrow, not the token snapshot alone.\n return borrow.amount.gt(fallbackBaseUnits) ? borrow.amount : fallbackBaseUnits;\n}\n\n/**\n * Resolves the utilization target (bps) for leverage sizing and whether that same\n * bps should appear on-chain as `targetUtilizationRateBps` for manager post-repay checks.\n */\nasync function resolveRepaySteeringUtilization(\n manager: LycLendingPositionManager,\n position: TokenLendingPositionData,\n steering?: DecreaseCarryRepaySteering\n) {\n if (!steering) {\n return {\n targetUtilizationBps: position.config.targetUtilizationRateBps,\n passTargetUtilizationOnChain: false,\n };\n }\n\n switch (steering.mode) {\n case \"collateralWithdrawal\": {\n const postWithdrawalTargetUtilizationRateBps =\n steering.postWithdrawalTargetUtilizationRateBps ?? position.config.targetUtilizationRateBps;\n const targetUtilizationBps = await manager.calcPreWithdrawalTargetUtilizationRateBps(\n steering.collateralWithdrawalUiAmount,\n postWithdrawalTargetUtilizationRateBps\n );\n return {\n targetUtilizationBps,\n passTargetUtilizationOnChain: steering.allowBelowTargetOnChain === true,\n };\n }\n case \"explicitTargetUtilization\":\n return {\n targetUtilizationBps: steering.targetUtilizationRateBps,\n passTargetUtilizationOnChain: true,\n };\n default: {\n throw new Error(`Unexpected repaySteering: ${JSON.stringify(steering)}`);\n }\n }\n}\n\n/**\n * Swap context when the yielding bank's source asset differs from the debt mint.\n */\nfunction resolveSwapContext(\n swap: SwapClient,\n signer: Address,\n params: DecreaseCarryPositionBuilderParams,\n bank: LYCYieldingBank,\n debtMint: Address\n): {\n swapContext: LeverageSwapContext | undefined;\n sourceAssetHoldingIndex: number | null;\n needsSwapPath: boolean;\n} {\n const sourceMint = params.sourceMint ?? bank.defaultRedemptionMint;\n const sourceAssetHoldingIndex = bank.findAssetHoldingIndex(sourceMint);\n const needsSwapPath = sourceAssetHoldingIndex != null && sourceMint !== debtMint;\n\n if (!needsSwapPath) {\n return { swapContext: undefined, sourceAssetHoldingIndex, needsSwapPath };\n }\n\n const sourceHolding = bank.findAssetHolding(sourceMint);\n\n return {\n swapContext: {\n swap,\n sourceMint,\n debtMint,\n sourceBalanceBaseUnits: sourceHolding ? BigInt(sourceHolding.amount.toString()) : 0n,\n swapTarget: params.yieldingBank,\n payer: signer,\n slippageBps: params.swapSlippageBps,\n excludeDexes: params.swapExcludeDexes,\n },\n sourceAssetHoldingIndex,\n needsSwapPath,\n };\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { TransactionCacheInvalidation } from \"common\";\nimport type {\n DecreaseCarryPositionTxBuilderParams,\n DecreaseCarryPositionTxParams,\n LongYieldCarryTransactionPlan,\n} from \"../types\";\nimport type { LongYieldCarryBuilderContext } from \"../types/builders\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { DecreaseCarryPositionIxArgs, DecreaseCarryPositionTxArgs } from \"./args\";\nimport { getLendingUserAccountCacheInvalidation } from \"lending-platforms\";\nimport {\n getCreateAtaInstructions,\n requestHeapFrameIx,\n toKitInstruction,\n toWeb3AccountMeta,\n fromWeb3Pk,\n} from \"common\";\nimport { buildDecreaseCarryPositionPlan } from \"../plans/decreaseCarryPosition\";\nimport { MAX_HEAP_FRAME_BYTES } from \"../../constants/general\";\nimport {\n getTokenCacheInvalidation,\n getYieldingBankCacheInvalidation,\n type ResolvedDecreaseCarryCpiPlan,\n resolveDecreaseCarryCpiPlan,\n} from \"../../utils\";\n\nexport type { ResolvedDecreaseCarryCpiPlan } from \"../../utils\";\n\n/**\n * Options for {@link DecreaseCarryPositionBuilder.buildTx}. Supports pre-merged CPI accounts\n * and custom heap size.\n */\nexport type DecreaseCarryPositionBuildTxOptions = {\n includePreInstructions: boolean;\n /** Defaults to {@link MAX_HEAP_FRAME_BYTES}. */\n heapFrameBytes?: number;\n /**\n * When set, skips internal {@link resolveDecreaseCarryCpiPlan}(plan). Use when remaining\n * accounts already include additional CPI account slots (e.g. lending withdraw merged for burn).\n */\n resolvedCpiPlan?: ResolvedDecreaseCarryCpiPlan;\n /** When set, the DCP loss is attributed to this epoch instead of socialised into the price. */\n redemptionEpoch?: Address;\n};\n\nexport class DecreaseCarryPositionBuilder extends LongYieldCarryBuilderBase<\n DecreaseCarryPositionIxArgs,\n DecreaseCarryPositionTxArgs\n> {\n constructor(context: LongYieldCarryBuilderContext) {\n super(context);\n }\n\n async getIx(args: DecreaseCarryPositionIxArgs): Promise<Instruction> {\n return this.program.methods\n .decreaseCarryPosition({\n prerequisiteCpis: args.params.prerequisiteCpis ?? null,\n targetUtilizationRateBps: args.params.targetUtilizationRateBps ?? null,\n ybIxRefs: args.params.ybIxRefs ?? null,\n tokenIxRefs: args.params.tokenIxRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n repayAmount: args.params.repayAmount ?? null,\n sourceAssetHoldingIndex: args.params.sourceAssetHoldingIndex ?? null,\n })\n .accountsPartial({\n signer: args.signer,\n redemptionEpoch: args.params.redemptionEpoch ?? null,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: DecreaseCarryPositionTxArgs): Promise<LongYieldCarryTransactionPlan> {\n return this.buildTx(args.signer, args.token, args.params, {\n includePreInstructions: true,\n redemptionEpoch: args.redemptionEpoch,\n });\n }\n\n async buildTx(\n signer: Address,\n token: Address,\n params: DecreaseCarryPositionTxParams,\n options: DecreaseCarryPositionBuildTxOptions\n ): Promise<LongYieldCarryTransactionPlan> {\n const plan = \"plan\" in params ? params.plan : await this.buildPlan(signer, token, params);\n const tokenData = await this.account.fetchToken(token);\n const position = tokenData.data.lendingPositions[plan.lendingPositionIndex];\n const instructions: Instruction[] = [];\n\n if (options.includePreInstructions) {\n instructions.push(...plan.preInstructions);\n }\n\n const {\n accounts: remainingAccounts,\n prerequisiteCpis,\n tokenIxRefs,\n ybIxRefs,\n lookupTables,\n } = options.resolvedCpiPlan ?? resolveDecreaseCarryCpiPlan(plan);\n\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations: ataPostSuccess } =\n await getCreateAtaInstructions(this.rpc, signer, remainingAccounts);\n instructions.push(...ataCreationIxs);\n const decreaseCarryIx = await this.getIx({\n signer,\n params: {\n prerequisiteCpis,\n targetUtilizationRateBps: plan.targetUtilizationRateBps,\n ybIxRefs,\n tokenIxRefs,\n lendingPositionIndex: plan.lendingPositionIndex,\n ...(plan.omitOnChainRepayAmount ? {} : { repayAmount: plan.repayAmount }),\n sourceAssetHoldingIndex: plan.sourceAssetHoldingIndex,\n redemptionEpoch: options.redemptionEpoch,\n remainingAccounts,\n },\n });\n if (options.includePreInstructions) {\n // Heap configuration applies only to its transaction, so keep it\n // adjacent to and indivisible from the CPI-heavy instruction. Earlier\n // refresh and ATA setup instructions remain available to the splitter.\n instructions.push(\n requestHeapFrameIx(options.heapFrameBytes ?? MAX_HEAP_FRAME_BYTES),\n decreaseCarryIx\n );\n } else {\n instructions.push(decreaseCarryIx);\n }\n\n const postSuccessCacheInvalidations: TransactionCacheInvalidation[] = [\n getTokenCacheInvalidation(token),\n getYieldingBankCacheInvalidation(plan.yieldingBank),\n getLendingUserAccountCacheInvalidation(fromWeb3Pk(position.protocolUserAcc)),\n ...ataPostSuccess,\n ];\n\n return {\n instructions,\n lookupTables: this.getTxLookupTables(token, lookupTables ?? []),\n segmentLengths: options.includePreInstructions\n ? [...instructions.slice(0, -2).map(() => 1), 2]\n : undefined,\n postSuccessCacheInvalidations,\n };\n }\n\n async buildPlan(signer: Address, token: Address, params: DecreaseCarryPositionTxBuilderParams) {\n const tokenData = await this.account.fetchToken(token);\n const position = tokenData.data.lendingPositions[params.lendingPositionIndex];\n const lpClient = this.getLendingPlatformClient(position);\n\n return buildDecreaseCarryPositionPlan(this.account, this.swap, signer, token, {\n ...params,\n lendingIx: lpClient.ix,\n environment: this.context.environment,\n });\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { DepositUnlentCollateralIxArgs, DepositUnlentCollateralTxArgs } from \"./args\";\nimport {\n createCpiRefs,\n fromWeb3Pk,\n getCreateAtaInstructions,\n resolveTokenProgram,\n toKitInstruction,\n toUiAmount,\n toWeb3AccountMeta,\n} from \"common\";\n\nexport class DepositUnlentCollateralBuilder extends LongYieldCarryBuilderBase<\n DepositUnlentCollateralIxArgs,\n DepositUnlentCollateralTxArgs\n> {\n async getIx(args: DepositUnlentCollateralIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const position = tokenData.data.lendingPositions[args.params.lendingPositionIndex];\n const collateralMint = fromWeb3Pk(tokenData.data.collateral.mint);\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n\n return this.program.methods\n .depositUnlentCollateral(args.params.ixRefs, args.params.lendingPositionIndex)\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n collateralMint,\n collateralTokenProgram,\n lendingPositionUserAccount: position ? fromWeb3Pk(position.protocolUserAcc) : args.token,\n lendingPositionCollateralReserve: position\n ? fromWeb3Pk(position.collateralReserve)\n : args.token,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: DepositUnlentCollateralTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const tokenData = await this.account.fetchToken(args.token, { fresh: args.params.depositAll });\n const position = tokenData.data.lendingPositions[args.params.lendingPositionIndex];\n const uiAmount = args.params.depositAll\n ? toUiAmount(tokenData.data.collateral.unlentAmount, tokenData.data.collateral.decimals)\n : args.params.uiAmount!;\n\n if (args.params.depositAll && uiAmount === 0) {\n throw new Error(\n `depositAll: unlentAmount is 0 on token ${args.token} (raw: ${tokenData.data.collateral.unlentAmount})`\n );\n }\n\n const txId =\n args.params.txId ??\n `deposit-unlent-collateral-${Date.now()}-${position.protocolUserAcc.toBase58()}`;\n const manager = this.resolveTokenManager(tokenData.data);\n const cpiBundle = await this.getLendingOperationCpiData(\n args.token,\n manager,\n position,\n txId,\n \"deposit\",\n uiAmount\n );\n const {\n accounts: remainingAccounts,\n refs: ixRefs,\n lookupTables,\n } = createCpiRefs(cpiBundle.allCpis);\n const lpClient = this.getLendingPlatformClient(position);\n const preInstructions = await lpClient.ix.getPreInstructions(txId);\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations } =\n await getCreateAtaInstructions(this.rpc, args.manager, remainingAccounts);\n const depositIx = await this.getIx({\n token: args.token,\n params: {\n ixRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n remainingAccounts,\n },\n });\n\n return {\n instructions: [...preInstructions, ...ataCreationIxs, depositIx],\n lookupTables: this.getTxLookupTables(args.token, lookupTables ?? []),\n postSuccessCacheInvalidations: [\n ...cpiBundle.postSuccessCacheInvalidations,\n ...postSuccessCacheInvalidations,\n ],\n txId,\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { IncreaseCarryPositionIxArgs, IncreaseCarryPositionTxArgs } from \"./args\";\nimport {\n createMultiCpiRefs,\n fromWeb3Pk,\n getCreateAtaInstructions,\n toKitInstruction,\n toWeb3AccountMeta,\n} from \"common\";\nimport { NoOpTransactionError } from \"../../errors\";\nimport { getTokenCacheInvalidation, getYieldingBankCacheInvalidation } from \"../../utils\";\nimport { getLendingUserAccountCacheInvalidation } from \"lending-platforms\";\nimport { RefreshYieldingBankBuilder } from \"./refreshYieldingBankBuilder\";\n\nexport class IncreaseCarryPositionBuilder extends LongYieldCarryBuilderBase<\n IncreaseCarryPositionIxArgs,\n IncreaseCarryPositionTxArgs\n> {\n async getIx(args: IncreaseCarryPositionIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n return this.program.methods\n .increaseCarryPosition({\n prerequisiteCpis: args.params.prerequisiteCpis ?? null,\n ixRefs: args.params.ixRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n })\n .accountsPartial({ manager: this.resolveTokenManager(tokenData.data) })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: IncreaseCarryPositionTxArgs): Promise<LongYieldCarryTransactionPlan> {\n if (!Number.isFinite(args.params.uiAmount) || args.params.uiAmount <= 0) {\n throw new NoOpTransactionError(\n `Invalid uiAmount for increase carry position: ${args.params.uiAmount} (must be a positive finite number)`\n );\n }\n\n const tokenData = await this.account.fetchToken(args.token);\n const position = tokenData.data.lendingPositions[args.params.lendingPositionIndex];\n const carryTradeAccounts = await this.account.getCarryTradeAccounts(\n args.token,\n args.params.yieldingBank,\n args.params.lendingPositionIndex\n );\n const txId =\n args.params.txId ?? `increase-carry-${Date.now()}-${position.protocolUserAcc.toBase58()}`;\n const lpClient = this.getLendingPlatformClient(position);\n const manager = this.resolveTokenManager(tokenData.data);\n const { prerequisiteCpis, cpis, postSuccessCacheInvalidations } =\n await this.getLendingOperationCpiData(\n args.token,\n manager,\n position,\n txId,\n \"borrow\",\n args.params.uiAmount\n );\n const {\n accounts: remainingAccounts,\n refsGroups,\n lookupTables,\n } = createMultiCpiRefs(prerequisiteCpis.length ? [prerequisiteCpis, cpis] : [cpis], {\n initialAccounts: carryTradeAccounts,\n });\n const prerequisiteCpiRefs = prerequisiteCpis.length ? refsGroups[0] : undefined;\n const ixRefs = refsGroups[prerequisiteCpis.length ? 1 : 0];\n const preInstructions = await lpClient.ix.getPreInstructions(txId);\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations: ataCreationCacheInv } =\n await getCreateAtaInstructions(this.rpc, args.manager, remainingAccounts);\n const refreshYieldingBankPlan = await new RefreshYieldingBankBuilder(this.context).getTx({\n signer: args.manager,\n yieldingBank: args.params.yieldingBank,\n });\n\n return {\n instructions: [\n ...preInstructions,\n ...ataCreationIxs,\n ...refreshYieldingBankPlan.instructions,\n await this.getIx({\n token: args.token,\n params: {\n prerequisiteCpis: prerequisiteCpiRefs,\n ixRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n remainingAccounts,\n },\n }),\n ],\n lookupTables: this.getTxLookupTables(args.token, lookupTables ?? []),\n postSuccessCacheInvalidations: [\n getTokenCacheInvalidation(args.token),\n getYieldingBankCacheInvalidation(args.params.yieldingBank),\n getLendingUserAccountCacheInvalidation(fromWeb3Pk(position.protocolUserAcc)),\n ...postSuccessCacheInvalidations,\n ...ataCreationCacheInv,\n ],\n txId,\n };\n }\n}\n","import { BN } from \"@anchor-lang/core\";\nimport type { Instruction } from \"@solana/kit\";\nimport {\n createMultiCpiRefs,\n enumToOracleType,\n type CpiData,\n fromWeb3Pk,\n getCreateAtaInstructions,\n getCreateAtaIxIfNeeded,\n mints,\n requestHeapFrameIx,\n toKitInstruction,\n toUiAmount,\n toWeb3AccountMeta,\n} from \"common\";\nimport { oracle } from \"oracle\";\nimport {\n LeverageService,\n type FlashRebalanceContext,\n type FlashRebalanceResult,\n} from \"lending-platforms\";\nimport {\n getTokenCacheInvalidation,\n getYieldingBankCacheInvalidation,\n mergeLycLookupTables,\n} from \"../../utils\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport type { TokenLendingPositionData } from \"../../models/lycToken\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { RebalanceTokenIxArgs, RebalanceTokenTxArgs } from \"./args\";\nimport { MAX_HEAP_FRAME_BYTES } from \"../../constants/general\";\nimport { RefreshYieldingBankBuilder } from \"./refreshYieldingBankBuilder\";\nimport { CreateCpiPlanBuilder } from \"./createCpiPlanBuilder\";\n\nexport class RebalanceTokenBuilder extends LongYieldCarryBuilderBase<\n RebalanceTokenIxArgs,\n RebalanceTokenTxArgs\n> {\n async getIx(args: RebalanceTokenIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n\n return this.program.methods\n .rebalanceToken({\n lpIndex: args.params.lpIndex,\n destinationDebtOracleType: args.params.destinationDebtOracleType,\n flashFeeAmount: args.params.flashFeeAmount,\n repayAmount: args.params.repayAmount,\n })\n .accountsPartial({\n manager: this.resolveTokenManager(tokenData.data),\n cpiPlan: args.params.cpiPlan,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: RebalanceTokenTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const tokenData = await this.account.fetchToken(args.token);\n const { lpIndex, destinationDebtMint } = args.params;\n const position = tokenData.data.lendingPositions[lpIndex];\n if (!position) {\n throw new Error(`rebalance_token: no lending position at index ${lpIndex}`);\n }\n const txId = args.params.txId ?? `rebalance-token-${Date.now()}`;\n const yieldingBank =\n args.params.yieldingBank ?? (await tokenData.resolveFirstYieldingBankAddress(this.pda));\n const lpClient = this.getLendingPlatformClient(position);\n const pool = fromWeb3Pk(position.pool);\n const withdrawAll = args.params.uiAmount === \"all\";\n const collateralUiAmount =\n args.params.uiAmount === \"all\"\n ? toUiAmount(position.accounting.collateral, tokenData.data.collateral.decimals)\n : args.params.uiAmount;\n\n // Fetch source debt reserve (by address), supply reserve (by address), and\n // destination debt reserve (by mint, since the position currently holds the old mint).\n const [sourceDebtReserve, supplyReserve, destDebtReserve] = await Promise.all([\n lpClient.data.fetchReserve(pool, fromWeb3Pk(position.debtReserve)),\n lpClient.data.fetchReserve(pool, fromWeb3Pk(position.collateralReserve)),\n lpClient.data.fetchReserveByMint(pool, destinationDebtMint),\n ]);\n if (!sourceDebtReserve || !supplyReserve || !destDebtReserve) {\n throw new Error(\"rebalance_token: failed to fetch one or more lending-position reserves\");\n }\n\n const manager = this.resolveTokenManager(tokenData.data);\n const flashLoan = lpClient.getFlashLoan();\n const userAccount = fromWeb3Pk(position.protocolUserAcc);\n\n // Both legs operate on the same position: supply never moves, only debt mint changes.\n const flashContext: FlashRebalanceContext = {\n source: {\n lendingIx: lpClient.ix,\n supplyReserve,\n debtReserve: sourceDebtReserve,\n pool,\n userAccount,\n },\n destination: {\n lendingIx: lpClient.ix,\n supplyReserve,\n debtReserve: destDebtReserve,\n pool,\n userAccount,\n },\n flashLoan,\n swap: this.swap,\n user: args.token,\n payer: manager,\n txId,\n environment: this.environment,\n };\n\n const flash = await this.buildFlashRebalanceOrSkip(flashContext, {\n collateralUiAmount,\n sourceTargetUtilizationRateBps: position.config.targetUtilizationRateBps,\n destinationMaxUtilizationRateBps: this.maxPostRebalanceUtilizationBps(position),\n swapSlippageBps: args.params.swapSlippageBps,\n maxSwapCostBps: args.params.maxSwapCostBps,\n maxMarketBasisBps: args.params.maxMarketBasisBps,\n withdrawAll,\n });\n\n const destDebtOracleData = oracle.getOracleData(destinationDebtMint);\n if (!destDebtOracleData) {\n throw new Error(\n `rebalance_token: no oracle registered for destination debt mint ${destinationDebtMint}`\n );\n }\n const destDebtOracle = destDebtOracleData.oracle;\n const destDebtOracleType = enumToOracleType(destDebtOracleData.oracleType);\n\n const initialAccounts = await this.account.getRebalanceTokenInitialAccounts(\n args.token,\n yieldingBank,\n lpIndex,\n destDebtOracle,\n args.params.lpPosition\n );\n\n // Pack all inner CPIs into one remaining-accounts pool that starts with\n // the rebalance-token initial accounts. CPIs that reference the token,\n // yielding bank, ATAs, or LP refresh accounts deduplicate against these\n // fixed slots — shrinking the transaction's account list.\n // The new debt reserve is tracked in the borrow ref (tracked[0]) so the\n // on-chain handler can update the destination lending position's\n // debt_reserve in place without an extra instruction parameter.\n const cpiGroups = this.collectFlashCpiGroups(flash);\n const {\n accounts: remainingAccounts,\n refsGroups,\n lookupTables,\n } = createMultiCpiRefs(cpiGroups.groups, {\n initialAccounts,\n trackAddresses: [destDebtReserve.address, destinationDebtMint],\n });\n const refs = cpiGroups.indices;\n const planRefs = [\n refsGroups[refs.sourceRepay],\n refsGroups[refs.destinationBorrow],\n refsGroups[refs.swap],\n ];\n\n const { instructions: ataCreationIxs, postSuccessCacheInvalidations: ataPostSuccess } =\n await getCreateAtaInstructions(this.rpc, manager, remainingAccounts);\n\n // The Kamino destination borrow CPI sets `user_destination_liquidity` to\n // the token PDA's destination-debt ATA. When the token has never held\n // that mint, the ATA is missing and Kamino fails with\n // `AccountNotInitialized` (Anchor 3012). The borrow's account meta does\n // carry an `isRequiredAta` seed, but `buildDeduplicatedPool` only\n // preserves the first occurrence's flag — if the same address shows up\n // earlier without seeds, the create-ATA pass above silently skips it.\n // Add an explicit idempotent create here so the destination debt ATA is\n // guaranteed to exist before the rebalance ix runs.\n // TODO: fix `buildDeduplicatedPool` to merge `isRequiredAta` flags\n // across duplicate occurrences instead of keeping only the first, then\n // remove this per-builder workaround. We resolve the mint's\n // token program through the same `mints` registry Kamino's\n // `reserveInteractionDetails` uses (kamino.ts → `liquidityMintTokenProgram`)\n // so the ATA address we create matches the one Kamino derives.\n const destDebtMintInfo = mints.get(destinationDebtMint);\n if (!destDebtMintInfo) {\n throw new Error(\n `RebalanceTokenBuilder: destination debt mint ${destinationDebtMint} not found in mint registry`\n );\n }\n const { instruction: destDebtAtaIx, postSuccessCacheInvalidations: destDebtAtaPostSuccess } =\n await getCreateAtaIxIfNeeded(\n this.rpc,\n manager,\n destinationDebtMint,\n args.token,\n destDebtMintInfo.tokenProgram\n );\n\n // The on-chain handler calls `verify_price_is_fresh` on the bank, so we\n // only need to prepend a refresh when the cached `lastRefreshedTs` is\n // outside the staleness window.\n const yieldingBankAccount = await this.account.fetchYieldingBank(yieldingBank);\n const refreshYieldingBankInstructions = yieldingBankAccount.isStale\n ? (\n await new RefreshYieldingBankBuilder(this.context).getTx({\n signer: manager,\n yieldingBank,\n })\n ).instructions\n : [];\n\n // For a full-position move (`withdrawAll`), send Kamino's `u64::MAX`\n // \"repay all\" sentinel so the on-chain `RepayObligationLiquidityV2` CPI\n // clears the obligation's actual debt exactly — interest accrual between\n // the off-chain snapshot and bundle landing can't leave dust that trips\n // `NetValueRemainingTooSmall` (klend error 6092). The flash-borrow is\n // over-borrowed by 5 bps in `LeverageService.buildFlashRebalance` to\n // cover that drift; the post-repay surplus is swept into the yielding\n // bank.\n //\n // For a partial rebalance, the flash-borrow only covers `sourceRepay`\n // (sized to bring source utilization back to target) — sending\n // `u64::MAX` would tell Kamino to repay the full obligation debt and\n // the ATA would underfund the SPL transfer (custom 0x1 insufficient\n // funds). Repay exactly what we flash-borrowed so the ATA balance\n // matches the requested CPI amount.\n const repayAllSentinel = lpClient.getRepayAllSentinel();\n if (withdrawAll && !repayAllSentinel) {\n throw new Error(\n \"RebalanceTokenBuilder: source lending platform does not expose a repay-all sentinel; cannot build a withdrawAll rebalance\"\n );\n }\n const repayAmount =\n withdrawAll && repayAllSentinel ? repayAllSentinel : flash.flashBorrowAmountBaseUnits;\n const cpiPlanCreatedTs = new BN(Math.floor(Date.now() / 1000));\n const [cpiPlan] = await this.pda.deriveCpiPlanPda(\n args.token,\n BigInt(cpiPlanCreatedTs.toString())\n );\n const createCpiPlanIx = await new CreateCpiPlanBuilder(this.context).getIx({\n manager,\n cpiPlan,\n params: {\n uniqueId: args.token,\n createdTs: cpiPlanCreatedTs,\n refs: planRefs,\n },\n });\n const rebalanceIx = await this.getIx({\n token: args.token,\n params: {\n lpIndex,\n destinationDebtOracleType: destDebtOracleType,\n flashFeeAmount: flash.flashFeeBaseUnits,\n repayAmount,\n cpiPlan,\n remainingAccounts,\n },\n });\n\n const mergedLookupTables = mergeLycLookupTables(\n this.context.environment,\n args.token,\n lookupTables ?? []\n );\n const preambleInstructions = [\n ...flash.preInstructions,\n ...ataCreationIxs,\n ...(destDebtAtaIx ? [destDebtAtaIx] : []),\n ...refreshYieldingBankInstructions,\n ];\n\n // The flash group must ride atomically in one tx — Kamino's flash-borrow\n // introspects its own tx's instructions sysvar to find the matching\n // flash-repay (`flash_ixs.rs:NoFlashRepayFound`). We also need its\n // position inside that tx to be predictable so the `borrowInstructionIndex`\n // we encode here matches what Kamino sees at runtime. Marking the group\n // as one indivisible segment AND forcing it to start a fresh bin pins\n // the borrow at index 1 (after the heap-frame ix at index 0), regardless\n // of how the preamble packs.\n const flashBorrowIxIndex = 1;\n const flashRepayIx = await LeverageService.buildFlashRepayIx(\n flashContext,\n flash,\n flashBorrowIxIndex\n );\n const flashGroup = [\n requestHeapFrameIx(MAX_HEAP_FRAME_BYTES),\n flash.flashBorrowIx,\n rebalanceIx,\n flashRepayIx,\n ];\n\n // Each preamble ix is its own segment (length 1), followed by the CPI plan\n // creation, followed by the flash cycle as one indivisible segment of\n // length 4. Scope refresh-price instructions must remain first in their tx,\n // so the CPI plan creation cannot precede lending-platform pre-instructions.\n const segmentLengths = [...preambleInstructions.map(() => 1), 1, flashGroup.length];\n const flashSegmentIndex = preambleInstructions.length + 1;\n\n return {\n instructions: [...preambleInstructions, createCpiPlanIx, ...flashGroup],\n lookupTables: mergedLookupTables,\n segmentLengths,\n freshBinSegments: [flashSegmentIndex],\n postSuccessCacheInvalidations: [\n getTokenCacheInvalidation(args.token),\n getYieldingBankCacheInvalidation(yieldingBank),\n ...ataPostSuccess,\n ...destDebtAtaPostSuccess,\n ...flash.postSuccessCacheInvalidations,\n ],\n };\n }\n\n private maxPostRebalanceUtilizationBps(position: TokenLendingPositionData): number {\n return (\n position.config.targetUtilizationRateBps + position.config.maxDeviationAboveTargetUtilBps\n );\n }\n\n private async buildFlashRebalanceOrSkip(\n context: FlashRebalanceContext,\n params: Parameters<typeof LeverageService.buildFlashRebalance>[1]\n ): Promise<FlashRebalanceResult> {\n return await LeverageService.buildFlashRebalance(context, params);\n }\n\n private collectFlashCpiGroups(flash: FlashRebalanceResult): {\n groups: CpiData[][];\n indices: {\n sourceRepay: number;\n destinationBorrow: number;\n swap: number;\n };\n } {\n // Each op's prereqs (reserve + obligation refreshes) stay bundled with\n // that op. Kamino marks both the obligation AND any written reserves\n // stale after a write op, so the next op's RefreshObligation needs all\n // its referenced reserves re-refreshed before it can pass — we can't\n // dedup `RefreshReserve` CPIs across bundles, even within a single slot.\n const groups: CpiData[][] = [];\n const indices = {} as {\n sourceRepay: number;\n destinationBorrow: number;\n swap: number;\n };\n indices.sourceRepay = groups.length;\n groups.push(flash.sourceRepayCpis);\n indices.destinationBorrow = groups.length;\n groups.push(flash.destinationBorrowCpis);\n indices.swap = groups.length;\n groups.push(flash.swapCpis);\n\n return { groups, indices };\n }\n}\n","import type { Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { RebalanceYieldingBankIxArgs, RebalanceYieldingBankTxArgs } from \"./args\";\nimport {\n SYSTEM_PROGRAM_META,\n type CpiData,\n createCpiRefs,\n getCreateAtaInstructions,\n toKitInstruction,\n toWeb3AccountMeta,\n} from \"common\";\nimport { getYieldingBankCacheInvalidation } from \"../../utils\";\nimport { CreateYieldingBankAllocationBuilder } from \"./createYieldingBankAllocationBuilder\";\n\nexport class RebalanceYieldingBankBuilder extends LongYieldCarryBuilderBase<\n RebalanceYieldingBankIxArgs,\n RebalanceYieldingBankTxArgs\n> {\n async getIx(args: RebalanceYieldingBankIxArgs): Promise<Instruction> {\n const bankData = await this.account.fetchYieldingBank(args.yieldingBank);\n return this.program.methods\n .rebalanceYieldingBank(args.params.ixRefs)\n .accountsPartial({\n manager: this.resolveYieldingBankManager(bankData.data),\n yieldingBank: args.yieldingBank,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: RebalanceYieldingBankTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const bankData = await this.account.fetchYieldingBank(args.yieldingBank);\n const manager = this.resolveYieldingBankManager(bankData.data);\n const resolvedCpiData: CpiData[] = [...(args.params.cpiData ?? [])];\n if (args.params.swaps?.length) {\n const swapCpiData = await Promise.all(\n args.params.swaps.map(async (swap) => {\n const swapClient = swap.swapClient ?? this.swap;\n const quote = await swapClient.getQuote({\n inputMint: swap.inputMint,\n outputMint: swap.outputMint,\n amount: swap.amount,\n slippageBps: swap.slippageBps ?? 50,\n });\n return swapClient.getSwapCpiData(quote, args.yieldingBank, { payer: manager });\n })\n );\n resolvedCpiData.push(...swapCpiData);\n }\n\n const { externalLiquiditySources, postSuccessCacheInvalidations: refreshCacheInvalidations } =\n await this.externalLiquidityResolver.resolveYieldingBankRefreshExternalLiquidity(\n this.account,\n args.yieldingBank,\n resolvedCpiData\n );\n const oracleAccounts = await this.account.getYieldingBankRefreshAccounts(\n args.yieldingBank,\n args.params.newAllocation?.config,\n externalLiquiditySources\n );\n const {\n accounts: remainingAccounts,\n refs: ixRefs,\n lookupTables,\n } = createCpiRefs(resolvedCpiData, {\n initialAccounts: [...oracleAccounts, SYSTEM_PROGRAM_META],\n });\n const preamble: Instruction[] = [];\n if (args.params.newAllocation) {\n preamble.push(\n await new CreateYieldingBankAllocationBuilder(this.context).getIx({\n yieldingBank: args.yieldingBank,\n config: args.params.newAllocation.config,\n })\n );\n }\n const { instructions, postSuccessCacheInvalidations } = await getCreateAtaInstructions(\n this.rpc,\n manager,\n remainingAccounts\n );\n const swapPreInstructions = resolvedCpiData.flatMap((cpi) => cpi.preInstructions ?? []);\n\n return {\n instructions: [\n ...swapPreInstructions,\n ...instructions,\n ...preamble,\n await this.getIx({\n yieldingBank: args.yieldingBank,\n params: {\n ixRefs,\n remainingAccounts,\n },\n }),\n ],\n lookupTables: this.getTxLookupTables(undefined, lookupTables ?? []),\n postSuccessCacheInvalidations: [\n getYieldingBankCacheInvalidation(args.yieldingBank),\n ...resolvedCpiData.flatMap((cpi) => cpi.postSuccessCacheInvalidations ?? []),\n ...refreshCacheInvalidations,\n ...postSuccessCacheInvalidations,\n ],\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { RecollateralizeLossIxArgs, RecollateralizeLossTxArgs } from \"./args\";\nimport { NoOpTransactionError } from \"../../errors\";\nimport { DecreaseCarryPositionBuilder } from \"./decreaseCarryPositionBuilder\";\nimport {\n type SwapQuote,\n createMultiCpiRefs,\n fromWeb3Pk,\n getAtaAddress,\n getCreateAtaInstructions,\n requestHeapFrameIx,\n resolveTokenProgram,\n toBigInt,\n toKitInstruction,\n toUiAmount,\n toWeb3AccountMeta,\n tvlUsdToBaseUnits,\n} from \"common\";\nimport { getLendingUserAccountCacheInvalidation } from \"lending-platforms\";\nimport {\n DEFAULT_RECOLLATERALIZE_LOSS_SLIPPAGE_BPS,\n MAX_HEAP_FRAME_BYTES,\n} from \"../../constants/general\";\nimport { LycLendingPositionManager } from \"../../services/carry\";\nimport { getTokenCacheInvalidation } from \"../../utils\";\nimport type { LYCToken, TokenLendingPositionData } from \"../../models/lycToken\";\n\ninterface RecollateralizationTarget {\n tokenData: LYCToken;\n totalDebtUsd: bigint;\n totalCarryUsd: bigint;\n lendingPositionIndex: number;\n position: TokenLendingPositionData;\n yieldingBank: Address;\n}\n\ninterface RecollateralizationSwapPlan {\n collateralToWithdrawUi: number;\n repayUiAmount: number;\n repayBaseUnits: bigint;\n swapQuote: SwapQuote;\n}\n\n// Extra repay (bps of the measured deficit) to offset swap costs and oracle\n// drift, which also scale with the swap size. On-chain only requires the\n// deficit to strictly shrink, so an undershoot just leaves a dust residual\n// for the next run; any surplus (carry > debt) must stay within the on-chain\n// RECOLLATERALIZE_LOSS_THRESHOLD_BPS (20 bps of debt) ceiling.\nconst RECOLLATERALIZE_LOSS_OVERSHOOT_BUFFER_BPS = BigInt(10);\n\nexport class RecollateralizeLossBuilder extends LongYieldCarryBuilderBase<\n RecollateralizeLossIxArgs,\n RecollateralizeLossTxArgs,\n LongYieldCarryTransactionPlan[]\n> {\n async getIx(args: RecollateralizeLossIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const collateralMint = fromWeb3Pk(tokenData.data.collateral.mint);\n const collateralOracle = fromWeb3Pk(tokenData.data.collateral.oracle);\n const secondaryCollateralOracle = this.resolveOptionalSecondaryCollateralOracle(\n tokenData.data.collateral\n );\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const collateralTokenAccount = await getAtaAddress(\n collateralMint,\n args.token,\n collateralTokenProgram\n );\n\n const lpIdx = args.params.lendingPositionIndex;\n const requested = tokenData.data.lendingPositions[lpIdx];\n // The requested slot may be out-of-bounds or inactive (zeroed debt mint).\n // We still build the ix so the on-chain InvalidLendingPosition check is what\n // rejects it — but the account list needs a real debt mint to derive the\n // debt ATAs. Use the largest active position as a deterministic reference\n // (never an empty/None slot, whose debt mint is the default pubkey and would\n // derive a garbage ATA). With multiple active positions this picks the same\n // slot regardless of iteration order, so the account list is stable.\n const requestedIsActive =\n requested !== undefined && !requested.accounting.debt.mint.equals(PublicKey.default);\n const refPositionEntry = requestedIsActive\n ? { index: lpIdx, data: requested }\n : this.largestActiveLendingPosition(tokenData);\n if (!refPositionEntry) {\n throw new Error(\n `recollateralize_loss: token ${args.token} has no active lending position to reference`\n );\n }\n const refPosition = refPositionEntry.data;\n const debtMint = fromWeb3Pk(refPosition.accounting.debt.mint);\n const debtTokenProgram = resolveTokenProgram(refPosition.accounting.debt.tokenProgram);\n const yieldingBank = args.params.yieldingBank ?? args.token;\n const [tokenLpDebtTa, yieldingBankTa] = await Promise.all([\n getAtaAddress(debtMint, args.token, debtTokenProgram),\n getAtaAddress(debtMint, yieldingBank, debtTokenProgram),\n ]);\n\n // For an invalid requested index, pass the reference position's slot so the\n // account list is well-formed. The on-chain bounds/active check rejects the\n // ix (via the unchanged `lendingPositionIndex` param) before accounts matter.\n const lpPositionAccountIdx = requestedIsActive ? lpIdx : refPositionEntry.index;\n\n const builtIx = await this.program.methods\n .recollateralizeLoss({\n prerequisiteCpis: args.params.prerequisiteCpis ?? null,\n ixRefs: args.params.ixRefs,\n lendingPositionIndex: args.params.lendingPositionIndex,\n })\n .accountsStrict({\n manager: this.resolveTokenManager(tokenData.data),\n token: args.token,\n collateralMint,\n collateralTokenAccount,\n collateralOracle,\n secondaryCollateralOracle,\n lpPosition: this.account.getTokenLendingPositionRefreshAccounts(\n tokenData.data,\n lpPositionAccountIdx,\n args.params.lpPosition\n ),\n collateralTokenProgram,\n yieldingBank,\n debtMint,\n tokenLpDebtTa,\n yieldingBankTa,\n debtTokenProgram,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction();\n\n return toKitInstruction(builtIx);\n }\n\n /**\n * The active lending position holding the most collateral, or `undefined`\n * when the token has no active positions. Used only to supply a well-formed\n * reference account layout when `getIx` is called with an invalid index.\n */\n private largestActiveLendingPosition(tokenData: LYCToken) {\n const active = tokenData.activeLendingPositions;\n if (active.length === 0) return undefined;\n return active.reduce((best, current) =>\n toBigInt(current.data.accounting.collateral) > toBigInt(best.data.accounting.collateral)\n ? current\n : best\n );\n }\n\n async getTx(args: RecollateralizeLossTxArgs): Promise<LongYieldCarryTransactionPlan[]> {\n const tokenData = await this.account.fetchToken(args.token, { fresh: true });\n const txId = args.params.txId ?? `recollateralize-loss-${Date.now()}`;\n const slippageBps = args.params.swapSlippageBps ?? DEFAULT_RECOLLATERALIZE_LOSS_SLIPPAGE_BPS;\n const target = await this.selectRecollateralizationTarget(tokenData);\n const swapPlan = await this.buildRecollateralizationSwapPlan(target, slippageBps);\n const dcpPhase = await this.buildOptionalDecreaseCarryPhase(args, target, swapPlan, txId);\n const recollateralizePhase = await this.buildRecollateralizePhase(args, target, swapPlan, txId);\n\n return dcpPhase ? [dcpPhase, recollateralizePhase] : [recollateralizePhase];\n }\n\n private async selectRecollateralizationTarget(\n tokenData: LYCToken\n ): Promise<RecollateralizationTarget> {\n const totalDebtUsd = tokenData.activeLendingPositions.reduce(\n (sum, { data: lp }) => sum + toBigInt(lp.accounting.debt.tvlUsd),\n BigInt(0)\n );\n const totalCarryUsd = tokenData.activeCarryPositions.reduce(\n (sum, { data: carry }) => sum + toBigInt(carry.tvlUsd),\n BigInt(0)\n );\n\n if (totalDebtUsd <= totalCarryUsd) {\n throw new NoOpTransactionError(\"Recollateralization not needed: debt does not exceed carry\");\n }\n\n const bestLp = tokenData.activeLendingPositions.reduce((best, current) =>\n toBigInt(current.data.accounting.collateral) > toBigInt(best.data.accounting.collateral)\n ? current\n : best\n );\n const bestCarry = tokenData.activeCarryPositions.reduce((best, current) =>\n toBigInt(current.data.tvlUsd) > toBigInt(best.data.tvlUsd) ? current : best\n );\n const yieldingBank = await tokenData.deriveYieldingBankAddressForDebtCarryIndex(\n bestCarry.index,\n this.pda\n );\n\n return {\n tokenData,\n totalDebtUsd,\n totalCarryUsd,\n lendingPositionIndex: bestLp.index,\n position: bestLp.data,\n yieldingBank,\n };\n }\n\n private async buildRecollateralizationSwapPlan(\n target: RecollateralizationTarget,\n slippageBps: number\n ): Promise<RecollateralizationSwapPlan> {\n const { tokenData, position, totalDebtUsd, totalCarryUsd } = target;\n const debtExcessUsd = totalDebtUsd - totalCarryUsd;\n const overshootBuffer =\n (debtExcessUsd * RECOLLATERALIZE_LOSS_OVERSHOOT_BUFFER_BPS) / BigInt(10000);\n const targetRepayUsd = debtExcessUsd + overshootBuffer;\n\n const collateralPrice = toBigInt(tokenData.data.collateral.price);\n if (collateralPrice === BigInt(0)) {\n throw new Error(\"Collateral price is zero — refresh the token state first\");\n }\n const collateralInputAmount = tvlUsdToBaseUnits(\n targetRepayUsd,\n collateralPrice,\n tokenData.data.collateral.decimals\n );\n if (collateralInputAmount === BigInt(0)) {\n throw new NoOpTransactionError(\n \"Collateral input rounds to zero — no recollateralization needed\"\n );\n }\n\n const swapQuote = await this.swap.getQuote({\n inputMint: tokenData.collateralMint,\n outputMint: fromWeb3Pk(position.accounting.debt.mint),\n amount: Number(collateralInputAmount),\n slippageBps,\n });\n\n // Minimum guaranteed output after slippage; on-chain repays exactly this amount.\n // Any surplus from the actual swap sits in the debt ATA and gets deposited to the\n // yielding bank by the on-chain handler.\n const repayBaseUnits = (swapQuote.outputAmount * BigInt(10000 - slippageBps)) / BigInt(10000);\n\n return {\n collateralToWithdrawUi: toUiAmount(swapQuote.inputAmount, tokenData.data.collateral.decimals),\n repayUiAmount: toUiAmount(repayBaseUnits, position.accounting.debt.decimals),\n repayBaseUnits,\n swapQuote,\n };\n }\n\n private async buildOptionalDecreaseCarryPhase(\n args: RecollateralizeLossTxArgs,\n target: RecollateralizationTarget,\n swapPlan: RecollateralizationSwapPlan,\n txId: string\n ): Promise<LongYieldCarryTransactionPlan | undefined> {\n const { position, lendingPositionIndex, yieldingBank } = target;\n const lpClient = this.getLendingPlatformClient(position);\n lpClient.ix.clearCacheEntry(\n lpClient.ix.data.userAccountCatKey,\n fromWeb3Pk(position.protocolUserAcc)\n );\n\n const lycLendingPositionManager = await LycLendingPositionManager.create(\n lpClient.data,\n position\n );\n const postWithdrawalUtilBps =\n await lycLendingPositionManager.calcPostWithdrawalUtilizationRateBps(\n swapPlan.collateralToWithdrawUi\n );\n if (postWithdrawalUtilBps <= position.config.targetUtilizationRateBps) {\n return undefined;\n }\n\n const preWithdrawalTargetBps =\n await lycLendingPositionManager.calcPreWithdrawalTargetUtilizationRateBps(\n swapPlan.collateralToWithdrawUi\n );\n return new DecreaseCarryPositionBuilder(this.context).buildTx(\n this.resolveTokenManager(target.tokenData.data),\n args.token,\n {\n lendingPositionIndex,\n yieldingBank,\n sourceMint: args.params.sourceMint,\n swapSlippageBps: args.params.swapSlippageBps,\n repaySteering: {\n mode: \"explicitTargetUtilization\",\n targetUtilizationRateBps: preWithdrawalTargetBps,\n },\n txId,\n },\n { includePreInstructions: true }\n );\n }\n\n private async buildRecollateralizePhase(\n args: RecollateralizeLossTxArgs,\n target: RecollateralizationTarget,\n swapPlan: RecollateralizationSwapPlan,\n txId: string\n ): Promise<LongYieldCarryTransactionPlan> {\n const { position, lendingPositionIndex } = target;\n const manager = this.resolveTokenManager(target.tokenData.data);\n const lpClient = this.getLendingPlatformClient(position);\n const withdrawCpiData = await this.getLendingOperationCpiData(\n args.token,\n manager,\n position,\n txId,\n \"withdraw\",\n swapPlan.collateralToWithdrawUi\n );\n const swapCpiData = await this.swap.getSwapCpiData(swapPlan.swapQuote, args.token, {\n payer: manager,\n });\n const repayCpiData = await this.getLendingOperationCpiData(\n args.token,\n manager,\n position,\n txId,\n \"repay\",\n swapPlan.repayUiAmount\n );\n const prerequisiteCpiGroup = [...withdrawCpiData.prerequisiteCpis];\n const executionCpiGroup = [\n ...withdrawCpiData.cpis,\n swapCpiData,\n ...repayCpiData.prerequisiteCpis,\n ...repayCpiData.cpis,\n ];\n const {\n accounts: remainingAccounts,\n refsGroups,\n lookupTables,\n } = createMultiCpiRefs(\n prerequisiteCpiGroup.length ? [prerequisiteCpiGroup, executionCpiGroup] : [executionCpiGroup]\n );\n const prerequisiteCpis = prerequisiteCpiGroup.length ? refsGroups[0] : undefined;\n const ixRefs = refsGroups[prerequisiteCpiGroup.length ? 1 : 0];\n const preInstructions = await lpClient.ix.getPreInstructions(txId);\n const carryTradeAccounts = await this.account.getCarryTradeAccounts(\n args.token,\n target.yieldingBank,\n lendingPositionIndex\n );\n const [\n { instructions, postSuccessCacheInvalidations },\n { instructions: debtAtaInstructions, postSuccessCacheInvalidations: debtAtaInvalidations },\n ] = await Promise.all([\n getCreateAtaInstructions(this.rpc, manager, remainingAccounts),\n getCreateAtaInstructions(this.rpc, manager, carryTradeAccounts),\n ]);\n const recollateralizeIx = await this.getIx({\n token: args.token,\n params: {\n prerequisiteCpis,\n ixRefs,\n lendingPositionIndex,\n remainingAccounts,\n yieldingBank: target.yieldingBank,\n lpPosition: args.params.lpPosition,\n },\n });\n const setupInstructions = [\n ...preInstructions,\n ...(swapCpiData.preInstructions ?? []),\n ...debtAtaInstructions,\n ...instructions,\n ];\n\n return {\n instructions: [\n ...setupInstructions,\n // The heap frame applies only to this transaction. Keep it with the\n // CPI-heavy instruction while allowing refresh and ATA setup to move\n // into earlier transactions in the same atomic bundle.\n requestHeapFrameIx(MAX_HEAP_FRAME_BYTES),\n recollateralizeIx,\n ],\n lookupTables: this.getTxLookupTables(args.token, lookupTables ?? []),\n segmentLengths: [...setupInstructions.map(() => 1), 2],\n postSuccessCacheInvalidations: [\n getTokenCacheInvalidation(args.token),\n getLendingUserAccountCacheInvalidation(fromWeb3Pk(position.protocolUserAcc)),\n ...postSuccessCacheInvalidations,\n ...debtAtaInvalidations,\n ...withdrawCpiData.postSuccessCacheInvalidations,\n ...repayCpiData.postSuccessCacheInvalidations,\n ...(swapCpiData.postSuccessCacheInvalidations ?? []),\n ],\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { ResetTokenBurnRateLimitIxArgs } from \"./args\";\n\nexport class ResetTokenBurnRateLimitBuilder extends LongYieldCarrySingleInstructionBuilderService<ResetTokenBurnRateLimitIxArgs> {\n async getIx(args: ResetTokenBurnRateLimitIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n return this.program.methods\n .resetTokenBurnRateLimit()\n .accountsPartial({ admin: this.resolveTokenAdmin(tokenData.data), token: args.token })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(\n args: ResetTokenBurnRateLimitIxArgs\n ): Promise<readonly Address[]> {\n return this.getTxLookupTables(args.token);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { getTokenCacheInvalidation } from \"../../utils\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { SetTokenCircuitBreakerIxArgs, SetTokenCircuitBreakerTxArgs } from \"./args\";\n\nexport class SetTokenCircuitBreakerBuilder extends LongYieldCarrySingleInstructionBuilderService<\n SetTokenCircuitBreakerIxArgs,\n SetTokenCircuitBreakerTxArgs\n> {\n protected async deriveIxArgs(\n txArgs: SetTokenCircuitBreakerTxArgs\n ): Promise<SetTokenCircuitBreakerIxArgs> {\n return {\n authority: txArgs.authority,\n token: txArgs.token,\n active: txArgs.active,\n };\n }\n\n async getIx(args: SetTokenCircuitBreakerIxArgs): Promise<Instruction> {\n return this.program.methods\n .setTokenCircuitBreaker(args.active)\n .accountsPartial({ authority: args.authority, token: args.token })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(\n args: SetTokenCircuitBreakerIxArgs\n ): Promise<readonly Address[]> {\n return this.getTxLookupTables(args.token);\n }\n\n protected async buildPlanExtras(args: SetTokenCircuitBreakerIxArgs) {\n return {\n postSuccessCacheInvalidations: [getTokenCacheInvalidation(args.token)],\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type {\n SetYieldingBankCircuitBreakerIxArgs,\n SetYieldingBankCircuitBreakerTxArgs,\n} from \"./args\";\n\nexport class SetYieldingBankCircuitBreakerBuilder extends LongYieldCarrySingleInstructionBuilderService<\n SetYieldingBankCircuitBreakerIxArgs,\n SetYieldingBankCircuitBreakerTxArgs\n> {\n protected async deriveIxArgs(\n txArgs: SetYieldingBankCircuitBreakerTxArgs\n ): Promise<SetYieldingBankCircuitBreakerIxArgs> {\n return {\n authority: txArgs.authority,\n yieldingBank: txArgs.yieldingBank,\n active: txArgs.active,\n };\n }\n\n async getIx(args: SetYieldingBankCircuitBreakerIxArgs): Promise<Instruction> {\n return this.program.methods\n .setYieldingBankCircuitBreaker(args.active)\n .accountsPartial({\n authority: args.authority,\n yieldingBank: args.yieldingBank,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(): Promise<readonly Address[]> {\n return this.getTxLookupTables();\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { getTokenCacheInvalidation } from \"../../utils\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { UpdateLendingPositionConfigIxArgs } from \"./args\";\n\nexport class UpdateLendingPositionConfigBuilder extends LongYieldCarrySingleInstructionBuilderService<UpdateLendingPositionConfigIxArgs> {\n async getIx(args: UpdateLendingPositionConfigIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n return this.program.methods\n .updateLendingPositionConfig({\n lendingPositionIndex: args.params.lendingPositionIndex,\n targetUtilizationRateBps: args.params.targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps: args.params.maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps: args.params.maxDeviationBelowTargetUtilBps,\n })\n .accountsPartial({ manager: this.resolveTokenManager(tokenData.data), token: args.token })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(\n args: UpdateLendingPositionConfigIxArgs\n ): Promise<readonly Address[]> {\n return this.getTxLookupTables(args.token);\n }\n\n protected async buildPlanExtras(args: UpdateLendingPositionConfigIxArgs) {\n return {\n postSuccessCacheInvalidations: [getTokenCacheInvalidation(args.token)],\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { UpdateTokenConfigurationIxArgs } from \"./args\";\n\nexport class UpdateTokenConfigurationBuilder extends LongYieldCarrySingleInstructionBuilderService<UpdateTokenConfigurationIxArgs> {\n /**\n * Builds an update signed by the token admin by default. Callers may pass the\n * token manager (`feeDripMaxApyBps` only) or curator (curator fee wallet)\n * through the compatibility-named `admin` argument.\n *\n * Omitted fee/config fields are sent as `null` (on-chain `None` = no change).\n */\n async getIx(args: UpdateTokenConfigurationIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n return this.program.methods\n .updateTokenConfiguration({\n performanceFeeBps: args.params.performanceFeeBps ?? null,\n mintingFeeBps: args.params.mintingFeeBps ?? null,\n burningFeeBps: args.params.burningFeeBps ?? null,\n protocolMintBurnPctBps: args.params.protocolMintBurnPctBps ?? null,\n curatorMintBurnPctBps: args.params.curatorMintBurnPctBps ?? null,\n curatorPerfPctBps: args.params.curatorPerfPctBps ?? null,\n feeDripMaxApyBps: args.params.feeDripMaxApyBps ?? null,\n burnRateLimit: args.params.burnRateLimit\n ? {\n maxAmount: args.params.burnRateLimit.maxAmount,\n windowDurationSecs: args.params.burnRateLimit.windowDurationSecs,\n }\n : null,\n depositLimit: args.params.depositLimit !== undefined ? args.params.depositLimit : null,\n })\n .accountsPartial({\n admin: args.admin ?? this.resolveTokenAdmin(tokenData.data),\n token: args.token,\n managerRole: args.managerRole ?? null,\n curatorFeeWallet: args.curatorFeeWallet ?? null,\n cbControllerRole: args.cbControllerRole ?? null,\n curatorRole: args.curatorRole ?? null,\n adminRole: args.adminRole ?? null,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(\n args: UpdateTokenConfigurationIxArgs\n ): Promise<readonly Address[]> {\n return this.getTxLookupTables(args.token);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction, toWeb3AccountMeta } from \"common\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { UpdateTokenMetadataIxArgs } from \"./args\";\n\nexport class UpdateTokenMetadataBuilder extends LongYieldCarrySingleInstructionBuilderService<UpdateTokenMetadataIxArgs> {\n async getIx(args: UpdateTokenMetadataIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n return this.program.methods\n .updateTokenMetadata(args.params.ixRefs)\n .accountsPartial({\n admin: this.resolveTokenAdmin(tokenData.data),\n token: args.token,\n mint: args.mint,\n })\n .remainingAccounts(args.params.remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(args: UpdateTokenMetadataIxArgs): Promise<readonly Address[]> {\n return this.getTxLookupTables(args.token);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { toKitInstruction } from \"common\";\nimport { getYieldingBankCacheInvalidation } from \"../../utils\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { UpdateYieldingBankConfigIxArgs } from \"./args\";\n\nexport class UpdateYieldingBankConfigBuilder extends LongYieldCarrySingleInstructionBuilderService<UpdateYieldingBankConfigIxArgs> {\n async getIx(args: UpdateYieldingBankConfigIxArgs): Promise<Instruction> {\n const bankData = await this.account.fetchYieldingBank(args.yieldingBank);\n return this.program.methods\n .updateYieldingBankConfig({})\n .accountsPartial({\n admin: args.admin ?? this.resolveYieldingBankAdmin(bankData.data),\n yieldingBank: args.yieldingBank,\n defaultRedemptionMint: args.params.defaultRedemptionMint,\n managerRole: args.managerRole ?? null,\n cbControllerRole: args.cbControllerRole ?? null,\n curatorRole: args.curatorRole ?? null,\n adminRole: args.adminRole ?? null,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n protected async buildLookupTables(): Promise<readonly Address[]> {\n return this.getTxLookupTables();\n }\n\n protected async buildPlanExtras(args: UpdateYieldingBankConfigIxArgs) {\n return {\n postSuccessCacheInvalidations: [getYieldingBankCacheInvalidation(args.yieldingBank)],\n };\n }\n}\n","import type { TransactionPlan as BaseTransactionPlan } from \"common\";\nimport type { LongYieldCarryBuilderContext } from \"./types/builders\";\nimport {\n BurnTokenBuilder,\n ClaimIncentivesBuilder,\n CollectFeesBuilder,\n CollectInterestBuilder,\n CreditUnlentToRedemptionEpochBuilder,\n CreateCpiPlanBuilder,\n CreateTokenBuilder,\n CreateTokenLendingPositionBuilder,\n CreateYieldingBankAllocationBuilder,\n CreateYieldingBankBuilder,\n DecreaseCarryPositionBuilder,\n DepositUnlentCollateralBuilder,\n IncreaseCarryPositionBuilder,\n MintTokenBuilder,\n RebalanceTokenBuilder,\n RebalanceYieldingBankBuilder,\n RecollateralizeLossBuilder,\n RefreshTokenStateBuilder,\n RefreshTokensBuilder,\n RefreshYieldingBankBuilder,\n ProcessAsyncBurnBuilder,\n ResetTokenBurnRateLimitBuilder,\n SetRedemptionEpochStatusBuilder,\n SetTokenCircuitBreakerBuilder,\n SetYieldingBankCircuitBreakerBuilder,\n UpdateLendingPositionConfigBuilder,\n UpdateTokenConfigurationBuilder,\n UpdateTokenMetadataBuilder,\n UpdateYieldingBankConfigBuilder,\n TopUpUnlentReservesBuilder,\n} from \"./builders\";\nimport type { LongYieldCarryTransactionPlan } from \"./types\";\n\nexport * from \"./builders\";\n\nexport class TransactionClient {\n readonly burnToken: BurnTokenBuilder;\n readonly claimIncentives: ClaimIncentivesBuilder;\n readonly collectFees: CollectFeesBuilder;\n readonly collectInterest: CollectInterestBuilder;\n readonly creditUnlentToRedemptionEpoch: CreditUnlentToRedemptionEpochBuilder;\n readonly createCpiPlan: CreateCpiPlanBuilder;\n readonly createToken: CreateTokenBuilder;\n readonly createTokenLendingPosition: CreateTokenLendingPositionBuilder;\n readonly createYieldingBank: CreateYieldingBankBuilder;\n readonly createYieldingBankAllocation: CreateYieldingBankAllocationBuilder;\n readonly decreaseCarryPosition: DecreaseCarryPositionBuilder;\n readonly depositUnlentCollateral: DepositUnlentCollateralBuilder;\n readonly increaseCarryPosition: IncreaseCarryPositionBuilder;\n readonly mintToken: MintTokenBuilder;\n readonly rebalanceToken: RebalanceTokenBuilder;\n readonly rebalanceYieldingBank: RebalanceYieldingBankBuilder;\n readonly recollateralizeLoss: RecollateralizeLossBuilder;\n readonly refreshTokenState: RefreshTokenStateBuilder;\n readonly refreshTokens: RefreshTokensBuilder;\n readonly refreshYieldingBank: RefreshYieldingBankBuilder;\n readonly processAsyncBurn: ProcessAsyncBurnBuilder;\n readonly resetTokenBurnRateLimit: ResetTokenBurnRateLimitBuilder;\n readonly setRedemptionEpochStatus: SetRedemptionEpochStatusBuilder;\n readonly setTokenCircuitBreaker: SetTokenCircuitBreakerBuilder;\n readonly setYieldingBankCircuitBreaker: SetYieldingBankCircuitBreakerBuilder;\n readonly updateLendingPositionConfig: UpdateLendingPositionConfigBuilder;\n readonly updateTokenConfiguration: UpdateTokenConfigurationBuilder;\n readonly updateTokenMetadata: UpdateTokenMetadataBuilder;\n readonly updateYieldingBankConfig: UpdateYieldingBankConfigBuilder;\n readonly topUpUnlentReserves: TopUpUnlentReservesBuilder;\n\n constructor(readonly context: LongYieldCarryBuilderContext) {\n this.burnToken = new BurnTokenBuilder(context);\n this.claimIncentives = new ClaimIncentivesBuilder(context);\n this.collectFees = new CollectFeesBuilder(context);\n this.collectInterest = new CollectInterestBuilder(context);\n this.creditUnlentToRedemptionEpoch = new CreditUnlentToRedemptionEpochBuilder(context);\n this.createCpiPlan = new CreateCpiPlanBuilder(context);\n this.createToken = new CreateTokenBuilder(context);\n this.createTokenLendingPosition = new CreateTokenLendingPositionBuilder(context);\n this.createYieldingBank = new CreateYieldingBankBuilder(context);\n this.createYieldingBankAllocation = new CreateYieldingBankAllocationBuilder(context);\n this.decreaseCarryPosition = new DecreaseCarryPositionBuilder(context);\n this.depositUnlentCollateral = new DepositUnlentCollateralBuilder(context);\n this.increaseCarryPosition = new IncreaseCarryPositionBuilder(context);\n this.mintToken = new MintTokenBuilder(context);\n this.rebalanceToken = new RebalanceTokenBuilder(context);\n this.rebalanceYieldingBank = new RebalanceYieldingBankBuilder(context);\n this.recollateralizeLoss = new RecollateralizeLossBuilder(context);\n this.refreshTokenState = new RefreshTokenStateBuilder(context);\n this.refreshTokens = new RefreshTokensBuilder(context);\n this.refreshYieldingBank = new RefreshYieldingBankBuilder(context);\n this.processAsyncBurn = new ProcessAsyncBurnBuilder(context);\n this.resetTokenBurnRateLimit = new ResetTokenBurnRateLimitBuilder(context);\n this.setRedemptionEpochStatus = new SetRedemptionEpochStatusBuilder(context);\n this.setTokenCircuitBreaker = new SetTokenCircuitBreakerBuilder(context);\n this.setYieldingBankCircuitBreaker = new SetYieldingBankCircuitBreakerBuilder(context);\n this.updateLendingPositionConfig = new UpdateLendingPositionConfigBuilder(context);\n this.updateTokenConfiguration = new UpdateTokenConfigurationBuilder(context);\n this.updateTokenMetadata = new UpdateTokenMetadataBuilder(context);\n this.updateYieldingBankConfig = new UpdateYieldingBankConfigBuilder(context);\n this.topUpUnlentReserves = new TopUpUnlentReservesBuilder(context);\n }\n}\n\nexport type TransactionBuilder = TransactionClient[keyof TransactionClient];\nexport type CompositeTransactionPlan = BaseTransactionPlan | LongYieldCarryTransactionPlan;\n","// --- InterestDistribution ---\n\nexport type AnchorInterestDistribution = { intoTokenPrice: {} } | { intoWallets: {} };\n\nexport enum InterestDistribution {\n IntoTokenPrice = 0,\n IntoWallets = 1,\n}\n\nexport function interestDistributionToEnum(v: AnchorInterestDistribution): InterestDistribution {\n if (\"intoTokenPrice\" in v) return InterestDistribution.IntoTokenPrice;\n if (\"intoWallets\" in v) return InterestDistribution.IntoWallets;\n throw new Error(\"Unknown InterestDistribution variant\");\n}\n\nexport function enumToInterestDistribution(t: InterestDistribution): AnchorInterestDistribution {\n switch (t) {\n case InterestDistribution.IntoTokenPrice:\n return { intoTokenPrice: {} };\n case InterestDistribution.IntoWallets:\n return { intoWallets: {} };\n }\n}\n\n// --- LendingType ---\n\nexport type AnchorLendingType = { lendingMarket: {} } | { vault: {} };\n\nexport enum LendingType {\n LendingMarket = 0,\n Vault = 1,\n}\n\nexport function lendingTypeToEnum(v: AnchorLendingType): LendingType {\n if (\"lendingMarket\" in v) return LendingType.LendingMarket;\n if (\"vault\" in v) return LendingType.Vault;\n throw new Error(\"Unknown LendingType variant\");\n}\n\nexport function enumToLendingType(t: LendingType): AnchorLendingType {\n switch (t) {\n case LendingType.LendingMarket:\n return { lendingMarket: {} };\n case LendingType.Vault:\n return { vault: {} };\n }\n}\n","import { type Address } from \"@solana/kit\";\nimport { fromWeb3Pk, mints, toUiAmount } from \"common\";\nimport { KAMINO_MAIN_MARKET } from \"lending-platforms\";\nimport type { LendingPlatformData, ReserveBase, TokenIncentiveBase } from \"lending-platforms\";\nimport type { IndexedLendingPosition, LYCToken } from \"../../models/lycToken\";\nimport type { LYCYieldingBank } from \"../../models/yieldingBank\";\nimport type { DebtAllocationTarget, DebtReallocation } from \"./types\";\n\n/**\n * Supported borrow tokens by registry symbol. Addresses are taken from\n * `mints` (common mint registry) when resolving candidates.\n */\nconst BORROW_TOKEN_SYMBOLS = [\"USDC\", \"PYUSD\", \"USDT\", \"CASH\", \"USDG\", \"USDS\"] as const;\nconst USDC_MINT = mints.get(\"USDC\")!.address;\nconst USD_STAR_MINT = mints.get(\"USD*\")!.address;\n\n/**\n * Selection-only discount applied to USDC's effective borrow APY when the\n * token's yielding bank holds USD*. Borrowing USDC avoids the otherwise\n * required debt-mint → USDC swap and its occasional execution loss.\n */\nconst USDC_BORROW_APY_BIAS = 0.005;\n\n/**\n * Discrete allocation steps for the per-position DP grid. 20 → 5% increments.\n * Complexity is O(positions × candidates × K²) — all synchronous, negligible.\n */\nconst ALLOCATION_STEPS = 20;\n\n/**\n * Minimum borrow-APY improvement that justifies emitting a reallocation. Below\n * this, the rebalance is skipped — on-chain costs (flash-loan fee + swap\n * slippage + tx fees) eat marginal gains, and thrashing positions for a few\n * basis points adds noise without value. 0.025 = 250 bps on the position's APY.\n */\nconst MIN_REALLOC_APY_IMPROVEMENT = 0.025;\n\n/**\n * Positions with debt below this threshold (in the borrowed token's UI units)\n * are dust — typically idle or near-closed slots — and are excluded from\n * optimization. Without this filter, dust slots generate phantom reallocations\n * with zero economic effect but real on-chain transaction costs.\n */\nconst DUST_DEBT_THRESHOLD = 1.0;\n\n// ─── Internal types ────────────────────────────────────────────────────────\n\ninterface ResolvedPosition {\n pool: Address;\n token: LYCToken;\n lendingPositionIndex: number;\n debtMint: Address;\n debtAmountUi: number;\n collateralReserve: ReserveBase;\n debtReserve: ReserveBase;\n currentBorrowApy: number;\n /** Borrow APY minus the supply incentive the collateral earns from this debt token. */\n currentEffectiveBorrowApy: number;\n /** Whether USDC should receive the selection-only borrow-rate discount. */\n biasTowardUsdc: boolean;\n}\n\ninterface GroupCandidate {\n mint: Address;\n reserve: ReserveBase;\n /** Total debt already borrowed from this reserve across all positions in the group. */\n existingGroupDebt: number;\n /** Available borrow capacity in UI units — caps per-position allocations in the DP. */\n liquidityAvailableUi: number;\n}\n\ninterface PositionMintAlloc {\n mint: Address;\n reserve: ReserveBase;\n amountUi: number;\n weightBps: number;\n borrowApy: number;\n supplyIncentiveApy: number;\n effectiveBorrowApy: number;\n selectionBorrowApy: number;\n}\n\ninterface PositionOptimum {\n mints: PositionMintAlloc[];\n /** Debt-weighted average effective borrow APY (borrow − supply incentive) across all mints. */\n blendedEffectiveBorrowApy: number;\n /** Effective borrow APY after applying selection-only mint biases. */\n blendedSelectionBorrowApy: number;\n}\n\n// ─── LTV helpers ───────────────────────────────────────────────────────────\n\n/**\n * Returns the LTV (as a decimal) for a collateral/debt pair, using the\n * e-mode config if one exists for the pair, otherwise the base LTV.\n */\nfunction getPairLtv(collateralReserve: ReserveBase, debtReserveAddress: Address): number {\n const emode = collateralReserve.emodes?.find((e) => e.debtReserve === debtReserveAddress);\n return emode?.ltvPct ?? collateralReserve.ltvPct;\n}\n\n// ─── Log formatters ────────────────────────────────────────────────────────\n\nfunction mintSymbol(mint: Address): string {\n return mints.get(mint)?.symbol ?? `${mint.slice(0, 6)}…`;\n}\n\nfunction tokenLabel(pos: ResolvedPosition): string {\n return pos.token.label ?? pos.token.address.slice(0, 6);\n}\n\nfunction positionTag(pos: ResolvedPosition): string {\n return `${tokenLabel(pos)}#${pos.lendingPositionIndex}`;\n}\n\nfunction formatApy(x: number): string {\n return `${(x * 100).toFixed(3)}%`;\n}\n\nfunction formatApyDelta(x: number): string {\n const sign = x >= 0 ? \"+\" : \"\";\n return `${sign}${(x * 100).toFixed(3)}%`;\n}\n\nfunction formatAmount(x: number): string {\n return x.toLocaleString(undefined, { maximumFractionDigits: 2 });\n}\n\nfunction formatIncentive(inc: TokenIncentiveBase): string {\n const pair = inc.config.requiresPairReserve\n ? `pair=${inc.config.requiresPairReserve.slice(0, 6)}…`\n : \"pair=none\";\n const active = inc.active() ? \"active\" : \"inactive\";\n return (\n `type=${inc.config.incentiveType} ${pair} ` +\n `reward=${mintSymbol(inc.config.rewardMint)} apy=${formatApy(inc.apy())} ${active}`\n );\n}\n\n// ─── Service ───────────────────────────────────────────────────────────────\n\nexport interface AllocationServiceOptions {\n /**\n * Receives diagnostic log messages. When omitted, the service is silent\n * (used by unit tests). Pass `console.log` from scripts to inspect per-pool\n * candidate evaluation, incentive eligibility, and the chosen allocation.\n */\n logger?: (message: string) => void;\n /**\n * Yielding-bank state used to identify tokens whose active bank holds USD*.\n * Without this data, allocation remains unbiased.\n */\n yieldingBanks?: readonly LYCYieldingBank[];\n}\n\nexport class AllocationService {\n private readonly log: (message: string) => void;\n private readonly yieldingBanks: readonly LYCYieldingBank[];\n\n constructor(\n private readonly lpData: LendingPlatformData,\n options: AllocationServiceOptions = {}\n ) {\n this.log = options.logger ?? (() => {});\n this.yieldingBanks = options.yieldingBanks ?? [];\n }\n\n /**\n * Returns the debt mint with the highest pair-adjusted net APY\n * (supplyAPY − borrowAPY) for a given pool and collateral reserve.\n *\n * Use this when creating a new lending position to pick the optimal debt\n * mint rather than hardcoding a default.\n */\n async findOptimalDebtMint(\n pool: Address,\n collateralReserve: ReserveBase,\n token?: LYCToken\n ): Promise<{ mint: Address; symbol: string; borrowApy: number } | null> {\n const biasTowardUsdc = token ? this.tokenUsesUsdStarYieldingBank(token) : false;\n const candidates = await Promise.all(\n BORROW_TOKEN_SYMBOLS.map(async (symbol) => {\n const info = mints.get(symbol);\n if (!info) return null;\n const reserve = await this.fetchOptionalReserveByMint(pool, info.address);\n if (!reserve) return null;\n // TODO: revert to pair-adjusted rates once Kamino main-market incentive distortions are resolved.\n // Revert to:\n // const pairedBorrowApy = reserve.borrowAPY(collateralReserve.address);\n // const supplyIncentiveApy = collateralReserve.supplyAPY(reserve.address) - collateralReserve.supplyAPY();\n const isKaminoMain = pool === KAMINO_MAIN_MARKET;\n const pairedBorrowApy = isKaminoMain\n ? reserve.borrowAPY()\n : reserve.borrowAPY(collateralReserve.address);\n const supplyIncentiveApy = isKaminoMain\n ? 0\n : collateralReserve.supplyAPY(reserve.address) - collateralReserve.supplyAPY();\n const effectiveBorrowApy = pairedBorrowApy - supplyIncentiveApy;\n const selectionBorrowApy = this.applyUsdcBias(\n effectiveBorrowApy,\n info.address,\n biasTowardUsdc\n );\n const incentiveNote =\n supplyIncentiveApy > 0\n ? ` − ${formatApy(supplyIncentiveApy)} incentive = ${formatApy(effectiveBorrowApy)} effective`\n : \"\";\n const biasNote =\n selectionBorrowApy !== effectiveBorrowApy\n ? ` − ${formatApy(USDC_BORROW_APY_BIAS)} USDC bias = ${formatApy(selectionBorrowApy)} selection`\n : \"\";\n this.log(\n ` [findOptimalDebtMint] ${symbol.padEnd(6)} borrow ${formatApy(pairedBorrowApy)}${incentiveNote}${biasNote}`\n );\n return {\n mint: info.address,\n symbol,\n pairedBorrowApy,\n effectiveBorrowApy,\n selectionBorrowApy,\n };\n })\n );\n\n const valid = candidates.filter((c): c is NonNullable<typeof c> => c !== null);\n if (valid.length === 0) return null;\n\n valid.sort((a, b) => a.selectionBorrowApy - b.selectionBorrowApy);\n const best = valid[0];\n this.log(\n ` [findOptimalDebtMint] → ${best.symbol}` +\n ` (borrow ${formatApy(best.pairedBorrowApy)} effective ${formatApy(best.effectiveBorrowApy)}` +\n (best.selectionBorrowApy !== best.effectiveBorrowApy\n ? ` selection ${formatApy(best.selectionBorrowApy)}`\n : \"\") +\n `)`\n );\n return { mint: best.mint, symbol: best.symbol, borrowApy: best.effectiveBorrowApy };\n }\n\n /**\n * Groups all active lending positions by pool, then for each position in a\n * pool finds the allocation across supported borrow mints that minimises\n * that position's pair-adjusted borrow cost. Positions are optimised\n * independently — pair-incentive eligibility is keyed on the position's\n * (debt, collateral) pair, so positions with different collaterals can have\n * different optimal debt mints. (Utilization coupling between positions on\n * the same reserve is not modelled; pair-incentive deltas dominate marginal\n * utilization deltas at typical position sizes.)\n *\n * Returns one entry per position whose allocation would change.\n */\n async computeOptimalAllocations(tokens: LYCToken[]): Promise<DebtReallocation[]> {\n const positions = await this.resolveAllPositions(tokens);\n const poolGroups = this.groupByPool(positions);\n this.log(\n `[AllocationService] ${positions.length} active position${positions.length === 1 ? \"\" : \"s\"} across ${poolGroups.size} pool${poolGroups.size === 1 ? \"\" : \"s\"}`\n );\n const reallocations: DebtReallocation[] = [];\n\n for (const [pool, group] of poolGroups) {\n const groupReallocations = await this.processPoolGroup(pool, group);\n reallocations.push(...groupReallocations);\n }\n\n return reallocations;\n }\n\n // ─── Position resolution ─────────────────────────────────────────────────\n\n private async resolveAllPositions(tokens: LYCToken[]): Promise<ResolvedPosition[]> {\n const maybePositions = await Promise.all(\n tokens.flatMap((token) =>\n token.activeLendingPositions.map((lp) => this.resolvePosition(token, lp))\n )\n );\n return maybePositions.filter((p): p is ResolvedPosition => p !== null);\n }\n\n private async resolvePosition(\n token: LYCToken,\n { index, data: lp }: IndexedLendingPosition\n ): Promise<ResolvedPosition | null> {\n const pool = fromWeb3Pk(lp.pool);\n const debtAmountUi = toUiAmount(lp.accounting.debt.amount, lp.accounting.debt.decimals);\n\n // Skip dust slots — idle positions whose debt is too small for a\n // reallocation to recover its on-chain transaction cost.\n if (debtAmountUi < DUST_DEBT_THRESHOLD) return null;\n\n const [collateralReserve, debtReserve] = await Promise.all([\n this.lpData.fetchReserve(pool, fromWeb3Pk(lp.collateralReserve)),\n this.lpData.fetchReserve(pool, fromWeb3Pk(lp.debtReserve)),\n ]);\n\n if (!collateralReserve || !debtReserve) return null;\n\n return {\n pool,\n token,\n lendingPositionIndex: index,\n // `lp.accounting.debt.mint` is set at position creation and is NOT\n // updated when the debt is rebalanced into a different mint. The\n // debt reserve, by contrast, reflects the live borrow on-chain — so\n // that's the source of truth for which token is actually borrowed.\n debtMint: debtReserve.mint.mint,\n debtAmountUi,\n collateralReserve,\n debtReserve,\n // TODO: revert to pair-adjusted rates once Kamino main-market incentive distortions are resolved.\n // Revert to:\n // currentBorrowApy: debtReserve.borrowAPY(collateralReserve.address),\n // currentEffectiveBorrowApy:\n // debtReserve.borrowAPY(collateralReserve.address) -\n // (collateralReserve.supplyAPY(debtReserve.address) - collateralReserve.supplyAPY()),\n currentBorrowApy:\n pool === KAMINO_MAIN_MARKET\n ? debtReserve.borrowAPY()\n : debtReserve.borrowAPY(collateralReserve.address),\n currentEffectiveBorrowApy:\n pool === KAMINO_MAIN_MARKET\n ? debtReserve.borrowAPY()\n : debtReserve.borrowAPY(collateralReserve.address) -\n (collateralReserve.supplyAPY(debtReserve.address) - collateralReserve.supplyAPY()),\n biasTowardUsdc: this.tokenUsesUsdStarYieldingBank(token),\n };\n }\n\n private tokenUsesUsdStarYieldingBank(token: LYCToken): boolean {\n // A yielding-bank PDA is identified by its base mint + id. Match both so a\n // USD* holding in an unrelated global bank cannot influence this token.\n // `activeCarryPositions` also ensures the token has real shares in the bank,\n // rather than merely retaining an initialized but unused carry slot.\n return token.activeCarryPositions.some(({ data: carry }) =>\n this.yieldingBanks.some(\n (bank) =>\n bank.baseMint === fromWeb3Pk(carry.yieldingBaseMint) &&\n bank.id === carry.yieldingBankId &&\n bank.findAssetHolding(USD_STAR_MINT) !== null\n )\n );\n }\n\n private applyUsdcBias(effectiveBorrowApy: number, mint: Address, enabled: boolean): number {\n return enabled && mint === USDC_MINT\n ? effectiveBorrowApy - USDC_BORROW_APY_BIAS\n : effectiveBorrowApy;\n }\n\n private groupByPool(positions: ResolvedPosition[]): Map<Address, ResolvedPosition[]> {\n const groups = new Map<Address, ResolvedPosition[]>();\n for (const pos of positions) {\n if (!groups.has(pos.pool)) groups.set(pos.pool, []);\n groups.get(pos.pool)!.push(pos);\n }\n return groups;\n }\n\n // ─── Pool group processing ────────────────────────────────────────────────\n\n private async processPoolGroup(\n pool: Address,\n group: ResolvedPosition[]\n ): Promise<DebtReallocation[]> {\n this.log(`\\n${\"═\".repeat(70)}`);\n this.log(\n `Pool ${pool.slice(0, 6)}… (${group.length} position${group.length === 1 ? \"\" : \"s\"})`\n );\n this.log(`${\"─\".repeat(70)}`);\n for (const pos of group) {\n this.log(\n ` ${positionTag(pos).padEnd(14)}` +\n ` collateral=${mintSymbol(pos.collateralReserve.mint.mint)}` +\n ` debt=${mintSymbol(pos.debtMint)} $${formatAmount(pos.debtAmountUi)}` +\n ` borrow ${formatApy(pos.currentBorrowApy)}`\n );\n }\n\n const existingDebtByMint = this.aggregateExistingDebtByMint(group);\n const candidates = await this.resolveGroupCandidates(pool, group, existingDebtByMint);\n if (candidates.length === 0) {\n this.log(\" no borrow-token candidates resolved on this pool; skipping\");\n return [];\n }\n\n this.logCandidates(group, candidates);\n\n const reallocations: DebtReallocation[] = [];\n for (const pos of group) {\n const realloc = this.evaluatePosition(pos, candidates);\n if (realloc !== null) reallocations.push(realloc);\n }\n return reallocations;\n }\n\n /**\n * Optimises a single position against the candidate set, logs the result,\n * applies the minimum-improvement gate, and returns a reallocation if one\n * should be emitted. Returns `null` when the position is already optimal,\n * the optimum doesn't beat current, or the gain is below threshold.\n *\n */\n private evaluatePosition(\n pos: ResolvedPosition,\n candidates: GroupCandidate[]\n ): DebtReallocation | null {\n const tag = positionTag(pos);\n const {\n mints: optimumMints,\n blendedEffectiveBorrowApy: optimumEffectiveBorrowApy,\n blendedSelectionBorrowApy: optimumSelectionBorrowApy,\n } = this.optimizePosition(pos, candidates);\n const currentSelectionBorrowApy = this.applyUsdcBias(\n pos.currentEffectiveBorrowApy,\n pos.debtMint,\n pos.biasTowardUsdc\n );\n\n this.log(`\\n ── ${tag} ──`);\n const currentSupplyIncentive =\n pos.collateralReserve.supplyAPY(pos.debtReserve.address) - pos.collateralReserve.supplyAPY();\n const currentEffectiveNote =\n currentSupplyIncentive > 0\n ? ` − ${formatApy(currentSupplyIncentive)} incentive = ${formatApy(pos.currentEffectiveBorrowApy)} effective`\n : \"\";\n this.log(\n ` Current: ${mintSymbol(pos.debtMint)} $${formatAmount(pos.debtAmountUi)}` +\n ` borrow ${formatApy(pos.currentBorrowApy)}${currentEffectiveNote}`\n );\n this.log(\n ` Optimum: effective borrow ${formatApy(optimumEffectiveBorrowApy)}` +\n (optimumSelectionBorrowApy !== optimumEffectiveBorrowApy\n ? ` selection ${formatApy(optimumSelectionBorrowApy)}`\n : \"\")\n );\n for (const m of optimumMints) {\n const incentiveNote =\n m.supplyIncentiveApy > 0\n ? ` − ${formatApy(m.supplyIncentiveApy)} incentive = ${formatApy(m.effectiveBorrowApy)} effective`\n : \"\";\n const biasNote =\n m.selectionBorrowApy !== m.effectiveBorrowApy\n ? ` − ${formatApy(USDC_BORROW_APY_BIAS)} USDC bias = ${formatApy(m.selectionBorrowApy)} selection`\n : \"\";\n this.log(\n ` ${mintSymbol(m.mint).padEnd(6)} ${(m.weightBps / 100).toFixed(0).padStart(3)}%` +\n ` $${formatAmount(m.amountUi)} borrow ${formatApy(m.borrowApy)}${incentiveNote}${biasNote}`\n );\n }\n\n const isAlreadyOptimal =\n optimumMints.length === 1 &&\n optimumMints[0].mint === pos.debtMint &&\n optimumMints[0].weightBps === 10_000;\n if (isAlreadyOptimal) {\n this.log(` → No change (already optimal)`);\n return null;\n }\n\n if (optimumSelectionBorrowApy >= currentSelectionBorrowApy) {\n this.log(` → No change (optimum effective borrow rate does not beat current)`);\n return null;\n }\n\n const improvement = currentSelectionBorrowApy - optimumSelectionBorrowApy;\n if (improvement < MIN_REALLOC_APY_IMPROVEMENT) {\n this.log(\n ` → No change (improvement ${formatApyDelta(improvement)}` +\n ` below ${formatApyDelta(MIN_REALLOC_APY_IMPROVEMENT)} threshold)`\n );\n return null;\n }\n this.log(\n ` → Rebalancing (effective borrow rate improves by ${formatApyDelta(improvement)})`\n );\n\n const targets: DebtAllocationTarget[] = optimumMints.map((m) => ({\n mint: m.mint,\n amountUi: m.amountUi,\n weightBps: m.weightBps,\n }));\n\n // Build fallback single-mint options: every candidate that beats current,\n // sorted by effective borrow APY ascending, excluding the primary target\n // mint(s) already in `targets`.\n const isKaminoMain = pos.pool === KAMINO_MAIN_MARKET;\n const baseSupplyApy = pos.collateralReserve.supplyAPY();\n const primaryMints = new Set(targets.map((t) => t.mint));\n const fallbackTargets: DebtAllocationTarget[][] = candidates\n .map(({ mint, reserve }) => {\n if (primaryMints.has(mint)) return null;\n const supplyIncentiveApy = isKaminoMain\n ? 0\n : pos.collateralReserve.supplyAPY(reserve.address) - baseSupplyApy;\n const borrowApy = isKaminoMain\n ? reserve.simulateNewBorrowAPY({ debtChange: pos.debtAmountUi })\n : reserve.simulateNewBorrowAPY(\n { debtChange: pos.debtAmountUi },\n pos.collateralReserve.address\n );\n const effectiveBorrowApy = borrowApy - supplyIncentiveApy;\n const selectionBorrowApy = this.applyUsdcBias(effectiveBorrowApy, mint, pos.biasTowardUsdc);\n if (selectionBorrowApy >= currentSelectionBorrowApy) return null;\n return {\n selectionBorrowApy,\n target: {\n mint,\n amountUi: pos.debtAmountUi,\n weightBps: 10_000,\n } satisfies DebtAllocationTarget,\n };\n })\n .filter((x): x is NonNullable<typeof x> => x !== null)\n .sort((a, b) => a.selectionBorrowApy - b.selectionBorrowApy)\n .map((x) => [x.target]);\n\n return {\n token: pos.token.address,\n lendingPositionIndex: pos.lendingPositionIndex,\n currentDebtMint: pos.debtMint,\n currentDebtAmountUi: pos.debtAmountUi,\n currentBorrowApy: pos.currentBorrowApy,\n currentSupplyIncentiveApy: currentSupplyIncentive,\n projectedBorrowApy: optimumEffectiveBorrowApy,\n targets,\n fallbackTargets,\n };\n }\n\n /**\n * Logs, in this order:\n * 1. Each collateral reserve in the pool group + its incentives (once).\n * 2. Each candidate debt reserve: base borrow APY, utilization, and its\n * borrow-side incentives (once).\n * 3. A net-APY matrix (candidate rows × collateral columns) showing the\n * pair-adjusted supply APY, borrow APY, and net APY = supply − borrow.\n * The matrix answers \"should I borrow USDS or USDG against cbBTC?\" at a\n * glance — compare rows within the cbBTC column.\n *\n * The matrix uses `supplyAPY(debtReserve)` and `borrowAPY(supplyReserve)`,\n * which include pair-gated incentives. A `★` marks rows where a pair\n * incentive activates (supplyApy or borrowApy differs from the base).\n */\n private logCandidates(group: ResolvedPosition[], candidates: GroupCandidate[]) {\n const collateralReserves = new Map<Address, ReserveBase>();\n for (const pos of group) {\n collateralReserves.set(pos.collateralReserve.address, pos.collateralReserve);\n }\n\n this.log(`\\nCollateral reserves:`);\n for (const r of collateralReserves.values()) {\n const activeIncentives = (r.incentives ?? []).filter((i) => i.active());\n const inactiveCount = (r.incentives ?? []).length - activeIncentives.length;\n this.log(\n ` ${mintSymbol(r.mint.mint).padEnd(8)} base supply ${formatApy(r.supplyAPY())}` +\n (activeIncentives.length > 0\n ? ` +${activeIncentives.length} active incentive${activeIncentives.length === 1 ? \"\" : \"s\"}`\n : \"\") +\n (inactiveCount > 0 ? ` (${inactiveCount} inactive)` : \"\")\n );\n for (const inc of activeIncentives) {\n this.log(` ${formatIncentive(inc)}`);\n }\n }\n\n this.log(`\\nDebt candidates:`);\n for (const c of candidates) {\n const activeIncentives = (c.reserve.incentives ?? []).filter((i) => i.active());\n const inactiveCount = (c.reserve.incentives ?? []).length - activeIncentives.length;\n this.log(\n ` ${mintSymbol(c.mint).padEnd(8)} borrow ${formatApy(c.reserve.borrowAPY())}` +\n ` util ${(c.reserve.utilizationRatePct() * 100).toFixed(1)}%` +\n ` capacity $${formatAmount(c.liquidityAvailableUi)}` +\n ` group debt $${formatAmount(c.existingGroupDebt)}` +\n (activeIncentives.length > 0\n ? ` +${activeIncentives.length} active incentive${activeIncentives.length === 1 ? \"\" : \"s\"}`\n : \" no incentives\") +\n (inactiveCount > 0 ? ` (${inactiveCount} inactive)` : \"\")\n );\n for (const inc of activeIncentives) {\n this.log(` ${formatIncentive(inc)}`);\n }\n }\n\n this.logBorrowRateMatrix(collateralReserves, candidates);\n }\n\n private logBorrowRateMatrix(\n collateralReserves: Map<Address, ReserveBase>,\n candidates: GroupCandidate[]\n ) {\n const collateralList = [...collateralReserves.values()];\n const symW = 8;\n const borrowW = 8;\n const cellW = 9;\n\n this.log(`\\nBorrow rate matrix (pair-adjusted ★ = pair incentive changes rate)`);\n const header =\n ` ${\"Debt\".padEnd(symW)} ${\"Base\".padStart(borrowW)}` +\n collateralList.map((r) => `vs ${mintSymbol(r.mint.mint)}`.padStart(cellW + 3)).join(\"\");\n this.log(header);\n\n for (const c of candidates) {\n const baseBorrow = c.reserve.borrowAPY();\n const cells = collateralList.map((coll) => {\n const pairedBorrow = c.reserve.borrowAPY(coll.address);\n const pairedSupply = coll.supplyAPY(c.reserve.address);\n const pairActive = pairedBorrow !== baseBorrow || pairedSupply !== coll.supplyAPY();\n return `${formatApy(pairedBorrow).padStart(cellW)} ${pairActive ? \"★\" : \" \"}`;\n });\n this.log(\n ` ${mintSymbol(c.mint).padEnd(symW)} ${formatApy(baseBorrow).padStart(borrowW)}` +\n cells.join(\" \")\n );\n }\n }\n\n private aggregateExistingDebtByMint(group: ResolvedPosition[]): Map<Address, number> {\n const existingDebtByMint = new Map<Address, number>();\n for (const pos of group) {\n existingDebtByMint.set(\n pos.debtMint,\n (existingDebtByMint.get(pos.debtMint) ?? 0) + pos.debtAmountUi\n );\n }\n return existingDebtByMint;\n }\n\n private async resolveGroupCandidates(\n pool: Address,\n group: ResolvedPosition[],\n existingDebtByMint: Map<Address, number>\n ): Promise<GroupCandidate[]> {\n // Reuse already-fetched reserves where possible to avoid redundant RPC calls\n const fetchedByMint = new Map<Address, ReserveBase>(\n group.map((p) => [p.debtMint, p.debtReserve])\n );\n\n const results = await Promise.all(\n BORROW_TOKEN_SYMBOLS.map(async (symbol) => {\n const info = mints.get(symbol);\n if (!info) {\n throw new Error(\n `AllocationService: borrow token symbol \"${symbol}\" not found in mint registry`\n );\n }\n const mint = info.address;\n const reserve =\n fetchedByMint.get(mint) ?? (await this.fetchOptionalReserveByMint(pool, mint));\n if (!reserve) return;\n return {\n mint,\n reserve,\n existingGroupDebt: existingDebtByMint.get(mint) ?? 0,\n liquidityAvailableUi: reserve.liquidityAvailable(),\n } satisfies GroupCandidate;\n })\n );\n\n return results.filter((c): c is GroupCandidate => Boolean(c));\n }\n\n private async fetchOptionalReserveByMint(\n pool: Address,\n mint: Address\n ): Promise<ReserveBase | null> {\n try {\n return await this.lpData.fetchReserveByMint(pool, mint);\n } catch (error) {\n if (error instanceof Error && error.message === `Unable to find reserve by mint ${mint}`) {\n this.log(` (${mintSymbol(mint)} not listed on this pool — skipping)`);\n return null;\n }\n throw error;\n }\n }\n\n // ─── Per-position DP optimization ─────────────────────────────────────────\n\n /**\n * Finds the allocation of `pos.debtAmountUi` across `candidates` that\n * MAXIMISES this position's pair-adjusted net APY (supplyApy − borrowApy)\n * using DP over a discrete grid of size K = ALLOCATION_STEPS.\n *\n * Both legs are pair-adjusted with this position's own collateral reserve,\n * since incentive eligibility is keyed on the (debt, collateral) pair. This\n * matters because some pair incentives (e.g. USDG★cbBTC) act on the supply\n * side — minimising borrow cost alone would miss them.\n *\n * For candidate `i` at step `n`:\n * target = n × stepSize\n * posExisting = pos.debtAmountUi if pos.debtMint == candidate.mint else 0\n * debtChange = target − posExisting\n * borrowApy = simulateNewBorrowAPY({debtChange}, pos.collateralReserve)\n * supplyApy = pos.collateralReserve.supplyAPY(reserve.address)\n *\n * The DP minimises Σ target × (borrowApy − supplyApy) — equivalent to\n * maximising debt-weighted net APY. Utilization coupling with sibling\n * positions is not modelled; the simulator only sees this position's\n * marginal change.\n */\n private optimizePosition(pos: ResolvedPosition, candidates: GroupCandidate[]): PositionOptimum {\n const K = ALLOCATION_STEPS;\n const stepSize = pos.debtAmountUi / K;\n\n const baseSupplyApy = pos.collateralReserve.supplyAPY();\n\n // TODO: revert to pair-adjusted rates once Kamino main-market incentive distortions are resolved.\n // In costGrid: revert borrowApy to reserve.simulateNewBorrowAPY({ debtChange }, pos.collateralReserve.address)\n // and supplyIncentiveApy to pos.collateralReserve.supplyAPY(reserve.address) - baseSupplyApy.\n // In mintAllocs: same reversions for borrowApy and supplyIncentiveApy.\n const isKaminoMain = pos.pool === KAMINO_MAIN_MARKET;\n const costGrid = candidates.map(({ reserve, mint }) => {\n const posExisting = mint === pos.debtMint ? pos.debtAmountUi : 0;\n const supplyIncentiveApy = isKaminoMain\n ? 0\n : pos.collateralReserve.supplyAPY(reserve.address) - baseSupplyApy;\n return Array.from({ length: K + 1 }, (_, n) => {\n const target = n * stepSize;\n const debtChange = target - posExisting;\n const borrowApy = isKaminoMain\n ? reserve.simulateNewBorrowAPY({ debtChange })\n : reserve.simulateNewBorrowAPY({ debtChange }, pos.collateralReserve.address);\n const effectiveBorrowApy = borrowApy - supplyIncentiveApy;\n return target * this.applyUsdcBias(effectiveBorrowApy, mint, pos.biasTowardUsdc);\n });\n });\n\n // Cap each candidate's DP steps by:\n // 1. Reserve liquidity (can't borrow more than what's available)\n // 2. LTV-ratio feasibility: if the candidate pair has lower LTV than the\n // current pair, the position can only hold (candidateLtv/currentLtv)\n // of its current debt in that token. posExisting offsets the cap since\n // existing debt in the same token needs no new capacity.\n const currentPairLtv = getPairLtv(pos.collateralReserve, pos.debtReserve.address);\n const maxStepsPerCandidate = candidates.map(({ mint, reserve, liquidityAvailableUi }) => {\n const posExisting = mint === pos.debtMint ? pos.debtAmountUi : 0;\n const candidateLtv = getPairLtv(pos.collateralReserve, reserve.address);\n // Max debt in candidate token = current_debt * (candidateLtv / currentLtv),\n // assuming position is at current LTV and both tokens have ~equal price.\n const ltvCapUi =\n currentPairLtv > 0 ? (pos.debtAmountUi * candidateLtv) / currentPairLtv : pos.debtAmountUi;\n const effectiveCap = posExisting + Math.min(ltvCapUi, liquidityAvailableUi);\n return Math.min(K, Math.floor(effectiveCap / stepSize));\n });\n const optimalSteps = this.runDp(costGrid, candidates.length, K, maxStepsPerCandidate);\n\n // Keep the real APY separate from the biased selection score. The bias\n // models avoided debt-mint → USDC swap losses; it is not an actual lending\n // rate and therefore must not be reported as the projected borrow APY.\n let blendedEffectiveBorrowApy = 0;\n let blendedSelectionBorrowApy = 0;\n const mintAllocs: PositionMintAlloc[] = optimalSteps\n .map((n, i) => {\n const { mint, reserve } = candidates[i];\n const amountUi = n * stepSize;\n const posExisting = mint === pos.debtMint ? pos.debtAmountUi : 0;\n const borrowApy = isKaminoMain\n ? reserve.simulateNewBorrowAPY({ debtChange: amountUi - posExisting })\n : reserve.simulateNewBorrowAPY(\n { debtChange: amountUi - posExisting },\n pos.collateralReserve.address\n );\n const supplyIncentiveApy = isKaminoMain\n ? 0\n : pos.collateralReserve.supplyAPY(reserve.address) - baseSupplyApy;\n const effectiveBorrowApy = borrowApy - supplyIncentiveApy;\n const selectionBorrowApy = this.applyUsdcBias(effectiveBorrowApy, mint, pos.biasTowardUsdc);\n if (pos.debtAmountUi > 0) {\n blendedEffectiveBorrowApy += (amountUi / pos.debtAmountUi) * effectiveBorrowApy;\n blendedSelectionBorrowApy += (amountUi / pos.debtAmountUi) * selectionBorrowApy;\n }\n return {\n mint,\n reserve,\n amountUi,\n weightBps: Math.round((n / K) * 10_000),\n borrowApy,\n supplyIncentiveApy,\n effectiveBorrowApy,\n selectionBorrowApy,\n };\n })\n .filter((m) => m.weightBps > 0);\n\n return { mints: mintAllocs, blendedEffectiveBorrowApy, blendedSelectionBorrowApy };\n }\n\n private runDp(\n costGrid: number[][],\n numCandidates: number,\n K: number,\n maxStepsPerCandidate?: number[]\n ): number[] {\n type DPState = { minCost: number; steps: number[] };\n\n let dp: DPState[] = Array.from({ length: K + 1 }, (_, s) =>\n s === 0 ? { minCost: 0, steps: [] } : { minCost: Infinity, steps: [] }\n );\n\n for (let i = 0; i < numCandidates; i++) {\n const maxN = maxStepsPerCandidate ? maxStepsPerCandidate[i] : K;\n const next: DPState[] = Array.from({ length: K + 1 }, () => ({\n minCost: Infinity,\n steps: [],\n }));\n\n for (let s = 0; s <= K; s++) {\n if (dp[s].minCost === Infinity) continue;\n for (let n = 0; n <= Math.min(maxN, K - s); n++) {\n const cost = dp[s].minCost + costGrid[i][n];\n if (cost < next[s + n].minCost) {\n next[s + n] = { minCost: cost, steps: [...dp[s].steps, n] };\n }\n }\n }\n\n dp = next;\n }\n\n return dp[K].steps;\n }\n}\n","import { type Address, type TransactionSigner } from \"@solana/kit\";\nimport { fromWeb3Pk, LendingPlatform, mints, toBigInt, toUiAmount } from \"common\";\nimport type { LongYieldCarryClient } from \"../../client/client\";\nimport type { LongYieldCarryTransactionPlan } from \"../../client/types\";\nimport { LendingPositionBootstrapError } from \"../../errors\";\nimport type { IndexedLendingPosition, LYCToken } from \"../../models/lycToken\";\nimport {\n getAvailableTokenLendingUserAccountId,\n resolveDefaultPool,\n updateTokenLutIfNeeded,\n} from \"../../utils\";\nimport { AllocationService } from \"../allocation\";\nimport { computeConfigForCollateral } from \"../carry/carryAllocationConfig\";\n\n/** A lending position paired with the amount to deposit into it, in raw base units. */\nexport interface EvenDepositAllocation {\n lp: IndexedLendingPosition;\n depositRaw: bigint;\n}\n\n/**\n * Distributes `totalDepositRaw` across `positions` so their post-deposit\n * collateral balances end up as even as possible. Deposits only — a position\n * that is already above the resulting water level is left untouched (we never\n * withdraw to level down).\n *\n * Water-filling: the lowest-collateral positions are topped up first until they\n * reach the next tier, then the remainder is spread evenly across the leveled\n * front. Base-unit remainders from integer division go to the lowest-collateral\n * positions first, so the returned deposits sum exactly to `totalDepositRaw`.\n *\n * Only positions receiving a positive deposit are returned; each keeps its\n * original `index` for the on-chain `lendingPositions[index]` reference.\n */\nexport function computeEvenDepositAllocation(\n positions: IndexedLendingPosition[],\n totalDepositRaw: bigint\n): EvenDepositAllocation[] {\n if (positions.length === 0 || totalDepositRaw <= BigInt(0)) return [];\n\n // Copy + sort ascending by current collateral so the fill front grows from\n // the smallest position up.\n const entries = positions\n .map((lp) => ({ lp, collateral: toBigInt(lp.data.accounting.collateral) }))\n .sort((a, b) => (a.collateral < b.collateral ? -1 : a.collateral > b.collateral ? 1 : 0));\n\n const n = entries.length;\n let remaining = totalDepositRaw;\n let level = entries[0].collateral;\n let front = 1;\n\n // Raise the leveled front up to each successive tier while the budget covers\n // bringing every front position to that tier.\n while (front < n) {\n const step = entries[front].collateral - level;\n const cost = step * BigInt(front);\n if (remaining < cost) break;\n remaining -= cost;\n level = entries[front].collateral;\n front++;\n }\n\n // Spread whatever's left evenly across the `front` leveled positions.\n const base = remaining / BigInt(front);\n const extra = remaining % BigInt(front);\n const finalLevel = level + base;\n\n const allocations: EvenDepositAllocation[] = [];\n for (let i = 0; i < front; i++) {\n // Sorted ascending, so the lowest-collateral positions absorb the +1\n // base-unit remainders first.\n const deposit =\n finalLevel - entries[i].collateral + (BigInt(i) < extra ? BigInt(1) : BigInt(0));\n if (deposit > BigInt(0)) {\n allocations.push({ lp: entries[i].lp, depositRaw: deposit });\n }\n }\n return allocations;\n}\n\ntype LogFn = (msg: string) => void;\n\nexport interface EnsureInitialKaminoLendingPositionOptions {\n manager: TransactionSigner;\n /** When set, refreshes the per-token LUT after the new LP is created. */\n lutManager?: TransactionSigner;\n token: LYCToken;\n sendPlan: (plan: LongYieldCarryTransactionPlan, label: string) => Promise<void>;\n log?: LogFn;\n}\n\n/**\n * Shared logic for interacting with a token's lending positions: bootstrapping\n * the first position, and depositing unlent collateral across positions. Used\n * by deposit scripts and backend services.\n */\nexport class LendingPositionService {\n constructor(private readonly client: LongYieldCarryClient) {}\n\n /**\n * Opens the first Kamino lending position on a token that has none yet.\n *\n * Mirrors `scripts/createTokenLendingPosition.ts` and the create-LP branch in\n * `TokenRebalanceWorker`: resolve pool + optimal debt mint, compute carry\n * allocation config, send `createTokenLendingPosition`, then refetch the token.\n *\n * Kamino-specific: the flow resolves the default Kamino pool, fetches Kamino\n * reserves, and uses {@link AllocationService} over Kamino reserve data. It is\n * named accordingly until a second lending platform actually needs bootstrap\n * support (avoid speculative platform abstraction with a single implementation).\n *\n * No-op when the token already has at least one active lending position slot.\n *\n * @throws {LendingPositionBootstrapError} when the token cannot be bootstrapped\n * because of a permanent configuration gap (collateral mint not in any pool,\n * no preset, no viable debt mint / reserve). Callers should treat this as a\n * skip rather than a retryable failure.\n */\n async ensureInitialKaminoLendingPosition(\n options: EnsureInitialKaminoLendingPositionOptions\n ): Promise<LYCToken> {\n const { manager, lutManager, token, sendPlan, log } = options;\n\n if (token.activeLendingPositions.length > 0) {\n return token;\n }\n\n log?.(\"No lending positions — creating initial LP\");\n\n let pool: Address;\n try {\n pool = resolveDefaultPool(token.collateralMint);\n } catch (err) {\n throw new LendingPositionBootstrapError(\n `Cannot resolve a default pool for ${token.label} (${token.collateralMint}): ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n\n const kamino = this.client.getLendingPlatformClientByPlatform(LendingPlatform.Kamino);\n const collateralReserve = await kamino.data.fetchReserveByMint(pool, token.collateralMint);\n if (!collateralReserve) {\n throw new LendingPositionBootstrapError(\n `No Kamino reserve found for collateral ${token.label} (${token.collateralMint}) in pool ${pool}`\n );\n }\n\n const yieldingBanks = await this.client.account.fetchAllYieldingBanks();\n const allocationService = new AllocationService(kamino.data, { logger: log, yieldingBanks });\n const optimalDebt = await allocationService.findOptimalDebtMint(pool, collateralReserve, token);\n if (!optimalDebt) {\n throw new LendingPositionBootstrapError(\n `No viable debt mint found for ${token.label} on pool ${pool}`\n );\n }\n\n log?.(\n `Selected debt mint ${optimalDebt.symbol} (borrow APY ${(optimalDebt.borrowApy * 100).toFixed(3)}%)`\n );\n\n const debtReserve = await kamino.data.fetchReserveByMint(pool, optimalDebt.mint);\n if (!debtReserve) {\n throw new LendingPositionBootstrapError(\n `No Kamino reserve found for debt mint ${optimalDebt.symbol} (${optimalDebt.mint})`\n );\n }\n\n let config: ReturnType<typeof computeConfigForCollateral>;\n try {\n config = computeConfigForCollateral({\n collateralMint: token.collateralMint,\n collateralReserve,\n debtReserve,\n });\n } catch (err) {\n throw new LendingPositionBootstrapError(\n `No carry allocation config for ${token.label} (${token.collateralMint}): ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n\n const userAccountId = await getAvailableTokenLendingUserAccountId({\n lendingClient: kamino,\n token,\n pool,\n });\n\n const label = `create-initial-lp-${token.label}-${optimalDebt.symbol}`;\n const plan = await this.client.tx.createTokenLendingPosition.getTx({\n token: token.address,\n debtMint: optimalDebt.mint,\n userAccountId,\n pool,\n ...config,\n });\n await sendPlan(plan, label);\n log?.(`Sent createTokenLendingPosition (${plan.instructions.length} ix)`);\n\n this.client.clearAllCache();\n const freshToken = await this.client.account.fetchToken(token.address, { fresh: true });\n\n if (lutManager) {\n try {\n await updateTokenLutIfNeeded(lutManager, this.client.rpc, this.client, freshToken);\n log?.(\"Updated per-token LUT after initial lending position\");\n } catch (err) {\n log?.(`updateTokenLutIfNeeded failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (freshToken.activeLendingPositions.length === 0) {\n throw new Error(\n `Initial lending position creation completed but ${token.label} still has no active LPs`\n );\n }\n\n return freshToken;\n }\n\n /**\n * Deposits all unlent collateral across the token's active lending positions,\n * distributing it so their post-deposit collateral balances end up as even as\n * possible (see {@link computeEvenDepositAllocation}).\n *\n * Refreshes the token state first, then sends one `depositUnlentCollateral`\n * per position that receives an allocation. Returns one entry per deposit sent.\n */\n async depositEvenlyAcrossPositions(\n signer: TransactionSigner,\n token: LYCToken,\n log?: LogFn\n ): Promise<\n { signature: string; lendingPositionIndex: number; depositUi: number; debtSymbol: string }[]\n > {\n const positions = token.activeLendingPositions;\n if (positions.length === 0) {\n throw new Error(`Token ${token.address} has no active lending positions to deposit into`);\n }\n\n const refreshPlan = await this.client.tx.refreshTokens.getTx({\n signer: signer.address,\n params: { tokens: [token.address] },\n });\n await this.client.sendTransaction(signer, refreshPlan);\n this.client.clearAllCache();\n\n // Re-read after the refresh so the allocation is computed from the freshest\n // unlent balance and per-position collateral.\n const fresh = await this.client.account.fetchToken(token.address, { fresh: true });\n const unlentRaw = toBigInt(fresh.data.collateral.unlentAmount);\n const decimals = fresh.data.collateral.decimals;\n if (unlentRaw <= BigInt(0)) {\n throw new Error(`Token ${token.address} has no unlent collateral to deposit`);\n }\n\n const allocations = computeEvenDepositAllocation(fresh.activeLendingPositions, unlentRaw);\n if (allocations.length === 0) {\n throw new Error(`Token ${token.address}: even-deposit allocation produced no deposits`);\n }\n\n const results: {\n signature: string;\n lendingPositionIndex: number;\n depositUi: number;\n debtSymbol: string;\n }[] = [];\n for (const { lp, depositRaw } of allocations) {\n const depositUi = toUiAmount(depositRaw, decimals);\n const debtMint = fromWeb3Pk(lp.data.accounting.debt.mint);\n const debtSymbol = mints.get(debtMint)?.symbol ?? debtMint.slice(0, 6);\n log?.(`Depositing ${depositUi} into LP[${lp.index}] (debt: ${debtSymbol})...`);\n\n const depositPlan = await this.client.tx.depositUnlentCollateral.getTx({\n manager: signer.address,\n token: token.address,\n params: {\n lendingPositionIndex: lp.index,\n uiAmount: depositUi,\n },\n });\n const signature = await this.client.sendTransaction(signer, depositPlan);\n this.client.clearAllCache();\n log?.(`Deposit into LP[${lp.index}] done: ${signature}`);\n\n results.push({ signature, lendingPositionIndex: lp.index, depositUi, debtSymbol });\n }\n\n return results;\n }\n}\n","import type { Address } from \"@solana/kit\";\nimport { ExactInQuoteExceedsMaxInputError } from \"jupiter-helpers\";\nimport { FlashRebalanceSwapCostExceededError } from \"lending-platforms\";\nimport { NoOpTransactionError } from \"../../../errors\";\nimport type { LYCToken } from \"../../../models/lycToken\";\nimport type { LongYieldCarryTransactionPlan } from \"../../../client/types\";\nimport type { DebtAllocationTarget, DebtReallocation } from \"../../allocation/types\";\nimport type { LongYieldCarryClient } from \"../../../client/client\";\nimport { REBALANCE_TOKEN_RATE_LIMIT_SECS } from \"../../../constants/general\";\nimport { mints } from \"common\";\n\nexport type RebalancePlanResult =\n | { outcome: \"skipped\"; reason: string }\n | { outcome: \"plan\"; plan: LongYieldCarryTransactionPlan; label: string };\n\n/**\n * Shared logic for building a token rebalance plan from a {@link DebtReallocation}.\n * Callers are responsible for sending the returned plan (and any post-send steps such as\n * excess-rent reclaim).\n */\nexport interface TokenRebalanceServiceOptions {\n /**\n * Maximum acceptable execution cost (route fees + price impact) of the\n * rebalance swap quote vs the oracle-fair cross rate, in bps. Candidates\n * quoting worse are skipped — that cost is permanently lost value.\n * Unset = no limit.\n */\n maxSwapCostBps?: number;\n /**\n * Maximum acceptable market basis between the two debt stables, in bps\n * either direction. Bounds how much mark-to-market difference the $1-pinned\n * books absorb per conversion, and blocks rebalancing through a depegging\n * stable. Unset = no limit.\n */\n maxMarketBasisBps?: number;\n}\n\nexport class TokenRebalanceService {\n constructor(\n private readonly client: LongYieldCarryClient,\n private readonly options: TokenRebalanceServiceOptions = {}\n ) {}\n\n /**\n * Validates a reallocation and builds the rebalance transaction plan.\n * If the primary targets fail due to insufficient borrow/swap capacity\n * ({@link ExactInQuoteExceedsMaxInputError}), retries with each fallback\n * option in order before giving up.\n *\n * Returns `{ outcome: \"skipped\" }` for benign no-ops (inactive token, no active LP for the\n * reallocation index, no targets). Throws on unexpected errors from the builder.\n */\n async buildPlan(token: LYCToken, realloc: DebtReallocation): Promise<RebalancePlanResult> {\n if (!token.isActive) {\n return { outcome: \"skipped\", reason: \"token inactive (circuit breaker)\" };\n }\n\n const lpIndex = realloc.lendingPositionIndex;\n const lp = token.activeLendingPositions.find((p) => p.index === lpIndex);\n if (!lp) {\n return { outcome: \"skipped\", reason: `no active lending position at index ${lpIndex}` };\n }\n\n // Rate limit: the program rejects a rebalance on a position touched within\n // REBALANCE_TOKEN_RATE_LIMIT_SECS (RebalanceRateLimited). Skip client-side\n // so we don't build a transaction that would revert on-chain.\n const lastUpdatedTs = Number(lp.data.lastUpdatedTs.toString());\n const nowSecs = Math.floor(Date.now() / 1000);\n const elapsed = nowSecs - lastUpdatedTs;\n if (lastUpdatedTs > 0 && elapsed < REBALANCE_TOKEN_RATE_LIMIT_SECS) {\n const hoursLeft = ((REBALANCE_TOKEN_RATE_LIMIT_SECS - elapsed) / 3600).toFixed(1);\n const reason =\n `lp${lpIndex} rebalanced ${(elapsed / 3600).toFixed(1)}h ago; ` +\n `rate limit is ${REBALANCE_TOKEN_RATE_LIMIT_SECS / 3600}h (${hoursLeft}h remaining)`;\n console.log(`Skip token ${token.address.slice(0, 8)}…: ${reason}`);\n return { outcome: \"skipped\", reason };\n }\n\n const label = `rebalance-token-${token.address.slice(0, 8)}-lp${lpIndex}`;\n const allOptions = [realloc.targets, ...(realloc.fallbackTargets ?? [])];\n\n for (const targets of allOptions) {\n const targetMint = targets[0]?.mint;\n if (!targetMint) continue;\n\n try {\n const plan = await this.client.tx.rebalanceToken.getTx({\n token: token.address,\n params: {\n lpIndex,\n destinationDebtMint: targetMint,\n uiAmount: \"all\",\n maxSwapCostBps: this.options.maxSwapCostBps,\n maxMarketBasisBps: this.options.maxMarketBasisBps,\n },\n });\n return { outcome: \"plan\", plan, label };\n } catch (err) {\n if (err instanceof NoOpTransactionError) {\n return { outcome: \"skipped\", reason: err.message };\n }\n if (err instanceof FlashRebalanceSwapCostExceededError) {\n const symbol = mints.get(targetMint)?.symbol ?? targetMint.slice(0, 6);\n console.log(\n `Skip ${symbol}: swap ${err.reason} over ${err.limitBps} bps limit ` +\n `(execution cost ${err.executionCostBps.toFixed(2)} bps, ` +\n `market basis ${err.marketBasisBps.toFixed(2)} bps); trying next candidate`\n );\n continue;\n }\n if (err instanceof ExactInQuoteExceedsMaxInputError) {\n const symbol = mints.get(targetMint)?.symbol ?? targetMint.slice(0, 6);\n console.log(\n `Skip ${symbol}: borrow capacity (${err.maxInputAmount}) < swap input (${err.inputAmount}); trying next candidate`\n );\n continue;\n }\n if (err instanceof Error && err.message.includes(\"no available borrow capacity\")) {\n const symbol = mints.get(targetMint)?.symbol ?? targetMint.slice(0, 6);\n console.log(`Skip ${symbol}: no available borrow capacity; trying next candidate`);\n continue;\n }\n throw err;\n }\n }\n\n return {\n outcome: \"skipped\",\n reason:\n \"all candidates exhausted — insufficient borrow/swap capacity or swap cost above limit for each\",\n };\n }\n\n /** Convenience: fetch a fresh token then call {@link buildPlan}. */\n async fetchAndBuildPlan(\n tokenAddress: Address,\n realloc: DebtReallocation\n ): Promise<RebalancePlanResult> {\n const token = await this.client.account.fetchToken(tokenAddress, { fresh: true });\n return this.buildPlan(token, realloc);\n }\n}\n","import { mints } from \"common\";\nimport { usdStarAllocationConfig } from \"../../../constants\";\nimport type { LYCYieldingBank } from \"../../../models\";\nimport type { TargetAllocation } from \"./types\";\n\nconst USD_STAR = mints.get(\"USD*\")!;\n\n/**\n * Decides the target allocation for a yielding bank's non-base assets.\n *\n * Implementations receive the current bank state and return the desired\n * distribution across yield-bearing assets. The {@link RebalancePlanner}\n * then computes the delta (swaps) needed to reach that target.\n *\n * Strategies should be pure functions of the bank state (and any external\n * data injected through the constructor). They must not perform RPC calls\n * or side effects.\n */\nexport interface AllocationStrategy {\n computeTarget(bank: LYCYieldingBank): TargetAllocation;\n}\n\n/**\n * Default strategy: deploy 100% of idle base asset into USD*.\n *\n * This is the simplest possible allocation — all non-base value goes to\n * a single Perena stablecoin. Replace with a multi-asset strategy when\n * additional yield-bearing positions (e.g. USD*-J) are introduced.\n */\nexport class SimpleUsdStarStrategy implements AllocationStrategy {\n computeTarget(_bank: LYCYieldingBank): TargetAllocation {\n return [\n {\n mint: USD_STAR.address,\n weightBps: 10_000,\n slippageBps: 50,\n allocationConfig: usdStarAllocationConfig,\n },\n ];\n }\n}\n","import type { Address } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport { applyBps, fromWeb3Pk, toBigInt } from \"common\";\nimport type { RebalanceSwapSpec, YieldingBankAllocationConfig } from \"../../../client/types\";\nimport type { LYCYieldingBank } from \"../../../models\";\nimport type { AllocationStrategy } from \"./strategy\";\nimport type { AllocationTarget, YieldingBankRebalancePlan } from \"./types\";\n\n/** Minimum 6-decimal stablecoin amount worth swapping: 0.01 token (~$0.01). */\nconst MIN_STABLE_SWAP_AMOUNT = 10_000;\n\ninterface HoldingSnapshot {\n mint: Address;\n amount: bigint;\n}\n\n/**\n * Computes the swaps needed to move a yielding bank from its current\n * asset distribution to a target allocation.\n *\n * The planner is stateless and performs no RPC — it operates entirely on\n * the in-memory bank model and the strategy's target. This makes it\n * straightforward to unit-test.\n *\n * ## How it works\n *\n * 1. The {@link AllocationStrategy} produces a {@link TargetAllocation}\n * (e.g. 25% USD*, 75% USD*-J).\n * 2. The planner classifies every bank holding as either a **target**\n * (a mint the strategy manages) or an **idle source** (everything\n * else — the base asset, plus any non-target stablecoins that\n * arrived from borrows in other denominations).\n * 3. Each idle source with a non-trivial balance gets its own\n * {@link YieldingBankRebalancePlan} that deploys its capital\n * proportionally across the targets according to their weights.\n * 4. If existing target holdings are imbalanced relative to their\n * weights (overweight / underweight), a separate rebalance plan\n * routes through the base mint. The resulting swaps are sorted\n * sells-first so freed base-mint liquidity is available for\n * subsequent buy swaps.\n *\n * All swaps route through the bank's base mint as the common\n * intermediate, matching how the on-chain `rebalance_yielding_bank`\n * instruction processes CPI swaps.\n */\nexport class RebalancePlanner {\n constructor(private readonly strategy: AllocationStrategy) {}\n\n /**\n * Plan the rebalance for a single yielding bank.\n * Returns an empty array if no action is needed.\n *\n * Each element is an independent plan that can be sent as its own\n * transaction. Separate plans are produced for:\n * - Each idle source (base asset, or non-target stablecoins)\n * - Target-to-target rebalancing (selling overweight, buying underweight)\n */\n plan(bank: LYCYieldingBank): YieldingBankRebalancePlan[] {\n const targets = this.strategy.computeTarget(bank);\n const targetMints = new Set(targets.map((t) => t.mint));\n\n const idleSources = this.discoverIdleSources(bank, targetMints);\n const targetHoldings = this.snapshotTargetHoldings(bank, targetMints);\n\n const plans: YieldingBankRebalancePlan[] = [];\n\n for (const source of idleSources) {\n const plan = this.buildDeploymentPlan(bank, targets, source);\n if (plan) plans.push(plan);\n }\n\n const rebalancePlan = this.buildTargetRebalancePlan(bank, targets, targetHoldings);\n if (rebalancePlan) plans.push(rebalancePlan);\n\n return plans;\n }\n\n // ---------------------------------------------------------------------------\n // Idle source discovery\n // ---------------------------------------------------------------------------\n\n /**\n * Returns every holding on the bank that is NOT a strategy target.\n * This includes the base asset and any non-target asset slots with\n * a positive balance (e.g. a stablecoin that arrived from a\n * non-base-mint borrow).\n */\n private discoverIdleSources(bank: LYCYieldingBank, targetMints: Set<string>): HoldingSnapshot[] {\n const sources: HoldingSnapshot[] = [];\n\n const baseAmount = toBigInt(bank.data.baseAsset.amount);\n if (baseAmount > 0n) {\n sources.push({ mint: bank.baseMint, amount: baseAmount });\n }\n\n for (const asset of bank.data.assets) {\n if (asset.mint.equals(PublicKey.default)) continue;\n const mint = fromWeb3Pk(asset.mint);\n if (targetMints.has(mint)) continue;\n const amount = toBigInt(asset.amount);\n if (amount > 0n) {\n sources.push({ mint, amount });\n }\n }\n\n return sources;\n }\n\n /** Snapshot only the holdings that ARE strategy targets. */\n private snapshotTargetHoldings(\n bank: LYCYieldingBank,\n targetMints: Set<string>\n ): HoldingSnapshot[] {\n const result: HoldingSnapshot[] = [];\n\n for (const asset of bank.data.assets) {\n if (asset.mint.equals(PublicKey.default)) continue;\n const mint = fromWeb3Pk(asset.mint);\n if (!targetMints.has(mint)) continue;\n result.push({ mint, amount: toBigInt(asset.amount) });\n }\n\n return result;\n }\n\n // ---------------------------------------------------------------------------\n // Plan builders\n // ---------------------------------------------------------------------------\n\n /**\n * Build a plan that deploys a single idle source proportionally\n * across the strategy's targets according to their weights.\n */\n private buildDeploymentPlan(\n bank: LYCYieldingBank,\n targets: AllocationTarget[],\n source: HoldingSnapshot\n ): YieldingBankRebalancePlan | null {\n if (source.amount < BigInt(MIN_STABLE_SWAP_AMOUNT)) return null;\n\n const swaps: RebalanceSwapSpec[] = [];\n let newAllocation: { config: YieldingBankAllocationConfig } | undefined;\n\n for (const alloc of targets) {\n const share = applyBps(source.amount, alloc.weightBps);\n if (Number(share) < MIN_STABLE_SWAP_AMOUNT) continue;\n\n swaps.push({\n inputMint: source.mint,\n outputMint: alloc.mint,\n amount: Number(share),\n slippageBps: alloc.slippageBps,\n });\n\n if (!newAllocation && bank.findAssetHolding(alloc.mint) === null) {\n newAllocation = { config: alloc.allocationConfig };\n }\n }\n\n if (swaps.length === 0 && !newAllocation) return null;\n return { swaps, newAllocation };\n }\n\n /**\n * Build a plan that rebalances between existing target holdings when\n * they've drifted from the strategy's desired weights. Overweight\n * targets are sold back to the base mint; underweight targets are\n * bought with the freed base.\n */\n private buildTargetRebalancePlan(\n bank: LYCYieldingBank,\n targets: AllocationTarget[],\n targetHoldings: HoldingSnapshot[]\n ): YieldingBankRebalancePlan | null {\n const totalTargetValue = targetHoldings.reduce((sum, h) => sum + h.amount, 0n);\n if (totalTargetValue <= 0n) return null;\n\n const swaps: RebalanceSwapSpec[] = [];\n\n for (const alloc of targets) {\n const desired = applyBps(totalTargetValue, alloc.weightBps);\n const current = this.findCurrentAmount(targetHoldings, alloc.mint);\n const delta = desired - current;\n const absDelta = delta < 0n ? -delta : delta;\n\n if (Number(absDelta) < MIN_STABLE_SWAP_AMOUNT) continue;\n\n if (delta < 0n) {\n swaps.push({\n inputMint: alloc.mint,\n outputMint: bank.baseMint,\n amount: Number(absDelta),\n slippageBps: alloc.slippageBps,\n });\n } else {\n swaps.push({\n inputMint: bank.baseMint,\n outputMint: alloc.mint,\n amount: Number(delta),\n slippageBps: alloc.slippageBps,\n });\n }\n }\n\n if (swaps.length === 0) return null;\n swaps.sort(\n (a, b) => (a.inputMint === bank.baseMint ? 1 : 0) - (b.inputMint === bank.baseMint ? 1 : 0)\n );\n return { swaps };\n }\n\n private findCurrentAmount(holdings: HoldingSnapshot[], mint: string): bigint {\n return holdings.find((h) => h.mint === mint)?.amount ?? 0n;\n }\n}\n","import { type Address, type TransactionSigner } from \"@solana/kit\";\nimport { toBigInt, toUiAmount } from \"common\";\nimport type { LongYieldCarryClient } from \"../../client/client\";\nimport type {\n DecreaseCarryRepaySteering,\n LongYieldCarryTransactionPlan,\n RedemptionEpochSnapshot,\n} from \"../../client/types\";\nimport {\n REDEMPTION_EPOCH_STATUS_FUNDING,\n REDEMPTION_EPOCH_STATUS_OPEN,\n REDEMPTION_EPOCH_STATUS_PROCESSING,\n} from \"../../constants/general\";\nimport type { IndexedLendingPosition, LYCToken } from \"../../models/lycToken\";\n\nconst EPOCH_WINDOW_MS = 60_000;\nconst DEFAULT_DCP_SWAP_SLIPPAGE_BPS = 100;\n// Retries after the initial attempt (3 attempts total). Each attempt\n// re-fetches a fresh swap quote.\nconst DCP_MAX_RETRIES = 2;\n// Mirrors on-chain UTILIZATION_RATE_DEVIATION_THRESHOLD_BPS (150 bps relative margin).\nconst UTILIZATION_RATE_DEVIATION_THRESHOLD_BPS = 150;\n// Extra fraction added to partial withdrawals so Kamino rounding never leaves\n// the epoch a few lamports short. 0.1% is well within the utilization margin.\nconst WITHDRAWAL_OVERSHOOT_BPS = 10;\n\nexport interface RedemptionServiceOptions {\n /** Swap slippage tolerance for DCP transactions, in bps. Defaults to 100. */\n dcpSwapSlippageBps?: number;\n /** Optional structured sink for warnings (funding CPI failures, partial funding). */\n structuredLog?: (entry: StructuredRedemptionLog) => void;\n}\n\n/** Single LP-targeted funding failure captured during epoch funding. */\nexport interface RedemptionFundingFailure {\n lpIndex: number;\n message: string;\n}\n\n/** Aggregated non-fatal failures while funding an epoch (DCP vs withdraw phases). */\nexport interface RedemptionFundingErrors {\n dcp: RedemptionFundingFailure[];\n withdraw: RedemptionFundingFailure[];\n}\n\nexport interface StructuredRedemptionLog {\n level: \"warn\" | \"info\";\n event: string;\n data?: Record<string, unknown>;\n}\n\nexport interface FundRedemptionEpochResult {\n funded: boolean;\n fundedCollateral: bigint;\n grossCollateralClaim: bigint;\n realizedUnwindLoss: bigint;\n errors: RedemptionFundingErrors;\n}\n\nexport interface ProcessEpochResult {\n requestsProcessed: number;\n}\n\ntype LogFn = (msg: string) => void;\n\nfunction emptyFundingErrors(): RedemptionFundingErrors {\n return { dcp: [], withdraw: [] };\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction errorNameAndMessage(err: unknown): string {\n if (err instanceof Error) return `${err.name}: ${err.message}`;\n return String(err);\n}\n\nfunction compactStack(stack: string): string {\n return stack\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .slice(0, 12)\n .join(\" | \");\n}\n\nfunction errorCause(err: unknown): unknown {\n return err !== null && typeof err === \"object\" && \"cause\" in err\n ? (err as { cause?: unknown }).cause\n : undefined;\n}\n\nfunction errorDiagnostics(err: unknown): string[] {\n const diagnostics: string[] = [];\n let current: unknown = err;\n\n for (let depth = 0; current !== undefined && depth < 4; depth += 1) {\n const prefix = depth === 0 ? \"error\" : `cause[${depth}]`;\n diagnostics.push(`${prefix}: ${errorNameAndMessage(current)}`);\n\n if (current instanceof Error && current.stack) {\n diagnostics.push(`${prefix} stack: ${compactStack(current.stack)}`);\n }\n\n current = errorCause(current);\n }\n\n return diagnostics;\n}\n\n/**\n * Orchestrates the redemption epoch lifecycle: detecting open epochs, waiting\n * for their time window to elapse, funding (DCP + top-up), and processing\n * individual async burn requests.\n *\n * Holds a reference to the LYC client and caches yielding-bank PDAs per token\n * so repeated calls against the same token avoid redundant derivation.\n */\nexport class RedemptionService {\n private readonly yieldingBankCache = new Map<string, Address[]>();\n private readonly dcpSwapSlippageBps: number;\n private readonly structuredLog?: (entry: StructuredRedemptionLog) => void;\n\n constructor(\n private readonly client: LongYieldCarryClient,\n opts?: RedemptionServiceOptions\n ) {\n this.dcpSwapSlippageBps = opts?.dcpSwapSlippageBps ?? DEFAULT_DCP_SWAP_SLIPPAGE_BPS;\n this.structuredLog = opts?.structuredLog;\n }\n\n // ── Epoch discovery ────────────────────────────────────────────────────────\n\n /** Delegates to `client.account.fetchAllRedemptionEpochs`. */\n async getAllEpochs(): Promise<RedemptionEpochSnapshot[]> {\n return this.client.account.fetchAllRedemptionEpochs({ fresh: true });\n }\n\n /** Delegates to `client.account.fetchRedemptionEpoch`. */\n async getEpoch(epochPda: Address): Promise<RedemptionEpochSnapshot> {\n return this.client.account.fetchRedemptionEpoch(epochPda, { fresh: true });\n }\n\n /** Re-fetches an existing snapshot from on-chain state. */\n async refreshEpoch(epoch: RedemptionEpochSnapshot): Promise<RedemptionEpochSnapshot> {\n return this.getEpoch(epoch.pda);\n }\n\n // ── Epoch window ───────────────────────────────────────────────────────────\n\n /**\n * Returns the number of milliseconds until the epoch's acceptance window\n * closes. Zero or negative means the window has already elapsed.\n */\n epochWindowRemainingMs(epoch: RedemptionEpochSnapshot): number {\n return Number(epoch.epochId) + EPOCH_WINDOW_MS - Date.now();\n }\n\n /**\n * Sleeps until the epoch's 60-second acceptance window has elapsed. Returns\n * immediately if the window is already closed.\n */\n async waitForEpochWindow(epoch: RedemptionEpochSnapshot, log?: LogFn): Promise<void> {\n const remainingMs = this.epochWindowRemainingMs(epoch);\n if (remainingMs <= 0) {\n log?.(\"Epoch window already closed.\");\n return;\n }\n log?.(`Waiting ${Math.ceil(remainingMs / 1000)}s for epoch window to close...`);\n await new Promise((resolve) => setTimeout(resolve, remainingMs));\n log?.(\"Window closed.\");\n }\n\n // ── Status transitions ─────────────────────────────────────────────────────\n\n /**\n * Transitions an epoch from Open → Funding. Waits for the epoch window to\n * close first so in-flight burns can still land.\n */\n async closeEpoch(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n log?: LogFn\n ): Promise<void> {\n if (epoch.status !== REDEMPTION_EPOCH_STATUS_OPEN) return;\n\n await this.waitForEpochWindow(epoch, log);\n\n log?.(\"Setting status → Funding...\");\n const plan = await this.client.tx.setRedemptionEpochStatus.getTx({\n token: epoch.tokenPda,\n redemptionEpoch: epoch.pda,\n params: { status: REDEMPTION_EPOCH_STATUS_FUNDING },\n });\n await this.client.sendTransaction(signer, plan);\n this.client.clearAllCache();\n }\n\n /** Transitions an epoch from Funding → Processing. */\n async startProcessing(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n log?: LogFn\n ): Promise<void> {\n if (epoch.status > REDEMPTION_EPOCH_STATUS_FUNDING) return;\n\n log?.(\"Setting status → Processing...\");\n const plan = await this.client.tx.setRedemptionEpochStatus.getTx({\n token: epoch.tokenPda,\n redemptionEpoch: epoch.pda,\n params: { status: REDEMPTION_EPOCH_STATUS_PROCESSING },\n });\n await this.client.sendTransaction(signer, plan);\n this.client.clearAllCache();\n }\n\n // ── Funding ────────────────────────────────────────────────────────────────\n\n /**\n * Funds a redemption epoch. Withdraws from debt-free LPs first (no DCP\n * needed), then — if a deficit remains — runs targeted DCP + withdraw on\n * carry-loaded LPs, prioritizing non-optimal positions.\n */\n async fundEpoch(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n log?: LogFn\n ): Promise<FundRedemptionEpochResult> {\n const fundingErrors = emptyFundingErrors();\n const fresh = await this.refreshEpoch(epoch);\n if (this.isFullyFunded(fresh)) {\n log?.(\"Already fully funded.\");\n return this.fundResult(fresh, fundingErrors);\n }\n\n const token = await this.client.account.fetchToken(fresh.tokenPda, { fresh: true });\n const decimals = token.data.collateral.decimals;\n const deficitUi = this.deficitUi(fresh, decimals);\n log?.(`Deficit: ${deficitUi}`);\n\n await this.fundFromDebtFreeLps(signer, token, fresh, decimals, fundingErrors, log);\n\n const afterDirect = await this.refreshEpoch(epoch);\n if (this.isFullyFunded(afterDirect)) {\n log?.(\"Fully funded from debt-free LPs — no DCP needed.\");\n return this.fundResult(afterDirect, fundingErrors);\n }\n\n await this.fundFromCarryLps(signer, fresh.tokenPda, afterDirect, decimals, fundingErrors, log);\n\n const afterCarry = await this.refreshEpoch(epoch);\n if (this.isFullyFunded(afterCarry)) {\n log?.(\"Fully funded.\");\n return this.fundResult(afterCarry, fundingErrors);\n }\n\n await this.creditResidualUnlent(signer, afterCarry, decimals, log);\n\n const afterResidual = await this.refreshEpoch(epoch);\n if (this.isFullyFunded(afterResidual)) {\n log?.(\"Fully funded from lending positions and residual unlent reserves.\");\n }\n return this.fundResult(afterResidual, fundingErrors);\n }\n\n // ── Request processing ─────────────────────────────────────────────────────\n\n /**\n * Processes all remaining async burn requests in a redemption epoch in FIFO\n * order.\n */\n async processRequests(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n log?: LogFn\n ): Promise<ProcessEpochResult> {\n const snap = await this.refreshEpoch(epoch);\n let processed = 0;\n for (let seq = snap.processedRequestCount; seq < snap.requestCount; seq++) {\n const plan = await this.client.tx.processAsyncBurn.getTx({\n token: snap.tokenPda,\n params: { epochId: snap.epochId, sequence: seq },\n });\n const debug = plan.debug?.processAsyncBurn;\n if (debug) {\n const payoutTarget =\n debug.collateralDelivery === \"nativeSol\"\n ? `native SOL via request escrow ${debug.requestCollateralAccount ?? \"unknown\"}`\n : `user collateral ATA ${debug.userCollateralAccount ?? \"unknown\"}`;\n log?.(`Request ${seq}: user ${debug.user}, payout ${payoutTarget}`);\n }\n const sig = await this.client.sendTransaction(signer, plan);\n log?.(`Request ${seq}: ${sig}`);\n this.client.clearAllCache();\n processed++;\n }\n return { requestsProcessed: processed };\n }\n\n // ── Full lifecycle ─────────────────────────────────────────────────────────\n\n /**\n * Runs the complete epoch lifecycle: close → fund → transition to\n * processing → process all requests.\n *\n * Returns true if the epoch was fully processed and closed.\n */\n async processEpoch(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n log?: LogFn\n ): Promise<boolean> {\n await this.closeEpoch(signer, epoch, log);\n\n const afterClose = await this.refreshEpoch(epoch);\n const fundResult = await this.fundEpoch(signer, afterClose, log);\n if (fundResult.errors.dcp.length > 0 || fundResult.errors.withdraw.length > 0) {\n const summary = `${fundResult.errors.dcp.length} DCP failure(s), ${fundResult.errors.withdraw.length} withdraw failure(s)`;\n log?.(`Funding phase recorded ${summary}.`);\n this.structuredLog?.({\n level: \"warn\",\n event: \"redemption_epoch_funding_failures\",\n data: {\n epochPda: afterClose.pda,\n tokenPda: afterClose.tokenPda,\n dcp: fundResult.errors.dcp,\n withdraw: fundResult.errors.withdraw,\n },\n });\n }\n if (!fundResult.funded) {\n log?.(\n `Epoch underfunded (${fundResult.fundedCollateral} / ${fundResult.grossCollateralClaim}; ` +\n `realized unwind loss ${fundResult.realizedUnwindLoss}).`\n );\n return false;\n }\n\n const afterFunding = await this.refreshEpoch(afterClose);\n await this.startProcessing(signer, afterFunding, log);\n\n const processingEpoch = await this.refreshEpoch(afterFunding);\n const remaining = processingEpoch.requestCount - processingEpoch.processedRequestCount;\n log?.(`Processing ${remaining} request(s)...`);\n await this.processRequests(signer, processingEpoch, log);\n return true;\n }\n\n // ── Cache management ───────────────────────────────────────────────────────\n\n clearYieldingBankCache(): void {\n this.yieldingBankCache.clear();\n }\n\n // ── Private: funding phases ───────────────────────────────────────────────\n\n /**\n * Credits only the residual shortfall from collateral already sitting in the\n * token PDA's unlent reserve. LP withdrawals run first so existing reserves\n * are used as the tail of mixed LP/unlent funding, not the first source.\n */\n private async creditResidualUnlent(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n decimals: number,\n log?: LogFn\n ): Promise<void> {\n const current = await this.refreshEpoch(epoch);\n const shortfall = current.grossCollateralClaim - current.fundedCollateral;\n if (shortfall <= 0n) return;\n\n const token = await this.client.account.fetchToken(current.tokenPda, { fresh: true });\n const rawUnlent = token.data.collateral.unlentAmount;\n const unlent = rawUnlent === undefined ? 0n : toBigInt(rawUnlent);\n const uncreditedUnlent =\n unlent > current.fundedCollateral ? unlent - current.fundedCollateral : 0n;\n if (uncreditedUnlent === 0n) return;\n\n const credit = shortfall < uncreditedUnlent ? shortfall : uncreditedUnlent;\n log?.(`Crediting residual unlent reserves (${toUiAmount(credit, decimals)}) to epoch...`);\n const plan = await this.client.tx.creditUnlentToRedemptionEpoch.getTx({\n token: token.address,\n redemptionEpoch: current.pda,\n });\n await this.client.sendTransaction(signer, plan);\n this.client.clearAllCache();\n }\n\n /** Phase 1: withdraw directly from LPs that have no debt (no DCP needed). */\n private async fundFromDebtFreeLps(\n signer: TransactionSigner,\n token: LYCToken,\n epoch: RedemptionEpochSnapshot,\n decimals: number,\n fundingErrors: RedemptionFundingErrors,\n log?: LogFn\n ): Promise<void> {\n const debtFreeLps = token.usedLendingPositions.filter(\n (lp) => toBigInt(lp.data.accounting.debt.amount) === 0n\n );\n if (debtFreeLps.length === 0) {\n log?.(\"No debt-free LP collateral available for direct withdrawal.\");\n return;\n }\n\n log?.(`${debtFreeLps.length} debt-free LP(s) — withdrawing directly...`);\n await this.withdrawFromLps(signer, epoch, decimals, debtFreeLps, fundingErrors, log);\n }\n\n /**\n * Phase 2: DCP + withdraw from carry-loaded LPs, processed in position order\n * (first slot to last) so burns unwind positions deterministically.\n */\n private async fundFromCarryLps(\n signer: TransactionSigner,\n tokenPda: Address,\n epoch: RedemptionEpochSnapshot,\n decimals: number,\n fundingErrors: RedemptionFundingErrors,\n log?: LogFn\n ): Promise<void> {\n const remainingDeficitUi = this.deficitUi(epoch, decimals);\n log?.(`Remaining deficit after debt-free withdrawals: ${remainingDeficitUi}`);\n\n const token = await this.client.account.fetchToken(tokenPda, { fresh: true });\n // `usedLendingPositions` preserves on-chain slot order, so this iterates\n // first slot to last.\n const carryLps = token.usedLendingPositions.filter(\n (lp) => toBigInt(lp.data.accounting.debt.amount) > 0n\n );\n if (carryLps.length === 0) {\n log?.(\"No carry-loaded LP collateral available for DCP funding.\");\n return;\n }\n\n await this.dcpAcrossLps(\n signer,\n token,\n epoch,\n remainingDeficitUi,\n decimals,\n carryLps,\n fundingErrors,\n log\n );\n await this.withdrawFromLps(signer, epoch, decimals, carryLps, fundingErrors, log);\n }\n\n // ── Private: DCP ──────────────────────────────────────────────────────────\n\n /**\n * Runs a targeted DCP on each LP that needs collateral freed. Iterates `lps`\n * in the caller-provided order (on-chain slot order, first to last).\n */\n private async dcpAcrossLps(\n signer: TransactionSigner,\n token: LYCToken,\n epoch: RedemptionEpochSnapshot,\n totalDeficitUi: number,\n decimals: number,\n lps: IndexedLendingPosition[],\n fundingErrors: RedemptionFundingErrors,\n log?: LogFn\n ): Promise<void> {\n if (token.activeCarryPositions.length === 0) return;\n\n const fallbackBanks = await this.resolveYieldingBanks(token);\n const fallbackBank = fallbackBanks[0];\n if (!fallbackBank) return;\n\n let remainingDeficitUi = totalDeficitUi;\n\n for (const lp of lps) {\n if (remainingDeficitUi <= 0) break;\n\n const lpCollateralUi = toUiAmount(toBigInt(lp.data.accounting.collateral), decimals);\n\n // Skip DCP only when the amount this LP must supply (plus the withdrawal\n // overshoot) can be withdrawn directly while keeping post-withdraw\n // utilization within the on-chain threshold. Current utilization being\n // in range is not enough: withdrawing collateral with debt outstanding\n // raises utilization, and both Kamino's max LTV and the\n // top_up_unlent_reserves post-withdraw check validate the resulting state.\n const neededUi = Math.min(remainingDeficitUi, lpCollateralUi);\n const neededWithOvershootUi = neededUi * (1 + WITHDRAWAL_OVERSHOOT_BPS / 10_000);\n const maxDirectUi = toUiAmount(this.maxDirectWithdrawal(lp), decimals);\n if (maxDirectUi >= neededWithOvershootUi) {\n log?.(\n `DCP LP[${lp.index}] skipped — needed ${neededUi} within direct-withdrawal headroom (${maxDirectUi}).`\n );\n remainingDeficitUi -= neededUi;\n continue;\n }\n\n const fullUnwind = remainingDeficitUi >= lpCollateralUi;\n\n const dcpSucceeded = await this.dcpSingleLp(\n signer,\n epoch,\n lp,\n fallbackBank,\n fullUnwind,\n neededUi,\n fundingErrors,\n log\n );\n if (dcpSucceeded) {\n remainingDeficitUi -= neededUi;\n }\n }\n }\n\n /**\n * Max collateral (native units) withdrawable from an LP without a prior DCP.\n *\n * TopUpUnlentReserves re-checks `is_utilization_rate_at_or_below_target`\n * AFTER the withdrawal (util <= target + target * threshold / 10_000), and\n * utilization scales as `util_after = util * collateral / (collateral - w)`\n * when debt and prices stay constant (mirrors on-chain\n * `simulate_utilization_rate_bps_after_collateral_withdraw`). Inverting\n * against the upper bound gives:\n * w_max = collateral * (limit - util) / limit\n */\n private maxDirectWithdrawal(lp: IndexedLendingPosition): bigint {\n const collateral = toBigInt(lp.data.accounting.collateral);\n const utilBps = BigInt(lp.data.accounting.ltvUtilizationRateBps);\n if (utilBps === 0n) return collateral;\n\n const target = lp.data.config.targetUtilizationRateBps;\n const margin = Math.floor((target * UTILIZATION_RATE_DEVIATION_THRESHOLD_BPS) / 10_000);\n const limitBps = BigInt(Math.min(target + margin, 10_000));\n if (utilBps >= limitBps) return 0n;\n return (collateral * (limitBps - utilBps)) / limitBps;\n }\n\n /**\n * Executes a single DCP on one lending position with retry logic. Uses full\n * unwind (target utilization 0) when the deficit exceeds the LP's collateral,\n * otherwise uses `collateralWithdrawal` steering.\n */\n private async dcpSingleLp(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n lp: IndexedLendingPosition,\n yieldingBank: Address,\n fullUnwind: boolean,\n withdrawUi: number,\n fundingErrors: RedemptionFundingErrors,\n log?: LogFn\n ): Promise<boolean> {\n const repaySteering: DecreaseCarryRepaySteering = fullUnwind\n ? {\n mode: \"explicitTargetUtilization\",\n targetUtilizationRateBps: 0,\n }\n : {\n mode: \"collateralWithdrawal\",\n collateralWithdrawalUiAmount: withdrawUi,\n allowBelowTargetOnChain: true,\n };\n\n const label = fullUnwind ? \"full unwind\" : \"collateralWithdrawal steering\";\n log?.(`DCP LP[${lp.index}] (${label})...`);\n\n let lastError = \"unknown error\";\n for (let attempt = 0; attempt <= DCP_MAX_RETRIES; attempt++) {\n if (attempt > 0) {\n log?.(`DCP LP[${lp.index}] retry ${attempt}/${DCP_MAX_RETRIES}...`);\n this.client.clearAllCache();\n }\n\n const attemptLabel = `${attempt + 1}/${DCP_MAX_RETRIES + 1}`;\n log?.(\n `DCP LP[${lp.index}] attempt ${attemptLabel}: building plan ` +\n `(token=${epoch.tokenPda}, epoch=${epoch.pda}, yieldingBank=${yieldingBank}, signer=${signer.address}).`\n );\n\n let plan: LongYieldCarryTransactionPlan;\n try {\n plan = await this.client.tx.decreaseCarryPosition.getTx({\n signer: signer.address,\n token: epoch.tokenPda,\n redemptionEpoch: epoch.pda,\n params: {\n lendingPositionIndex: lp.index,\n yieldingBank,\n swapSlippageBps: this.dcpSwapSlippageBps,\n ...(repaySteering ? { repaySteering } : {}),\n },\n });\n } catch (err) {\n lastError = errorMessage(err);\n log?.(`DCP LP[${lp.index}] plan build failed: ${lastError}`);\n for (const detail of errorDiagnostics(err)) {\n log?.(`DCP LP[${lp.index}] plan build ${detail}`);\n }\n continue;\n }\n\n log?.(\n `DCP LP[${lp.index}] attempt ${attemptLabel}: plan built ` +\n `(${plan.instructions.length} ix, ${plan.lookupTables?.length ?? 0} LUT(s)); sending transaction.`\n );\n\n try {\n await this.client.sendTransaction(signer, plan);\n this.client.clearAllCache();\n log?.(`DCP LP[${lp.index}] done.`);\n return true;\n } catch (err) {\n lastError = errorMessage(err);\n log?.(`DCP LP[${lp.index}] send failed: ${lastError}`);\n for (const detail of errorDiagnostics(err)) {\n log?.(`DCP LP[${lp.index}] send ${detail}`);\n }\n }\n }\n log?.(`DCP LP[${lp.index}] exhausted retries — continuing.`);\n fundingErrors.dcp.push({ lpIndex: lp.index, message: lastError });\n return false;\n }\n\n // ── Private: top-up withdrawals ───────────────────────────────────────────\n\n /**\n * Withdraws collateral from lending positions into unlent reserves, crediting\n * the redemption epoch. Stops as soon as the epoch is fully funded.\n */\n private async withdrawFromLps(\n signer: TransactionSigner,\n epoch: RedemptionEpochSnapshot,\n decimals: number,\n lps: IndexedLendingPosition[],\n fundingErrors: RedemptionFundingErrors,\n log?: LogFn\n ): Promise<void> {\n for (const lp of lps) {\n const current = await this.refreshEpoch(epoch);\n if (this.isFullyFunded(current)) break;\n\n // Re-fetch the LP so post-DCP debt/collateral (and thus utilization) are\n // current — the caller's snapshot predates any DCPs run this funding pass.\n const token = await this.client.account.fetchToken(epoch.tokenPda, { fresh: true });\n const freshLp = token.usedLendingPositions.find((p) => p.index === lp.index);\n if (!freshLp) continue;\n\n const remainingDeficit = current.grossCollateralClaim - current.fundedCollateral;\n const lpCollateral = toBigInt(freshLp.data.accounting.collateral);\n\n // For partial withdrawals, overshoot slightly so Kamino rounding never\n // leaves the epoch a few lamports short of fully funded.\n const overshoot = (remainingDeficit * BigInt(WITHDRAWAL_OVERSHOOT_BPS)) / 10_000n;\n const withOvershoot = remainingDeficit + overshoot;\n const requested =\n withOvershoot < lpCollateral\n ? withOvershoot\n : remainingDeficit < lpCollateral\n ? remainingDeficit\n : lpCollateral;\n\n // Cap at what the post-withdraw utilization checks (Kamino max LTV and\n // on-chain is_utilization_rate_at_or_below_target) allow with the LP's\n // remaining debt.\n const maxWithdraw = this.maxDirectWithdrawal(freshLp);\n if (maxWithdraw === 0n) {\n log?.(`LP[${lp.index}]: skipped — no utilization headroom for a direct withdrawal.`);\n continue;\n }\n const amount = requested < maxWithdraw ? requested : maxWithdraw;\n if (amount < requested) {\n log?.(\n `LP[${lp.index}]: capping withdrawal at utilization headroom (${toUiAmount(maxWithdraw, decimals)}).`\n );\n }\n\n const drainAll = amount >= lpCollateral;\n const fundsFully = amount >= remainingDeficit;\n const uiAmount: number | \"all\" = drainAll ? \"all\" : toUiAmount(amount, decimals);\n\n log?.(`LP[${lp.index}]: withdrawing ${drainAll ? \"all\" : uiAmount}...`);\n try {\n const plan = await this.client.tx.topUpUnlentReserves.getTx({\n token: epoch.tokenPda,\n params: {\n lendingPositionIndex: lp.index,\n uiAmount,\n redemptionEpoch: epoch.pda,\n },\n });\n if (!drainAll && fundsFully) {\n // Bundle Funding → Processing in the same tx. On-chain the status\n // instruction validates funded_collateral >= gross_collateral_claim,\n // so the whole tx rolls back atomically if the withdrawal fell short.\n const statusIx = await this.client.tx.setRedemptionEpochStatus.getIx({\n token: epoch.tokenPda,\n redemptionEpoch: epoch.pda,\n params: { status: REDEMPTION_EPOCH_STATUS_PROCESSING },\n });\n plan.instructions.push(statusIx);\n }\n await this.client.sendTransaction(signer, plan);\n this.client.clearAllCache();\n if (fundsFully) break;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log?.(`LP[${lp.index}] withdraw failed: ${message}`);\n fundingErrors.withdraw.push({ lpIndex: lp.index, message });\n }\n }\n }\n\n // ── Private: utilities ────────────────────────────────────────────────────\n\n private isFullyFunded(epoch: RedemptionEpochSnapshot): boolean {\n return epoch.fundedCollateral >= epoch.grossCollateralClaim;\n }\n\n private deficitUi(epoch: RedemptionEpochSnapshot, decimals: number): number {\n return toUiAmount(epoch.grossCollateralClaim - epoch.fundedCollateral, decimals);\n }\n\n private fundResult(\n epoch: RedemptionEpochSnapshot,\n errors: RedemptionFundingErrors\n ): FundRedemptionEpochResult {\n return {\n funded: this.isFullyFunded(epoch),\n fundedCollateral: epoch.fundedCollateral,\n grossCollateralClaim: epoch.grossCollateralClaim,\n realizedUnwindLoss: epoch.realizedUnwindLoss,\n errors,\n };\n }\n\n private async resolveYieldingBanks(token: LYCToken): Promise<Address[]> {\n const cached = this.yieldingBankCache.get(token.address);\n if (cached) return cached;\n\n const seen = new Set<string>();\n const banks: Address[] = [];\n for (const carry of token.activeCarryPositions) {\n const bankPda = await token.deriveYieldingBankAddressForDebtCarryIndex(\n carry.index,\n this.client.pda\n );\n if (!seen.has(bankPda)) {\n seen.add(bankPda);\n banks.push(bankPda);\n }\n }\n\n this.yieldingBankCache.set(token.address, banks);\n return banks;\n }\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport type { Address } from \"@solana/kit\";\nimport { fetchMaybeToken, TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport {\n fetchMaybeToken as fetchMaybeToken2022,\n TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport {\n calculateTvlUsd,\n fromWeb3Pk,\n getAtaAddress,\n LendingPlatform,\n lendingPlatformToEnum,\n mintSymbol,\n resolveTokenProgram,\n toBigInt,\n toUiAmount,\n TVL_USD_DECIMAL_PLACES,\n type AnchorTokenProgram,\n} from \"common\";\nimport type { LendingPositionInspectMetrics, ReserveBase } from \"lending-platforms\";\nimport type { LongYieldCarryClient } from \"../client\";\nimport { PROTOCOL_FEE_WALLET } from \"../constants/general\";\nimport type { LYCToken, TokenLendingPositionData } from \"../models/lycToken\";\nimport type { LYCYieldingBank, YieldingBankAccountData } from \"../models/yieldingBank\";\nimport { calculateFeeDripMetrics, type FeeDripAbsorptionStatus } from \"../utils/feeDripMetrics\";\nimport { podBoolToNumber } from \"../utils/general\";\nimport { collectableNetYieldUsd } from \"../utils/tokenFeeMath\";\n\n/** Skip dust Kamino slots when a material position exists on the same token. */\nexport const MIN_MATERIAL_KAMINO_COLLATERAL_USD = 1;\n\nexport interface LendingPositionInspectMetricSnapshot {\n utilizationRealtimeBps: number;\n utilizationEmaBps: number;\n lowerTriggerPriceChangePct?: number;\n upperTriggerPriceChangePct?: number;\n}\n\nexport interface YieldingBankExternalPositionMetricSnapshot {\n platform: LendingPlatform;\n pool: Address;\n tvlUsdRaw: string;\n tvlUsd: number;\n}\n\nexport type ProtocolMetricEntityType =\n | \"token\"\n | \"yielding_bank\"\n | \"yielding_bank_asset\"\n | \"kamino_position_rate\"\n | \"token_lending_position\"\n | \"token_carry_position\"\n | \"fee_wallet_balance\"\n | \"protocol_manifest\";\n\n/**\n * Balance held by the protocol fee wallet for one mint. Performance fees\n * arrive here as collateral at `collect_interest` time (no pending counter\n * exists on the token), and mint/burn fees arrive as yTokens via\n * `collect_fees` — so these balances are the only on-chain record of\n * cumulative collected fees.\n */\nexport interface FeeWalletBalanceMetricSnapshot {\n entityType: \"fee_wallet_balance\";\n wallet: Address;\n mint: Address;\n symbol: string;\n /** \"collateral\" = performance fees; \"ytoken\" = collected mint/burn fees. */\n kind: \"collateral\" | \"ytoken\";\n decimals: number;\n amountRaw: string;\n amountUi: number;\n priceUsd: number;\n valueUsd: number;\n}\n\n/** Index of entity keys written for a single ingestion hour (enables API assembly). */\nexport interface ProtocolManifestSnapshot {\n entityType: \"protocol_manifest\";\n tokenMints: Address[];\n bankAddresses: Address[];\n kaminoPositions: Array<{ mint: Address; lendingPositionIndex: number }>;\n yieldingBankAssets: Array<{ bank: Address; mint: Address }>;\n /** Present on manifests written after Phase 2 ingestion deploy. */\n tokenLendingPositions?: Array<{ mint: Address; lendingPositionIndex: number }>;\n /** Present on manifests written after Phase 2 ingestion deploy. */\n tokenCarryPositions?: Array<{ mint: Address; carryPositionIndex: number }>;\n /** Present on manifests written after fee-wallet tracking deploy. */\n feeWalletBalances?: Array<{ wallet: Address; mint: Address }>;\n /**\n * Per-row build failures from this ingestion hour (skipped Kamino rate rows,\n * failed inspect enrichment). Persisted so the ops dashboard can surface\n * partial snapshots instead of silently dropping rows.\n */\n errors?: ProtocolMetricsSnapshotError[];\n}\n\nexport const PROTOCOL_MANIFEST_PK = \"protocol_manifest\";\n\nexport interface TokenMetricSnapshot {\n entityType: \"token\";\n token: Address;\n mint: Address;\n collateralMint: Address;\n isActive: boolean;\n priceCollateral: number;\n collateralPriceUsd: number;\n priceUsd: number;\n totalSupply: number;\n tvlUsdRaw: string;\n tvlUsd: number;\n carryTvlUsdRaw: string;\n carryTvlUsd: number;\n debtUsdRaw: string;\n debtUsd: number;\n netYieldUsdRaw: string;\n netYieldUsd: number;\n pendingProtocolFeesRaw: string;\n pendingProtocolFeesUi: number;\n pendingCuratorFeesRaw: string;\n pendingCuratorFeesUi: number;\n performanceFeeBps: number;\n mintingFeeBps: number;\n burningFeeBps: number;\n protocolMintBurnPctBps: number;\n curatorMintBurnPctBps: number;\n curatorPerfPctBps: number;\n /** Absent on snapshots ingested before fee-drip projection metrics were added. */\n feeDripMaxApyBps?: number;\n feeDripCurrentApyBps?: number | null;\n undrippedFeeCollateralUi?: number;\n feeDripAbsorptionEtaSeconds?: number | null;\n feeDripAbsorptionStatus?: FeeDripAbsorptionStatus;\n firstMintTs: number;\n collateralOracle: Address;\n collateralLastRefreshedTs: number;\n unlentCollateralUi: number;\n lastRefreshedTs: number;\n}\n\nexport interface YieldingBankMetricSnapshot {\n entityType: \"yielding_bank\";\n bank: Address;\n id: number;\n baseMint: Address;\n isActive: boolean;\n sharePriceRaw: string;\n sharePriceUsd: number;\n totalSharesRaw: string;\n totalShares: number;\n tvlUsdRaw: string;\n tvlUsd: number;\n baseSymbol: string;\n curator: Address;\n circuitBreaker: number;\n defaultRedemptionMint?: Address;\n externalYieldingPositions: YieldingBankExternalPositionMetricSnapshot[];\n lastRefreshedTs: number;\n lastRebalancedTs: number;\n}\n\nexport interface YieldingBankAssetMetricSnapshot {\n entityType: \"yielding_bank_asset\";\n bank: Address;\n assetIndex: number;\n assetKind: \"base\" | \"asset\";\n mint: Address;\n amountRaw: string;\n amountUi: number;\n decimals: number;\n priceRaw: string;\n priceUsd: number;\n tvlUsdRaw: string;\n tvlUsd: number;\n}\n\nexport interface TokenLendingPositionMetricSnapshot {\n entityType: \"token_lending_position\";\n token: Address;\n mint: Address;\n lendingPositionIndex: number;\n platform: LendingPlatform;\n withdrawPending: boolean;\n pool: Address;\n userAccount: Address;\n collateralAmountRaw: string;\n collateralAmountUi: number;\n collateralSymbol: string;\n collateralUsd: number;\n debtAmountRaw: string;\n debtAmountUi: number;\n debtTvlUsdRaw: string;\n debtTvlUsd: number;\n debtMint: Address;\n debtSymbol: string;\n debtPriceUsd: number;\n onChainUtilizationRateBps: number;\n targetUtilizationRateBps: number;\n maxDeviationAboveTargetUtilBps: number;\n maxDeviationBelowTargetUtilBps: number;\n inspect?: LendingPositionInspectMetricSnapshot;\n}\n\nexport interface TokenCarryPositionMetricSnapshot {\n entityType: \"token_carry_position\";\n token: Address;\n mint: Address;\n carryPositionIndex: number;\n yieldingBankId: number;\n yieldingBankAddress?: Address;\n baseMint: Address;\n baseSymbol: string;\n sharesRaw: string;\n sharesUi?: number;\n tvlUsdRaw: string;\n tvlUsd: number;\n}\n\nexport interface KaminoPositionRateSnapshot {\n entityType: \"kamino_position_rate\";\n token: Address;\n mint: Address;\n lendingPositionIndex: number;\n pool: Address;\n userAccount: Address;\n collateralReserve: Address;\n debtReserve: Address;\n collateralMint: Address;\n debtMint: Address;\n supplyBaseApy: number;\n borrowBaseApy: number;\n supplyEffectiveApy: number;\n borrowEffectiveApy: number;\n netEffectiveApy: number;\n collateralReserveUtilizationPct: number;\n debtReserveUtilizationPct: number;\n onChainLtvUtilizationBps: number;\n targetUtilizationRateBps: number;\n maxDeviationAboveTargetUtilBps: number;\n maxDeviationBelowTargetUtilBps: number;\n}\n\nexport type ProtocolMetricSnapshotRow =\n | TokenMetricSnapshot\n | YieldingBankMetricSnapshot\n | YieldingBankAssetMetricSnapshot\n | KaminoPositionRateSnapshot\n | TokenLendingPositionMetricSnapshot\n | TokenCarryPositionMetricSnapshot\n | FeeWalletBalanceMetricSnapshot\n | ProtocolManifestSnapshot;\n\nexport interface ProtocolMetricsSnapshot {\n timestamp: number;\n tokens: TokenMetricSnapshot[];\n yieldingBanks: YieldingBankMetricSnapshot[];\n yieldingBankAssets: YieldingBankAssetMetricSnapshot[];\n kaminoPositionRates: KaminoPositionRateSnapshot[];\n tokenLendingPositions: TokenLendingPositionMetricSnapshot[];\n tokenCarryPositions: TokenCarryPositionMetricSnapshot[];\n feeWalletBalances: FeeWalletBalanceMetricSnapshot[];\n errors: ProtocolMetricsSnapshotError[];\n}\n\nexport interface ProtocolMetricsSnapshotError {\n scope: \"kamino_position_rate\" | \"lending_position_inspect\";\n token: Address;\n lendingPositionIndex: number;\n message: string;\n}\n\nexport interface BuildProtocolMetricsSnapshotOptions {\n timestamp?: number;\n includeInactive?: boolean;\n tokens?: LYCToken[];\n yieldingBanks?: LYCYieldingBank[];\n}\n\nexport function protocolMetricPartitionKey(metric: ProtocolMetricSnapshotRow): string {\n switch (metric.entityType) {\n case \"token\":\n return `token#${metric.mint}`;\n case \"yielding_bank\":\n return `yielding_bank#${metric.bank}`;\n case \"yielding_bank_asset\":\n return `yielding_bank_asset#${metric.bank}#${metric.mint}`;\n case \"kamino_position_rate\":\n return `kamino_position#${metric.mint}#${metric.lendingPositionIndex}`;\n case \"token_lending_position\":\n return `token_lending_position#${metric.mint}#${metric.lendingPositionIndex}`;\n case \"token_carry_position\":\n return `token_carry_position#${metric.mint}#${metric.carryPositionIndex}`;\n case \"fee_wallet_balance\":\n return `fee_wallet#${metric.wallet}#${metric.mint}`;\n case \"protocol_manifest\":\n return PROTOCOL_MANIFEST_PK;\n }\n}\n\nexport function buildProtocolManifestSnapshot(\n snapshot: ProtocolMetricsSnapshot\n): ProtocolManifestSnapshot {\n return {\n entityType: \"protocol_manifest\",\n tokenMints: snapshot.tokens.map((token) => token.mint),\n bankAddresses: snapshot.yieldingBanks.map((bank) => bank.bank),\n kaminoPositions: snapshot.kaminoPositionRates.map((rate) => ({\n mint: rate.mint,\n lendingPositionIndex: rate.lendingPositionIndex,\n })),\n yieldingBankAssets: snapshot.yieldingBankAssets.map((asset) => ({\n bank: asset.bank,\n mint: asset.mint,\n })),\n tokenLendingPositions: snapshot.tokenLendingPositions.map((position) => ({\n mint: position.mint,\n lendingPositionIndex: position.lendingPositionIndex,\n })),\n tokenCarryPositions: snapshot.tokenCarryPositions.map((position) => ({\n mint: position.mint,\n carryPositionIndex: position.carryPositionIndex,\n })),\n feeWalletBalances: snapshot.feeWalletBalances.map((balance) => ({\n wallet: balance.wallet,\n mint: balance.mint,\n })),\n errors: snapshot.errors,\n };\n}\n\nexport function flattenProtocolMetricsSnapshot(\n snapshot: ProtocolMetricsSnapshot\n): ProtocolMetricSnapshotRow[] {\n return [\n ...snapshot.tokens,\n ...snapshot.yieldingBanks,\n ...snapshot.yieldingBankAssets,\n ...snapshot.kaminoPositionRates,\n ...snapshot.tokenLendingPositions,\n ...snapshot.tokenCarryPositions,\n ...snapshot.feeWalletBalances,\n buildProtocolManifestSnapshot(snapshot),\n ];\n}\n\n/** Dynamo item shape written by {@link buildProtocolMetricDynamoItems}. */\nexport interface ProtocolMetricDynamoItem {\n pk: string;\n timestamp: number;\n entityType: ProtocolMetricEntityType;\n metrics: ProtocolMetricSnapshotRow;\n ttl?: number;\n}\n\nexport function toProtocolMetricDynamoItem(\n metric: ProtocolMetricSnapshotRow,\n hourTimestamp: number,\n ttl?: number\n): ProtocolMetricDynamoItem {\n return {\n pk: protocolMetricPartitionKey(metric),\n timestamp: hourTimestamp,\n entityType: metric.entityType,\n metrics: metric,\n ttl,\n };\n}\n\nexport interface BuildProtocolMetricDynamoItemsOptions extends BuildProtocolMetricsSnapshotOptions {\n hourTimestamp: number;\n ttl?: number;\n}\n\nexport interface BuildProtocolMetricDynamoItemsResult {\n items: ProtocolMetricDynamoItem[];\n errors: ProtocolMetricsSnapshotError[];\n}\n\n/** Builds on-chain snapshot rows and maps them to Dynamo put payloads. */\nexport async function buildProtocolMetricDynamoItems(\n client: LongYieldCarryClient,\n opts: BuildProtocolMetricDynamoItemsOptions\n): Promise<BuildProtocolMetricDynamoItemsResult> {\n const snapshot = await buildProtocolMetricsSnapshot(client, {\n ...opts,\n timestamp: opts.hourTimestamp,\n });\n\n const items = flattenProtocolMetricsSnapshot(snapshot).map((row) =>\n toProtocolMetricDynamoItem(row, opts.hourTimestamp, opts.ttl)\n );\n\n return { items, errors: snapshot.errors };\n}\n\nexport async function buildProtocolMetricsSnapshot(\n client: LongYieldCarryClient,\n opts: BuildProtocolMetricsSnapshotOptions = {}\n): Promise<ProtocolMetricsSnapshot> {\n const timestamp = opts.timestamp ?? Math.floor(Date.now() / 1000);\n const { tokens, yieldingBanks } =\n opts.tokens && opts.yieldingBanks\n ? { tokens: opts.tokens, yieldingBanks: opts.yieldingBanks }\n : await client.account.fetchAllTokensAndYieldingBanks();\n\n const filteredTokens = opts.includeInactive ? tokens : tokens.filter((token) => token.isActive);\n const filteredBanks = opts.includeInactive\n ? yieldingBanks\n : yieldingBanks.filter((bank) => bank.isActive);\n\n const tokenSnapshots = filteredTokens.map((token) =>\n buildTokenMetricSnapshot(token, filteredBanks, timestamp)\n );\n const bankSnapshots = filteredBanks.map(buildYieldingBankMetricSnapshot);\n const assetSnapshots = filteredBanks.flatMap(buildYieldingBankAssetMetricSnapshots);\n const lendingPositionResults = await Promise.all(\n filteredTokens.map((token) =>\n buildTokenLendingPositionMetricSnapshotsAsync(client, token, filteredBanks)\n )\n );\n const lendingPositionSnapshots = lendingPositionResults.flatMap((result) => result.snapshots);\n // Kamino rate rows use `usedLendingPositions` (collateral > 0) while lending position\n // snapshots use `activeLendingPositions` (all configured slots). Zero-collateral slots\n // can still appear in lending rows; Kamino rate rows and stale-slot alerts handle that.\n const { rates, errors } = await buildKaminoPositionRateSnapshots(client, filteredTokens);\n const carryPositionSnapshots = filteredTokens.flatMap((token) =>\n buildTokenCarryPositionMetricSnapshots(token, filteredBanks)\n );\n const feeWalletBalances = await buildFeeWalletBalanceSnapshots(client, filteredTokens);\n\n return {\n timestamp,\n tokens: tokenSnapshots,\n yieldingBanks: bankSnapshots,\n yieldingBankAssets: assetSnapshots,\n kaminoPositionRates: rates,\n tokenLendingPositions: lendingPositionSnapshots,\n tokenCarryPositions: carryPositionSnapshots,\n feeWalletBalances,\n errors: [...errors, ...lendingPositionResults.flatMap((result) => result.errors)],\n };\n}\n\n/**\n * Snapshots the protocol fee wallet's ATA balances for every token's\n * collateral mint (cumulative performance fees) and yToken mint (cumulative\n * collected mint/burn fees). Collateral mints shared by multiple tokens are\n * deduped — the balance is per mint, not per token. RPC failures skip the\n * row rather than failing the whole snapshot; the balance reappears next hour.\n */\ntype FeeWalletTarget = {\n kind: \"collateral\" | \"ytoken\";\n symbol: string;\n decimals: number;\n priceUsd: number;\n tokenProgram: Address;\n};\n\nfunction resolveFeeWalletTokenProgram(tp: AnchorTokenProgram | undefined): Address {\n if (tp == null) {\n return TOKEN_PROGRAM_ADDRESS;\n }\n return resolveTokenProgram(tp);\n}\n\n/** Read an SPL or Token-2022 ATA balance using the mint's token program. */\nasync function fetchFeeWalletTokenAmountRaw(\n rpc: LongYieldCarryClient[\"rpc\"],\n ata: Address,\n tokenProgram: Address\n): Promise<bigint> {\n const account =\n tokenProgram === TOKEN_2022_PROGRAM_ADDRESS\n ? await fetchMaybeToken2022(rpc, ata)\n : await fetchMaybeToken(rpc, ata);\n return account.exists ? account.data.amount : 0n;\n}\n\nexport async function buildFeeWalletBalanceSnapshots(\n client: LongYieldCarryClient,\n tokens: LYCToken[]\n): Promise<FeeWalletBalanceMetricSnapshot[]> {\n const wallet = PROTOCOL_FEE_WALLET[client.environment];\n const targets = new Map<Address, FeeWalletTarget>();\n\n for (const token of tokens) {\n const collateralPriceUsd = toUiAmount(\n token.data.collateral.price,\n token.data.collateral.decimals\n );\n const collateralTokenProgram = resolveFeeWalletTokenProgram(token.data.collateral.tokenProgram);\n if (!targets.has(token.collateralMint)) {\n targets.set(token.collateralMint, {\n kind: \"collateral\",\n symbol: mintSymbol(token.collateralMint),\n decimals: token.data.collateral.decimals,\n priceUsd: collateralPriceUsd,\n tokenProgram: collateralTokenProgram,\n });\n }\n targets.set(token.mint, {\n kind: \"ytoken\",\n symbol: `y${mintSymbol(token.collateralMint)}`,\n decimals: token.decimals,\n priceUsd: token.price * collateralPriceUsd,\n tokenProgram: resolveFeeWalletTokenProgram(token.data.config.tokenProgram),\n });\n }\n\n const snapshots = await Promise.all(\n [...targets.entries()].map(\n async ([mint, target]): Promise<FeeWalletBalanceMetricSnapshot | null> => {\n try {\n const ata = await getAtaAddress(mint, wallet, target.tokenProgram);\n const amountRaw = await fetchFeeWalletTokenAmountRaw(\n client.rpc,\n ata,\n target.tokenProgram\n );\n const amountUi = toUiAmount(amountRaw, target.decimals);\n return {\n entityType: \"fee_wallet_balance\",\n wallet,\n mint,\n symbol: target.symbol,\n kind: target.kind,\n decimals: target.decimals,\n amountRaw: amountRaw.toString(),\n amountUi,\n priceUsd: target.priceUsd,\n valueUsd: amountUi * target.priceUsd,\n };\n } catch {\n return null;\n }\n }\n )\n );\n\n return snapshots.filter((row): row is FeeWalletBalanceMetricSnapshot => row !== null);\n}\n\nexport function buildTokenMetricSnapshot(\n token: LYCToken,\n yieldingBanks: LYCYieldingBank[] = [],\n nowTs = Math.floor(Date.now() / 1000)\n): TokenMetricSnapshot {\n const carryTvlUsdRaw = token.data.debtCarry\n .filter(\n (carry) =>\n !carry.yieldingBaseMint.equals(PublicKey.default) && toBigInt(carry.shares) > BigInt(0)\n )\n .reduce((sum, carry) => sum + toBigInt(carry.tvlUsd), 0n);\n const debtUsdRaw = token.activeLendingPositions.reduce(\n (sum, { data }) => sum + toBigInt(data.accounting.debt.tvlUsd),\n 0n\n );\n const netYieldUsdRaw = collectableNetYieldUsd(carryTvlUsdRaw, debtUsdRaw);\n const collateralPriceUsd = toUiAmount(\n token.data.collateral.price,\n token.data.collateral.decimals\n );\n const feeDripMetrics = calculateFeeDripMetrics({\n currentPriceRaw: toBigInt(token.data.accounting.price),\n apyReferencePriceRaw: toBigInt(token.data.feeDrip.apyReferencePrice),\n apyReferenceTs: toBigInt(token.data.feeDrip.apyReferenceTs),\n currentPriceTs: BigInt(token.data.accounting.lastRefreshedTs.toNumber()),\n totalSupplyRaw: toBigInt(token.data.accounting.totalSupply),\n tokenDecimals: token.decimals,\n undrippedFeeCollateralRaw: toBigInt(token.data.feeDrip.undrippedFeeCollateral),\n feeDripMaxApyBps: token.data.fees.feeDripMaxApyBps,\n nowTs: BigInt(nowTs),\n });\n\n return {\n entityType: \"token\",\n token: token.address,\n mint: token.mint,\n collateralMint: token.collateralMint,\n isActive: token.isActive,\n priceCollateral: token.price,\n collateralPriceUsd,\n priceUsd: token.price * collateralPriceUsd,\n totalSupply: token.totalSupply,\n tvlUsdRaw: toBigInt(token.data.accounting.tvlUsd).toString(),\n tvlUsd: toUiAmount(token.data.accounting.tvlUsd, TVL_USD_DECIMAL_PLACES),\n carryTvlUsdRaw: carryTvlUsdRaw.toString(),\n carryTvlUsd: toUiAmount(carryTvlUsdRaw, TVL_USD_DECIMAL_PLACES),\n debtUsdRaw: debtUsdRaw.toString(),\n debtUsd: toUiAmount(debtUsdRaw, TVL_USD_DECIMAL_PLACES),\n netYieldUsdRaw: netYieldUsdRaw.toString(),\n netYieldUsd: toUiAmount(netYieldUsdRaw, TVL_USD_DECIMAL_PLACES),\n pendingProtocolFeesRaw: toBigInt(token.data.accounting.pendingProtocolFees).toString(),\n pendingProtocolFeesUi: toUiAmount(token.data.accounting.pendingProtocolFees, token.decimals),\n pendingCuratorFeesRaw: toBigInt(token.data.accounting.pendingCuratorFees).toString(),\n pendingCuratorFeesUi: toUiAmount(token.data.accounting.pendingCuratorFees, token.decimals),\n performanceFeeBps: token.data.fees.performanceFeeBps,\n mintingFeeBps: token.data.fees.mintingFeeBps,\n burningFeeBps: token.data.fees.burningFeeBps,\n protocolMintBurnPctBps: token.data.fees.protocolMintBurnPctBps,\n curatorMintBurnPctBps: token.data.fees.curatorMintBurnPctBps,\n curatorPerfPctBps: token.data.fees.curatorPerfPctBps,\n feeDripMaxApyBps: token.data.fees.feeDripMaxApyBps,\n feeDripCurrentApyBps: feeDripMetrics.currentApyBps,\n undrippedFeeCollateralUi: toUiAmount(\n token.data.feeDrip.undrippedFeeCollateral,\n token.data.collateral.decimals\n ),\n feeDripAbsorptionEtaSeconds: feeDripMetrics.absorptionEtaSeconds,\n feeDripAbsorptionStatus: feeDripMetrics.absorptionStatus,\n firstMintTs: token.data.accounting.firstMintTs.toNumber(),\n collateralOracle: fromWeb3Pk(token.data.collateral.oracle),\n collateralLastRefreshedTs: token.data.collateral.lastRefreshedTs.toNumber(),\n unlentCollateralUi: toUiAmount(\n token.data.collateral.unlentAmount,\n token.data.collateral.decimals\n ),\n lastRefreshedTs: token.data.accounting.lastRefreshedTs.toNumber(),\n };\n}\n\nexport function buildYieldingBankMetricSnapshot(bank: LYCYieldingBank): YieldingBankMetricSnapshot {\n const defaultRedemptionMint =\n bank.defaultRedemptionMint !== PublicKey.default.toBase58()\n ? bank.defaultRedemptionMint\n : undefined;\n\n const externalYieldingPositions = bank.externalYieldingPositions\n .map((position) => ({\n platform: lendingPlatformToEnum(position.lendingPlatform),\n pool: fromWeb3Pk(position.pool),\n tvlRaw: toBigInt(position.tvl),\n tvlUsd: toUiAmount(position.tvl, TVL_USD_DECIMAL_PLACES),\n }))\n .filter((position) => position.platform !== LendingPlatform.None)\n .map((position) => ({\n platform: position.platform,\n pool: position.pool,\n tvlUsdRaw: position.tvlRaw.toString(),\n tvlUsd: position.tvlUsd,\n }));\n\n return {\n entityType: \"yielding_bank\",\n bank: bank.address,\n id: bank.id,\n baseMint: bank.baseMint,\n baseSymbol: mintSymbol(bank.baseMint),\n curator: fromWeb3Pk(bank.data.roles.curator),\n isActive: bank.isActive,\n circuitBreaker: bank.circuitBreaker,\n defaultRedemptionMint,\n externalYieldingPositions,\n sharePriceRaw: toBigInt(bank.data.accounting.sharePrice).toString(),\n sharePriceUsd: bank.sharePrice,\n totalSharesRaw: toBigInt(bank.data.accounting.totalShares).toString(),\n totalShares: bank.totalShares,\n tvlUsdRaw: toBigInt(bank.data.accounting.tvl).toString(),\n tvlUsd: toUiAmount(bank.data.accounting.tvl, TVL_USD_DECIMAL_PLACES),\n lastRefreshedTs: bank.data.accounting.lastRefreshedTs.toNumber(),\n lastRebalancedTs: bank.data.accounting.lastRebalancedTs.toNumber(),\n };\n}\n\nexport function buildTokenLendingPositionMetricSnapshots(\n token: LYCToken,\n yieldingBanks: LYCYieldingBank[] = []\n): TokenLendingPositionMetricSnapshot[] {\n const collateralSymbol = mintSymbol(token.collateralMint);\n const collateralDecimals = token.data.collateral.decimals;\n const collateralPriceUsd = toUiAmount(\n token.data.collateral.price,\n token.data.collateral.decimals\n );\n return token.activeLendingPositions.map(({ index, data: position }) => {\n const platform = lendingPlatformToEnum(position.platform);\n const collateralAmountUi = toUiAmount(position.accounting.collateral, collateralDecimals);\n const debtMint = fromWeb3Pk(position.accounting.debt.mint);\n const debtTvlUsdRaw = toBigInt(position.accounting.debt.tvlUsd);\n\n return {\n entityType: \"token_lending_position\",\n token: token.address,\n mint: token.mint,\n lendingPositionIndex: index,\n platform,\n withdrawPending: podBoolToNumber(position.withdrawPending) !== 0,\n pool: fromWeb3Pk(position.pool),\n userAccount: fromWeb3Pk(position.protocolUserAcc),\n collateralAmountRaw: toBigInt(position.accounting.collateral).toString(),\n collateralAmountUi,\n collateralSymbol,\n collateralUsd: collateralAmountUi * collateralPriceUsd,\n debtAmountRaw: toBigInt(position.accounting.debt.amount).toString(),\n debtAmountUi: toUiAmount(position.accounting.debt.amount, position.accounting.debt.decimals),\n debtTvlUsdRaw: debtTvlUsdRaw.toString(),\n debtTvlUsd: toUiAmount(debtTvlUsdRaw, TVL_USD_DECIMAL_PLACES),\n debtMint,\n debtSymbol: mintSymbol(debtMint),\n debtPriceUsd: toUiAmount(position.accounting.debt.price, position.accounting.debt.decimals),\n onChainUtilizationRateBps: position.accounting.ltvUtilizationRateBps,\n targetUtilizationRateBps: position.config.targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps: position.config.maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps: position.config.maxDeviationBelowTargetUtilBps,\n };\n });\n}\n\nexport async function buildTokenLendingPositionMetricSnapshotsAsync(\n client: LongYieldCarryClient,\n token: LYCToken,\n yieldingBanks: LYCYieldingBank[] = []\n): Promise<{\n snapshots: TokenLendingPositionMetricSnapshot[];\n errors: ProtocolMetricsSnapshotError[];\n}> {\n const baseSnapshots = buildTokenLendingPositionMetricSnapshots(token, yieldingBanks);\n const kaminoData = client.getLendingPlatformClientByPlatform(LendingPlatform.Kamino).data;\n const errors: ProtocolMetricsSnapshotError[] = [];\n\n const snapshots = await Promise.all(\n baseSnapshots.map(async (snapshot) => {\n if (snapshot.platform !== LendingPlatform.Kamino) {\n return snapshot;\n }\n\n const position = token.activeLendingPositions.find(\n (row) => row.index === snapshot.lendingPositionIndex\n )?.data;\n if (!position) {\n return snapshot;\n }\n\n try {\n const { LycLendingPositionManager } = await import(\"../services/carry\");\n const manager = await LycLendingPositionManager.create(kaminoData, position);\n const inspectMetrics = await manager.getInspectMetrics();\n const inspect = serializeLendingPositionInspectMetrics(inspectMetrics);\n return inspect ? { ...snapshot, inspect } : snapshot;\n } catch (err) {\n // The base snapshot is still valid without inspect enrichment, but the\n // failure must be recorded — silently missing Util RT/EMA cells have\n // hidden real bugs (e.g. trigger-band math throwing on >100% bands).\n errors.push({\n scope: \"lending_position_inspect\",\n token: token.address,\n lendingPositionIndex: snapshot.lendingPositionIndex,\n message: err instanceof Error ? err.message : String(err),\n });\n return snapshot;\n }\n })\n );\n\n return { snapshots, errors };\n}\n\nexport function serializeLendingPositionInspectMetrics(\n metrics: LendingPositionInspectMetrics | null | undefined\n): LendingPositionInspectMetricSnapshot | undefined {\n if (!metrics) {\n return undefined;\n }\n\n return {\n utilizationRealtimeBps: metrics.utilizationRateBps.realtime,\n utilizationEmaBps: metrics.utilizationRateBps.ema,\n lowerTriggerPriceChangePct: metrics.triggerBand.lower?.priceChangePct,\n upperTriggerPriceChangePct: metrics.triggerBand.upper?.priceChangePct,\n };\n}\n\nexport function kaminoCollateralUsd(token: LYCToken, position: TokenLendingPositionData): number {\n const collateralAmountUi = toUiAmount(\n position.accounting.collateral,\n token.data.collateral.decimals\n );\n const collateralPriceUsd = toUiAmount(\n token.data.collateral.price,\n token.data.collateral.decimals\n );\n return collateralAmountUi * collateralPriceUsd;\n}\n\nexport function shouldIncludeKaminoPositionRate(\n collateralUsd: number,\n maxCollateralUsdOnToken: number\n): boolean {\n if (maxCollateralUsdOnToken < MIN_MATERIAL_KAMINO_COLLATERAL_USD) {\n return true;\n }\n return collateralUsd >= MIN_MATERIAL_KAMINO_COLLATERAL_USD;\n}\n\nexport function buildTokenCarryPositionMetricSnapshots(\n token: LYCToken,\n yieldingBanks: LYCYieldingBank[]\n): TokenCarryPositionMetricSnapshot[] {\n const snapshots: TokenCarryPositionMetricSnapshot[] = [];\n\n token.data.debtCarry.forEach((carry, carryPositionIndex) => {\n if (carry.yieldingBaseMint.equals(PublicKey.default)) {\n return;\n }\n\n const baseMint = fromWeb3Pk(carry.yieldingBaseMint);\n const resolvedBank = yieldingBanks.find(\n (bank) => bank.id === carry.yieldingBankId && bank.baseMint === baseMint\n );\n\n snapshots.push({\n entityType: \"token_carry_position\",\n token: token.address,\n mint: token.mint,\n carryPositionIndex,\n yieldingBankId: carry.yieldingBankId,\n yieldingBankAddress: resolvedBank?.address,\n baseMint,\n baseSymbol: mintSymbol(baseMint),\n sharesRaw: toBigInt(carry.shares).toString(),\n sharesUi: resolvedBank ? toUiAmount(carry.shares, resolvedBank.decimals) : undefined,\n tvlUsdRaw: toBigInt(carry.tvlUsd).toString(),\n tvlUsd: toUiAmount(carry.tvlUsd, TVL_USD_DECIMAL_PLACES),\n });\n });\n\n return snapshots;\n}\n\nexport function buildYieldingBankAssetMetricSnapshots(\n bank: LYCYieldingBank\n): YieldingBankAssetMetricSnapshot[] {\n const snapshots: YieldingBankAssetMetricSnapshot[] = [];\n if (!bank.data.baseAsset.mint.equals(PublicKey.default)) {\n snapshots.push(buildYieldingBankAssetMetricSnapshot(bank, bank.data.baseAsset, 0, \"base\"));\n }\n\n bank.data.assets.forEach((asset, index) => {\n if (asset.mint.equals(PublicKey.default)) return;\n snapshots.push(buildYieldingBankAssetMetricSnapshot(bank, asset, index + 1, \"asset\"));\n });\n\n return snapshots;\n}\n\nasync function buildKaminoPositionRateSnapshots(\n client: LongYieldCarryClient,\n tokens: LYCToken[]\n): Promise<{\n rates: KaminoPositionRateSnapshot[];\n errors: ProtocolMetricsSnapshotError[];\n}> {\n const rates: KaminoPositionRateSnapshot[] = [];\n const errors: ProtocolMetricsSnapshotError[] = [];\n const kaminoData = client.getLendingPlatformClientByPlatform(LendingPlatform.Kamino).data;\n\n for (const token of tokens) {\n const kaminoPositions = token.usedLendingPositions.filter(\n ({ data: position }) => lendingPlatformToEnum(position.platform) === LendingPlatform.Kamino\n );\n const maxCollateralUsd = Math.max(\n 0,\n ...kaminoPositions.map(({ data: position }) => kaminoCollateralUsd(token, position))\n );\n\n for (const { index, data: position } of kaminoPositions) {\n const collateralUsd = kaminoCollateralUsd(token, position);\n if (!shouldIncludeKaminoPositionRate(collateralUsd, maxCollateralUsd)) {\n continue;\n }\n\n try {\n const rate = await buildKaminoPositionRateSnapshot(token, index, position, kaminoData);\n rates.push(rate);\n } catch (err) {\n errors.push({\n scope: \"kamino_position_rate\",\n token: token.address,\n lendingPositionIndex: index,\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n return { rates, errors };\n}\n\nasync function buildKaminoPositionRateSnapshot(\n token: LYCToken,\n lendingPositionIndex: number,\n position: TokenLendingPositionData,\n kaminoData: ReturnType<LongYieldCarryClient[\"getLendingPlatformClientByPlatform\"]>[\"data\"]\n): Promise<KaminoPositionRateSnapshot> {\n const pool = fromWeb3Pk(position.pool);\n const [collateralReserve, debtReserve] = await Promise.all([\n kaminoData.fetchReserve(pool, fromWeb3Pk(position.collateralReserve)),\n kaminoData.fetchReserve(pool, fromWeb3Pk(position.debtReserve)),\n ]);\n\n if (!collateralReserve || !debtReserve) {\n throw new Error(\"Failed to fetch Kamino reserves\");\n }\n\n return buildKaminoPositionRateSnapshotFromReserves(\n token,\n lendingPositionIndex,\n position,\n collateralReserve,\n debtReserve\n );\n}\n\nexport function buildKaminoPositionRateSnapshotFromReserves(\n token: LYCToken,\n lendingPositionIndex: number,\n position: TokenLendingPositionData,\n collateralReserve: ReserveBase,\n debtReserve: ReserveBase\n): KaminoPositionRateSnapshot {\n const supplyEffectiveApy = collateralReserve.supplyAPY(debtReserve.address);\n const borrowEffectiveApy = debtReserve.borrowAPY(collateralReserve.address);\n\n return {\n entityType: \"kamino_position_rate\",\n token: token.address,\n mint: token.mint,\n lendingPositionIndex,\n pool: fromWeb3Pk(position.pool),\n userAccount: fromWeb3Pk(position.protocolUserAcc),\n collateralReserve: fromWeb3Pk(position.collateralReserve),\n debtReserve: fromWeb3Pk(position.debtReserve),\n collateralMint: collateralReserve.mint.mint,\n debtMint: debtReserve.mint.mint,\n supplyBaseApy: collateralReserve.deposits.apy,\n borrowBaseApy: debtReserve.borrows.apy,\n supplyEffectiveApy,\n borrowEffectiveApy,\n netEffectiveApy: supplyEffectiveApy - borrowEffectiveApy,\n collateralReserveUtilizationPct: collateralReserve.utilizationRatePct(),\n debtReserveUtilizationPct: debtReserve.utilizationRatePct(),\n onChainLtvUtilizationBps: position.accounting.ltvUtilizationRateBps,\n targetUtilizationRateBps: position.config.targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps: position.config.maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps: position.config.maxDeviationBelowTargetUtilBps,\n };\n}\n\nfunction buildYieldingBankAssetMetricSnapshot(\n bank: LYCYieldingBank,\n asset: YieldingBankAccountData[\"baseAsset\"],\n assetIndex: number,\n assetKind: \"base\" | \"asset\"\n): YieldingBankAssetMetricSnapshot {\n const amountRaw = toBigInt(asset.amount);\n const priceRaw = toBigInt(asset.price);\n const tvlUsdRaw = calculateTvlUsd(amountRaw, priceRaw, asset.decimals);\n\n return {\n entityType: \"yielding_bank_asset\",\n bank: bank.address,\n assetIndex,\n assetKind,\n mint: fromWeb3Pk(asset.mint),\n amountRaw: amountRaw.toString(),\n amountUi: toUiAmount(asset.amount, asset.decimals),\n decimals: asset.decimals,\n priceRaw: priceRaw.toString(),\n priceUsd: toUiAmount(asset.price, asset.decimals),\n tvlUsdRaw: tvlUsdRaw.toString(),\n tvlUsd: toUiAmount(tvlUsdRaw, TVL_USD_DECIMAL_PLACES),\n };\n}\n","/**\n * Anchor 8-byte instruction discriminators (see `idl/long_yield_carry.ts`).\n * Add new entries here when supporting additional indexed instructions.\n */\n\n/** `burn_token` */\nexport const BURN_TOKEN_DISCRIMINATOR = Uint8Array.from([185, 165, 216, 246, 144, 31, 70, 74]);\n\n/** `mint_token` */\nexport const MINT_TOKEN_DISCRIMINATOR = Uint8Array.from([172, 137, 183, 14, 207, 110, 234, 56]);\n","/**\n * IDL-backed account resolution for the LYC decoder.\n *\n * The decoder reads specific accounts (wallet, mint, collateral mint, user\n * ATAs) out of each indexed instruction's account list. Rather than hardcoding\n * positional indices — which silently break if the on-chain\n * `#[derive(Accounts)]` struct is ever reordered — we resolve positions by\n * account name off the SDK's shipped IDL at module load.\n *\n * Guarantees:\n * - **Resilient to reordering.** If the Rust program reorders accounts, the\n * regenerated IDL updates the name→index map and the decoder follows.\n * - **Fail-fast on rename/removal.** If an account we depend on is renamed\n * or removed, this module throws at import time — the SDK fails to load\n * instead of producing mislabeled events.\n * - **Minimal surface.** Only pins the accounts the decoder actually reads\n * (`signer`, `mint`, `collateral_mint`, `user_token_account`,\n * `user_collateral_account`). Unused accounts can be renamed freely.\n */\n\nimport { IDL } from \"../idl/long_yield_carry\";\n\nconst MINT_TOKEN_REQUIRED_ACCOUNT_NAMES = [\n \"signer\",\n \"mint\",\n \"collateral_mint\",\n \"user_collateral_account\",\n \"user_token_account\",\n] as const;\n\nconst BURN_TOKEN_REQUIRED_ACCOUNT_NAMES = [\n \"signer\",\n \"mint\",\n \"user_token_account\",\n \"user_collateral_account\",\n] as const;\n\ntype MintTokenAccountName = (typeof MINT_TOKEN_REQUIRED_ACCOUNT_NAMES)[number];\ntype BurnTokenAccountName = (typeof BURN_TOKEN_REQUIRED_ACCOUNT_NAMES)[number];\n\nfunction buildAccountIndexMap<const T extends readonly string[]>(\n instructionName: string,\n requiredNames: T\n): Readonly<Record<T[number], number>> {\n const ix = IDL.instructions.find((entry) => entry.name === instructionName);\n if (!ix) {\n throw new Error(`IDL account resolver: instruction \"${instructionName}\" not found`);\n }\n const map: Record<string, number> = {};\n for (const name of requiredNames) {\n const idx = ix.accounts.findIndex((a) => a.name === name);\n if (idx < 0) {\n throw new Error(\n `IDL account resolver: instruction \"${instructionName}\" is missing account \"${name}\"`\n );\n }\n map[name] = idx;\n }\n return Object.freeze(map) as Readonly<Record<T[number], number>>;\n}\n\n/** Name→index map for the accounts list of `mint_token`. */\nexport const MINT_TOKEN_ACCOUNTS = buildAccountIndexMap(\n \"mint_token\",\n MINT_TOKEN_REQUIRED_ACCOUNT_NAMES\n);\n\n/** Name→index map for the accounts list of `burn_token`. */\nexport const BURN_TOKEN_ACCOUNTS = buildAccountIndexMap(\n \"burn_token\",\n BURN_TOKEN_REQUIRED_ACCOUNT_NAMES\n);\n\nexport { MINT_TOKEN_REQUIRED_ACCOUNT_NAMES, BURN_TOKEN_REQUIRED_ACCOUNT_NAMES };\nexport type { MintTokenAccountName, BurnTokenAccountName };\n","import bs58 from \"bs58\";\nimport { TOKEN_PROGRAM_ADDRESS, TokenInstruction } from \"@solana-program/token\";\nimport { TOKEN_2022_PROGRAM_ADDRESS } from \"@solana-program/token-2022\";\n\nimport type {\n CompiledInstruction,\n InnerInstructionBlock,\n TokenBalanceRow,\n TxMeta,\n} from \"./transactionPayload\";\n\n/**\n * Inner-instruction (CPI) scanning primitives for the decoder.\n *\n * The decoder reads LYC user events off the on-chain CPIs the program emits,\n * not off net balance deltas. A `burn_token` top-level ix is decoded by finding\n * the SPL Token `Burn` CPI (for the token amount) and the SPL Token\n * `Transfer` / `TransferChecked` CPIs to the user's collateral ATA (for the\n * collateral amount + mint) inside the burn ix's inner-instructions block.\n *\n * Reading CPIs is robust to ATA lifecycle quirks (created + closed in the same\n * tx, wrap + unwrap side effects, etc.) because the CPIs are the actions that\n * actually happened — balance rows are just their net effect and can be hidden\n * or confounded by other same-tx ixs.\n *\n * Program IDs come from {@link TOKEN_PROGRAM_ADDRESS} / {@link TOKEN_2022_PROGRAM_ADDRESS}\n * (kit-aligned `@solana-program/*` clients). Instruction tags use {@link TokenInstruction}\n * — Token-2022 shares the same numeric tags for Transfer / TransferChecked / MintTo / Burn.\n */\n\nconst SPL_TOKEN_PROGRAM_IDS = new Set<string>([TOKEN_PROGRAM_ADDRESS, TOKEN_2022_PROGRAM_ADDRESS]);\n\ninterface ParsedSplIx {\n tag: number;\n amount: bigint;\n}\n\n/**\n * Decode an SPL Token ix and extract its tag + u64 amount, if the tag is one\n * we care about (Transfer, TransferChecked, MintTo, Burn). Returns null for\n * any other variant (approve, close, sync native, etc.) or for malformed data.\n *\n * Layout (all little-endian):\n * - Transfer: `[3, amount:u64]` (9 bytes)\n * - MintTo: `[7, amount:u64]` (9 bytes)\n * - Burn: `[8, amount:u64]` (9 bytes)\n * - TransferChecked: `[12, amount:u64, decimals:u8]` (10 bytes)\n */\nfunction parseSplAmountIx(ix: CompiledInstruction): ParsedSplIx | null {\n let bytes: Uint8Array;\n try {\n bytes = bs58.decode(ix.data);\n } catch {\n return null;\n }\n if (bytes.length < 9) return null;\n const tag = bytes[0];\n if (\n tag !== TokenInstruction.Transfer &&\n tag !== TokenInstruction.TransferChecked &&\n tag !== TokenInstruction.MintTo &&\n tag !== TokenInstruction.Burn\n ) {\n return null;\n }\n let amount = 0n;\n for (let i = 0; i < 8; i++) {\n amount |= BigInt(bytes[1 + i]) << BigInt(i * 8);\n }\n return { tag, amount };\n}\n\n/** Resolve the inner-instructions block for a given top-level instruction. */\nexport function findInnerInstructionBlock(\n meta: TxMeta,\n topLevelIndex: number\n): InnerInstructionBlock | undefined {\n return meta.innerInstructions?.find((b) => b.index === topLevelIndex);\n}\n\n/**\n * Find the SPL Token `Burn` CPI whose source token account matches\n * `sourceAtaIndex` and return its amount. Tx-level account indexes are shared\n * between outer and inner instructions, so callers resolve the source by\n * outer IDL-named account (e.g. `burn_token.user_token_account`) and we match\n * against `burn.accounts[0]` here.\n *\n * `Burn` account layout: `[source_ata, mint, authority, ...signers]`.\n */\nexport function splBurnAmountFromSource(\n keys: string[],\n block: InnerInstructionBlock,\n sourceAtaIndex: number\n): bigint | null {\n for (const ix of block.instructions) {\n if (!SPL_TOKEN_PROGRAM_IDS.has(keys[ix.programIdIndex] ?? \"\")) continue;\n if (ix.accounts.length < 3 || ix.accounts[0] !== sourceAtaIndex) continue;\n const parsed = parseSplAmountIx(ix);\n if (parsed?.tag !== TokenInstruction.Burn) continue;\n if (parsed.amount <= 0n) continue;\n return parsed.amount;\n }\n return null;\n}\n\n/**\n * Find the SPL Token `MintTo` CPI whose destination ATA matches `destAtaIndex`\n * and return its amount. The mint slot (`MintTo.accounts[0]`) is not checked:\n * an ATA has a fixed mint, so a MintTo landing in the right ATA cannot be for\n * any other mint — the on-chain SPL program rejects mismatches.\n *\n * `MintTo` account layout: `[mint, dest_ata, authority, ...signers]`.\n */\nexport function splMintToAmountToDest(\n keys: string[],\n block: InnerInstructionBlock,\n destAtaIndex: number\n): bigint | null {\n for (const ix of block.instructions) {\n if (!SPL_TOKEN_PROGRAM_IDS.has(keys[ix.programIdIndex] ?? \"\")) continue;\n if (ix.accounts.length < 3 || ix.accounts[1] !== destAtaIndex) continue;\n const parsed = parseSplAmountIx(ix);\n if (parsed?.tag !== TokenInstruction.MintTo) continue;\n if (parsed.amount <= 0n) continue;\n return parsed.amount;\n }\n return null;\n}\n\ninterface SplTransferSummary {\n sourceIndex: number;\n destIndex: number;\n amount: bigint;\n /**\n * For `TransferChecked` the mint sits in the ix's `accounts[1]`, so we can\n * pin it down without consulting the balance-row table. Plain `Transfer`\n * leaves this undefined — callers fall back to {@link mintForAccountIndex}.\n */\n explicitMint: string | undefined;\n}\n\nfunction extractTransfer(keys: string[], ix: CompiledInstruction): SplTransferSummary | null {\n if (!SPL_TOKEN_PROGRAM_IDS.has(keys[ix.programIdIndex] ?? \"\")) return null;\n const parsed = parseSplAmountIx(ix);\n if (!parsed) return null;\n if (parsed.amount <= 0n) return null;\n\n if (parsed.tag === TokenInstruction.Transfer && ix.accounts.length >= 3) {\n return {\n sourceIndex: ix.accounts[0],\n destIndex: ix.accounts[1],\n amount: parsed.amount,\n explicitMint: undefined,\n };\n }\n if (parsed.tag === TokenInstruction.TransferChecked && ix.accounts.length >= 4) {\n return {\n sourceIndex: ix.accounts[0],\n destIndex: ix.accounts[2],\n amount: parsed.amount,\n explicitMint: keys[ix.accounts[1]] ?? undefined,\n };\n }\n return null;\n}\n\n/**\n * Collect every SPL Token `Transfer` / `TransferChecked` CPI in the given inner\n * block whose destination matches `destAtaIndex`. Multiple transfers (e.g. fees\n * split across two CPIs, managed-unwind returning partial then final amounts)\n * are returned as-is so callers can aggregate per mint.\n */\nexport function collectSplTransfersTo(\n keys: string[],\n block: InnerInstructionBlock,\n destAtaIndex: number\n): SplTransferSummary[] {\n const out: SplTransferSummary[] = [];\n for (const ix of block.instructions) {\n const summary = extractTransfer(keys, ix);\n if (summary && summary.destIndex === destAtaIndex) {\n out.push(summary);\n }\n }\n return out;\n}\n\n/**\n * Sum the amounts of every SPL Token `Transfer` / `TransferChecked` CPI in the\n * given inner block whose source matches `sourceAtaIndex`. Returns 0n if none.\n *\n * Used by `decodeMintToken` to total the collateral moved out of the user's\n * collateral ATA. The collateral mint is known structurally from the IDL\n * (`mint_token.collateral_mint`), so we don't need to track per-transfer mints.\n */\nexport function sumSplTransfersFromSource(\n keys: string[],\n block: InnerInstructionBlock,\n sourceAtaIndex: number\n): bigint {\n let total = 0n;\n for (const ix of block.instructions) {\n const summary = extractTransfer(keys, ix);\n if (summary && summary.sourceIndex === sourceAtaIndex) {\n total += summary.amount;\n }\n }\n return total;\n}\n\n/**\n * Look up the mint a token account was holding by finding any row in pre/post\n * balances with the matching `accountIndex`. Used when a plain `Transfer` CPI\n * doesn't carry the mint in-line — we read it off the counterparty's row.\n */\nexport function mintForAccountIndex(\n pre: TokenBalanceRow[] | undefined,\n post: TokenBalanceRow[] | undefined,\n accountIndex: number\n): string | null {\n for (const row of pre ?? []) {\n if (row.accountIndex === accountIndex) return row.mint;\n }\n for (const row of post ?? []) {\n if (row.accountIndex === accountIndex) return row.mint;\n }\n return null;\n}\n\n/**\n * Given the inner-instruction transfers that delivered collateral to the user's\n * collateral ATA, resolve (mint, amount) per mint and return the largest.\n *\n * Multi-mint returns (dust + primary) are possible in managed-unwind paths; we\n * pick the dominant mint rather than summing across mints so the event's\n * `collateralMint` remains a single string that matches the user's intent.\n */\nexport function aggregateCollateralTransfers(\n meta: TxMeta,\n transfers: SplTransferSummary[]\n): { collateralMint: string; amount: bigint } | null {\n const totals = new Map<string, bigint>();\n for (const t of transfers) {\n const mint =\n t.explicitMint ??\n mintForAccountIndex(meta.preTokenBalances, meta.postTokenBalances, t.sourceIndex) ??\n mintForAccountIndex(meta.preTokenBalances, meta.postTokenBalances, t.destIndex);\n if (!mint) continue;\n totals.set(mint, (totals.get(mint) ?? 0n) + t.amount);\n }\n\n let bestMint: string | null = null;\n let bestAmt = 0n;\n for (const [mint, amt] of totals) {\n if (amt > bestAmt) {\n bestAmt = amt;\n bestMint = mint;\n }\n }\n if (bestMint === null || bestAmt <= 0n) return null;\n return { collateralMint: bestMint, amount: bestAmt };\n}\n","import bs58 from \"bs58\";\n\nimport type { TxMessage, TxMeta } from \"./transactionPayload\";\n\n/**\n * v0 message: static `accountKeys` + ALT-loaded writable addresses + readonly addresses.\n */\nexport function buildAccountKeys(message: TxMessage, meta: TxMeta): string[] {\n const staticKeys = message.accountKeys;\n const loadedWritable = meta.loadedAddresses?.writable ?? [];\n const loadedReadonly = meta.loadedAddresses?.readonly ?? [];\n return [...staticKeys, ...loadedWritable, ...loadedReadonly];\n}\n\nexport function decodeInstructionData(dataB58: string): Uint8Array {\n return bs58.decode(dataB58);\n}\n\nexport function discriminatorMatches(data: Uint8Array, disc: Uint8Array): boolean {\n if (data.length < disc.length) return false;\n for (let i = 0; i < disc.length; i++) {\n if (data[i] !== disc[i]) return false;\n }\n return true;\n}\n","/**\n * Decoder: streamed Solana transaction payloads → normalized LYC user events.\n *\n * Wire shape is validator-style `getTransaction` data wrapped by the API into\n * {@link LycProgramTransactionRecord} when enqueued. Downstream consumers (the\n * indexer Lambda, backfill jobs) validate the envelope with\n * {@link parseLycProgramTransactionRecord} then call\n * {@link decodeLycProgramTransaction} to produce zero or more user-facing\n * {@link LycTransactionEvent}s.\n *\n * The set of indexed instructions is currently `mint_token` and `burn_token`.\n * Both are inlined in this module — if we ever add a third, promote back to a\n * registry/interface pattern.\n */\n\nimport { LYC_PROGRAM_IDS } from \"../constants/general\";\nimport { BURN_TOKEN_DISCRIMINATOR, MINT_TOKEN_DISCRIMINATOR } from \"./discriminators\";\nimport { BURN_TOKEN_ACCOUNTS, MINT_TOKEN_ACCOUNTS } from \"./idlAccounts\";\nimport {\n aggregateCollateralTransfers,\n collectSplTransfersTo,\n findInnerInstructionBlock,\n splBurnAmountFromSource,\n splMintToAmountToDest,\n sumSplTransfersFromSource,\n} from \"./innerCpis\";\nimport { buildAccountKeys, decodeInstructionData, discriminatorMatches } from \"./solana\";\nimport type { TxMessage, TxMeta } from \"./transactionPayload\";\nimport type { LycProgramTransactionRecord, LycTransactionEvent } from \"./types\";\n\n/**\n * Validate and narrow an arbitrary JSON body (SQS message body / API request)\n * to {@link LycProgramTransactionRecord}. Returns `null` on any shape mismatch.\n */\nexport function parseLycProgramTransactionRecord(\n input: unknown\n): LycProgramTransactionRecord | null {\n if (!input || typeof input !== \"object\") return null;\n const o = input as Record<string, unknown>;\n if (o.source !== \"lyc-program-transaction\") return null;\n if (typeof o.signature !== \"string\" || o.signature.length === 0) return null;\n if (!(\"payload\" in o)) return null;\n\n return {\n source: \"lyc-program-transaction\",\n receivedAt: typeof o.receivedAt === \"number\" ? o.receivedAt : 0,\n signature: o.signature,\n slot: typeof o.slot === \"number\" ? o.slot : undefined,\n payload: o.payload,\n };\n}\n\n/**\n * Stable enum of why a matched-discriminator instruction produced no event.\n * All reasons are CPI-driven; none depend on balance deltas.\n */\nexport type DecoderRejectionReason =\n | \"accounts_too_short\"\n | \"missing_key\"\n | \"no_inner_instructions_block\"\n | \"no_token_burn_cpi\"\n | \"no_token_mint_to_cpi\"\n | \"no_collateral_out_delta\"\n | \"no_collateral_in_delta\";\n\n/**\n * One reason a tx produced zero events despite looking like something we index.\n *\n * - `payload_unparseable`: the envelope `payload` lacked `meta` / `transaction.message` and\n * we couldn't even enumerate instructions.\n * - `instruction_data_invalid`: an LYC-program instruction's `data` field wasn't valid\n * base58 so we couldn't read its discriminator.\n * - `decoder_rejected`: the discriminator matched a user-facing decoder but a guard rail\n * returned null — `reason` identifies which guard.\n */\nexport type DecodeRejection =\n | { kind: \"payload_unparseable\" }\n | { kind: \"instruction_data_invalid\"; instructionIndex: number }\n | {\n kind: \"decoder_rejected\";\n name: \"mint_token\" | \"burn_token\";\n reason: DecoderRejectionReason;\n };\n\nexport interface DecodeResult {\n events: LycTransactionEvent[];\n /**\n * Non-empty only when something anomalous happened. Consumers that want to\n * distinguish \"refresh-only tx, nothing to do\" from \"tried and bailed\" check\n * `rejections.length === 0` for the former and `rejections.length > 0` for\n * the latter.\n */\n rejections: DecodeRejection[];\n}\n\n/**\n * Decode one queued tx into zero or more user-facing events, in top-level\n * instruction order. Silently skips instructions we don't index or whose data\n * cannot be base58-decoded.\n */\nexport function decodeLycProgramTransaction(\n record: LycProgramTransactionRecord\n): LycTransactionEvent[] {\n return decodeLycProgramTransactionWithDiagnostics(record).events;\n}\n\n/**\n * Same as {@link decodeLycProgramTransaction} but also returns structured\n * rejections for the indexer's CloudWatch log path. Use this when \"zero events\"\n * isn't enough information — e.g. you need to know whether a burn-shaped tx\n * bailed because its inner-instructions block was missing or because no\n * collateral transfer CPI landed in the user's ATA.\n */\nexport function decodeLycProgramTransactionWithDiagnostics(\n record: LycProgramTransactionRecord\n): DecodeResult {\n const tx = parseRecordPayload(record);\n if (!tx) {\n return { events: [], rejections: [{ kind: \"payload_unparseable\" }] };\n }\n\n const events: LycTransactionEvent[] = [];\n const rejections: DecodeRejection[] = [];\n\n for (let i = 0; i < tx.message.instructions.length; i++) {\n const ix = tx.message.instructions[i]!;\n const programId = tx.keys[ix.programIdIndex];\n if (!programId || !LYC_PROGRAM_IDS.has(programId)) continue;\n\n let data: Uint8Array;\n try {\n data = decodeInstructionData(ix.data);\n } catch {\n rejections.push({ kind: \"instruction_data_invalid\", instructionIndex: i });\n continue;\n }\n\n if (discriminatorMatches(data, MINT_TOKEN_DISCRIMINATOR)) {\n const outcome = decodeMintToken(tx, ix.accounts, i);\n if (\"event\" in outcome) events.push(outcome.event);\n else\n rejections.push({ kind: \"decoder_rejected\", name: \"mint_token\", reason: outcome.reason });\n } else if (discriminatorMatches(data, BURN_TOKEN_DISCRIMINATOR)) {\n const outcome = decodeBurnToken(tx, ix.accounts, i);\n if (\"event\" in outcome) events.push(outcome.event);\n else\n rejections.push({ kind: \"decoder_rejected\", name: \"burn_token\", reason: outcome.reason });\n }\n }\n\n return { events, rejections };\n}\n\n/**\n * Per-tx data shared by the mint/burn decoders and by\n * {@link listLycTopLevelInstructionNames} in the sibling module. Exported so\n * the names helper can reuse the parse work — not part of the public SDK.\n */\nexport interface ParsedTx {\n message: TxMessage;\n meta: TxMeta;\n signature: string;\n slot: number;\n blockTime: number;\n fee: number;\n /** Static + ALT-loaded account keys, in the index order used by instructions. */\n keys: string[];\n}\n\nexport function parseRecordPayload(record: LycProgramTransactionRecord): ParsedTx | null {\n const payload = record.payload;\n if (!payload || typeof payload !== \"object\") return null;\n\n const p = payload as Record<string, unknown>;\n const meta = p.meta as TxMeta | undefined;\n const transaction = p.transaction as { message?: TxMessage } | undefined;\n const message = transaction?.message;\n if (!meta || !message?.accountKeys || !Array.isArray(message.instructions)) {\n return null;\n }\n\n const slot =\n typeof record.slot === \"number\" ? record.slot : typeof p.slot === \"number\" ? p.slot : 0;\n\n return {\n message,\n meta,\n signature: record.signature,\n slot,\n blockTime: typeof p.blockTime === \"number\" ? p.blockTime : 0,\n fee: typeof meta.fee === \"number\" ? meta.fee : 0,\n keys: buildAccountKeys(message, meta),\n };\n}\n\ntype DecoderOutcome = { event: LycTransactionEvent } | { reason: DecoderRejectionReason };\n\n/**\n * Authoritative reads: inner CPIs emitted by mint_token.\n * - Token amount: SPL Token `MintTo` CPI whose `accounts[1]` (dest ATA)\n * matches `user_token_account`. Amount is encoded in the ix data as a\n * little-endian u64.\n * - Collateral amount: sum of SPL Token `Transfer` / `TransferChecked`\n * CPIs whose source matches `user_collateral_account`. The collateral\n * mint is known structurally (`collateral_mint`), so we don't need to\n * derive it per-transfer.\n *\n * Account positions are resolved by name from the IDL via\n * {@link MINT_TOKEN_ACCOUNTS} — resilient to account-list reordering, and\n * fail-fast at module load if a required account is renamed or removed.\n */\nfunction decodeMintToken(tx: ParsedTx, accounts: number[], ixIndex: number): DecoderOutcome {\n const signerPos = MINT_TOKEN_ACCOUNTS.signer;\n const mintPos = MINT_TOKEN_ACCOUNTS.mint;\n const collateralMintPos = MINT_TOKEN_ACCOUNTS.collateral_mint;\n const userCollateralAtaPos = MINT_TOKEN_ACCOUNTS.user_collateral_account;\n const userTokenAtaPos = MINT_TOKEN_ACCOUNTS.user_token_account;\n\n const maxPos = Math.max(\n signerPos,\n mintPos,\n collateralMintPos,\n userCollateralAtaPos,\n userTokenAtaPos\n );\n if (accounts.length <= maxPos) return { reason: \"accounts_too_short\" };\n\n const wallet = tx.keys[accounts[signerPos]];\n const tokenMint = tx.keys[accounts[mintPos]];\n const collateralMint = tx.keys[accounts[collateralMintPos]];\n if (!wallet || !tokenMint || !collateralMint) return { reason: \"missing_key\" };\n\n const block = findInnerInstructionBlock(tx.meta, ixIndex);\n if (!block) return { reason: \"no_inner_instructions_block\" };\n\n const mintedAmount = splMintToAmountToDest(tx.keys, block, accounts[userTokenAtaPos]);\n if (mintedAmount === null) return { reason: \"no_token_mint_to_cpi\" };\n\n const collateralAmount = sumSplTransfersFromSource(\n tx.keys,\n block,\n accounts[userCollateralAtaPos]\n );\n if (collateralAmount <= 0n) return { reason: \"no_collateral_in_delta\" };\n\n return {\n event: {\n signature: tx.signature,\n slot: tx.slot,\n blockTime: tx.blockTime,\n type: \"mint\",\n wallet,\n tokenMint,\n tokenAmountBaseUnits: mintedAmount.toString(),\n collateralMint,\n collateralAmountBaseUnits: collateralAmount.toString(),\n fee: tx.fee,\n },\n };\n}\n\n/**\n * Authoritative reads: inner CPIs emitted by burn_token.\n * - Token amount: SPL Token `Burn` CPI whose `accounts[0]` (source ATA)\n * matches `user_token_account`. Amount is encoded in the ix data as a\n * little-endian u64, not derived from a balance delta.\n * - Collateral: SPL Token `Transfer` / `TransferChecked` CPIs whose\n * destination matches `user_collateral_account`. Amounts are summed per\n * mint; the dominant mint wins — in practice the Rust program emits a\n * single transfer with a single mint, so the aggregation step is defensive\n * (see `rust/.../burn_token.rs`).\n *\n * CPI-authoritative decoding does not depend on whether the user's collateral\n * ATA persists across the tx — created-and-closed-same-tx ATAs, pre-existing\n * ATAs closed at the end, and ATAs re-funded inside the same tx all decode\n * identically because the CPIs themselves never disappear.\n *\n * Account positions are resolved by name from the IDL via\n * {@link BURN_TOKEN_ACCOUNTS} — resilient to account-list reordering, and\n * fail-fast at module load if a required account is renamed or removed.\n */\nfunction decodeBurnToken(tx: ParsedTx, accounts: number[], ixIndex: number): DecoderOutcome {\n const signerPos = BURN_TOKEN_ACCOUNTS.signer;\n const mintPos = BURN_TOKEN_ACCOUNTS.mint;\n const userTokenAtaPos = BURN_TOKEN_ACCOUNTS.user_token_account;\n const userCollateralAtaPos = BURN_TOKEN_ACCOUNTS.user_collateral_account;\n\n const maxPos = Math.max(signerPos, mintPos, userTokenAtaPos, userCollateralAtaPos);\n if (accounts.length <= maxPos) return { reason: \"accounts_too_short\" };\n\n const wallet = tx.keys[accounts[signerPos]];\n const tokenMint = tx.keys[accounts[mintPos]];\n if (!wallet || !tokenMint) return { reason: \"missing_key\" };\n\n const block = findInnerInstructionBlock(tx.meta, ixIndex);\n if (!block) return { reason: \"no_inner_instructions_block\" };\n\n const burnedAmount = splBurnAmountFromSource(tx.keys, block, accounts[userTokenAtaPos]);\n if (burnedAmount === null) return { reason: \"no_token_burn_cpi\" };\n\n const transfers = collectSplTransfersTo(tx.keys, block, accounts[userCollateralAtaPos]);\n const collateral = aggregateCollateralTransfers(tx.meta, transfers);\n if (!collateral) return { reason: \"no_collateral_out_delta\" };\n\n return {\n event: {\n signature: tx.signature,\n slot: tx.slot,\n blockTime: tx.blockTime,\n type: \"burn\",\n wallet,\n tokenMint,\n tokenAmountBaseUnits: burnedAmount.toString(),\n collateralMint: collateral.collateralMint,\n collateralAmountBaseUnits: collateral.amount.toString(),\n fee: tx.fee,\n },\n };\n}\n","import { LYC_PROGRAM_IDS } from \"../constants/general\";\nimport { parseRecordPayload } from \"./decodeTransaction\";\nimport { decodeInstructionData } from \"./solana\";\nimport type { LycProgramTransactionRecord } from \"./types\";\n\n/**\n * Anchor instruction discriminators → camelCase names (from\n * `idl/long_yield_carry.ts` instructions tuple). Update when the IDL changes\n * (`npm run copy:idl`). Used only to populate the indexer's diagnostic\n * `instructionNames` column for the API's transaction-history response.\n */\nconst LYC_INSTRUCTION_DISCRIMINATOR_TO_NAME: Readonly<Record<string, string>> = {\n \"185,165,216,246,144,31,70,74\": \"burnToken\",\n \"79,126,77,51,253,163,193,248\": \"claimIncentives\",\n \"164,152,207,99,30,186,19,182\": \"collectFees\",\n \"238,101,253,86,160,25,16,134\": \"collectInterest\",\n \"84,52,204,228,24,140,234,75\": \"createToken\",\n \"32,13,223,159,125,144,219,148\": \"createTokenLendingPosition\",\n \"123,125,211,195,102,102,90,7\": \"createYieldingBank\",\n \"213,191,99,159,78,2,87,126\": \"createYieldingBankAllocation\",\n \"109,115,98,62,206,179,42,145\": \"decreaseCarryPosition\",\n \"112,210,209,249,61,231,192,207\": \"depositUnlentCollateral\",\n \"216,191,255,166,144,169,3,187\": \"increaseCarryPosition\",\n \"172,137,183,14,207,110,234,56\": \"mintToken\",\n \"152,98,123,66,134,191,199,73\": \"rebalanceToken\",\n \"181,53,252,136,138,104,145,137\": \"rebalanceYieldingBank\",\n \"98,11,43,3,199,227,100,112\": \"recollateralizeLoss\",\n \"229,167,209,155,223,252,150,188\": \"refreshTokenState\",\n \"234,183,180,72,113,250,213,76\": \"refreshYieldingBank\",\n \"152,222,104,180,163,231,152,77\": \"resetTokenBurnRateLimit\",\n \"123,100,170,97,214,192,245,151\": \"setTokenCircuitBreaker\",\n \"25,188,1,254,63,110,168,255\": \"setYieldingBankCircuitBreaker\",\n \"164,56,56,248,51,167,213,96\": \"updateLendingPositionConfig\",\n \"115,111,91,203,143,224,71,136\": \"updateTokenConfiguration\",\n \"243,6,8,23,126,181,251,158\": \"updateTokenMetadata\",\n \"236,3,226,53,30,160,216,24\": \"updateYieldingBankConfig\",\n};\n\nfunction lycInstructionNameFromData(data: Uint8Array): string {\n if (data.length < 8) return \"truncated_instruction_data\";\n let key = \"\";\n for (let i = 0; i < 8; i++) {\n if (i > 0) key += \",\";\n key += data[i];\n }\n return LYC_INSTRUCTION_DISCRIMINATOR_TO_NAME[key] ?? `unknown_discriminator(${key})`;\n}\n\n/**\n * Top-level instructions that invoke the LYC program, in tx order.\n * Returns `null` if the payload can't be parsed (missing meta/message).\n */\nexport function listLycTopLevelInstructionNames(\n record: LycProgramTransactionRecord\n): string[] | null {\n const parsed = parseRecordPayload(record);\n if (!parsed) return null;\n\n const { keys, message } = parsed;\n const names: string[] = [];\n for (let i = 0; i < message.instructions.length; i++) {\n const ix = message.instructions[i]!;\n const programId = keys[ix.programIdIndex];\n if (!programId || !LYC_PROGRAM_IDS.has(programId)) continue;\n\n try {\n names.push(lycInstructionNameFromData(decodeInstructionData(ix.data)));\n } catch {\n names.push(`invalid_ix_data@${i}`);\n }\n }\n return names;\n}\n"],"mappings":"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","names":["PublicKey","PublicKey","PublicKey","PublicKey","TOKEN_PROGRAM_ADDRESS","TOKEN_PROGRAM_ADDRESS","PublicKey","carry","PublicKey","BN","BN","TOKEN_PROGRAM_ADDRESS","TOKEN_PROGRAM_ADDRESS","TOKEN_PROGRAM_ADDRESS","TOKEN_PROGRAM_ADDRESS","BN","BN","PublicKey","PublicKey","InterestDistribution","LendingType","mintSymbol","USD_STAR","PublicKey","PublicKey","PublicKey","TOKEN_PROGRAM_ADDRESS","TOKEN_PROGRAM_ADDRESS","PublicKey","LycLendingPositionManager","TOKEN_PROGRAM_ADDRESS","TOKEN_2022_PROGRAM_ADDRESS","bs58"]}