@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":["../../../shared/common/src/utils/accounts/roles.ts","../../../shared/common/src/utils/accounts/meta.ts","../../../shared/common/src/utils/accounts/rpc.ts","../../../shared/common/src/utils/compat.ts","../../../shared/common/src/utils/accounts/pda.ts","../../../shared/common/src/utils/accounts/splBalances.ts","../../../shared/common/src/utils/accounts/index.ts","../../../shared/common/src/services/dataCache.ts","../../../shared/common/src/services/baseAccountClient.ts","../../../shared/common/src/utils/data.ts","../../../shared/common/src/utils/cpi/args.ts","../../../shared/common/src/utils/cpi/refs.ts","../../../shared/common/src/utils/cpi/index.ts","../../../shared/common/src/utils/general.ts","../../../shared/common/src/utils/solana.ts","../../../shared/common/src/services/mints/types.ts","../../../shared/common/src/services/mints/defaults.ts","../../../shared/common/src/constants/general.ts","../../../shared/common/src/utils/numbers.ts","../../../shared/common/src/services/mints/registry.ts","../../../shared/common/src/services/mints/symbols.ts","../../../shared/common/src/services/mints/index.ts","../../../shared/common/src/utils/instruction.ts","../../../shared/common/src/utils/retry.ts","../../../shared/common/src/utils/rpc.ts","../../../shared/common/src/utils/jsonRpcFetch.ts","../../../shared/common/src/utils/asyncConcurrency.ts","../../../shared/common/src/utils/anchor.ts","../../../shared/common/src/constants/accountMetas.ts","../../../shared/common/src/constants/generated/cpi.ts","../../../shared/common/src/constants/generated/index.ts","../../../shared/common/src/constants/index.ts","../../../shared/common/src/services/lutManager.ts","../../../shared/common/src/utils/jito.ts","../../../shared/common/src/utils/priorityFee.ts","../../../shared/common/src/utils/transactionSplitter.ts","../../../shared/common/src/utils/transaction.ts","../../../shared/common/src/utils/txAccountCoverage.ts","../../../shared/common/src/types/enums.ts","../../../shared/common/src/utils/token.ts","../../../shared/common/src/utils/timeSeries.ts","../../../shared/common/src/utils/metadata.ts","../../../shared/common/src/utils/json.ts","../../../shared/common/src/utils/index.ts","../../../shared/common/src/types/solana.ts","../../../shared/common/src/types/general.ts","../../../shared/common/src/types/cpi.ts","../../../shared/common/src/types/index.ts","../../../shared/common/src/services/baseIxBuilderService.ts","../../../shared/common/src/services/swap/types.ts","../../../shared/common/src/services/swap/swapClientBase.ts","../../../shared/common/src/services/swap/routableSwapClient.ts","../../../shared/common/src/services/swap/swapRouting.ts","../../../shared/common/src/services/swap/index.ts","../../../shared/common/src/services/token/types.ts","../../../shared/common/src/services/token/tokenProtocolClientBase.ts","../../../shared/common/src/services/token/index.ts","../../../shared/common/src/services/transactionSender.ts","../../../shared/common/src/services/index.ts","../../../shared/common/src/index.ts","../../../shared/oracle-service/src/constants/pyth.ts","../../../shared/oracle-service/src/constants/switchboard.ts","../../../shared/oracle-service/src/feeds/priceBase.ts","../../../shared/oracle-service/src/feeds/jupiter.ts","../../../shared/oracle-service/src/constants/splStake.ts","../../../shared/oracle-service/src/constants/index.ts","../../../shared/perena-helpers/src/constants.ts","../../../shared/perena-helpers/src/cpi/mint.ts","../../../shared/perena-helpers/src/cpi/burn.ts","../../../shared/perena-helpers/src/cpi/requestUnstake.ts","../../../shared/perena-helpers/src/cpi/index.ts","../../../shared/perena-helpers/src/client.ts","../../../shared/perena-helpers/src/accounts.ts","../../../shared/perena-helpers/src/utils.ts","../../../shared/perena-helpers/src/index.ts","../../../shared/oracle-service/src/feeds/splStake.ts","../../../shared/oracle-service/src/utils/general.ts","../../../shared/oracle-service/src/utils/index.ts","../../../shared/oracle-service/src/feeds/pyth.ts","../../../shared/oracle-service/src/feeds/switchboard.ts","../../../shared/oracle-service/src/feeds/custom.ts","../../../shared/oracle-service/src/oracle.ts","../../../shared/oracle-service/src/index.ts","../../../shared/lending-platforms/src/services/client/lpClientBase.ts","../../../shared/lending-platforms/src/constants/cache.ts","../../../shared/lending-platforms/src/data/platform/lpDataBase.ts","../../../shared/lending-platforms/src/constants/kamino.ts","../../../shared/lending-platforms/src/constants/lendingPosition.ts","../../../shared/lending-platforms/src/constants/index.ts","../../../shared/lending-platforms/src/types/kamino.ts","../../../shared/lending-platforms/src/types/general.ts","../../../shared/lending-platforms/src/types/index.ts","../../../shared/lending-platforms/src/utils/accounts.ts","../../../shared/lending-platforms/src/utils/cache.ts","../../../shared/lending-platforms/src/utils/kamino.ts","../../../shared/lending-platforms/src/utils/lendingPlatform.ts","../../../shared/lending-platforms/src/utils/math.ts","../../../shared/lending-platforms/src/utils/scope.ts","../../../shared/lending-platforms/src/utils/index.ts","../../../shared/lending-platforms/src/data/platform/kamino.ts","../../../shared/lending-platforms/src/data/platform/index.ts","../../../shared/lending-platforms/src/data/incentive/incentiveBase.ts","../../../shared/lending-platforms/src/data/incentive/kamino.ts","../../../shared/lending-platforms/src/data/incentive/index.ts","../../../shared/lending-platforms/src/data/reserve/reserveBase.ts","../../../shared/lending-platforms/src/data/reserve/kamino.ts","../../../shared/lending-platforms/src/data/reserve/index.ts","../../../shared/lending-platforms/src/data/userPosition/userPositionBase.ts","../../../shared/lending-platforms/src/data/userPosition/kamino.ts","../../../shared/lending-platforms/src/data/userPosition/index.ts","../../../shared/lending-platforms/src/data/instructions/lpInstructionsBase.ts","../../../shared/lending-platforms/src/data/instructions/kamino.ts","../../../shared/lending-platforms/src/data/instructions/types.ts","../../../shared/lending-platforms/src/data/instructions/index.ts","../../../shared/lending-platforms/src/data/accounts/lpAccountsBase.ts","../../../shared/lending-platforms/src/data/accounts/kamino.ts","../../../shared/lending-platforms/src/data/accounts/index.ts","../../../shared/lending-platforms/src/data/index.ts","../../../shared/lending-platforms/src/services/flashLoan/flashLoanBase.ts","../../../shared/lending-platforms/src/services/flashLoan/kamino.ts","../../../shared/lending-platforms/src/services/client/kamino.ts","../../../shared/lending-platforms/src/services/client/index.ts","../../../shared/lending-platforms/src/services/flashLoan/index.ts","../../../shared/jupiter-helpers/src/constants.ts","../../../shared/jupiter-helpers/src/types.ts","../../../shared/jupiter-helpers/src/api.ts","../../../shared/jupiter-helpers/src/extract.ts","../../../shared/jupiter-helpers/src/routePreInstructions.ts","../../../shared/jupiter-helpers/src/client.ts","../../../shared/jupiter-helpers/src/sizeExactInForMinOutput.ts","../../../shared/jupiter-helpers/src/index.ts","../../../shared/lending-platforms/src/services/reservesManager.ts","../../../shared/lending-platforms/src/services/lendingPosition/lendingPositionManager.ts","../../../shared/lending-platforms/src/services/leverage/leverageService.ts","../../../shared/lending-platforms/src/services/leverage/types.ts","../../../shared/lending-platforms/src/services/leverage/index.ts","../../../shared/lending-platforms/src/services/lendingPosition/types.ts","../../../shared/lending-platforms/src/services/lendingPosition/index.ts","../../../shared/lending-platforms/src/services/index.ts","../../../shared/lending-platforms/src/index.ts","../src/constants/configs/carryTradePresets.ts","../src/services/carry/carryAllocationConfig.ts","../src/services/carry/lycLendingPositionManager.ts","../src/services/carry/index.ts","../src/index.ts","../src/errors.ts","../src/idl/long_yield_carry.ts","../src/utils/enrichment.ts","../src/utils/feeDripMetrics.ts","../src/utils/general.ts","../src/utils/tokenFeeMath.ts","../src/utils/timelock.ts","../src/utils/lycData.ts","../src/utils/lookupTables.ts","../src/constants/general.ts","../src/constants/configs/allocations.ts","../src/constants/lycTokenMetadata.ts","../src/utils/ix.ts","../src/utils/data.ts","../src/utils/cache.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/pda.ts","../src/client/account.ts","../src/models/lycToken.ts","../src/models/yieldingBank.ts","../src/client/lendingPlatformClients.ts","../src/client/externalLiquidityResolver.ts","../src/client/builders/asyncBurnBuilder.ts","../src/client/builders/base.ts","../src/client/builders/refreshTokensBuilder.ts","../src/client/builders/refreshTokenStateBuilder.ts","../src/client/builders/refreshYieldingBankBuilder.ts","../src/client/builders/utils.ts","../src/client/builders/burnTokenBuilder.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/builders/decreaseCarryPositionBuilder.ts","../src/client/plans/decreaseCarryPosition.ts","../src/client/builders/depositUnlentCollateralBuilder.ts","../src/client/builders/increaseCarryPositionBuilder.ts","../src/client/builders/mintTokenBuilder.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 { AccountRole, upgradeRoleToSigner, upgradeRoleToWritable } from \"@solana/kit\";\nimport { CustomAccountMeta } from \"../../types\";\n\nexport function isRoleWritable(role: AccountRole): boolean {\n return role === AccountRole.WRITABLE || role === AccountRole.WRITABLE_SIGNER;\n}\n\nexport function isRoleSigner(role: AccountRole): boolean {\n return role === AccountRole.READONLY_SIGNER || role === AccountRole.WRITABLE_SIGNER;\n}\n\nexport function getAccountRole(isWritable: boolean, isSigner: boolean): AccountRole {\n let role: AccountRole = AccountRole.READONLY;\n if (isWritable) role = upgradeRoleToWritable(role);\n if (isSigner) role = upgradeRoleToSigner(role);\n return role;\n}\n\n/**\n * Downgrade a role from signer to non-signer, preserving writability.\n *\n * This is useful when preparing accounts for CPI patterns where a PDA\n * signs via `invoke_signed` on-chain, not externally.\n *\n * @param role - The account role to downgrade\n * @returns The role without signer status\n */\nexport function downgradeRoleFromSigner(role: AccountRole): AccountRole {\n if (role === AccountRole.READONLY_SIGNER) return AccountRole.READONLY;\n if (role === AccountRole.WRITABLE_SIGNER) return AccountRole.WRITABLE;\n return role;\n}\n\n/**\n * Strip signer status from all accounts in a list.\n *\n * Use this when passing accounts as remainingAccounts for CPI patterns\n * where a PDA signs via `invoke_signed`. The on-chain program handles\n * PDA signing, so remainingAccounts should not have signer flags.\n *\n * @param accounts - Array of accounts to strip signer status from\n * @returns New array with signer status removed\n */\nexport function stripSignerFromAccounts(accounts: CustomAccountMeta[]): CustomAccountMeta[] {\n return accounts.map((acc) => ({\n ...acc,\n role: downgradeRoleFromSigner(acc.role),\n }));\n}\n","import { Address } from \"@solana/kit\";\nimport { CustomAccountMeta } from \"../../types\";\nimport { getAccountRole } from \"./roles\";\nimport { AccountMeta } from \"@solana/web3.js\";\nimport { AssociatedTokenSeeds } from \"@solana-program/token\";\n\n/**\n * Create a CustomAccountMeta from individual parameters.\n *\n * @param address - The account's public key\n * @param isWritable - Whether the account is writable (default: false)\n * @param requiredAtaDetails - Optional ATA details if this account needs to be created\n * @param isSigner - Whether the account is a signer (default: false)\n * @returns A CustomAccountMeta object\n */\nexport function toCustomAccountMeta(\n address: Address,\n isWritable?: boolean,\n requiredAtaDetails?: AssociatedTokenSeeds,\n isSigner?: boolean\n): CustomAccountMeta {\n const role = getAccountRole(isWritable ?? false, isSigner ?? false);\n return { address, role, isRequiredAta: requiredAtaDetails };\n}\n\n/**\n * Convert a web3.js AccountMeta to a CustomAccountMeta.\n *\n * @param web3AccountMeta - The web3.js AccountMeta\n * @returns A CustomAccountMeta object\n */\nexport function toCustomAccountMetaFromWeb3AccountMeta(\n web3AccountMeta: AccountMeta\n): CustomAccountMeta {\n return toCustomAccountMeta(\n web3AccountMeta.pubkey.toBase58() as Address,\n web3AccountMeta.isWritable,\n undefined,\n web3AccountMeta.isSigner\n );\n}\n","import { Address, Rpc, SolanaRpcApi } from \"@solana/kit\";\n\nexport interface AllAccountsExistResult {\n existingAddresses: Address[];\n missingAddresses: Address[];\n existsByAddress: Map<Address, boolean>;\n}\n\nexport async function allAccountsExist(\n rpc: Rpc<SolanaRpcApi>,\n addresses: Address[]\n): Promise<AllAccountsExistResult> {\n if (!addresses.length) {\n return {\n existingAddresses: [],\n missingAddresses: [],\n existsByAddress: new Map(),\n };\n }\n\n const uniqueAddresses = [...new Set(addresses)];\n const response = await (\n rpc as Rpc<SolanaRpcApi> & {\n getMultipleAccounts: (\n addrs: Address[],\n config: { encoding: \"base64\" }\n ) => { send(): Promise<{ value: Array<unknown | null> }> };\n }\n )\n .getMultipleAccounts(uniqueAddresses, { encoding: \"base64\" })\n .send();\n\n const existsByAddress = new Map<Address, boolean>();\n for (let i = 0; i < uniqueAddresses.length; i += 1) {\n existsByAddress.set(uniqueAddresses[i], response.value[i] !== null);\n }\n\n return {\n existingAddresses: uniqueAddresses.filter((address) => existsByAddress.get(address)),\n missingAddresses: uniqueAddresses.filter((address) => !existsByAddress.get(address)),\n existsByAddress,\n };\n}\n\nexport async function accountExists(rpc: Rpc<SolanaRpcApi>, address: Address): Promise<boolean> {\n const accountInfo = await rpc.getAccountInfo(address, { encoding: \"base64\" }).send();\n return accountInfo.value !== null;\n}\n","/**\n * Kit <-> Web3.js compatibility helpers.\n *\n * These helpers bridge between Kit v2 types and web3.js v1 types,\n * which is needed when using Kit with Anchor (which still uses web3.js v1).\n */\n\nimport { AccountMeta as Web3AccountMeta, PublicKey, TransactionInstruction } from \"@solana/web3.js\";\nimport { Address, AccountMeta, AccountRole, Instruction, address } from \"@solana/kit\";\nimport { CustomAccountMeta } from \"../types\";\n\n/**\n * Convert a Kit Address to a web3.js PublicKey.\n *\n * @param addr - Kit Address (base58 string branded type)\n * @returns web3.js PublicKey\n */\nexport function toWeb3Pk(addr: Address): PublicKey {\n return new PublicKey(addr);\n}\n\n/**\n * Convert a web3.js PublicKey to a Kit Address\n *\n * @param addr - web3.js PublicKey\n * @returns Kit Address\n */\nexport function fromWeb3Pk(addr: PublicKey): Address {\n return address(addr.toString());\n}\n\n/**\n * Convert a Kit AccountMeta to web3.js AccountMeta format.\n *\n * Kit uses an AccountRole enum, while web3.js uses isSigner/isWritable booleans.\n * This is useful for Anchor's remainingAccounts which expects web3.js format.\n *\n * @param account - Kit AccountMeta\n * @returns web3.js compatible AccountMeta\n */\nexport function toWeb3AccountMeta(account: AccountMeta | CustomAccountMeta): {\n pubkey: PublicKey;\n isSigner: boolean;\n isWritable: boolean;\n} {\n return {\n pubkey: new PublicKey(account.address),\n isSigner:\n account.role === AccountRole.READONLY_SIGNER || account.role === AccountRole.WRITABLE_SIGNER,\n isWritable:\n account.role === AccountRole.WRITABLE || account.role === AccountRole.WRITABLE_SIGNER,\n };\n}\n\n/**\n * Convert a web3.js TransactionInstruction to Kit Instruction.\n *\n * This allows using Anchor-generated instructions with Kit's transaction building.\n *\n * @param ix - web3.js TransactionInstruction (from Anchor's .instruction())\n * @returns Kit Instruction\n */\nexport function toKitInstruction(ix: TransactionInstruction): Instruction {\n return {\n programAddress: ix.programId.toBase58() as Address,\n data: new Uint8Array(ix.data),\n accounts: ix.keys.map((key: Web3AccountMeta) => ({\n address: key.pubkey.toBase58() as Address,\n role: key.isWritable\n ? key.isSigner\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.WRITABLE\n : key.isSigner\n ? AccountRole.READONLY_SIGNER\n : AccountRole.READONLY,\n })),\n };\n}\n","import { Address } from \"@solana/kit\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport { fromWeb3Pk, toWeb3Pk } from \"../compat\";\n\n/**\n * SPL associated token account (ATA) for mint + owner + token program (same PDA as\n * `@solana-program/token`’s `findAssociatedTokenPda`).\n */\nfunction deriveAssociatedTokenAddress(\n mint: Address,\n owner: Address,\n tokenProgram: Address\n): Address {\n const [ata] = PublicKey.findProgramAddressSync(\n [toWeb3Pk(owner).toBuffer(), toWeb3Pk(tokenProgram).toBuffer(), toWeb3Pk(mint).toBuffer()],\n new PublicKey(ASSOCIATED_TOKEN_PROGRAM_ADDRESS)\n );\n return fromWeb3Pk(ata);\n}\n\nexport async function getAtaAddress(\n mint: Address,\n owner: Address,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS\n): Promise<Address> {\n return deriveAssociatedTokenAddress(mint, owner, tokenProgram);\n}\n","import { Address, Rpc, SolanaRpcApi } from \"@solana/kit\";\n\n/**\n * Byte offset of the `amount` field in an SPL token account's serialized layout:\n *\n * [0..32) mint\n * [32..64) owner\n * [64..72) amount: u64 little-endian\n *\n * Token-2022 preserves the same base layout at these offsets; account\n * extensions (if any) live after byte 165, so reading the base `amount` at 64\n * is correct for both token programs.\n */\nconst SPL_TOKEN_ACCOUNT_AMOUNT_OFFSET = 64;\n\n/** `getMultipleAccounts` is capped at this many keys per request. */\nconst GET_MULTIPLE_ACCOUNTS_MAX_KEYS = 100;\n\n/**\n * Fetch SPL token account `amount` values for a list of token accounts in one\n * (or a small number of) RPC calls.\n *\n * Keyed by token account address rather than mint so the caller can derive\n * whatever mapping they need. Closed or non-existent accounts are simply\n * absent from the returned map (callers should treat them as `0`).\n *\n * Works for both SPL Token and Token-2022 accounts — the base layout through\n * byte 72 is identical. Use this instead of `getTokenAccountsByOwner` when\n * the set of accounts to read is known in advance; it scales with the query\n * set size rather than with the wallet's total token-account count.\n */\nexport async function fetchSplTokenAccountAmounts(\n rpc: Rpc<SolanaRpcApi>,\n tokenAccounts: Address[]\n): Promise<Map<Address, bigint>> {\n if (tokenAccounts.length === 0) return new Map();\n\n const chunks: Address[][] = [];\n for (let i = 0; i < tokenAccounts.length; i += GET_MULTIPLE_ACCOUNTS_MAX_KEYS) {\n chunks.push(tokenAccounts.slice(i, i + GET_MULTIPLE_ACCOUNTS_MAX_KEYS));\n }\n\n const balances = new Map<Address, bigint>();\n await Promise.all(\n chunks.map(async (chunk) => {\n const response = await (\n rpc as Rpc<SolanaRpcApi> & {\n getMultipleAccounts: (\n addrs: Address[],\n config: { encoding: \"base64\" }\n ) => {\n send(): Promise<{\n value: Array<{ data: [string, \"base64\"] } | null>;\n }>;\n };\n }\n )\n .getMultipleAccounts(chunk, { encoding: \"base64\" })\n .send();\n\n for (let i = 0; i < chunk.length; i++) {\n const entry = response.value[i];\n if (!entry) continue;\n const buf = Buffer.from(entry.data[0], \"base64\");\n balances.set(chunk[i], buf.readBigUInt64LE(SPL_TOKEN_ACCOUNT_AMOUNT_OFFSET));\n }\n })\n );\n return balances;\n}\n","export * from \"./meta\";\nexport * from \"./roles\";\nexport * from \"./rpc\";\nexport * from \"./pda\";\nexport * from \"./splBalances\";\n","interface CacheEntry<T> {\n data: T;\n timestamp: number;\n}\n\nexport interface CacheTtlConfig {\n defaultTtlMs?: number;\n categoryTtlMs?: Record<string, number>;\n}\n\nexport class DataCache {\n protected cache: Map<string, Map<string, CacheEntry<any>>> = new Map();\n protected ttlConfig: CacheTtlConfig;\n\n constructor(ttlConfig?: CacheTtlConfig) {\n this.ttlConfig = {\n defaultTtlMs: ttlConfig?.defaultTtlMs ?? 60_000 * 5, // 5 minute default\n categoryTtlMs: ttlConfig?.categoryTtlMs ?? {},\n };\n }\n\n async getData<T>(\n fetchFn: () => Promise<T | null>,\n category: string,\n id: string,\n options?: { cacheNull?: boolean }\n ): Promise<{ data: T | null; fromCache: boolean }> {\n let data = this.tryFromCache<T>(category, id);\n let fromCache = true;\n if (!data) {\n data = await fetchFn();\n\n if (data !== null || options?.cacheNull !== false) {\n this.setCache(category, id, data);\n }\n fromCache = false;\n }\n return { data, fromCache };\n }\n\n async getDataOrThrow<T>(\n fetchFn: () => Promise<T | null>,\n category: string,\n id: string,\n options?: { cacheNull?: boolean }\n ): Promise<{ data: T; fromCache: boolean }> {\n const { data, fromCache } = await this.getData(fetchFn, category, id, options);\n if (!data) {\n throw new Error(`Failed to fetch ${category} data, ID: ${id}`);\n }\n return { data, fromCache };\n }\n\n async getDataBatch<T>(\n fetchFn: () => Promise<(T | null)[]>,\n category: string,\n ids: string[]\n ): Promise<{ data: T[]; fromCache: boolean }> {\n let data = ids.map((id) => this.tryFromCache<T>(category, id));\n let fromCache = true;\n\n if (data.some((item) => item === null)) {\n data = await fetchFn();\n if (!data) {\n throw new Error(`Failed to batch fetch ${category} data`);\n }\n for (let i = 0; i < ids.length; i++) {\n this.setCache(category, ids[i], data[i]);\n }\n fromCache = false;\n }\n\n return { data: data as T[], fromCache };\n }\n\n private getTtlForCategory(category: string): number {\n return this.ttlConfig.categoryTtlMs?.[category] ?? this.ttlConfig.defaultTtlMs!;\n }\n\n protected isStale(entry: CacheEntry<any>, category: string): boolean {\n const ttl = this.getTtlForCategory(category);\n const age = Date.now() - entry.timestamp;\n return age > ttl;\n }\n\n /** Returns null if not found or stale */\n protected tryFromCache<T>(category: string, id: string): T | null {\n const categoryCache = this.cache.get(category);\n if (!categoryCache) {\n return null;\n }\n\n const entry = categoryCache.get(id);\n if (!entry) {\n return null;\n }\n\n if (this.isStale(entry, category)) {\n categoryCache.delete(id);\n return null;\n }\n\n return entry.data as T;\n }\n\n protected getCacheAge(category: string, id: string): number | null {\n const categoryCache = this.cache.get(category);\n if (!categoryCache) {\n return null;\n }\n\n const entry = categoryCache.get(id);\n if (!entry) {\n return null;\n }\n\n return Date.now() - entry.timestamp;\n }\n\n setCache(category: string, id: string, data: any): void {\n let categoryCache = this.cache.get(category);\n if (!categoryCache) {\n categoryCache = new Map();\n this.cache.set(category, categoryCache);\n }\n\n categoryCache.set(id, {\n data,\n timestamp: Date.now(),\n });\n }\n\n refreshCategory(category: string): void {\n const categoryCache = this.cache.get(category);\n if (categoryCache) {\n categoryCache.clear();\n }\n }\n\n clearCacheEntry(category: string, id: string): boolean {\n const categoryCache = this.cache.get(category);\n if (!categoryCache) {\n return false;\n }\n return categoryCache.delete(id);\n }\n\n clearStaleEntries(category: string): number {\n const categoryCache = this.cache.get(category);\n if (!categoryCache) {\n return 0;\n }\n\n let cleared = 0;\n for (const [id, entry] of categoryCache.entries()) {\n if (this.isStale(entry, category)) {\n categoryCache.delete(id);\n cleared++;\n }\n }\n return cleared;\n }\n\n clearAllStaleEntries(): number {\n let totalCleared = 0;\n for (const category of this.cache.keys()) {\n totalCleared += this.clearStaleEntries(category);\n }\n return totalCleared;\n }\n\n clearAllCache(): void {\n this.cache.clear();\n }\n}\n","import type { Address, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { fetchMaybeToken } from \"@solana-program/token\";\nimport { DataCache, type CacheTtlConfig } from \"./dataCache\";\n\n/**\n * DataCache category for SPL associated-token-account existence (e.g. `BaseAccountClient#splAtaExists`).\n * Must match the `splAta` branch of `TransactionCacheInvalidation` for post-success cache clears.\n */\nexport const SPL_ATA_CACHE_CATEGORY = \"splAta\" as const;\n\n/** Default TTL for {@link SPL_ATA_CACHE_CATEGORY} entries (SPL token account existence). */\nconst DEFAULT_SPL_ATA_TTL_MS = 60_000 * 10;\n\n/**\n * Program-agnostic account helpers: shared {@link DataCache} wiring and SPL ATA existence\n * checks for instruction builders (e.g. `getCreateAtaIxIfNeeded`). Extend this in per-program\n * SDKs for typed account fetchers and domain-specific cache categories.\n */\nexport class BaseAccountClient {\n readonly dataCache: DataCache;\n\n protected constructor(\n protected readonly rpc: Rpc<SolanaRpcApi>,\n options?: Pick<CacheTtlConfig, \"defaultTtlMs\" | \"categoryTtlMs\">\n ) {\n this.dataCache = new DataCache({\n defaultTtlMs: options?.defaultTtlMs,\n categoryTtlMs: {\n [SPL_ATA_CACHE_CATEGORY]: DEFAULT_SPL_ATA_TTL_MS,\n ...options?.categoryTtlMs,\n },\n });\n }\n\n /**\n * Whether an SPL token account exists at `ata`. Cached under {@link SPL_ATA_CACHE_CATEGORY};\n * clear via post-success `splAta` transaction cache invalidations after successful creates.\n */\n async splAtaExists(ata: Address): Promise<boolean> {\n const { data } = await this.dataCache.getData(\n async () => (await fetchMaybeToken(this.rpc, ata)).exists,\n SPL_ATA_CACHE_CATEGORY,\n ata\n );\n return data ?? false;\n }\n}\n","import type { TransactionCacheInvalidation } from \"../types/general\";\nimport { SPL_ATA_CACHE_CATEGORY } from \"../services/baseAccountClient\";\nimport type { DataCache } from \"../services/dataCache\";\n\nexport interface ApplyDataCacheTransactionInvalidationsOptions {\n /**\n * `DataCache` category used for `lycToken` invalidations (program-specific; e.g. LYC uses `\"token\"`).\n */\n tokenPdaCategory: string;\n /**\n * `DataCache` category used for `lycYieldingBank` invalidations.\n */\n yieldingBankPdaCategory: string;\n}\n\n/**\n * Clears {@link DataCache} entries described by post-success invalidations.\n *\n * Handles `lycToken`, `lycYieldingBank`, `splAta`, and `perena` branches of\n * {@link TransactionCacheInvalidation}. Ignores `kamino` entries (those are\n * applied by lending-platform clients).\n */\nexport function applyDataCacheTransactionInvalidations(\n dataCache: DataCache,\n invalidations: TransactionCacheInvalidation[],\n options: ApplyDataCacheTransactionInvalidationsOptions\n): void {\n for (const inv of invalidations) {\n if (inv.client === \"lycToken\") {\n dataCache.clearCacheEntry(options.tokenPdaCategory, inv.tokenPda);\n } else if (inv.client === \"lycYieldingBank\") {\n dataCache.clearCacheEntry(options.yieldingBankPdaCategory, inv.yieldingBankPda);\n } else if (inv.client === \"splAta\") {\n dataCache.clearCacheEntry(SPL_ATA_CACHE_CATEGORY, inv.ata);\n } else if (inv.client === \"perena\") {\n inv.dataCache.clearCacheEntry(inv.category, inv.id);\n }\n }\n}\n","/**\n * CPI args buffer utilities.\n *\n * # Wire format (per CPI slot)\n *\n * ```text\n * [u16 LE length]\n * • 0xFFFF → skip (program must compute args)\n * • 0 → no instruction args (invoke with empty data)\n * • N > 0 → N bytes of client-provided data follow\n * ```\n *\n * Protocol-specific getter functions (e.g. `getPerenaMintArgs`) return raw\n * serialized bytes (no prefix). Wrap them with `serializeArgs()` to add\n * the u16 length prefix before packing into the CPI args buffer.\n */\n\n/** Sentinel u16 value meaning \"program must provide args.\" */\nexport const SKIP_SENTINEL = 0xffff;\n\n/**\n * Serialize CPI args with a u16 LE length prefix.\n *\n * - Called with data → `[u16_len, ...data]` (client provides args; len may be 0)\n * - Called without data → `[0xFF, 0xFF]` (skip — program provides args)\n *\n * @example\n * ```typescript\n * serializeArgs(getPerenaMintArgs({ ... })) // [16, 0, ...16 bytes]\n * serializeArgs(jupiterSwapData) // [N, 0, ...N bytes]\n * serializeArgs(Buffer.alloc(0)) // [0, 0] — no-args instruction\n * serializeArgs() // [0xFF, 0xFF] — skip\n * ```\n */\nexport function serializeArgs(data?: Buffer | Uint8Array): Buffer {\n if (data === undefined) {\n const buf = Buffer.alloc(2);\n buf.writeUInt16LE(SKIP_SENTINEL);\n return buf;\n }\n const len = data.length;\n const buf = Buffer.alloc(2 + len);\n buf.writeUInt16LE(len);\n if (len > 0) {\n Buffer.from(data).copy(buf, 2);\n }\n return buf;\n}\n\n/**\n * Fluent builder for packing CPI args into a single buffer.\n *\n * Each `.add()` call wraps the provided data with a u16 length prefix\n * via `serializeArgs`, then appends it.\n *\n * @example\n * ```typescript\n * const cpiArgs = new CpiArgsBuilder()\n * .add(getPerenaMintArgs({ amountYieldingDeposit: 1e6, minBankMintMinted: 9e5 }))\n * .add(jupiterSwapData)\n * .noArgs() // no-args instruction (len = 0)\n * .skip() // program provides args (0xFFFF)\n * .build();\n * ```\n */\nexport class CpiArgsBuilder {\n private parts: Buffer[] = [];\n\n /**\n * Add client-provided args for the next CPI slot.\n * Automatically wraps with a u16 LE length prefix.\n */\n add(data: Buffer | Uint8Array): this {\n this.parts.push(serializeArgs(data));\n return this;\n }\n\n /**\n * Mark the next CPI slot as a no-args instruction (length = 0).\n * The Rust side will invoke the CPI with empty instruction data.\n */\n noArgs(): this {\n this.parts.push(serializeArgs(Buffer.alloc(0)));\n return this;\n }\n\n /**\n * Mark the next CPI slot as program-provided (sentinel 0xFFFF).\n * The Rust handler must compute args and call `invoke_cpi` directly.\n */\n skip(): this {\n this.parts.push(serializeArgs());\n return this;\n }\n\n /** Build the final packed buffer. */\n build(): Buffer {\n return Buffer.concat(this.parts);\n }\n}\n","/**\n * CPI account mapping utilities for multi-CPI transactions.\n */\n\nimport { upgradeRoleToSigner, upgradeRoleToWritable, type Address } from \"@solana/kit\";\nimport { CpiData, CustomAccountMeta, InstructionRefs } from \"../../types\";\nimport { isRoleWritable, isRoleSigner, stripSignerFromAccounts } from \"../accounts/roles\";\nimport { CpiArgsBuilder } from \"./args\";\nimport { toCustomAccountMeta } from \"../accounts\";\n\n/**\n * Mapping for extracting accounts from `remainingAccounts` across multiple CPIs.\n *\n * @example\n * For 2 CPIs where CPI 0 needs 10 accounts and CPI 1 needs 8 accounts:\n * ```\n * indices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 5, 7, 10, 11, 12, 13, 14]\n * lengths: [10, 8]\n *\n * CPI 0 uses indices[0..10]\n * CPI 1 uses indices[10..18]\n * ```\n *\n * Matches Rust `CpiMapping` struct.\n */\nexport interface CpiMapping {\n /** All indices into the account pool, flattened across all CPIs */\n indices: Buffer;\n /** Number of accounts per CPI - used to slice indices */\n lengths: Buffer;\n}\n\n/**\n * Input for a single CPI in deduplication.\n *\n * Any object with `cpiType` and `accounts` can be used, including `CpiData`.\n *\n * @property cpiType - Index into CPI_REGISTRY\n * @property accounts - Accounts for this CPI (PROGRAM MUST BE FIRST!)\n */\nexport interface CpiInput {\n /** Index into CPI_REGISTRY (e.g., CpiTypes.PERENA_MINT) */\n cpiType: number;\n /** Accounts for this CPI - PROGRAM MUST BE FIRST ACCOUNT */\n accounts: CustomAccountMeta[];\n}\n\n/**\n * Options for deduplicating CPI accounts.\n */\nexport interface DeduplicateOptions {\n /**\n * Accounts to pre-populate the pool with before processing CPIs.\n *\n * These accounts are inserted at the beginning of the pool (positions 0..N-1)\n * so that CPI account indices correctly reference them. Any CPI account\n * whose address matches an initial account reuses that slot (deduplication).\n *\n * Use this to merge oracle accounts with CPI accounts in a single pass.\n */\n initialAccounts?: CustomAccountMeta[];\n /** Addresses to track - returns their indices in the pool */\n trackAddresses?: Address[];\n}\n\n/**\n * Result of creating CPI refs from multiple CPI account lists.\n */\nexport interface CreateCpiRefsResult {\n /** The deduplicated pool of unique accounts (pass as remainingAccounts) */\n accounts: CustomAccountMeta[];\n /** Anchor-serializable instruction refs (pass to Rust) */\n refs: InstructionRefs;\n lookupTables: Address[];\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Build indices for a single account list against a pool.\n */\nfunction buildIndicesForCpi(\n accounts: CustomAccountMeta[],\n poolIndex: Map<Address, number>\n): number[] {\n return accounts.map((acc) => {\n const idx = poolIndex.get(acc.address);\n if (idx === undefined) {\n throw new Error(`Account ${acc.address} not found in pool`);\n }\n return idx;\n });\n}\n\n/**\n * Build deduplicated pool from multiple account lists.\n */\nfunction buildDeduplicatedPool(\n accountLists: CustomAccountMeta[][]\n): Map<Address, CustomAccountMeta> {\n const poolMap = new Map<Address, CustomAccountMeta>();\n\n for (const accounts of accountLists) {\n for (const acc of accounts) {\n const existing = poolMap.get(acc.address);\n if (!existing) {\n poolMap.set(acc.address, { ...acc });\n } else {\n // Upgrade role if needed (most permissive wins)\n if (isRoleWritable(acc.role) && !isRoleWritable(existing.role)) {\n existing.role = upgradeRoleToWritable(existing.role);\n }\n if (isRoleSigner(acc.role) && !isRoleSigner(existing.role)) {\n existing.role = upgradeRoleToSigner(existing.role);\n }\n }\n }\n }\n\n return poolMap;\n}\n\n/**\n * Build a pool that preserves the exact sequential order of `initialAccounts`\n * (no deduplication within them) and then appends CPI accounts deduplicated\n * against the pool's first-occurrence index.\n *\n * This is required for instructions like `refresh_yielding_bank` that read\n * remaining_accounts **positionally** — deduplicating the initial accounts\n * would shift indices and break the sequential read order.\n */\nfunction buildPoolWithOrderedInitial(\n initialAccounts: CustomAccountMeta[],\n accountLists: CustomAccountMeta[][]\n): { pool: CustomAccountMeta[]; poolIndex: Map<Address, number> } {\n // Preserve every initial account entry in order (duplicates allowed).\n const pool: CustomAccountMeta[] = initialAccounts.map((acc) => ({ ...acc }));\n\n // Index maps each address to its FIRST occurrence for CPI dedup lookups.\n const poolIndex = new Map<Address, number>();\n pool.forEach((acc, i) => {\n if (!poolIndex.has(acc.address)) {\n poolIndex.set(acc.address, i);\n }\n });\n\n // Append CPI accounts, deduplicating against the pool.\n for (const accounts of accountLists) {\n for (const acc of accounts) {\n const existingIdx = poolIndex.get(acc.address);\n if (existingIdx === undefined) {\n const idx = pool.length;\n poolIndex.set(acc.address, idx);\n pool.push({ ...acc });\n } else {\n // Upgrade role on the first-occurrence entry (most permissive wins).\n const existing = pool[existingIdx];\n if (isRoleWritable(acc.role) && !isRoleWritable(existing.role)) {\n existing.role = upgradeRoleToWritable(existing.role);\n }\n if (isRoleSigner(acc.role) && !isRoleSigner(existing.role)) {\n existing.role = upgradeRoleToSigner(existing.role);\n }\n }\n }\n }\n\n return { pool, poolIndex };\n}\n\n// ============================================================================\n// Shared Internal Helpers\n// ============================================================================\n\n/**\n * Build a deduplicated account pool from CPI account lists, respecting\n * optional `initialAccounts` ordering.\n */\nfunction buildPool(\n accountLists: CustomAccountMeta[][],\n options?: DeduplicateOptions\n): { pool: CustomAccountMeta[]; poolIndex: Map<Address, number> } {\n if (options?.initialAccounts) {\n return buildPoolWithOrderedInitial(options.initialAccounts, accountLists);\n }\n\n const poolMap = buildDeduplicatedPool(accountLists);\n const pool = Array.from(poolMap.values());\n const poolIndex = new Map<Address, number>();\n pool.forEach((acc, i) => poolIndex.set(acc.address, i));\n return { pool, poolIndex };\n}\n\n/**\n * Resolve tracked addresses to their indices in the pool.\n */\nfunction resolveTrackedIndices(\n poolIndex: Map<Address, number>,\n trackAddresses?: Address[]\n): number[] {\n if (!trackAddresses) return [];\n\n return trackAddresses.map((addr) => {\n const idx = poolIndex.get(addr);\n if (idx === undefined) {\n throw new Error(`Tracked address ${addr} not found in pool`);\n }\n return idx;\n });\n}\n\n/**\n * Build a single `InstructionRefs` from a flat list of CPIs and their\n * pre-built account lists, all indexing into a shared pool.\n */\nfunction buildInstructionRefs(\n cpis: CpiData[],\n accountLists: CustomAccountMeta[][],\n poolIndex: Map<Address, number>,\n trackedIndices: number[]\n): InstructionRefs {\n const allIndices: number[] = [];\n const lengths: number[] = [];\n const cpiTypes: number[] = [];\n const cpiArgs = new CpiArgsBuilder();\n\n for (let i = 0; i < cpis.length; i++) {\n const indices = buildIndicesForCpi(accountLists[i], poolIndex);\n allIndices.push(...indices);\n lengths.push(indices.length);\n cpiTypes.push(cpis[i].cpiType);\n\n if (cpis[i].data !== undefined) {\n cpiArgs.add(cpis[i].data!);\n } else {\n cpiArgs.skip();\n }\n }\n\n return {\n cpi: {\n accounts: {\n indices: Buffer.from(allIndices),\n lengths: Buffer.from(lengths),\n },\n types: Buffer.from(cpiTypes),\n args: cpiArgs.build(),\n },\n tracked: Buffer.from(trackedIndices),\n };\n}\n\n/** Prepend the program account to each CPI's account list. */\nfunction toCpiAccountLists(cpis: CpiData[]): CustomAccountMeta[][] {\n return cpis.map((cpi) => [toCustomAccountMeta(cpi.programId), ...cpi.accounts]);\n}\n\n/** Collect all lookup tables from a flat list of CPIs. */\nfunction collectLookupTables(cpis: CpiData[]): Address[] {\n return cpis.flatMap((x) => x.lookupTables ?? []);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Result of creating multiple separate CPI ref groups from a shared account pool.\n */\nexport interface CreateMultiCpiRefsResult {\n /** The single deduplicated pool of unique accounts (pass as remainingAccounts) */\n accounts: CustomAccountMeta[];\n /** One InstructionRefs per input group, all indexing into the shared pool */\n refsGroups: InstructionRefs[];\n lookupTables: Address[];\n}\n\n/**\n * Deduplicate multiple groups of CPI data into a single shared account pool,\n * returning separate `InstructionRefs` for each group.\n *\n * Use this when an instruction accepts multiple independent refs arguments\n * (e.g. `ybIxRefs` + `tokenIxRefs`) that must index into the same\n * `remainingAccounts` pool.\n *\n * @param cpiGroups - Array of CPI data groups; each group produces one InstructionRefs\n * @param options - Optional initial accounts and tracked addresses\n *\n * @example\n * ```typescript\n * const swapCpis = [jupiterSwapCpiData];\n * const repayCpis = [kaminoRepayCpiData];\n *\n * const { accounts, refsGroups } = createMultiCpiRefs(\n * [swapCpis, repayCpis],\n * { initialAccounts: carryTradeAccounts }\n * );\n * const [ybIxRefs, tokenIxRefs] = refsGroups;\n * ```\n */\nexport function createMultiCpiRefs(\n cpiGroups: CpiData[][],\n options?: DeduplicateOptions\n): CreateMultiCpiRefsResult {\n const allCpis = cpiGroups.flat();\n const allAccountLists = toCpiAccountLists(allCpis);\n\n const { pool, poolIndex } = buildPool(allAccountLists, options);\n const trackedIndices = resolveTrackedIndices(poolIndex, options?.trackAddresses);\n\n let flatIdx = 0;\n const refsGroups: InstructionRefs[] = cpiGroups.map((group) => {\n const groupAccountLists = allAccountLists.slice(flatIdx, flatIdx + group.length);\n flatIdx += group.length;\n return buildInstructionRefs(group, groupAccountLists, poolIndex, trackedIndices);\n });\n\n return {\n accounts: stripSignerFromAccounts(pool),\n refsGroups,\n lookupTables: collectLookupTables(allCpis),\n };\n}\n\n/**\n * Deduplicate multiple CPI account lists into a single pool with CPI refs.\n *\n * Accepts any array of objects with `cpiType` and `accounts`, including `CpiData[]`.\n *\n * @param cpis - Array of CPI inputs (each with cpiType and accounts)\n * @param options - Optional configuration (e.g., addresses to track)\n * @returns Deduplicated pool and CPI refs\n *\n * @example\n * ```typescript\n * // CpiData includes cpiType, so pass it directly\n * const perenaIx = await perenaClient.getSwapCpiData(quote, pda);\n * const jupiterIx = await jupiterClient.getSwapCpiData(quote, pda);\n *\n * const { accounts, refs } = createCpiRefs([perenaIx, jupiterIx]);\n *\n * // Use accounts as remainingAccounts, refs as instruction arg\n * ```\n */\nexport function createCpiRefs(cpis: CpiData[], options?: DeduplicateOptions): CreateCpiRefsResult {\n const accountLists = toCpiAccountLists(cpis);\n const { pool, poolIndex } = buildPool(accountLists, options);\n const trackedIndices = resolveTrackedIndices(poolIndex, options?.trackAddresses);\n\n return {\n accounts: stripSignerFromAccounts(pool),\n refs: buildInstructionRefs(cpis, accountLists, poolIndex, trackedIndices),\n lookupTables: collectLookupTables(cpis),\n };\n}\n","export * from \"./args\";\nexport * from \"./refs\";\n","import { Address } from \"@solana/kit\";\nimport os from \"os\";\nimport path from \"path\";\n\nexport function resolveFp(keypairFp: string) {\n // Expand ~ to home dir\n if (keypairFp.startsWith(\"~\")) {\n keypairFp = path.join(os.homedir(), keypairFp.slice(1));\n }\n\n // Resolve relative paths to absolute ones\n keypairFp = path.resolve(keypairFp);\n\n return keypairFp;\n}\n\nexport function deduplicateAccounts(addresses: Address[]) {\n return Array.from(new Set(addresses).values());\n}\n\n/**\n * Returns items in encounter order; later entries with the same `key(item)` are skipped.\n */\nexport function dedupeOrdered<T>(items: readonly T[], key: (item: T) => string): T[] {\n const ordered: T[] = [];\n const seen = new Set<string>();\n for (const item of items) {\n const k = key(item);\n if (seen.has(k)) continue;\n seen.add(k);\n ordered.push(item);\n }\n return ordered;\n}\n\n/**\n * {@link dedupeOrdered} for Solana Kit `Address` values (compares base58 strings).\n */\nexport function dedupeOrderedAddresses(addresses: readonly Address[]): Address[] {\n return dedupeOrdered(addresses, (a) => a as string);\n}\n\n/** Return `addresses` excluding any address present in `excluded`. */\nexport function filterSpecificAccounts(\n addresses: readonly Address[],\n excluded: readonly Address[]\n): Address[] {\n const excludedSet = new Set<Address>(excluded);\n return addresses.filter((address) => !excludedSet.has(address));\n}\n\nexport function zip<T, U>(list1: T[], list2: U[]): [T, U][] {\n const minLength = Math.min(list1.length, list2.length);\n const result: [T, U][] = [];\n\n for (let i = 0; i < minLength; i++) {\n result.push([list1[i], list2[i]]);\n }\n\n return result;\n}\n\n/**\n * Returns the element with the highest numeric score. Throws if `items` is empty.\n */\nexport function maxByNumber<T>(items: T[], score: (item: T) => number): T {\n if (items.length === 0) {\n throw new Error(\"maxByNumber: empty items\");\n }\n let best = items[0]!;\n let bestScore = score(best);\n for (let i = 1; i < items.length; i++) {\n const item = items[i]!;\n const s = score(item);\n if (s > bestScore) {\n best = item;\n bestScore = s;\n }\n }\n return best;\n}\n\nexport function createRecord<T>(keys: string[], values: T[]): Record<string, T> {\n return Object.fromEntries(zip(keys, values).map(([k, v]) => [k.toString(), v]));\n}\n\n/**\n * Case-insensitive key lookup on a record. Returns the first matching key, or undefined.\n */\nexport function findKeyIgnoreCase(\n record: Record<string, unknown>,\n key: string\n): string | undefined {\n const lower = key.toLowerCase();\n return Object.keys(record).find((k) => k.toLowerCase() === lower);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import {\n createKeyPairSignerFromBytes,\n type Address,\n type KeyPairSigner,\n type Rpc,\n type Signature,\n type SolanaRpcApi,\n type TransactionSigner,\n} from \"@solana/kit\";\nimport { Keypair } from \"@solana/web3.js\";\nimport fs from \"fs\";\nimport { resolveFp } from \"./general\";\n\nexport function createSignerFromAddress(address: Address): TransactionSigner {\n return { address } as TransactionSigner;\n}\n\nexport async function getSlot(\n rpc: Rpc<SolanaRpcApi>,\n commitment: \"processed\" | \"confirmed\" | \"finalized\" = \"confirmed\"\n) {\n return rpc.getSlot({ commitment }).send();\n}\n\nexport function isTransactionSigner(x: unknown): x is TransactionSigner {\n return (\n typeof x === \"object\" &&\n x !== null &&\n \"address\" in x &&\n typeof (x as TransactionSigner).address === \"string\"\n );\n}\n\n/** Raw secret key bytes from a Solana CLI JSON keypair file. */\nexport function readLocalKeypairSecret(keypairPath: string): Uint8Array {\n const walletData = JSON.parse(fs.readFileSync(resolveFp(keypairPath), \"utf-8\"));\n return new Uint8Array(walletData);\n}\n\n/**\n * Loads a Solana keypair signer from a JSON file on disk.\n * @param keypairPath - Path to the JSON keypair file (e.g. ~/.config/solana/tp/id.json)\n */\nexport async function loadLocalKeypair(\n keypairPath = \"~/.config/solana/tp/id.json\"\n): Promise<KeyPairSigner> {\n return createKeyPairSignerFromBytes(readLocalKeypairSecret(keypairPath), true);\n}\n\n/**\n * Same keypair file as {@link loadLocalKeypair}, returned as both a Kit signer and a\n * `@solana/web3.js` {@link Keypair} for Anchor (`AnchorProvider` / `Wallet`).\n *\n * Kit's `KeyPairSigner.keyPair` is a Web Crypto `CryptoKeyPair`, not a web3.js `Keypair`.\n */\nexport async function loadLocalKeypairWithWeb3(\n keypairPath = \"~/.config/solana/tp/id.json\"\n): Promise<{ signer: KeyPairSigner; web3Keypair: Keypair }> {\n const secret = readLocalKeypairSecret(keypairPath);\n const signer = await createKeyPairSignerFromBytes(secret, true);\n const web3Keypair = Keypair.fromSecretKey(secret);\n return { signer, web3Keypair };\n}\n\nexport async function logTxMessages(rpc: Rpc<SolanaRpcApi>, sig: Signature) {\n const info = await rpc\n .getTransaction(sig, {\n commitment: \"confirmed\",\n encoding: \"base64\",\n })\n .send();\n\n console.log((info?.meta?.logMessages ?? []).join(\"\\n\"));\n}\n","import type { Address } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\n\nexport type AssetType = \"LST\" | \"YBA\" | \"Stablecoin\" | \"Standard\";\n\nexport interface MintConfig {\n address: Address;\n symbol: string;\n decimals: number;\n name?: string;\n assetType: AssetType;\n isToken2022?: boolean;\n}\n\n/**\n * Runtime information for a token mint.\n * Extends MintConfig with methods for dynamic data.\n */\nexport interface MintInfo extends MintConfig {\n tokenProgram: Address;\n\n /**\n * Get the current APY for this token (LSTs & YBAs only).\n * Returns undefined for non-LST tokens.\n */\n getApy?: () => Promise<number | undefined>;\n\n toUiAmount: (amount: bigint | BN) => number;\n fromUiAmount: (amount: number) => BN;\n}\n\nexport interface MintRegistryOptions {\n /** Default: true */\n includeDefaults?: boolean;\n custom?: MintConfig[];\n}\n","import { address } from \"@solana/kit\";\nimport type { MintConfig } from \"./types\";\n\nexport const DEFAULT_MINTS: MintConfig[] = [\n // Risk assets\n {\n address: address(\"So11111111111111111111111111111111111111112\"),\n symbol: \"SOL\",\n name: \"Solana\",\n decimals: 9,\n assetType: \"Standard\",\n },\n {\n address: address(\"3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh\"),\n symbol: \"wBTC\",\n name: \"Wrapped Bitcoin\",\n decimals: 8,\n assetType: \"Standard\",\n },\n {\n address: address(\"cbbtcf3aa214zXHbiAZQwf4122FBYbraNdFqgw4iMij\"),\n symbol: \"cbBTC\",\n name: \"Coinbase Wrapped Bitcoin\",\n decimals: 8,\n assetType: \"Standard\",\n },\n {\n address: address(\"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs\"),\n symbol: \"wETH\",\n name: \"Wrapped Ethereum\",\n decimals: 8,\n assetType: \"Standard\",\n },\n {\n address: address(\"27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4\"),\n symbol: \"JLP\",\n name: \"Jupiter Perps LP\",\n decimals: 6,\n assetType: \"Standard\",\n },\n {\n address: address(\"XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W\"),\n symbol: \"SPYx\",\n name: \"SP500 xStock\",\n decimals: 8,\n assetType: \"Standard\",\n isToken2022: true,\n },\n {\n address: address(\"Xs8S1uUs1zvS2p7iwtsG3b6fkhpvmwz4GYU3gWAmWHZ\"),\n symbol: \"QQQx\",\n name: \"Nasdaq xStock\",\n decimals: 8,\n assetType: \"Standard\",\n isToken2022: true,\n },\n // Stablecoins\n {\n address: address(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"),\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n assetType: \"Stablecoin\",\n },\n {\n address: address(\"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\"),\n symbol: \"USDT\",\n name: \"Tether USD\",\n decimals: 6,\n assetType: \"Stablecoin\",\n },\n {\n address: address(\"USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA\"),\n symbol: \"USDS\",\n decimals: 6,\n assetType: \"Stablecoin\",\n },\n {\n address: address(\"2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH\"),\n symbol: \"USDG\",\n name: \"Global Dollar\",\n decimals: 6,\n assetType: \"Stablecoin\",\n isToken2022: true,\n },\n {\n address: address(\"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo\"),\n symbol: \"PYUSD\",\n name: \"PayPal USD\",\n decimals: 6,\n assetType: \"Stablecoin\",\n isToken2022: true,\n },\n {\n address: address(\"CASHx9KJUStyftLFWGvEVf59SGeG9sh5FfcnZMVPCASH\"),\n symbol: \"CASH\",\n decimals: 6,\n assetType: \"Stablecoin\",\n isToken2022: true,\n },\n {\n address: address(\"USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB\"),\n symbol: \"USD1\",\n decimals: 6,\n assetType: \"Stablecoin\",\n },\n // LSTs\n {\n address: address(\"J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn\"),\n symbol: \"JitoSOL\",\n name: \"Jito SOL\",\n decimals: 9,\n assetType: \"LST\",\n },\n {\n address: address(\"jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v\"),\n symbol: \"JupSOL\",\n name: \"Jupiter Staked SOL\",\n decimals: 9,\n assetType: \"LST\",\n },\n {\n address: address(\"sctmB7GPi5L2Q5G9tUSzXvhZ4YiDMEGcRov9KfArQpx\"),\n symbol: \"dfdvSOL\",\n name: \"DeFi Development Corp SOL\",\n decimals: 9,\n assetType: \"LST\",\n },\n // Yield bearing assets\n {\n address: address(\"star9agSpjiFe3M49B3RniVU4CMBBEK3Qnaqn3RGiFM\"),\n symbol: \"USD*\",\n name: \"USD Star\",\n decimals: 6,\n assetType: \"YBA\",\n },\n {\n address: address(\"3AJYCjrhKitmBd8tRUurPA5dGHCAQh6A8L9DkuSC37Rm\"),\n symbol: \"USD*-J\",\n name: \"USD Star Junior\",\n decimals: 6,\n assetType: \"YBA\",\n },\n {\n address: address(\"59obFNBzyTBGowrkif5uK7ojS58vsuWz3ZCvg6tfZAGw\"),\n symbol: \"PST\",\n name: \"PayFi Strategy Token\",\n decimals: 6,\n assetType: \"YBA\",\n },\n];\n","import { address, Address } from \"@solana/kit\";\nimport type { DeployedEnv, Environment } from \"../types\";\n\nexport const ENVIRONMENT: Environment = (process.env.ENVIRONMENT as Environment) ?? \"local\";\n\nexport const LAMPORTS_PER_SOL = 1_000_000_000;\nexport const DAYS_PER_YEAR = 365;\nexport const TVL_USD_DECIMAL_PLACES = 8;\nexport const TVL_USD_SCALE = BigInt(10 ** TVL_USD_DECIMAL_PLACES);\nexport const BPS_DENOMINATOR = 10_000n;\nexport const DEFAULT_PUBLIC_KEY: Address = address(\"11111111111111111111111111111111\");\n\nexport const LOCALNET_URL = \"http://127.0.0.1:8899\";\n\nexport const TP_ID_KEYPAIR_FP = \"~/.config/solana/tp/id.json\";\nexport const TP_LUT_MANAGER_KP_FP = \"~/.config/solana/tp/lut-manager.json\";\n\n/**\n * Program-level admin pubkey shared across deployed programs (LYC protocol admin,\n * consensus oracle admin seed, etc.). Matches Rust `PROTOCOL_ADMIN`.\n */\nexport const PROTOCOL_ADMIN: Record<Environment, Address> = {\n local: address(\"7PxS1VMxKbzUTF4sxeAw4LqBfnGMaeQH2KwabmUcVxYC\"),\n test: address(\"8S1Ta7xZVsiqtf9mrUPwXKSNmBPzmsK3RdhonDu3kzk\"),\n prod: address(\"42GmTZiLdcJHmxCik4WvxTYeNirzFqsr7DXWZDst4gxE\"), // TODO: multisig admin\n};\n\n/** Admin keypair paths for deployed (test/prod) CLI scripts. */\nexport const DEPLOYED_ADMIN_KEYPAIR_FP: Record<DeployedEnv, string> = {\n test: \"~/.config/solana/tp/lyc-admin-test.json\",\n prod: \"~/.config/solana/tp/lyc-admin-prod.json\",\n};\n\nexport const PRICE_STALENESS_SECONDS = 60;\n\nexport const METAPLEX_TOKEN_METADATA_PROGRAM_ID: Address = address(\n \"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\"\n);\n","import { BN } from \"@anchor-lang/core\";\nimport { BPS_DENOMINATOR, TVL_USD_SCALE } from \"../constants/general\";\n\nexport const U64_MAX = BigInt(\"18446744073709551615\");\nexport const U64_MAX_BN = new BN(U64_MAX.toString());\n\nexport function toUiAmount(amount: bigint | BN, decimals: number): number {\n const bigintValue = typeof amount === \"bigint\" ? amount : BigInt(amount.toString());\n\n // Treat max u64 as unlimited\n if (bigintValue >= U64_MAX) {\n return Infinity;\n }\n\n // For values that fit in safe integer range, convert directly\n if (bigintValue <= BigInt(Number.MAX_SAFE_INTEGER)) {\n return Number(bigintValue) / Math.pow(10, decimals);\n }\n\n // For large values, divide first using BigInt then convert\n // This preserves more precision for the significant digits\n const divisor = BigInt(Math.pow(10, decimals));\n const wholePart = bigintValue / divisor;\n const remainder = bigintValue % divisor;\n return Number(wholePart) + Number(remainder) / Math.pow(10, decimals);\n}\n\nexport function fromUiAmount(amount: number, decimals: number) {\n return new BN(Math.round(amount * Math.pow(10, decimals)));\n}\n\n/** Base-unit amount representing exactly 1 whole token for `decimals`. */\nexport function wholeTokenAmount(decimals: number): number {\n return Math.pow(10, decimals);\n}\n\n/**\n * Compute USD TVL from a raw token amount and a raw oracle price, normalized\n * to 8-decimal USD ($1 = 100_000_000).\n *\n * Mirrors the on-chain `calculate_tvl_usd`:\n * `tvl = amount * price / (10^(2*decimals) / 10^8)`\n *\n * Oracle prices are scaled to `10^decimals` per dollar (e.g. $1 USDC at 6 dec\n * = 1_000_000; $130 SOL at 9 dec = 130_000_000_000).\n */\nexport function calculateTvlUsd(amount: bigint, price: bigint, decimals: number): bigint {\n const assetScale = BigInt(wholeTokenAmount(decimals));\n const scaleFactor = (assetScale * assetScale) / TVL_USD_SCALE;\n return (amount * price) / scaleFactor;\n}\n\n/**\n * Inverse of {@link calculateTvlUsd}: convert a normalized 8-decimal USD value\n * back to base units given a raw oracle price and decimal precision.\n *\n * `amount = tvlUsd * (10^(2*decimals) / 10^8) / price`\n */\nexport function tvlUsdToBaseUnits(tvlUsd: bigint, price: bigint, decimals: number): bigint {\n const assetScale = BigInt(wholeTokenAmount(decimals));\n const scaleFactor = (assetScale * assetScale) / TVL_USD_SCALE;\n return (tvlUsd * scaleFactor) / price;\n}\n\n/** `bigint` → Anchor `BN` without floating-point loss (e.g. raw lamports / token amounts). */\nexport function bnFromBigInt(n: bigint): BN {\n return new BN(n.toString());\n}\n\n/**\n * `bigint × number → bigint` with sign-preserving half-away-from-zero rounding.\n *\n * JS has no native `bigint * float` op; we go through `Number(a) * b` and\n * round. Precision loss is bounded by Number's ~15 significant digits, which\n * is well inside sub-cent tolerance for realistic token balances. Returns\n * `0n` when either input is zero or the multiplier is non-finite.\n *\n * Typical use: applying a floating-point rate (NAV, APY multiplier, oracle\n * price per UI) to an integer base-unit balance.\n */\nexport function bigintMulNumber(a: bigint, b: number): bigint {\n if (a === 0n || !Number.isFinite(b) || b === 0) return 0n;\n return BigInt(Math.round(Number(a) * b));\n}\n\n/**\n * Ceiling-round `principal * feeRate`, returning the result as a bigint.\n *\n * Use this when undershooting the fee can cause a transaction to fail (e.g.\n * a flash-loan repay that must cover principal + fee — over-paying by at most\n * one base unit is fine, under-paying reverts).\n *\n * `feeRate` is a unitless fraction (e.g. `0.003` for 0.3%). Returns `0n` for\n * non-positive rates.\n */\nexport function applyFeeCeil(principal: bigint, feeRate: number): bigint {\n if (feeRate <= 0) return 0n;\n // Scale rate to 1e9 for integer math; ceil so we over-pay by at most one unit.\n const scale = 1_000_000_000n;\n const rateScaled = BigInt(Math.ceil(feeRate * Number(scale)));\n const numerator = principal * rateScaled;\n return (numerator + (scale - 1n)) / scale;\n}\n\nexport function getBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n}\n\nexport function currentUnixSeconds() {\n return Math.floor(Date.now() / 1000);\n}\n\nexport function sum(numbers: number[]) {\n return numbers.reduce((prev, curr) => prev + curr, 0);\n}\n\nexport function toBigInt(value: BN | number | bigint) {\n return BigInt(value.toString());\n}\n\n/** Apply a basis-points multiplier: `(value × bps) / 10_000`. */\nexport function applyBps(value: bigint, bps: bigint | number): bigint {\n return (value * BigInt(bps)) / BPS_DENOMINATOR;\n}\n\n/** Compute the basis-points ratio: `(part / whole) × 10_000`. */\nexport function toBps(part: bigint, whole: bigint): bigint {\n if (whole === 0n) return 0n;\n return (part * BPS_DENOMINATOR) / whole;\n}\n\nexport function toSafeNumber(value: bigint | BN, field: string) {\n const asBigInt = typeof value === \"bigint\" ? value : BigInt(value.toString());\n if (asBigInt > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(`${field} exceeds Number.MAX_SAFE_INTEGER and cannot be quoted safely`);\n }\n\n return Number(asBigInt);\n}\n\nfunction numberToLEBytes(value: number | bigint | BN, byteLength = 8): Uint8Array {\n const bigintValue = typeof value === \"bigint\" ? value : BigInt(value.toString());\n const buf = new ArrayBuffer(byteLength);\n const view = new DataView(buf);\n\n if (byteLength === 8) {\n view.setBigUint64(0, bigintValue, true);\n } else {\n // Generic little-endian encoding for other byte lengths\n let remaining = bigintValue;\n for (let i = 0; i < byteLength; i++) {\n view.setUint8(i, Number(remaining & 0xffn));\n remaining >>= 8n;\n }\n }\n\n return new Uint8Array(buf);\n}\n\nexport function numToU64Bytes(value: number | bigint | BN) {\n return numberToLEBytes(value, 8);\n}\n\nexport function numToU32Bytes(value: number | bigint | BN) {\n return numberToLEBytes(value, 4);\n}\n\nexport function numToU16Bytes(value: number | bigint | BN) {\n return numberToLEBytes(value, 2);\n}\n\n/**\n * Compute annualized percentage yield from two price snapshots.\n *\n * Formula:\n * growthRate = priceEnd / priceStart\n * APY = (growthRate ^ (365 / daysBetween) - 1) * 100\n *\n * Returns `null` if either price is missing/zero or the time delta is zero.\n */\nexport function computeApy(\n priceEnd: number,\n priceStart: number,\n windowSeconds: number\n): number | null {\n const SECONDS_PER_DAY = 86_400;\n const DAYS_PER_YEAR = 365;\n\n if (priceStart <= 0 || priceEnd <= 0 || windowSeconds <= 0) return null;\n\n const daysBetween = windowSeconds / SECONDS_PER_DAY;\n const growthRate = priceEnd / priceStart;\n const apy = (Math.pow(growthRate, DAYS_PER_YEAR / daysBetween) - 1) * 100;\n return Number.isFinite(apy) ? apy : null;\n}\n","import type { Address } from \"@solana/kit\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { TOKEN_2022_PROGRAM_ADDRESS } from \"@solana-program/token-2022\";\nimport type { AssetType, MintConfig, MintInfo, MintRegistryOptions } from \"./types\";\nimport { DEFAULT_MINTS } from \"./defaults\";\nimport { MintIdentifier } from \"../../types\";\nimport { toUiAmount, fromUiAmount } from \"../../utils/numbers\";\n\n/**\n * Registry for token mint information.\n *\n * Provides a unified interface to query token metadata by address or symbol.\n * Supports both well-known tokens and custom configurations.\n *\n * @example\n * ```typescript\n * // Create registry with defaults\n * const mints = new MintRegistry();\n *\n * // Query by symbol\n * const usdc = mints.get(\"USDC\");\n * console.log(usdc?.decimals); // 6\n *\n * // Query by address\n * const token = mints.get(someAddress);\n * console.log(token?.symbol); // \"USDC\"\n *\n * // Add custom tokens\n * const mints = new MintRegistry({\n * custom: [{ address: \"...\", symbol: \"MY_TOKEN\", decimals: 9 }]\n * });\n * ```\n */\nexport class MintRegistry {\n private byAddress: Map<Address, MintInfo> = new Map();\n private bySymbol: Map<string, MintInfo> = new Map();\n\n constructor(options: MintRegistryOptions = {}) {\n const { includeDefaults = true, custom = [] } = options;\n\n if (includeDefaults) {\n for (const config of DEFAULT_MINTS) {\n this.register(config);\n }\n }\n\n for (const config of custom) {\n this.register(config);\n }\n }\n\n /**\n * Register a new mint configuration.\n * Overwrites existing entries with the same address or symbol.\n */\n register(config: MintConfig): void {\n const mintInfo: MintInfo = {\n ...config,\n tokenProgram: config.isToken2022 ? TOKEN_2022_PROGRAM_ADDRESS : TOKEN_PROGRAM_ADDRESS,\n toUiAmount: (amount) => toUiAmount(amount, config.decimals),\n fromUiAmount: (amount) => fromUiAmount(amount, config.decimals),\n };\n this.byAddress.set(config.address, mintInfo);\n this.bySymbol.set(config.symbol.toUpperCase(), mintInfo);\n }\n\n /**\n * Get mint information by address or symbol.\n *\n * @param mint - Mint address or token symbol (case-insensitive)\n * @returns MintInfo if found, undefined otherwise\n *\n * @example\n * ```typescript\n * mints.get(\"USDC\")?.decimals // 6\n * mints.get(usdcAddress)?.symbol // \"USDC\"\n * ```\n */\n get(mint: MintIdentifier): MintInfo | undefined {\n const upperKey = mint.toUpperCase();\n const bySymbol = this.bySymbol.get(upperKey);\n if (bySymbol) {\n return bySymbol;\n }\n\n return this.byAddress.get(mint as Address);\n }\n\n all(): MintInfo[] {\n return Array.from(this.byAddress.values());\n }\n\n standardAssets(): MintInfo[] {\n return this.filterAssetsByType(\"Standard\");\n }\n\n stablecoins(): MintInfo[] {\n return this.filterAssetsByType(\"Stablecoin\");\n }\n\n lsts(): MintInfo[] {\n return this.filterAssetsByType(\"LST\");\n }\n\n yieldBearingAssets(): MintInfo[] {\n return this.filterAssetsByType(\"YBA\");\n }\n\n filterAssetsByType(assetType: AssetType) {\n return Array.from(this.byAddress.values()).filter((x) => x.assetType === assetType);\n }\n\n symbols(): string[] {\n return Array.from(this.bySymbol.keys());\n }\n\n addresses(): Address[] {\n return Array.from(this.byAddress.keys());\n }\n}\n\n/**\n * Default MintRegistry instance with well-known tokens.\n * Use this for quick access without creating a new instance.\n *\n * @example\n * ```typescript\n * import { mints } from \"./services/mints\";\n * const usdc = mints.get(\"USDC\");\n * ```\n */\nexport const mints = new MintRegistry();\n","import type { MintIdentifier } from \"../../types\";\nimport type { MintRegistry } from \"./registry\";\nimport { mints } from \"./registry\";\n\n/** Human-readable token symbol from the registry, or a short address prefix when unknown. */\nexport function mintSymbol(mint: MintIdentifier, registry: MintRegistry = mints): string {\n return registry.get(mint)?.symbol ?? String(mint).slice(0, 6);\n}\n\n/** Pair label for two mints, e.g. `cbBTC/PYUSD`. */\nexport function formatMintPair(\n leftMint: MintIdentifier,\n rightMint: MintIdentifier,\n registry: MintRegistry = mints\n): string {\n return `${mintSymbol(leftMint, registry)}/${mintSymbol(rightMint, registry)}`;\n}\n","export * from \"./types\";\nexport * from \"./registry\";\nexport * from \"./defaults\";\nexport * from \"./symbols\";\n","import { BN } from \"@anchor-lang/core\";\nimport { Address, type Instruction, type TransactionSigner, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport {\n getRequestHeapFrameInstruction,\n getSetComputeUnitLimitInstruction,\n getSetComputeUnitPriceInstruction,\n} from \"@solana-program/compute-budget\";\nimport {\n fetchMaybeToken,\n getCreateAssociatedTokenIdempotentInstruction,\n getSyncNativeInstruction,\n getCloseAccountInstruction,\n TOKEN_PROGRAM_ADDRESS,\n} from \"@solana-program/token\";\nimport { getTransferSolInstruction } from \"@solana-program/system\";\nimport { type BaseAccountClient, SPL_ATA_CACHE_CATEGORY } from \"../services/baseAccountClient\";\nimport type { TransactionCacheInvalidation } from \"../types/general\";\nimport { CustomAccountMeta } from \"../types\";\nimport { createSignerFromAddress, isTransactionSigner } from \"./solana\";\nimport { getAtaAddress } from \"./accounts/pda\";\nimport { allAccountsExist } from \"./accounts/rpc\";\nimport { mints } from \"../services/mints\";\n\nexport function setComputeUnitLimitIx(maxComputeUnits: number): Instruction {\n return getSetComputeUnitLimitInstruction({\n units: maxComputeUnits,\n });\n}\n\nexport function setComputeUnitPriceIx(microLamports: number): Instruction {\n return getSetComputeUnitPriceInstruction({\n microLamports,\n });\n}\n\n/**\n * Request a larger BPF heap for the transaction (default is 32 KiB).\n * Use for instructions that chain many CPIs and allocate temporary `Vec`s\n * (e.g. burn-with-unwind through Perena + Kamino).\n *\n * @param bytes - Must be a multiple of 1024; Solana allows up to 256 KiB.\n */\nexport function requestHeapFrameIx(bytes: number): Instruction {\n return getRequestHeapFrameInstruction({ bytes });\n}\n\n/**\n * Scans accounts for required ATAs, checks which ones exist on-chain in a\n * single batched RPC call, and returns idempotent create-ATA instructions\n * for any that are missing.\n *\n * @param rpc - Solana RPC client\n * @param payer - Fee payer for ATA creation\n * @param accounts - Account metas to scan (from CpiData, etc.)\n * @returns Create-ATA instructions and SPL ATA cache invalidations for each new ATA\n */\nexport async function getCreateAtaInstructions(\n rpc: Rpc<SolanaRpcApi>,\n payer: Address,\n accounts: CustomAccountMeta[]\n): Promise<{\n instructions: Instruction[];\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}> {\n // Collect unique accounts that are marked as required ATAs\n const requiredAtas = accounts.filter((x) => x.isRequiredAta);\n\n if (!requiredAtas.length) {\n return { instructions: [], postSuccessCacheInvalidations: [] };\n }\n\n const { existsByAddress } = await allAccountsExist(\n rpc,\n requiredAtas.map((account) => account.address)\n );\n\n const payerSigner = createSignerFromAddress(payer);\n const instructions: Instruction[] = [];\n const postSuccessCacheInvalidations: TransactionCacheInvalidation[] = [];\n\n for (const account of requiredAtas) {\n if (!existsByAddress.get(account.address)) {\n const seeds = account.isRequiredAta!;\n instructions.push(\n getCreateAssociatedTokenIdempotentInstruction({\n payer: payerSigner,\n ata: account.address,\n owner: seeds.owner,\n mint: seeds.mint,\n tokenProgram: seeds.tokenProgram,\n })\n );\n postSuccessCacheInvalidations.push({ client: SPL_ATA_CACHE_CATEGORY, ata: account.address });\n }\n }\n\n return { instructions, postSuccessCacheInvalidations };\n}\n\nexport interface GetCreateAtaIxIfNeededOptions {\n /**\n * When set, {@link BaseAccountClient#splAtaExists} is used instead of a one-off\n * `fetchMaybeToken` RPC read (shared cache + consistent behavior with program SDKs).\n */\n accountClient?: BaseAccountClient;\n}\n\nexport interface CreateAtaIxIfNeededResult {\n instruction: Instruction | null;\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\n/**\n * Checks if an ATA exists on-chain and returns a create-ATA instruction if it\n * doesn't.\n *\n * @param rpc - Solana RPC client (used for the default existence check unless overridden)\n * @param payer - Fee payer for ATA creation\n * @param mint - Token mint address\n * @param owner - Owner of the ATA\n * @param tokenProgram - Token program (defaults to TOKEN_PROGRAM_ADDRESS)\n * @param options - Optional account client for SPL ATA existence (otherwise uses RPC read)\n */\nexport async function getCreateAtaIxIfNeeded(\n rpc: Rpc<SolanaRpcApi>,\n payer: Address | TransactionSigner,\n mint: Address,\n owner: Address,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS,\n options?: GetCreateAtaIxIfNeededOptions\n): Promise<CreateAtaIxIfNeededResult> {\n const ata = await getAtaAddress(mint, owner, tokenProgram);\n\n const exists =\n options?.accountClient !== undefined\n ? await options.accountClient.splAtaExists(ata)\n : (await fetchMaybeToken(rpc, ata)).exists;\n\n if (exists) {\n return { instruction: null, postSuccessCacheInvalidations: [] };\n }\n\n const payerSigner = isTransactionSigner(payer) ? payer : createSignerFromAddress(payer);\n\n const instruction = getCreateAssociatedTokenIdempotentInstruction({\n payer: payerSigner,\n ata,\n owner,\n mint,\n tokenProgram,\n });\n\n return {\n instruction,\n postSuccessCacheInvalidations: [{ client: SPL_ATA_CACHE_CATEGORY, ata }],\n };\n}\n\nexport interface WrapSolInstructionsResult {\n instructions: Instruction[];\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\n/**\n * Returns instructions to wrap SOL into WSOL for a given wallet.\n *\n * Creates the WSOL ATA (idempotent), transfers SOL into it, and syncs the\n * native balance so the token account reflects the deposited lamports.\n */\nexport async function getWrapSolInstructions(\n rpc: Rpc<SolanaRpcApi>,\n owner: Address,\n payer: TransactionSigner,\n lamports: BN,\n createAtaOptions?: GetCreateAtaIxIfNeededOptions\n): Promise<WrapSolInstructionsResult> {\n const solMint = mints.get(\"SOL\")!;\n const solMintAddress = solMint.address;\n const ata = await getAtaAddress(solMintAddress, owner);\n\n const { instruction: createAtaIx, postSuccessCacheInvalidations } = await getCreateAtaIxIfNeeded(\n rpc,\n payer,\n solMintAddress,\n owner,\n TOKEN_PROGRAM_ADDRESS,\n createAtaOptions\n );\n\n const instructions: Instruction[] = [];\n if (createAtaIx) instructions.push(createAtaIx);\n\n instructions.push(\n getTransferSolInstruction({\n source: payer,\n destination: ata,\n amount: BigInt(lamports.toString()),\n }),\n getSyncNativeInstruction({ account: ata })\n );\n\n return { instructions, postSuccessCacheInvalidations };\n}\n\n/**\n * Returns instruction to unwrap WSOL back into SOL for a given wallet.\n *\n * Closes the WSOL token account, sending all lamports (including the wrapped\n * SOL balance and the rent-exempt reserve) to the specified destination.\n *\n * @param owner - Wallet that owns the WSOL ATA (must be a TransactionSigner to authorize the close)\n * @param destination - Address to receive the unwrapped SOL (defaults to the owner's address)\n * @returns Instructions to include in a transaction\n */\nexport async function getUnwrapSolInstruction(\n owner: TransactionSigner,\n destination?: Address\n): Promise<Instruction> {\n const solMint = mints.get(\"SOL\");\n if (!solMint) throw new Error(\"WSOL mint not found in registry\");\n const solMintAddress = solMint.address;\n const ata = await getAtaAddress(solMintAddress, owner.address);\n\n return getCloseAccountInstruction({\n account: ata,\n destination: destination ?? owner.address,\n owner,\n });\n}\n","import { sleep } from \"./general\";\n\nconst DEFAULT_MAX_ATTEMPTS = 4;\nconst INITIAL_DELAY_MS = 200;\nconst MAX_DELAY_MS = 2000;\n\nexport function isTransientNetworkError(err: unknown): boolean {\n if (err instanceof TypeError) return true;\n const msg = ((err as Error)?.message ?? \"\").toLowerCase();\n return (\n msg.includes(\"fetch failed\") ||\n msg.includes(\"econnreset\") ||\n msg.includes(\"econnrefused\") ||\n msg.includes(\"etimedout\") ||\n msg.includes(\"socket hang up\") ||\n msg.includes(\"network timeout\") ||\n msg.includes(\"all providers failed\") ||\n msg.includes(\"all rpc providers failed\") ||\n msg.includes(\"failed to get info about account\") ||\n msg.includes(\"429\") ||\n msg.includes(\"rate limit\") ||\n msg.includes(\"too many requests\") ||\n msg.includes(\"timeout\") ||\n // Local validators / forked RPCs can intermittently surface account-load\n // issues as a generic internal JSON-RPC error before the account is warmed.\n msg.includes(\"json-rpc error: internal json-rpc error\") ||\n msg.includes(\"json-rpc error: internal error\")\n );\n}\n\nfunction retryDelay(attempt: number): number {\n return Math.min(INITIAL_DELAY_MS * 2 ** attempt, MAX_DELAY_MS);\n}\n\n/**\n * Retry an async function on transient network errors with exponential backoff.\n *\n * Only retries errors that indicate the request never reached the server\n * (`TypeError: fetch failed`, connection resets, timeouts) plus generic\n * internal JSON-RPC errors that local/forked Solana validators can emit\n * transiently while warming cloned accounts. Deterministic application-level\n * errors (HTTP 4xx/5xx, custom program errors, validation failures) are thrown\n * immediately.\n */\nexport async function withNetworkRetry<T>(\n fn: () => Promise<T>,\n maxAttempts = DEFAULT_MAX_ATTEMPTS\n): Promise<T> {\n let lastErr: unknown;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastErr = err;\n if (!isTransientNetworkError(err) || attempt === maxAttempts - 1) break;\n await sleep(retryDelay(attempt));\n }\n }\n throw lastErr;\n}\n\n/**\n * Drop-in replacement for `globalThis.fetch` that retries on transient\n * network errors (connection resets, DNS failures, `TypeError: fetch failed`).\n *\n * HTTP error responses (4xx, 5xx) are NOT retried — the server received and\n * processed the request; the caller should decide how to handle those.\n */\nexport function fetchWithRetry(input: string | URL, init?: RequestInit): Promise<Response> {\n return withNetworkRetry(() => fetch(input, init));\n}\n","import {\n type Rpc,\n type SolanaRpcApi,\n createDefaultRpcTransport,\n createSolanaRpc,\n createSolanaRpcFromTransport,\n} from \"@solana/kit\";\nimport type { Environment } from \"../types\";\nimport { isTransientNetworkError, withNetworkRetry } from \"./retry\";\n\n/**\n * Create a Solana RPC client with automatic retry on transient network\n * failures (connection resets, DNS timeouts, `fetch failed`).\n *\n * Use this instead of `createSolanaRpc(url)` for any non-local RPC endpoint.\n */\nexport function createRpcWithRetry(url: string): Rpc<SolanaRpcApi> {\n const inner = createDefaultRpcTransport({ url });\n const retryingTransport: typeof inner = async <TResponse>(...args: Parameters<typeof inner>) =>\n withNetworkRetry(() => inner(...args)) as Promise<TResponse>;\n return createSolanaRpcFromTransport(retryingTransport);\n}\n\n/**\n * Create a Solana RPC client that retries each provider and then fails over to\n * the next configured provider for transient read failures.\n */\nexport function createRpcWithFailover(urls: string[]): Rpc<SolanaRpcApi> {\n const uniqueUrls = uniqueRpcUrls(urls);\n if (uniqueUrls.length === 0) {\n throw new Error(\"createRpcWithFailover requires at least one RPC URL\");\n }\n if (uniqueUrls.length === 1) {\n return createRpcWithRetry(uniqueUrls[0]);\n }\n\n const providers = uniqueUrls.map((url) => ({\n url,\n transport: createDefaultRpcTransport({ url }),\n }));\n const failoverTransport: (typeof providers)[number][\"transport\"] = async <TResponse>(\n ...args: Parameters<(typeof providers)[number][\"transport\"]>\n ) => {\n const failures: string[] = [];\n for (const provider of providers) {\n try {\n return (await withNetworkRetry(() => provider.transport(...args))) as TResponse;\n } catch (err) {\n if (!isTransientNetworkError(err)) {\n throw err;\n }\n failures.push(\n `${redactRpcUrlForLog(provider.url)}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n throw new Error(`All RPC providers failed: ${failures.join(\" | \")}`);\n };\n\n return createSolanaRpcFromTransport(failoverTransport);\n}\n\nexport function createRpc(environment: Environment): Rpc<SolanaRpcApi> {\n const urls = getRpcUrls(environment);\n if (environment === \"local\") return createSolanaRpc(urls[0]);\n return createRpcWithFailover(urls);\n}\n\nexport function heliusRpcUrl(heliusApiKey: string) {\n return `https://mainnet.helius-rpc.com/?api-key=${heliusApiKey}`;\n}\n\nexport function ironforgeRpcUrl(ironforgeApiKey: string) {\n return `https://rpc.ironforge.network/mainnet?apiKey=${ironforgeApiKey}`;\n}\n\nconst PUBLIC_MAINNET_RPC_URL = \"https://api.mainnet-beta.solana.com\";\n\n/**\n * Returns the RPC URL for the given environment.\n *\n * Resolution order (non-local):\n * 1. `IRONFORGE_API_KEY` env var → constructs Ironforge URL. Preferred over\n * `RPC_URL` so a stray `RPC_URL` (e.g. pointing at Helius) does not silently\n * override Ironforge when both are present.\n * 2. `RPC_URL` env var (explicit override, if set).\n * 3. `HELIUS_API_KEY` env var → constructs Helius URL.\n * 4. None → throws with a clear message.\n *\n * Browser bundles (e.g. Next.js) do not expose arbitrary `process.env` keys to the client.\n * The app may inject these same names at build time — see the frontend `next.config.ts`.\n */\nexport function getRpcUrl(environment: Environment): string {\n return getRpcUrls(environment)[0];\n}\n\nexport function getRpcUrls(environment: Environment): string[] {\n if (environment === \"local\") return [\"http://127.0.0.1:8899\"];\n\n const urls = uniqueRpcUrls([\n process.env.IRONFORGE_API_KEY ? ironforgeRpcUrl(process.env.IRONFORGE_API_KEY) : undefined,\n process.env.RPC_URL,\n process.env.HELIUS_API_KEY ? heliusRpcUrl(process.env.HELIUS_API_KEY) : undefined,\n ]);\n\n if (urls.length > 0) return urls;\n\n throw new Error(\n \"Non-local environment requires an RPC endpoint. \" +\n \"Set RPC_URL, IRONFORGE_API_KEY, or HELIUS_API_KEY.\"\n );\n}\n\n/**\n * Returns the preferred mainnet RPC URL while preserving a public fallback for\n * local tools and tests that need mainnet reads without extra env setup.\n */\nexport function getMainnetRpcUrl(): string {\n try {\n return getRpcUrl(\"prod\");\n } catch {\n return PUBLIC_MAINNET_RPC_URL;\n }\n}\n\n/** Redact API key query params for logs (Helius, Ironforge, etc.). */\nexport function redactRpcUrlForLog(url: string): string {\n return url.replace(/([?&]api-key=)[^&]*/gi, \"$1…\").replace(/([?&]apiKey=)[^&]*/gi, \"$1…\");\n}\n\nfunction uniqueRpcUrls(urls: Array<string | undefined>): string[] {\n const seen = new Set<string>();\n const unique: string[] = [];\n for (const url of urls) {\n if (!url) continue;\n const normalized = url.trim();\n if (!normalized || seen.has(normalized)) continue;\n seen.add(normalized);\n unique.push(normalized);\n }\n return unique;\n}\n","import { sleep } from \"./general\";\nimport { redactRpcUrlForLog } from \"./rpc\";\n\n/** Thrown when the JSON-RPC error should be retried (rate limits, transient HTTP, transport). */\nexport class JsonRpcTransientError extends Error {\n constructor(\n message: string,\n readonly suggestedDelayMs?: number\n ) {\n super(message);\n this.name = \"JsonRpcTransientError\";\n }\n}\n\nconst RETRYABLE_HTTP = new Set([408, 429, 502, 503, 504]);\n\nfunction parseRetryAfterMs(header: string | null): number | undefined {\n if (!header) return undefined;\n const sec = Number(header.trim());\n if (Number.isFinite(sec) && sec >= 0) return Math.floor(sec * 1000);\n return undefined;\n}\n\nfunction isRetryableJsonRpcError(err: { code: number; message: string } | undefined): boolean {\n if (!err) return false;\n if (err.code === -32429) return true;\n return /rate limit/i.test(err.message);\n}\n\n/**\n * Serialize async work and enforce a minimum gap (ms) between the end of one\n * invocation and the start of the next. Use `minIntervalMs === 0` to disable.\n */\nexport function createMinIntervalThrottle(minIntervalMs: number) {\n if (minIntervalMs <= 0) {\n return async function run<T>(fn: () => Promise<T>): Promise<T> {\n return fn();\n };\n }\n let queue: Promise<unknown> = Promise.resolve();\n let lastEnd = 0;\n return function run<T>(fn: () => Promise<T>): Promise<T> {\n const task = queue.then(async () => {\n const now = Date.now();\n const wait = Math.max(0, minIntervalMs - (now - lastEnd));\n if (wait > 0) await sleep(wait);\n try {\n return await fn();\n } finally {\n lastEnd = Date.now();\n }\n });\n queue = task.then(\n () => undefined,\n () => undefined\n );\n return task as Promise<T>;\n };\n}\n\n/**\n * One JSON-RPC 2.0 POST. Uses raw `fetch` so response JSON matches RPC wire\n * shape (e.g. Helius webhooks) without SDK bigint coercion.\n */\nexport async function jsonRpcFetchOnce<T>(\n rpcUrl: string,\n method: string,\n params: unknown[]\n): Promise<T> {\n let res: Response;\n try {\n res = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ jsonrpc: \"2.0\", id: 1, method, params }),\n });\n } catch (e) {\n const cause = e instanceof Error ? e.message : String(e);\n const local =\n rpcUrl.includes(\"127.0.0.1\") || rpcUrl.includes(\"localhost\")\n ? \" No process is listening on that URL — start a local validator (e.g. surfpool/solana-test-validator) or set ENVIRONMENT + RPC_URL / HELIUS_API_KEY for a remote endpoint.\"\n : \"\";\n throw new JsonRpcTransientError(\n `RPC ${method} fetch failed (${redactRpcUrlForLog(rpcUrl)}): ${cause}.${local}`\n );\n }\n\n const retryAfterMs = parseRetryAfterMs(res.headers.get(\"Retry-After\"));\n\n if (RETRYABLE_HTTP.has(res.status)) {\n const text = await res.text();\n throw new JsonRpcTransientError(`RPC ${method} HTTP ${res.status}: ${text}`, retryAfterMs);\n }\n\n if (!res.ok) {\n throw new Error(`RPC ${method} HTTP ${res.status}: ${await res.text()}`);\n }\n\n let body: { result?: T; error?: { code: number; message: string; data?: unknown } };\n try {\n body = (await res.json()) as {\n result?: T;\n error?: { code: number; message: string; data?: unknown };\n };\n } catch {\n throw new JsonRpcTransientError(`RPC ${method}: invalid JSON response body`);\n }\n\n if (body.error) {\n const dataStr =\n body.error.data !== undefined\n ? ` data=${JSON.stringify(body.error.data, (_, v) => (typeof v === \"bigint\" ? v.toString() : v))}`\n : \"\";\n if (isRetryableJsonRpcError(body.error)) {\n throw new JsonRpcTransientError(\n `RPC ${method} error ${body.error.code}: ${body.error.message}${dataStr}`,\n retryAfterMs\n );\n }\n throw new Error(`RPC ${method} error ${body.error.code}: ${body.error.message}${dataStr}`);\n }\n\n return body.result as T;\n}\n\nfunction retryDelayMs(attempt: number, baseDelayMs: number, err: unknown): number {\n const cap = 30_000;\n if (err instanceof JsonRpcTransientError && err.suggestedDelayMs != null) {\n return Math.min(cap, err.suggestedDelayMs);\n }\n return Math.min(cap, baseDelayMs * 2 ** attempt);\n}\n\nexport type JsonRpcThrottle = <T>(fn: () => Promise<T>) => Promise<T>;\n\n/**\n * JSON-RPC call with throttling + exponential backoff on {@link JsonRpcTransientError}.\n */\nexport async function jsonRpcFetchWithRetries<T>(\n throttle: JsonRpcThrottle,\n rpcUrl: string,\n method: string,\n params: unknown[],\n maxAttempts: number,\n baseDelayMs: number\n): Promise<T> {\n let lastErr: unknown;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await throttle(() => jsonRpcFetchOnce<T>(rpcUrl, method, params));\n } catch (e) {\n lastErr = e;\n const retryable = e instanceof JsonRpcTransientError;\n if (!retryable || attempt === maxAttempts - 1) break;\n await sleep(retryDelayMs(attempt, baseDelayMs, e));\n }\n }\n throw lastErr;\n}\n\nexport type JsonRpcCall = <T>(method: string, params: unknown[]) => Promise<T>;\n","/**\n * Process items from an async iterable with at most `concurrency` parallel workers.\n * The source iterator is advanced serially; workers run in parallel up to the limit.\n */\nexport async function runWithConcurrency<T>(\n source: AsyncIterable<T>,\n concurrency: number,\n worker: (item: T) => Promise<void>,\n onWorkerError?: (error: unknown) => void\n): Promise<void> {\n const pending = new Set<Promise<void>>();\n const logError =\n onWorkerError ??\n ((e: unknown) => {\n console.error(\n \"runWithConcurrency worker error\",\n JSON.stringify({ error: e instanceof Error ? e.message : String(e) })\n );\n });\n for await (const item of source) {\n if (pending.size >= concurrency) {\n await Promise.race(pending);\n }\n const p = worker(item)\n .catch((e) => {\n logError(e);\n })\n .finally(() => {\n pending.delete(p);\n });\n pending.add(p);\n }\n await Promise.all(pending);\n}\n","// `Wallet` is absent from Anchor's browser bundle (gated behind `!isBrowser`),\n// so a named import breaks strict ESM bundlers consuming this module in a\n// frontend. Access it lazily through the namespace instead — the Keypair\n// wrapping below is a Node/script-only path.\nimport * as anchor from \"@anchor-lang/core\";\nimport { AnchorProvider, type Wallet } from \"@anchor-lang/core\";\nimport { Connection, type ConfirmOptions, Keypair } from \"@solana/web3.js\";\nimport type { Environment } from \"../types\";\nimport { getRpcUrl } from \"./rpc\";\n\nconst DEFAULT_COMMITMENT = \"confirmed\" as const;\n\n/**\n * Builds an {@link AnchorProvider} for the given cluster with the standard script defaults\n * (`Connection` + `opts` use the same commitment, default `\"confirmed\"`).\n *\n * @param walletOrKeypair - Anchor `Wallet`, or a `@solana/web3.js` `Keypair` (wrapped as `Wallet`).\n */\nexport function createDefaultAnchorProvider(\n env: Environment,\n walletOrKeypair: Wallet | Keypair,\n confirmOptions?: ConfirmOptions\n): AnchorProvider {\n const commitment = confirmOptions?.commitment ?? DEFAULT_COMMITMENT;\n const wallet =\n walletOrKeypair instanceof Keypair ? new anchor.Wallet(walletOrKeypair) : walletOrKeypair;\n const opts: ConfirmOptions = { commitment, ...confirmOptions };\n\n return new AnchorProvider(new Connection(getRpcUrl(env), commitment), wallet, opts);\n}\n\n/**\n * Builds a read-only {@link AnchorProvider} 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 */\nexport function createReadOnlyAnchorProvider(env: Environment): AnchorProvider {\n return createDefaultAnchorProvider(env, Keypair.generate());\n}\n","import { SYSVAR_INSTRUCTIONS_ADDRESS, SYSVAR_RENT_ADDRESS } from \"@solana/sysvars\";\nimport { SYSTEM_PROGRAM_ADDRESS } from \"@solana-program/system\";\nimport { toCustomAccountMeta } from \"../utils\";\n\nexport const RENT_SYSVAR_META = toCustomAccountMeta(SYSVAR_RENT_ADDRESS);\nexport const SYSTEM_PROGRAM_META = toCustomAccountMeta(SYSTEM_PROGRAM_ADDRESS);\nexport const IX_SYSVAR_META = toCustomAccountMeta(SYSVAR_INSTRUCTIONS_ADDRESS);\n","// This file is auto-generated from the Rust CPI registry.\n// Do not edit manually. Run `cargo test -p common export_cpi_registry -- --ignored` to regenerate.\n\nexport const CpiTypes = {\n JUPITER_SWAP: 0,\n PERENA_MINT: 1,\n PERENA_BURN: 2,\n PERENA_STAKE: 3,\n PERENA_INSTANT_UNSTAKE: 4,\n PERENA_REQUEST_UNSTAKE: 5,\n PERENA_FULFILL_UNSTAKE: 6,\n K_INIT_USER_METADATA: 7,\n K_INIT_OBLIGATION: 8,\n K_INIT_USER_FARM: 9,\n K_REFRESH_RESERVE: 10,\n K_REFRESH_OBLIGATION: 11,\n K_REFRESH_USER_FARM: 12,\n K_HARVEST_REWARD: 13,\n K_REQUEST_ELEVATION_GROUP: 14,\n K_DEPOSIT: 15,\n K_WITHDRAW: 16,\n K_BORROW: 17,\n K_REPAY: 18,\n MPL_UPDATE_METADATA: 19,\n MPL_CREATE_METADATA: 20,\n} as const;\n","export * from \"./cpi\";\n","export * from \"./general\";\nexport * from \"./accountMetas\";\nexport * from \"./generated\";\n","import type {\n Address,\n ProgramDerivedAddress,\n Rpc,\n SolanaRpcApi,\n TransactionSigner,\n} from \"@solana/kit\";\nimport { getProgramDerivedAddress, getAddressEncoder, getU64Encoder } from \"@solana/kit\";\nimport {\n getCreateLookupTableInstruction,\n getExtendLookupTableInstruction,\n fetchAddressLookupTable,\n ADDRESS_LOOKUP_TABLE_PROGRAM_ADDRESS,\n} from \"@solana-program/address-lookup-table\";\nimport {\n TransactionError,\n deduplicateAccounts,\n getBatches,\n getSlot,\n signSendAndConfirmTransaction,\n} from \"../utils\";\nimport { DataCache, type CacheTtlConfig } from \"./dataCache\";\nimport { DEFAULT_PUBLIC_KEY } from \"../constants\";\n\nexport type LookupTableInput = {\n address: Address;\n addresses: Address[];\n};\n\nconst LUT_CACHE_CATEGORY = \"lookupTable\";\n\nexport class LutManager {\n private cache: DataCache;\n\n constructor(cacheTtlConfig?: CacheTtlConfig) {\n this.cache = new DataCache({\n defaultTtlMs: cacheTtlConfig?.defaultTtlMs ?? 60_000 * 15,\n categoryTtlMs: cacheTtlConfig?.categoryTtlMs,\n });\n }\n\n /**\n * Fetch a single lookup table's data, with caching.\n */\n private async fetchLookupTable(\n rpc: Rpc<SolanaRpcApi>,\n address: Address\n ): Promise<LookupTableInput> {\n const { data } = await this.cache.getDataOrThrow<LookupTableInput>(\n async () => {\n const table = await fetchAddressLookupTable(rpc, address);\n return {\n address,\n addresses: table.data.addresses,\n };\n },\n LUT_CACHE_CATEGORY,\n address\n );\n return data;\n }\n\n /**\n * Fetch address lookup table data for the given addresses, with caching.\n */\n async getLookupTableInputs(\n rpc: Rpc<SolanaRpcApi>,\n lookupTableAddresses: Address[]\n ): Promise<LookupTableInput[]> {\n return Promise.all(lookupTableAddresses.map((address) => this.fetchLookupTable(rpc, address)));\n }\n\n private async addAddressesIfNeeded(\n signer: TransactionSigner,\n rpc: Rpc<SolanaRpcApi>,\n lookupTableAddress: Address,\n existingAddresses: Address[],\n addressesToAdd: Address[]\n ) {\n const existingSet = new Set(existingAddresses);\n const addresses = addressesToAdd.filter((x) => !existingSet.has(x));\n\n if (addresses.length > 0) {\n const batches = getBatches(addresses, 20);\n for (const addressBatch of batches) {\n const extendIx = getExtendLookupTableInstruction({\n address: lookupTableAddress,\n authority: signer,\n payer: signer,\n addresses: addressBatch,\n });\n await signSendAndConfirmTransaction(rpc, signer, [extendIx]);\n }\n }\n }\n\n private async deriveLookupTableAddress(\n signerAddress: Address,\n recentSlot: bigint\n ): Promise<ProgramDerivedAddress> {\n const addressEncoder = getAddressEncoder();\n const u64Encoder = getU64Encoder();\n\n return await getProgramDerivedAddress({\n programAddress: ADDRESS_LOOKUP_TABLE_PROGRAM_ADDRESS,\n seeds: [addressEncoder.encode(signerAddress), u64Encoder.encode(recentSlot)],\n });\n }\n\n async updateLookupTable(\n signer: TransactionSigner,\n rpc: Rpc<SolanaRpcApi>,\n accounts: Address[],\n existingLookupTableAddress?: Address\n ): Promise<Address> {\n if (existingLookupTableAddress === DEFAULT_PUBLIC_KEY) {\n existingLookupTableAddress = undefined;\n }\n\n let lookupTableAddress: Address;\n let existingAccounts: Address[];\n\n if (existingLookupTableAddress) {\n lookupTableAddress = existingLookupTableAddress;\n const lutInput = await this.fetchLookupTable(rpc, lookupTableAddress);\n existingAccounts = lutInput.addresses;\n } else {\n const maxAttempts = 3;\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n // CreateLookupTable requires recentSlot to be in the SlotHashes sysvar. A\n // confirmed slot can be forked out and never land there; finalized is\n // guaranteed rooted and still well within the 512-slot window.\n const slot = await getSlot(rpc, \"finalized\");\n const lutPda = await this.deriveLookupTableAddress(signer.address, slot);\n\n const createLutIx = getCreateLookupTableInstruction({\n address: lutPda,\n authority: signer,\n recentSlot: slot,\n });\n\n try {\n await signSendAndConfirmTransaction(rpc, signer, [createLutIx], {\n hideFailureInfo: attempt < maxAttempts,\n });\n lookupTableAddress = lutPda[0];\n console.log(`Created new lookup table: ${lookupTableAddress}`);\n this.cache.setCache(LUT_CACHE_CATEGORY, lookupTableAddress, {\n address: lookupTableAddress,\n addresses: [],\n });\n lastError = undefined;\n break;\n } catch (e) {\n lastError = e;\n const errorStr = String(e);\n const logsStr = e instanceof TransactionError ? e.programLogs.join(\"\\n\") : \"\";\n const isStaleSlot =\n errorStr.includes(\"is not a recent slot\") || logsStr.includes(\"is not a recent slot\");\n if (isStaleSlot && attempt < maxAttempts) {\n console.warn(\n `LUT creation failed (stale slot ${slot}), retrying (${attempt}/${maxAttempts})...`\n );\n await new Promise((r) => setTimeout(r, 2_000));\n continue;\n }\n throw e;\n }\n }\n\n if (lastError) throw lastError;\n lookupTableAddress = lookupTableAddress!;\n existingAccounts = [];\n }\n\n await this.addAddressesIfNeeded(\n signer,\n rpc,\n lookupTableAddress,\n existingAccounts,\n deduplicateAccounts(accounts).filter((x) => x !== DEFAULT_PUBLIC_KEY)\n );\n\n // Invalidate cache for this LUT since we just modified it\n this.clearLookupTableCache(lookupTableAddress);\n\n return lookupTableAddress;\n }\n\n /**\n * Clear all cached lookup table data.\n */\n clearCache() {\n this.cache.clearAllCache();\n }\n\n /**\n * Clear cached data for a specific lookup table.\n */\n clearLookupTableCache(address: Address) {\n this.cache.clearCacheEntry(LUT_CACHE_CATEGORY, address);\n }\n}\n\n/** Global LutManager instance for shared use across the application. */\nexport const lutManager = new LutManager();\n","/**\n * Minimal Jito bundle client.\n *\n * Submits bundles via the user's own RPC endpoint rather than Jito's public\n * block engine. Premium Solana RPC providers (Helius, Ironforge, Triton, etc.)\n * proxy the Jito JSON-RPC methods (`sendBundle`, `getBundleStatuses`,\n * `simulateBundle`) through their authenticated endpoint. This avoids the\n * public Jito endpoint's global rate limit (error `-32097` / HTTP 429).\n *\n * Reference implementation: `EXAMPLE/solauto-sdk/src/utils/jitoUtils.ts`,\n * which routes the same calls through the user's Umi RPC endpoint\n * (Ironforge).\n *\n * Helius sendBundle docs: https://helius.mintlify.app/api-reference/sender/sendbundle\n */\n\nimport type { Address, Instruction, TransactionSigner } from \"@solana/kit\";\nimport { getTransferSolInstruction } from \"@solana-program/system\";\n\nimport { sleep } from \"./general\";\nimport { jsonRpcFetchOnce } from \"./jsonRpcFetch\";\n\n/** Max transactions per Jito bundle. */\nexport const MAX_BUNDLE_TRANSACTIONS = 5;\n\n/** Default tip when the caller doesn't specify one. */\nexport const DEFAULT_JITO_TIP_LAMPORTS = 2_000_000;\n\nexport class JitoBundleError extends Error {\n constructor(\n message: string,\n readonly bundleId?: string\n ) {\n super(message);\n this.name = \"JitoBundleError\";\n }\n}\n\n/**\n * Static Jito tip accounts. Hardcoded to avoid a network call to\n * `getTipAccounts` on every bundle — the list rarely changes.\n *\n * Exported so tests can lock in the canonical list against the Jito docs\n * and catch any future typo. Verify against:\n * https://docs.jito.wtf/lowlatencytxnsend/#response-example-tips\n */\nexport const JITO_TIP_ACCOUNTS: readonly Address[] = [\n \"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5\" as Address,\n \"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe\" as Address,\n];\n\n/**\n * Conservative upper bound (in wire bytes) for the instructions we inject\n * into each bundle tx _after_ bin-packing: a setComputeUnitLimit ix and,\n * Used by the splitter to reserve headroom so post-split injection never\n * overflows the 1232-byte transaction limit. The tip transfer is injected\n * only into the smallest bin in the bundle, which is typically far from\n * the size limit, so we don't reserve for it here.\n *\n * Breakdown (worst case, ComputeBudget program not in any LUT):\n * • ComputeBudget program key = 32 B\n * • setComputeUnitLimit ix header + 5 B data ≈ 13 B\n * • setComputeUnitPrice ix header + 9 B data ≈ 17 B\n * Rounded up to 64 B to cover compact-u16 edge cases.\n */\nexport const BUNDLE_INJECTED_IX_RESERVED_BYTES = 64;\n\n/** Pick one of the 8 Jito tip accounts at random. */\nexport function getRandomTipAccount(): Address {\n return JITO_TIP_ACCOUNTS[Math.floor(Math.random() * JITO_TIP_ACCOUNTS.length)];\n}\n\n/** Build a SOL transfer instruction to a Jito tip account. */\nexport function buildTipInstruction(\n payer: TransactionSigner,\n tipAccount: Address,\n lamports: number\n): Instruction {\n return getTransferSolInstruction({\n source: payer,\n destination: tipAccount,\n amount: BigInt(lamports),\n });\n}\n\n/**\n * Submit a bundle of base64-encoded signed transactions to Jito via the\n * caller's RPC endpoint. Returns the `bundle_id` for status polling.\n *\n * Helius expects `[base64Txs, { encoding: \"base64\" }]`; Ironforge and the\n * raw Jito block engine accept the same shape and fall back to base58 when\n * encoding is omitted. Using base64 everywhere matches the wire format we\n * already produce via `getBase64EncodedWireTransaction`.\n */\nexport async function sendBundle(rpcUrl: string, base64Txs: string[]): Promise<string> {\n if (base64Txs.length > MAX_BUNDLE_TRANSACTIONS) {\n throw new JitoBundleError(\n `Bundle has ${base64Txs.length} transactions, max is ${MAX_BUNDLE_TRANSACTIONS}`\n );\n }\n try {\n return await jsonRpcFetchOnce<string>(rpcUrl, \"sendBundle\", [\n base64Txs,\n { encoding: \"base64\" },\n ]);\n } catch (e) {\n throw new JitoBundleError(`sendBundle failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n}\n\nexport interface BundleSimulationTxResult {\n /** Tx-level error object, or null on success. */\n err: object | null;\n /** Program logs emitted during this tx (may be empty on signature-only failures). */\n logs: string[];\n /** Compute units consumed by this tx; absent if the tx errored before CU accounting. */\n unitsConsumed?: number;\n /** Tx-level return data, opaque to callers. */\n returnData?: unknown;\n}\n\nexport interface BundleSimulationResult {\n /** \"succeeded\" string when every tx passed; an object containing `failed` otherwise. */\n summary: \"succeeded\" | { failed: { error: unknown; txSignature?: string } };\n /** Per-tx outcome, in the same order as the bundle's `encodedTransactions`. */\n transactionResults: BundleSimulationTxResult[];\n}\n\n/**\n * Atomically simulate a bundle of base64-encoded transactions through the\n * caller's RPC endpoint. Mirrors the Jito BlockEngine `simulateBundle` shape,\n * which Helius/Ironforge/Triton proxy.\n *\n * Set `skipSigVerify=true` and `replaceRecentBlockhash=true` (defaults) to\n * simulate _before_ signing — the simulator stamps placeholder signatures and\n * substitutes a fresh blockhash, letting us measure per-tx compute units and\n * verify the bundle composes correctly without paying the signing round trip\n * twice.\n *\n * Unlike running `simulateTransaction` per bin, this preserves the\n * intra-bundle sequencing — a refresh ix in tx 0 is observable to tx 1 — so\n * bundles whose sub-txs depend on each other can be validated without false\n * positives from bin-isolation.\n */\nexport async function simulateBundle(\n rpcUrl: string,\n base64Txs: string[],\n options: { skipSigVerify?: boolean; replaceRecentBlockhash?: boolean } = {}\n): Promise<BundleSimulationResult> {\n const { skipSigVerify = true, replaceRecentBlockhash = true } = options;\n if (base64Txs.length > MAX_BUNDLE_TRANSACTIONS) {\n throw new JitoBundleError(\n `Bundle has ${base64Txs.length} transactions, max is ${MAX_BUNDLE_TRANSACTIONS}`\n );\n }\n try {\n // `preExecutionAccountsConfigs` and `postExecutionAccountsConfigs` are\n // required fields (one entry per tx) on Jito's BlockEngine and on\n // proxying providers (Helius). We don't read pre/post account state, so\n // each entry is left as `null`.\n const accountsConfigs = base64Txs.map(() => null);\n // Some endpoints return `{ context, value: { ... } }` (Helius) and others\n // return the result directly (raw Jito). Normalize by unwrapping `value`\n // when present.\n const raw = await jsonRpcFetchOnce<\n BundleSimulationResult | { context?: unknown; value: BundleSimulationResult }\n >(rpcUrl, \"simulateBundle\", [\n { encodedTransactions: base64Txs },\n {\n preExecutionAccountsConfigs: accountsConfigs,\n postExecutionAccountsConfigs: accountsConfigs,\n skipSigVerify,\n replaceRecentBlockhash,\n transactionEncoding: \"base64\",\n },\n ]);\n return \"value\" in raw && raw.value ? raw.value : (raw as BundleSimulationResult);\n } catch (e) {\n throw new JitoBundleError(\n `simulateBundle failed: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n}\n\ninterface BundleStatusEntry {\n bundle_id: string;\n slot: number;\n confirmation_status: \"processed\" | \"confirmed\" | \"finalized\";\n /**\n * Jito encodes a Rust `Result`: `null` or `{ Ok: null }` = no failure;\n * `{ Err: ... }` = bundle failed. `{ Ok: null }` is truthy — do not treat\n * any non-null `err` as failure.\n */\n err: { Ok: null } | { Err: unknown } | null;\n}\n\n/**\n * Poll `getBundleStatuses` until the bundle confirms or fails.\n *\n * Mirrors the solauto reference: a `null` entry means Jito hasn't seen the\n * bundle yet (keep polling); only `err` with an `Err` key is a failure; a\n * `confirmation_status` of \"confirmed\" or \"finalized\" means success.\n */\nexport async function confirmBundle(\n rpcUrl: string,\n bundleId: string,\n timeoutMs: number = 60_000\n): Promise<{ slot: number }> {\n const pollIntervalMs = 1_000;\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n await sleep(pollIntervalMs);\n\n let result: { value: (BundleStatusEntry | null)[] };\n try {\n result = await jsonRpcFetchOnce<{ value: (BundleStatusEntry | null)[] }>(\n rpcUrl,\n \"getBundleStatuses\",\n [[bundleId]]\n );\n } catch (e) {\n console.warn(`[Jito] getBundleStatuses error: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n const entry = result.value?.[0];\n if (!entry) continue;\n\n if (entry.err != null && \"Err\" in entry.err) {\n throw new JitoBundleError(\n `Bundle ${bundleId} failed: ${JSON.stringify(entry.err)}`,\n bundleId\n );\n }\n\n if (entry.confirmation_status === \"confirmed\" || entry.confirmation_status === \"finalized\") {\n return { slot: entry.slot };\n }\n }\n\n throw new JitoBundleError(\n `Bundle ${bundleId} confirmation timeout after ${timeoutMs}ms`,\n bundleId\n );\n}\n","import type { Address, Base64EncodedWireTransaction, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport bs58 from \"bs58\";\n\n/** Helius priority levels accepted by `getPriorityFeeEstimate`. */\nexport enum PriorityFeeSetting {\n Min = \"Min\",\n Low = \"Low\",\n Medium = \"Medium\",\n High = \"High\",\n VeryHigh = \"VeryHigh\",\n}\n\nconst MAX_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS = 100_000_000;\n\ntype HeliusPriorityFeeEstimate = {\n // Solana Kit's RPC transport deserializes integer JSON values as bigint,\n // while fractional estimates remain numbers.\n priorityFeeEstimate?: number | bigint;\n};\n\nfunction normalizeEstimate(result: HeliusPriorityFeeEstimate): number {\n const estimate = result.priorityFeeEstimate;\n if (typeof estimate === \"bigint\") {\n if (estimate < 0n) {\n throw new Error(\"Helius getPriorityFeeEstimate returned an invalid estimate\");\n }\n\n return Number(\n estimate > BigInt(MAX_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS)\n ? BigInt(MAX_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS)\n : estimate\n );\n }\n\n if (estimate === undefined || !Number.isFinite(estimate) || estimate < 0) {\n throw new Error(\"Helius getPriorityFeeEstimate returned an invalid estimate\");\n }\n\n return Math.min(Math.round(estimate), MAX_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS);\n}\n\n/**\n * Estimate a compute-unit price through the configured RPC provider's\n * Helius-compatible `getPriorityFeeEstimate` method.\n *\n * Helius expects the serialized transaction in base58. If transaction-based\n * estimation is unavailable, retry with the transaction's account keys, which\n * preserves contention-aware pricing without silently dropping the requested fee.\n */\nexport async function getPriorityFeeEstimate(\n rpc: Rpc<SolanaRpcApi>,\n transaction: Base64EncodedWireTransaction,\n accountKeys: Address[],\n priorityFeeSetting: PriorityFeeSetting\n): Promise<number> {\n const transactionBase58 = bs58.encode(Buffer.from(transaction, \"base64\"));\n const priorityFeeRpc = rpc as unknown as {\n getPriorityFeeEstimate: (request: {\n transaction?: string;\n accountKeys?: Address[];\n options: { priorityLevel: PriorityFeeSetting };\n }) => { send: () => Promise<HeliusPriorityFeeEstimate> };\n };\n\n try {\n const result = await priorityFeeRpc\n .getPriorityFeeEstimate({\n transaction: transactionBase58,\n options: { priorityLevel: priorityFeeSetting },\n })\n .send();\n return normalizeEstimate(result);\n } catch {\n const result = await priorityFeeRpc\n .getPriorityFeeEstimate({\n accountKeys,\n options: { priorityLevel: priorityFeeSetting },\n })\n .send();\n return normalizeEstimate(result);\n }\n}\n","/**\n * Greedy bin-packing splitter for instruction lists that exceed the Solana\n * transaction wire limit (1232 bytes).\n *\n * Instructions are packed left-to-right (preserving caller order) into the\n * fewest bins where each bin compiles to a valid-sized transaction. The\n * result is an ordered array of instruction arrays, each of which can be\n * independently built into a v0 `TransactionMessage`.\n */\n\nimport type {\n Address,\n Blockhash,\n CompilableTransactionMessage,\n Instruction,\n Rpc,\n SolanaRpcApi,\n TransactionSigner,\n} from \"@solana/kit\";\nimport { compileTransaction, getBase64EncodedWireTransaction } from \"@solana/kit\";\n\nimport { buildTransactionMessage } from \"./transaction\";\nimport { MAX_BUNDLE_TRANSACTIONS } from \"./jito\";\n\n/**\n * Solana's maximum serialized transaction size in bytes. The base64 encoding\n * inflates this to ~1644 chars, but we measure the decoded wire bytes via\n * Kit's `compileTransaction` + `getBase64EncodedWireTransaction` and compare\n * against the decoded length.\n */\nexport const SOLANA_TX_SIZE_LIMIT = 1232;\n\n/**\n * Measure the wire size of a compilable transaction message in bytes.\n */\nexport function measureTxBytes(msg: CompilableTransactionMessage): number {\n const compiled = compileTransaction(msg);\n const b64 = getBase64EncodedWireTransaction(compiled);\n return Math.ceil((b64.length * 3) / 4);\n}\n\nexport interface SplitResult {\n /** Ordered instruction bins; each bin fits in one tx. */\n bins: Instruction[][];\n}\n\nexport interface SplitOptions {\n lookupTables?: Address[];\n additionalSigners?: TransactionSigner[];\n /**\n * Shared blockhash to use when compiling each candidate. Passing a stable\n * blockhash avoids a per-iteration `getLatestBlockhash` RPC call and keeps\n * every bin's size measurement consistent with what downstream signing\n * will actually produce.\n */\n blockhash?: Readonly<{ blockhash: Blockhash; lastValidBlockHeight: bigint }>;\n /**\n * Bytes to reserve below {@link SOLANA_TX_SIZE_LIMIT} for instructions\n * injected _after_ splitting (e.g. a compute-unit-limit ix on every bin\n * and a Jito tip ix on one bin). Default 0 means pack tight to the limit.\n */\n reservedBytes?: number;\n /**\n * When set, positive lengths must sum to `instructions.length`; each slice is\n * kept intact when packing. Same field as `TransactionPlan.segmentLengths`.\n * When omitted, each instruction is packed independently.\n */\n segmentLengths?: number[];\n /**\n * Segment indices (0-based, into the segments produced by `segmentLengths`)\n * that must always start a fresh bin. The current bin — if non-empty — is\n * flushed before the segment is appended, even if the segment would have\n * fit alongside it.\n *\n * Use case: a CPI whose on-chain check encodes a position-relative index\n * (e.g. Kamino's flash-borrow records `borrowInstructionIndex` for the\n * matching repay) needs the segment to land at a predictable index inside\n * its own tx. Marking that segment as a forced boundary keeps its index\n * stable regardless of how the preceding segments pack.\n */\n freshBinSegments?: number[];\n}\n\n/**\n * Turn a flat instruction list into indivisible segments for bin-packing.\n *\n * @throws If lengths are invalid or do not partition `instructions`.\n */\nexport function buildInstructionSegments(\n instructions: Instruction[],\n segmentLengths?: number[]\n): Instruction[][] {\n if (segmentLengths === undefined || segmentLengths.length === 0) {\n return instructions.map((ix) => [ix]);\n }\n\n const sum = segmentLengths.reduce((a, b) => a + b, 0);\n if (sum !== instructions.length) {\n throw new Error(\n `segmentLengths sum (${sum}) must equal instructions.length (${instructions.length}).`\n );\n }\n if (segmentLengths.some((n) => !Number.isInteger(n) || n <= 0)) {\n throw new Error(\"segmentLengths entries must be positive integers.\");\n }\n\n const segments: Instruction[][] = [];\n let offset = 0;\n for (const len of segmentLengths) {\n segments.push(instructions.slice(offset, offset + len));\n offset += len;\n }\n return segments;\n}\n\n/**\n * Split an instruction list into the minimum number of ordered bins where\n * each bin compiles to a transaction within the wire-size limit (minus\n * `reservedBytes` of headroom for post-split instruction injection).\n *\n * Preserves instruction ordering: segments and instructions are never\n * reordered across bins. Each bin is measured by actually compiling a v0\n * message with the provided fee payer + ALTs, so the measurement accounts for\n * signatures, account tables, and compact-u16 encoding exactly.\n *\n * Throws if:\n * - A single segment cannot fit in one tx (even alone).\n * - The total bins exceed `MAX_BUNDLE_TRANSACTIONS` (Jito's 5-tx limit).\n */\nexport async function splitIntoTransactionBins(\n rpc: Rpc<SolanaRpcApi>,\n payer: TransactionSigner,\n instructions: Instruction[],\n options: SplitOptions = {}\n): Promise<SplitResult> {\n const {\n lookupTables,\n additionalSigners,\n blockhash,\n reservedBytes = 0,\n segmentLengths,\n freshBinSegments,\n } = options;\n const effectiveLimit = SOLANA_TX_SIZE_LIMIT - reservedBytes;\n const freshBinSet = freshBinSegments ? new Set(freshBinSegments) : undefined;\n\n if (effectiveLimit <= 0) {\n throw new Error(\n `reservedBytes (${reservedBytes}) is >= the tx size limit (${SOLANA_TX_SIZE_LIMIT}).`\n );\n }\n\n const segments = buildInstructionSegments(instructions, segmentLengths);\n\n const bins: Instruction[][] = [];\n let currentBin: Instruction[] = [];\n\n const measureCandidate = async (candidate: Instruction[]): Promise<number> => {\n const msg = await buildTransactionMessage(\n rpc,\n payer,\n candidate,\n lookupTables,\n additionalSigners,\n blockhash\n );\n return measureTxBytes(msg);\n };\n\n for (let segIdx = 0; segIdx < segments.length; segIdx += 1) {\n const segment = segments[segIdx];\n\n // If this segment must start a fresh bin, flush the current bin first\n // so the segment lands at the start of a new bin.\n if (freshBinSet?.has(segIdx) && currentBin.length > 0) {\n bins.push(currentBin);\n currentBin = [];\n }\n\n const candidate = [...currentBin, ...segment];\n const size = await measureCandidate(candidate);\n\n if (size <= effectiveLimit) {\n currentBin = candidate;\n continue;\n }\n\n // Segment doesn't fit in the current bin. If the bin is non-empty, flush\n // it and start a new bin with the whole segment. If the bin IS empty,\n // the segment is too large on its own — unrecoverable.\n if (currentBin.length === 0) {\n throw new Error(\n `An indivisible instruction group (${segment.length} instruction(s)) measures ` +\n `${size} bytes, exceeding the ${effectiveLimit}-byte effective tx size limit ` +\n `(${SOLANA_TX_SIZE_LIMIT} - ${reservedBytes} reserved) even with address lookup ` +\n `tables. Cannot split.`\n );\n }\n\n bins.push(currentBin);\n currentBin = [...segment];\n\n const segmentSize = await measureCandidate(currentBin);\n if (segmentSize > effectiveLimit) {\n throw new Error(\n `An indivisible instruction group (${segment.length} instruction(s)) measures ` +\n `${segmentSize} bytes, exceeding the ${effectiveLimit}-byte effective tx size limit ` +\n `(${SOLANA_TX_SIZE_LIMIT} - ${reservedBytes} reserved) even with address lookup ` +\n `tables. Cannot split.`\n );\n }\n }\n\n if (currentBin.length > 0) {\n bins.push(currentBin);\n }\n\n if (bins.length > MAX_BUNDLE_TRANSACTIONS) {\n throw new Error(\n `Instruction list requires ${bins.length} transactions, but Jito bundles ` +\n `allow at most ${MAX_BUNDLE_TRANSACTIONS}.`\n );\n }\n\n return { bins };\n}\n","import type {\n Address,\n Base64EncodedWireTransaction,\n Blockhash,\n CompilableTransactionMessage,\n Instruction,\n Rpc,\n SolanaRpcApi,\n TransactionSigner,\n Signature,\n SignatureBytes,\n Transaction,\n} from \"@solana/kit\";\nimport {\n pipe,\n createTransactionMessage,\n setTransactionMessageLifetimeUsingBlockhash,\n appendTransactionMessageInstructions,\n compressTransactionMessageUsingAddressLookupTables,\n compileTransaction,\n signTransactionMessageWithSigners,\n getSignatureFromTransaction,\n getBase64EncodedWireTransaction,\n setTransactionMessageFeePayerSigner,\n addSignersToTransactionMessage,\n assertIsFullySignedTransaction,\n isTransactionModifyingSigner,\n isTransactionPartialSigner,\n} from \"@solana/kit\";\nimport { setComputeUnitLimitIx, setComputeUnitPriceIx } from \"./instruction\";\nimport { lutManager } from \"../services/lutManager\";\nimport { deduplicateAccounts } from \"./general\";\nimport { DEFAULT_PUBLIC_KEY } from \"../constants\";\nimport {\n getRandomTipAccount,\n buildTipInstruction,\n sendBundle,\n simulateBundle,\n confirmBundle,\n DEFAULT_JITO_TIP_LAMPORTS,\n JitoBundleError,\n BUNDLE_INJECTED_IX_RESERVED_BYTES,\n} from \"./jito\";\nimport { jsonRpcFetchOnce } from \"./jsonRpcFetch\";\nimport { isTransientNetworkError } from \"./retry\";\nimport { getMainnetRpcUrl, redactRpcUrlForLog } from \"./rpc\";\nimport { getPriorityFeeEstimate, PriorityFeeSetting } from \"./priorityFee\";\nimport {\n splitIntoTransactionBins,\n measureTxBytes,\n SOLANA_TX_SIZE_LIMIT,\n} from \"./transactionSplitter\";\n\nconst MAX_COMPUTE_UNIT_LIMIT = 1_400_000;\n\n/** Default headroom over simulated CU usage for typical operator transactions. */\nexport const DEFAULT_COMPUTE_UNIT_LIMIT_MULTIPLIER = 1.1;\n\n/**\n * Headroom for txs with deep CPI stacks (Jupiter + external liquidity mint/deposit).\n * Simulation often undershoots on-chain usage by more than 10%.\n */\nexport const HEAVY_CPI_COMPUTE_UNIT_LIMIT_MULTIPLIER = 1.2;\n\nexport function computeUnitLimitFromSimulation(\n unitsConsumed: number,\n multiplier: number = DEFAULT_COMPUTE_UNIT_LIMIT_MULTIPLIER\n): number {\n if (!(unitsConsumed > 0) || !(multiplier > 0)) {\n return MAX_COMPUTE_UNIT_LIMIT;\n }\n return Math.min(MAX_COMPUTE_UNIT_LIMIT, Math.ceil(unitsConsumed * multiplier));\n}\n\n/** Distinct writable account addresses across `instructions`. */\nfunction collectWritableAccounts(instructions: Instruction[]): Address[] {\n const seen = new Set<string>();\n const out: Address[] = [];\n for (const ix of instructions) {\n for (const acc of ix.accounts ?? []) {\n // Account flags: 1 = writable in Kit's `IAccountMeta` (signer is bit 0).\n const role = (acc as { role?: number }).role;\n if (role != null && (role & 1) === 1) {\n const addr = (acc as { address: Address }).address;\n if (!seen.has(addr as unknown as string)) {\n seen.add(addr as unknown as string);\n out.push(addr);\n }\n }\n }\n }\n return out;\n}\n\ntype SignatureDictionary = Record<Address, SignatureBytes>;\n\nasync function signTransactionsWithSigners(\n transactions: readonly Transaction[],\n signers: readonly TransactionSigner[]\n): Promise<Transaction[]> {\n let signedTransactions = [...transactions];\n const modifyingSigners = signers.filter(isTransactionModifyingSigner);\n const partialSigners = signers.filter(isTransactionPartialSigner);\n\n for (const signer of modifyingSigners) {\n signedTransactions = [...(await signer.modifyAndSignTransactions(signedTransactions))];\n }\n\n for (const signer of partialSigners) {\n const signatures = await signer.signTransactions(signedTransactions);\n signedTransactions = signedTransactions.map((transaction, index) => ({\n ...transaction,\n signatures: {\n ...transaction.signatures,\n ...(signatures[index] as SignatureDictionary),\n },\n }));\n }\n\n for (const transaction of signedTransactions) {\n assertIsFullySignedTransaction(transaction);\n }\n\n return signedTransactions;\n}\n\n/**\n * Error thrown when a transaction simulation or on-chain execution fails.\n * Carries the raw Solana program logs so callers (e.g. NestJS services)\n * can log them through their own structured logger instead of dumping\n * to stdout via `console.error`.\n */\nexport class TransactionError extends Error {\n readonly programLogs: string[];\n\n constructor(message: string, programLogs: string[] = []) {\n super(programLogs.length ? `${message}\\n\\nProgram logs:\\n${programLogs.join(\"\\n\")}` : message);\n this.name = \"TransactionError\";\n this.programLogs = programLogs;\n }\n}\n\nfunction logProgramLogsLineByLine(logs: string[], label = \"Program logs\") {\n if (!logs.length) {\n console.error(`${label}: (no logs returned)`);\n return;\n }\n console.error(`${label} (${logs.length} lines):`);\n logs.forEach((line, index) => {\n console.error(`[${index}] ${line}`);\n });\n}\n\ntype BlockhashResponse = {\n value: Readonly<{ blockhash: Blockhash; lastValidBlockHeight: bigint }>;\n};\n\n/**\n * Options for signSendAndConfirmTransaction.\n */\nexport interface SendTransactionOptions {\n /** Address lookup tables for transaction compression */\n lookupTables?: Address[];\n /** Additional signers beyond the fee payer (e.g., mint authority) */\n additionalSigners?: TransactionSigner[];\n /** Whether or not to print transaction logs after a simulation or transaction failure */\n hideFailureInfo?: boolean;\n /**\n * Jito tip in lamports for bundle submissions. Default: 10,000.\n * Set to 0 to disable bundle fallback (throws on oversize instead).\n */\n jitoTipLamports?: number;\n /**\n * Force the Jito bundle path even when the transaction fits in a single tx.\n * Useful for smoke-testing bundle submission on mainnet. Requires\n * `jitoTipLamports` > 0 unless {@link sendOversizedAsSequentialTransactions}\n * is set.\n */\n forceJitoBundle?: boolean;\n /**\n * When the oversize path runs, send each split transaction with normal\n * `sendTransaction` + confirmation instead of a Jito bundle. For Surfpool,\n * local validators, and other RPCs that do not implement `sendBundle`.\n *\n * Not atomic: ledger state may change between sub-transactions. Does not\n * add a Jito tip (`jitoTipLamports` is ignored). Uses a fresh blockhash per\n * sub-transaction so earlier confirmations cannot expire the next send.\n */\n sendOversizedAsSequentialTransactions?: boolean;\n /**\n * Override the estimated compute-unit price (in micro-lamports). When set,\n * skips priority-fee estimation and uses this value directly.\n */\n computeUnitPriceMicroLamports?: number;\n /**\n * Helius-compatible priority level requested through the configured RPC.\n * Explicit `computeUnitPriceMicroLamports` takes precedence. When both\n * options are omitted, no compute-unit-price instruction is added.\n */\n priorityFeeSetting?: PriorityFeeSetting;\n /**\n * Multiplier applied to simulated `unitsConsumed` when setting the compute\n * unit limit. Defaults to {@link DEFAULT_COMPUTE_UNIT_LIMIT_MULTIPLIER}.\n */\n computeUnitLimitMultiplier?: number;\n}\n\nasync function resolvePriorityFeeMicroLamports(\n rpc: Rpc<SolanaRpcApi>,\n transactionMessage: CompilableTransactionMessage,\n writableAccounts: Address[],\n options: SendTransactionOptions | undefined\n): Promise<number | undefined> {\n if (options?.computeUnitPriceMicroLamports !== undefined) {\n return options.computeUnitPriceMicroLamports;\n }\n\n if (options?.priorityFeeSetting === undefined) {\n return undefined;\n }\n\n const estimateMessage = appendTransactionMessageInstructions(\n [setComputeUnitLimitIx(MAX_COMPUTE_UNIT_LIMIT)],\n transactionMessage\n ) as CompilableTransactionMessage;\n const estimateTransaction = getBase64EncodedWireTransaction(compileTransaction(estimateMessage));\n return getPriorityFeeEstimate(\n rpc,\n estimateTransaction,\n writableAccounts,\n options.priorityFeeSetting\n );\n}\n\nfunction getComputeBudgetInstructions(\n computeUnitLimit: number,\n priorityFeeMicroLamports: number | undefined\n): Instruction[] {\n return priorityFeeMicroLamports === undefined\n ? [setComputeUnitLimitIx(computeUnitLimit)]\n : [setComputeUnitPriceIx(priorityFeeMicroLamports), setComputeUnitLimitIx(computeUnitLimit)];\n}\n\nexport interface TransactionPlan {\n instructions: Instruction[];\n lookupTables?: Address[];\n /**\n * Partition of `instructions` into indivisible segments when splitting for\n * wire size (Jito bundle or sequential oversize). Lengths must be positive\n * and sum to `instructions.length`. Omitted or undefined: each instruction\n * is its own segment (legacy `Instruction[]` behavior).\n *\n * Example: [1, 2, 3] means the first 1 instruction is in the first bin, the\n * next 2 are in the second bin, and the last 3 are in the third bin.\n *\n * Use this to keep an atomic group together — e.g. a Kamino flash\n * borrow/rebalance/repay triple, where the borrow's `flash_ixs.rs` check\n * introspects its own tx's instructions sysvar to find the matching repay.\n */\n segmentLengths?: number[];\n /**\n * Indices into the segments produced by `segmentLengths` that must\n * always start a fresh bin. The current bin (if any) is flushed before\n * the segment is appended, regardless of whether it would have fit.\n *\n * Use this when a CPI in the segment encodes a position-relative index at\n * build time (e.g. Kamino's flash-borrow records the position of the\n * matching repay in its data) — forcing the segment to start a new bin\n * keeps that index stable across runs.\n */\n freshBinSegments?: number[];\n}\n\nexport type SendTransactionOptionsWithPostSuccess = SendTransactionOptions & {\n onSuccess?: () => void;\n};\n\n/**\n * Build a transaction message from instructions with embedded signers.\n *\n * @param rpc - Solana RPC client\n * @param feePayer - Fee payer with TransactionSigner (signer will be embedded)\n * @param instructions - Instructions to include\n * @param lookupTableAddresses - Optional lookup tables for compression\n * @param additionalSigners - Optional additional signers beyond fee payer\n * @param blockhash - Optional blockhash (fetched if not provided)\n */\nexport async function buildTransactionMessage(\n rpc: Rpc<SolanaRpcApi>,\n feePayer: TransactionSigner,\n instructions: Instruction[],\n lookupTableAddresses?: Address[],\n additionalSigners?: TransactionSigner[],\n blockhash?: Readonly<{ blockhash: Blockhash; lastValidBlockHeight: bigint }>\n): Promise<CompilableTransactionMessage> {\n const blockhashInfo =\n blockhash ??\n ((await rpc.getLatestBlockhash({ commitment: \"confirmed\" }).send()) as BlockhashResponse).value;\n\n let transactionMessage = pipe(\n createTransactionMessage({ version: 0 }),\n (tx) => setTransactionMessageFeePayerSigner(feePayer, tx),\n (tx) => setTransactionMessageLifetimeUsingBlockhash(blockhashInfo, tx),\n (tx) => appendTransactionMessageInstructions(instructions, tx)\n );\n\n // Attach all signers (fee payer + additional) to instruction accounts that need them\n const allSigners = [feePayer, ...(additionalSigners ?? [])];\n transactionMessage = addSignersToTransactionMessage(allSigners, transactionMessage);\n\n if (lookupTableAddresses?.length) {\n const lutInputs = await lutManager.getLookupTableInputs(\n rpc,\n deduplicateAccounts(lookupTableAddresses)\n );\n const lookupTables: { [key: Address]: Address[] } = {};\n for (const lut of lutInputs) {\n lookupTables[lut.address] = [...lut.addresses];\n }\n transactionMessage = compressTransactionMessageUsingAddressLookupTables(\n transactionMessage,\n lookupTables\n );\n }\n\n return transactionMessage;\n}\n\nexport interface SimulationResult {\n err: object | null;\n logs: string[];\n unitsConsumed: bigint;\n}\n\n/**\n * Simulate a transaction message without requiring real signatures.\n *\n * Compiles the message into a wire-format transaction (with placeholder\n * signatures), sends it to `simulateTransaction` with signature verification\n * disabled, and validates the same recent blockhash that will be signed and\n * sent if simulation succeeds.\n *\n * @param rpc - Solana RPC client\n * @param transactionMessage - A compilable transaction message (with embedded signers)\n */\nexport async function simulateTransaction(\n rpc: Rpc<SolanaRpcApi>,\n transactionMessage: CompilableTransactionMessage\n): Promise<SimulationResult> {\n const compiledTransaction = compileTransaction(transactionMessage);\n const base64EncodedTransaction = getBase64EncodedWireTransaction(compiledTransaction);\n\n const {\n value: { err, logs, unitsConsumed },\n } = await rpc\n .simulateTransaction(base64EncodedTransaction, {\n encoding: \"base64\",\n sigVerify: false,\n replaceRecentBlockhash: false,\n commitment: \"confirmed\",\n })\n .send();\n\n return {\n err: err as object | null,\n logs: logs ?? [],\n unitsConsumed: unitsConsumed ?? 0n,\n };\n}\n\n/**\n * Build, sign, send, and confirm a transaction using embedded signers.\n *\n * Use this with instructions that have TransactionSigner objects embedded\n * in their accounts.\n *\n * @param rpc - Solana RPC client\n * @param payer - Fee payer with TransactionSigner\n * @param instructionsOrPlan - Kit Instructions or a composed transaction plan\n * (with embedded signers)\n * @param options - Optional configuration\n * @returns Transaction signature\n *\n * @example\n * ```typescript\n * const sig = await signSendAndConfirmTransaction(rpc, payer, [\n * computeBudgetIx,\n * transferIx,\n * ]);\n * ```\n */\nexport async function signSendAndConfirmTransaction(\n rpc: Rpc<SolanaRpcApi>,\n payer: TransactionSigner,\n instructionsOrPlan: Instruction[] | TransactionPlan,\n options?: SendTransactionOptionsWithPostSuccess\n): Promise<Signature> {\n const instructions = Array.isArray(instructionsOrPlan)\n ? instructionsOrPlan\n : instructionsOrPlan.instructions;\n const lookupTables = Array.isArray(instructionsOrPlan)\n ? options?.lookupTables\n : (options?.lookupTables ?? instructionsOrPlan.lookupTables);\n const segmentLengths = Array.isArray(instructionsOrPlan)\n ? undefined\n : instructionsOrPlan.segmentLengths;\n const freshBinSegments = Array.isArray(instructionsOrPlan)\n ? undefined\n : instructionsOrPlan.freshBinSegments;\n\n const filteredLuts = lookupTables?.filter((x) => x !== DEFAULT_PUBLIC_KEY);\n\n // Build transaction message with embedded signers\n const transactionMessage = await buildTransactionMessage(\n rpc,\n payer,\n instructions,\n filteredLuts,\n options?.additionalSigners\n );\n\n // Reserve room for compute-budget instructions added after this measurement.\n // Also route to the split path whenever the plan declares\n // `freshBinSegments`, since those boundaries only take effect there.\n const txBytes = measureTxBytes(transactionMessage);\n const maxUnaugmentedTxBytes = SOLANA_TX_SIZE_LIMIT - BUNDLE_INJECTED_IX_RESERVED_BYTES;\n const mustSplit =\n txBytes > maxUnaugmentedTxBytes || options?.forceJitoBundle || !!freshBinSegments?.length;\n if (mustSplit) {\n if (options?.sendOversizedAsSequentialTransactions) {\n return signSendAndConfirmSplitSequentially(\n rpc,\n payer,\n instructions,\n filteredLuts,\n options,\n segmentLengths,\n freshBinSegments\n );\n }\n return _signSendAndConfirmBundle(\n rpc,\n payer,\n instructions,\n filteredLuts,\n options,\n segmentLengths,\n freshBinSegments\n );\n }\n\n // ── Single-transaction happy path ──\n\n // Resolve the caller's explicit price or provider-routed priority level. If\n // neither is provided, the transaction carries no compute-unit-price instruction.\n const writableAccounts = collectWritableAccounts(instructions);\n const priorityFeeMicroLamports = await resolvePriorityFeeMicroLamports(\n rpc,\n transactionMessage,\n writableAccounts,\n options\n );\n\n // Simulate with the max CU limit and, when requested, the chosen priority\n // fee. Matching the final compute-budget instructions keeps preflight costs\n // consistent with the on-chain transaction.\n const simMessage = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(MAX_COMPUTE_UNIT_LIMIT, priorityFeeMicroLamports),\n transactionMessage\n ) as CompilableTransactionMessage;\n const simulation = await simulateTransaction(rpc, simMessage);\n if (simulation.err) {\n if (!options?.hideFailureInfo) {\n console.error(\"Simulation failed:\", simulation.err);\n logProgramLogsLineByLine(simulation.logs, \"Simulation logs\");\n }\n const errStr = JSON.stringify(simulation.err, (_, v) =>\n typeof v === \"bigint\" ? v.toString() : v\n );\n throw new TransactionError(`Transaction simulation failed: ${errStr}`, simulation.logs);\n }\n\n // Append the measured CU limit (with headroom) and the optional priority fee.\n const computeUnits = computeUnitLimitFromSimulation(\n Number(simulation.unitsConsumed),\n options?.computeUnitLimitMultiplier ?? DEFAULT_COMPUTE_UNIT_LIMIT_MULTIPLIER\n );\n const finalMessage = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(computeUnits, priorityFeeMicroLamports),\n transactionMessage\n );\n\n // Sign with embedded signers\n const signedTx = await signTransactionMessageWithSigners(\n finalMessage as typeof transactionMessage\n );\n\n // Send transaction\n const base64EncodedTransaction = getBase64EncodedWireTransaction(signedTx);\n const signature = getSignatureFromTransaction(signedTx);\n\n await rpc\n .sendTransaction(base64EncodedTransaction, {\n encoding: \"base64\",\n skipPreflight: true,\n })\n .send();\n\n // Confirm transaction at the specified commitment level\n try {\n await confirmTransaction(rpc, signature, \"confirmed\");\n options?.onSuccess?.();\n return signature;\n } catch (error) {\n // Before declaring failure, ask the RPC for the on-chain truth. The\n // confirmation loop can fail for reasons unrelated to the tx itself\n // (timeout, upstream provider returning \"All providers failed\", etc.),\n // and in those cases the tx may have actually landed.\n let logs: string[] = [];\n let landedSuccessfully = false;\n try {\n const info = await rpc\n .getTransaction(signature, { commitment: \"confirmed\", encoding: \"base64\" })\n .send();\n if (info) {\n logs = (info.meta?.logMessages ?? []) as string[];\n if (info.meta?.err == null) {\n landedSuccessfully = true;\n }\n }\n } catch {\n // Best-effort lookup; if this also fails, we fall through and throw.\n }\n\n if (landedSuccessfully) {\n console.warn(\n `Confirmation polling failed for signature ${signature} but the transaction landed on-chain; treating as success. Reason: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n options?.onSuccess?.();\n return signature;\n }\n\n if (!options?.hideFailureInfo) {\n console.error(\"Transaction failed:\", error);\n logProgramLogsLineByLine(logs, \"Transaction logs\");\n }\n throw new TransactionError(`Transaction failed: ${error}`, logs);\n }\n}\n\n/**\n * Build and sign one split bin.\n */\nasync function signSplitBin(\n rpc: Rpc<SolanaRpcApi>,\n payer: TransactionSigner,\n bin: Instruction[],\n lookupTables: Address[] | undefined,\n additionalSigners: TransactionSigner[] | undefined,\n blockhash: Readonly<{ blockhash: Blockhash; lastValidBlockHeight: bigint }>,\n priorityFeeMicroLamports: number | undefined\n): Promise<{ wireB64: Base64EncodedWireTransaction; signature: Signature }> {\n const msg = await buildTransactionMessage(\n rpc,\n payer,\n bin,\n lookupTables,\n additionalSigners,\n blockhash\n );\n\n const finalMsg = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(MAX_COMPUTE_UNIT_LIMIT, priorityFeeMicroLamports),\n msg\n );\n const signed = await signTransactionMessageWithSigners(finalMsg as typeof msg);\n return {\n wireB64: getBase64EncodedWireTransaction(signed),\n signature: getSignatureFromTransaction(signed),\n };\n}\n\n/**\n * Split an oversize instruction list into multiple transactions and submit\n * them atomically as a Jito bundle. If Jito is disabled (`jitoTipLamports === 0`),\n * throws instead of bundling.\n *\n * Bundle simulation runs through the RPC's `simulateBundle` (instead of a\n * per-bin `simulateTransaction`) so intra-bundle dependencies — e.g. a\n * refresh ix in bin 0 that the rebalance ix in bin 1 relies on — are honored\n * by the simulator the same way they are by atomic bundle execution. The\n * simulation skips signature verification but validates the same shared\n * blockhash that is retained for final signing.\n */\nasync function _signSendAndConfirmBundle(\n rpc: Rpc<SolanaRpcApi>,\n payer: TransactionSigner,\n instructions: Instruction[],\n lookupTables: Address[] | undefined,\n options?: SendTransactionOptionsWithPostSuccess,\n segmentLengths?: number[],\n freshBinSegments?: number[]\n): Promise<Signature> {\n const tipLamports = options?.jitoTipLamports ?? DEFAULT_JITO_TIP_LAMPORTS;\n\n if (tipLamports === 0) {\n throw new TransactionError(\n \"Transaction exceeds the Solana size limit and Jito bundling is disabled. \" +\n \"Set jitoTipLamports > 0 to enable bundle fallback.\"\n );\n }\n\n // Fetch one blockhash and reuse it for every tx in the bundle. This\n // avoids redundant RPC calls during splitting + per-bin build, and\n // ensures the whole bundle shares a single liveness window.\n const { value: blockhash } = (await rpc\n .getLatestBlockhash({ commitment: \"confirmed\" })\n .send()) as BlockhashResponse;\n\n // Split instructions, reserving headroom for the compute-unit-limit ix\n // that gets appended to every bin and the Jito tip ix that gets appended\n // to one bin. Without reservation, a near-full bin would overflow 1232\n // bytes once those are injected.\n const { bins } = await splitIntoTransactionBins(rpc, payer, instructions, {\n lookupTables,\n additionalSigners: options?.additionalSigners,\n blockhash,\n reservedBytes: BUNDLE_INJECTED_IX_RESERVED_BYTES,\n segmentLengths,\n freshBinSegments,\n });\n\n if (bins.length === 0) {\n throw new TransactionError(\"Bundle build produced 0 bins; cannot attach Jito tip.\");\n }\n // Build each bin's transaction message once; we'll reuse it for both the\n // pre-signing simulation and the final signing pass.\n const messages: CompilableTransactionMessage[] = [];\n for (const bin of bins) {\n messages.push(\n await buildTransactionMessage(\n rpc,\n payer,\n bin,\n lookupTables,\n options?.additionalSigners,\n blockhash\n )\n );\n }\n\n // Append the Jito tip ix AFTER LUT compression in `buildTransactionMessage`.\n // If we appended it before compression and any supplied LUT contained the\n // tip account, it would be moved into the LUT-loaded address set. Jito's\n // bundle validator only inspects *static* account keys for tip accounts and\n // rejects with \"Bundles must write lock at least one tip account to be\n // eligible for the auction\" otherwise.\n //\n // Pick the smallest tx to carry the tip so a bin already near the 1232-byte\n // wire limit isn't pushed over by the extra ~81 bytes of tip-transfer ix.\n const tipBinIdx = messages\n .map((m, i) => ({ i, bytes: measureTxBytes(m) }))\n .reduce((a, b) => (a.bytes <= b.bytes ? a : b)).i;\n const tipAccount = getRandomTipAccount();\n const tipIx = buildTipInstruction(payer, tipAccount, tipLamports);\n messages[tipBinIdx] = appendTransactionMessageInstructions(\n [tipIx],\n messages[tipBinIdx]\n ) as CompilableTransactionMessage;\n console.log(\n `[bundle] attached ${tipLamports} lamport tip to tx[${tipBinIdx}] (smallest of ${messages.length}) → ${tipAccount}`\n );\n\n const priorityFeeMicroLamports = await Promise.all(\n messages.map((message, index) =>\n resolvePriorityFeeMicroLamports(rpc, message, collectWritableAccounts(bins[index]), options)\n )\n );\n\n // Phase 1: encode each bin with a max CU limit and run a single bundle-level\n // simulation. `compileTransaction` stamps placeholder signatures, while\n // `skipSigVerify` lets the simulator validate the real shared blockhash\n // before the wallet signs.\n const simEncodedTxs: string[] = [];\n for (let i = 0; i < messages.length; i += 1) {\n const simMsg = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(MAX_COMPUTE_UNIT_LIMIT, priorityFeeMicroLamports[i]),\n messages[i]\n ) as CompilableTransactionMessage;\n const compiled = compileTransaction(simMsg);\n simEncodedTxs.push(getBase64EncodedWireTransaction(compiled));\n }\n\n const rpcUrl = getMainnetRpcUrl();\n const simResult = await simulateBundle(rpcUrl, simEncodedTxs, {\n replaceRecentBlockhash: false,\n });\n const failingIdx = simResult.transactionResults.findIndex((r) => r.err != null);\n if (simResult.summary !== \"succeeded\" || failingIdx >= 0) {\n const idx = failingIdx >= 0 ? failingIdx : 0;\n const failed = simResult.transactionResults[idx];\n if (!options?.hideFailureInfo) {\n console.error(`Bundle simulation failed at tx[${idx}] of ${bins.length}.`);\n console.error(\"Summary:\", JSON.stringify(simResult.summary, null, 2));\n simResult.transactionResults.forEach((r, i) => {\n const tag = i === idx ? \" ← FAILED\" : i < idx ? \" (succeeded)\" : \" (not run)\";\n console.error(`\\n── tx[${i}]${tag} (unitsConsumed=${r.unitsConsumed ?? \"—\"}) ──`);\n if (r.err != null) console.error(\" err:\", JSON.stringify(r.err));\n logProgramLogsLineByLine(r.logs ?? [], `tx[${i}] bundle simulation logs`);\n });\n\n // Fall back to a single-tx `simulateTransaction` on the failing bin —\n // it returns longer logs than `simulateBundle` (which truncates at\n // ~16 lines). Skips the intra-bundle effects from preceding bins, so\n // dependent failures (e.g. PriceIsStale when bin 0 was supposed to\n // refresh) surface here instead. Best-effort; we keep the original\n // error.\n //\n // Uses direct JSON-RPC instead of Kit's typed `rpc.simulateTransaction`\n // wrapper because the latter has thrown \"Do not know how to serialize\n // a BigInt\" on this code path — the raw fetch route gives us a\n // bigint-safe replacer in `jsonRpcFetchOnce`'s body builder.\n try {\n const failedSimMsg = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(MAX_COMPUTE_UNIT_LIMIT, priorityFeeMicroLamports[idx]),\n messages[idx]\n ) as CompilableTransactionMessage;\n const failedB64 = getBase64EncodedWireTransaction(compileTransaction(failedSimMsg));\n const standalone = await jsonRpcFetchOnce<{\n value: { err: object | null; logs: string[] | null };\n }>(rpcUrl, \"simulateTransaction\", [\n failedB64,\n {\n encoding: \"base64\",\n sigVerify: false,\n replaceRecentBlockhash: false,\n commitment: \"confirmed\",\n },\n ]);\n console.error(\n `\\n── tx[${idx}] standalone simulateTransaction (full logs, no preceding-bin effects) ──`\n );\n if (standalone.value.err != null)\n console.error(\n \" err:\",\n JSON.stringify(standalone.value.err, (_, v) =>\n typeof v === \"bigint\" ? v.toString() : v\n )\n );\n const logs = standalone.value.logs ?? [];\n logProgramLogsLineByLine(logs, `tx[${idx}] standalone simulation logs`);\n } catch (err) {\n console.error(\n \" (standalone fallback failed:\",\n err instanceof Error ? err.message : String(err),\n \")\"\n );\n }\n }\n const errStr = JSON.stringify(failed?.err ?? simResult.summary, (_, v) =>\n typeof v === \"bigint\" ? v.toString() : v\n );\n throw new TransactionError(\n `Bundle simulation failed at tx[${idx}]: ${errStr}`,\n failed?.logs ?? []\n );\n }\n\n // Phase 2: stamp each bin with its measured CU + 10% headroom while retaining\n // the blockhash validated by simulation, then compile and batch-sign them.\n // Browser wallets expose\n // `signTransactions`, and using it here preserves the intended multi-tx\n // approval flow for bundles instead of requesting one signature at a time.\n // Fall back to MAX_COMPUTE_UNIT_LIMIT if the simulator didn't report a\n // unitsConsumed value (some endpoints omit it on edge cases).\n const finalTransactions: Transaction[] = [];\n for (let i = 0; i < messages.length; i += 1) {\n const measured = simResult.transactionResults[i]?.unitsConsumed;\n const cu = measured && measured > 0 ? Math.ceil(measured * 1.1) : MAX_COMPUTE_UNIT_LIMIT;\n const withCu = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(cu, priorityFeeMicroLamports[i]),\n messages[i]\n ) as CompilableTransactionMessage;\n const finalMsg = setTransactionMessageLifetimeUsingBlockhash(\n blockhash,\n withCu\n ) as CompilableTransactionMessage;\n finalTransactions.push(compileTransaction(finalMsg));\n }\n const signedTransactions = await signTransactionsWithSigners(finalTransactions, [\n payer,\n ...(options?.additionalSigners ?? []),\n ]);\n const base64Txs = signedTransactions.map(getBase64EncodedWireTransaction);\n const lastSignature = getSignatureFromTransaction(\n signedTransactions[signedTransactions.length - 1]\n );\n\n // Submit and confirm the bundle through the user's own RPC endpoint\n // (Helius, Ironforge, etc.). These providers proxy Jito bundle methods,\n // avoiding the global rate limit on Jito's public block engine.\n try {\n console.log(`[bundle] sending via ${redactRpcUrlForLog(rpcUrl)}`);\n const bundleId = await sendBundle(rpcUrl, base64Txs);\n await confirmBundle(rpcUrl, bundleId);\n\n options?.onSuccess?.();\n\n // Last bin carries the tip; signature matches what landed on-chain.\n return lastSignature!;\n } catch (error) {\n if (error instanceof JitoBundleError) {\n throw new TransactionError(`Jito bundle failed: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Same bin-packing as {@link signSendAndConfirmBundle}, but no tip and each\n * bin is sent and confirmed via normal RPC (for environments without Jito).\n */\nasync function signSendAndConfirmSplitSequentially(\n rpc: Rpc<SolanaRpcApi>,\n payer: TransactionSigner,\n instructions: Instruction[],\n lookupTables: Address[] | undefined,\n options?: SendTransactionOptionsWithPostSuccess,\n segmentLengths?: number[],\n freshBinSegments?: number[]\n): Promise<Signature> {\n const { value: splitBlockhash } = (await rpc\n .getLatestBlockhash({ commitment: \"confirmed\" })\n .send()) as BlockhashResponse;\n\n const { bins } = await splitIntoTransactionBins(rpc, payer, instructions, {\n lookupTables,\n additionalSigners: options?.additionalSigners,\n blockhash: splitBlockhash,\n reservedBytes: BUNDLE_INJECTED_IX_RESERVED_BYTES,\n segmentLengths,\n freshBinSegments,\n });\n\n let lastSignature: Signature | undefined;\n\n for (const [binIndex, bin] of bins.entries()) {\n const { value: blockhash } = (await rpc\n .getLatestBlockhash({ commitment: \"confirmed\" })\n .send()) as BlockhashResponse;\n\n const transactionMessage = await buildTransactionMessage(\n rpc,\n payer,\n bin,\n lookupTables,\n options?.additionalSigners,\n blockhash\n );\n const priorityFeeMicroLamports = await resolvePriorityFeeMicroLamports(\n rpc,\n transactionMessage,\n collectWritableAccounts(bin),\n options\n );\n const simMsg = appendTransactionMessageInstructions(\n getComputeBudgetInstructions(MAX_COMPUTE_UNIT_LIMIT, priorityFeeMicroLamports),\n transactionMessage\n ) as CompilableTransactionMessage;\n const simulation = await simulateTransaction(rpc, simMsg);\n if (simulation.err) {\n if (!options?.hideFailureInfo) {\n console.error(`Simulation failed for split bin ${binIndex}:`, simulation.err);\n logProgramLogsLineByLine(simulation.logs, `split bin ${binIndex} simulation logs`);\n }\n const errStr = JSON.stringify(simulation.err, (_, v) =>\n typeof v === \"bigint\" ? v.toString() : v\n );\n throw new TransactionError(\n `Split bin ${binIndex} simulation failed: ${errStr}`,\n simulation.logs\n );\n }\n\n const { wireB64, signature } = await signSplitBin(\n rpc,\n payer,\n bin,\n lookupTables,\n options?.additionalSigners,\n blockhash,\n priorityFeeMicroLamports\n );\n\n await rpc\n .sendTransaction(wireB64, {\n encoding: \"base64\",\n skipPreflight: true,\n })\n .send();\n\n try {\n await confirmTransaction(rpc, signature, \"confirmed\");\n } catch (error) {\n const logs = await fetchTransactionLogsWithRetry(rpc, signature);\n if (!options?.hideFailureInfo) {\n console.error(`Transaction failed for split bin ${binIndex}:`, signature, error);\n logProgramLogsLineByLine(logs, `split bin ${binIndex} transaction logs`);\n }\n throw new TransactionError(`Transaction failed: ${error}`, logs);\n }\n\n lastSignature = signature;\n }\n\n options?.onSuccess?.();\n return lastSignature!;\n}\n\nasync function fetchTransactionLogsWithRetry(\n rpc: Rpc<SolanaRpcApi>,\n signature: Signature\n): Promise<string[]> {\n for (let attempt = 0; attempt < 10; attempt += 1) {\n try {\n const info = await rpc\n .getTransaction(signature, { commitment: \"confirmed\", encoding: \"base64\" })\n .send();\n const logs = (info?.meta?.logMessages ?? []) as string[];\n if (logs.length > 0) return logs;\n } catch {\n // Best-effort log retrieval; retry below.\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n return [];\n}\n\n/**\n * Wait for a transaction to be confirmed at the specified commitment level.\n *\n * @param rpc - Solana RPC client\n * @param signature - Transaction signature to confirm\n * @param commitment - Commitment level to wait for\n * @param timeoutMs - Maximum time to wait (default: 60000ms)\n */\nasync function confirmTransaction(\n rpc: Rpc<SolanaRpcApi>,\n signature: Signature,\n commitment: \"processed\" | \"confirmed\" | \"finalized\",\n timeoutMs: number = 60000\n): Promise<void> {\n const startTime = Date.now();\n const pollIntervalMs = 500;\n\n while (Date.now() - startTime < timeoutMs) {\n let status: Awaited<\n ReturnType<ReturnType<Rpc<SolanaRpcApi>[\"getSignatureStatuses\"]>[\"send\"]>\n >[\"value\"][number] = null;\n try {\n const response = await rpc.getSignatureStatuses([signature]).send();\n status = response.value[0];\n } catch (err) {\n // Transient upstream RPC failures during confirmation polling (e.g.\n // Ironforge returning \"All providers failed\", DNS hiccups, 429s) must\n // not declare the transaction failed — the tx may already have landed.\n // Keep polling until we get a real status or the timeout elapses.\n if (!isTransientNetworkError(err)) throw err;\n }\n\n if (status !== null) {\n // Check if transaction failed\n if (status.err) {\n // Use replacer to handle BigInt values in error objects\n const errStr = JSON.stringify(status.err, (_, v) =>\n typeof v === \"bigint\" ? v.toString() : v\n );\n throw new Error(`Transaction failed: ${errStr}`);\n }\n\n // Check if we've reached the desired commitment level\n const confirmationStatus = status.confirmationStatus;\n if (\n confirmationStatus === commitment ||\n (commitment === \"processed\" && confirmationStatus) ||\n (commitment === \"confirmed\" &&\n (confirmationStatus === \"confirmed\" || confirmationStatus === \"finalized\")) ||\n (commitment === \"finalized\" && confirmationStatus === \"finalized\")\n ) {\n return;\n }\n }\n\n // Wait before polling again\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n\n throw new Error(`Transaction confirmation timeout after ${timeoutMs}ms`);\n}\n","/**\n * Diagnostic helpers for inspecting which addresses a transaction references\n * and whether they are covered by the caller's address lookup tables.\n *\n * Useful when bin-packing fails: if a segment is over the per-tx wire limit,\n * the cheapest fix is usually adding addresses to a LUT so the compiler can\n * compress them from 32-byte static keys down to 1-byte indices. This module\n * surfaces the candidates by cross-referencing every account touched by the\n * instruction list against the full contents of every passed LUT.\n */\n\nimport type { Address, Instruction, Rpc, SolanaRpcApi, TransactionSigner } from \"@solana/kit\";\nimport { compileTransaction, getCompiledTransactionMessageDecoder } from \"@solana/kit\";\n\nimport { lutManager } from \"../services/lutManager\";\nimport { buildTransactionMessage } from \"./transaction\";\n\nexport interface LutUsage {\n /** Addresses pulled from this LUT into the compiled message's writable section. */\n writable: Address[];\n /** Addresses pulled from this LUT into the compiled message's readonly section. */\n readonly: Address[];\n /** Total addresses stored in the LUT (capacity reference). */\n size: number;\n}\n\nexport interface AccountCoverageReport {\n /** Compiled message's static account list (programs, fee payer, anything not LUT'd). */\n staticAccounts: Address[];\n /** Per-LUT: which entries the compiler actually used, plus the LUT's full size. */\n lutUsage: Map<Address, LutUsage>;\n /** All distinct addresses referenced by the instructions (programs + accounts + fee payer). */\n referenced: Address[];\n /** Distinct program IDs across all instructions (forced into static keys). */\n programIds: Address[];\n /** Addresses referenced but NOT present in any caller-supplied LUT. */\n uncoveredByCallerLuts: Address[];\n /**\n * Subset of `uncoveredByCallerLuts` that excludes program IDs and the fee\n * payer — i.e., concrete candidates to add to a LUT for further compression.\n */\n candidatesToAddToLut: Address[];\n}\n\n/**\n * Compile the message with the caller's LUTs, decode the result, and produce\n * a report describing which addresses are static, which came from LUTs, and\n * which referenced addresses are still uncovered.\n *\n * Note: program IDs MUST live in the static account list — the v0 message\n * format does not allow LUT lookup for the program-id slot. The report keeps\n * them in `referenced` and `programIds` but excludes them from\n * `candidatesToAddToLut` since putting a program in a LUT cannot help.\n */\nexport async function reportAccountCoverage(\n rpc: Rpc<SolanaRpcApi>,\n payer: TransactionSigner,\n instructions: Instruction[],\n lookupTableAddresses: Address[] | undefined\n): Promise<AccountCoverageReport> {\n // Fetch the FULL contents of every caller-supplied LUT (regardless of which\n // entries the compiler ends up referencing) so we can answer \"is this\n // address in any of MY LUTs?\" — the actionable question for tightening\n // coverage.\n const callerLuts = lookupTableAddresses?.length\n ? await lutManager.getLookupTableInputs(rpc, lookupTableAddresses)\n : [];\n const callerLutAddressSet = new Set<Address>(callerLuts.flatMap((l) => l.addresses));\n\n // Compile the message with LUTs to see what actually got compressed and\n // what spilled into the static account list.\n const msg = await buildTransactionMessage(rpc, payer, instructions, lookupTableAddresses);\n const compiled = compileTransaction(msg);\n const decoded = getCompiledTransactionMessageDecoder().decode(compiled.messageBytes);\n const staticAccounts = (decoded.staticAccounts ?? []) as Address[];\n const altLookups = \"addressTableLookups\" in decoded ? (decoded.addressTableLookups ?? []) : [];\n\n const lutUsage = new Map<Address, LutUsage>();\n for (const lut of callerLuts) {\n lutUsage.set(lut.address, { writable: [], readonly: [], size: lut.addresses.length });\n }\n for (const lookup of altLookups) {\n const fullAddrs = callerLuts.find((l) => l.address === lookup.lookupTableAddress)?.addresses;\n const usage = lutUsage.get(lookup.lookupTableAddress) ?? {\n writable: [],\n readonly: [],\n size: fullAddrs?.length ?? 0,\n };\n if (fullAddrs) {\n usage.writable = lookup.writableIndexes.map((i) => fullAddrs[i] as Address);\n usage.readonly = lookup.readonlyIndexes.map((i) => fullAddrs[i] as Address);\n }\n lutUsage.set(lookup.lookupTableAddress, usage);\n }\n\n const referencedSet = new Set<Address>();\n const programSet = new Set<Address>();\n referencedSet.add(payer.address);\n for (const ix of instructions) {\n referencedSet.add(ix.programAddress);\n programSet.add(ix.programAddress);\n for (const acc of ix.accounts ?? []) {\n referencedSet.add(acc.address);\n }\n }\n\n const referenced = [...referencedSet];\n const programIds = [...programSet];\n const uncoveredByCallerLuts = referenced.filter((a) => !callerLutAddressSet.has(a));\n const candidatesToAddToLut = uncoveredByCallerLuts.filter(\n (a) => a !== payer.address && !programSet.has(a)\n );\n\n return {\n staticAccounts,\n lutUsage,\n referenced,\n programIds,\n uncoveredByCallerLuts,\n candidatesToAddToLut,\n };\n}\n\n/** Pretty-print a coverage report. Designed for CLI/script diagnostic use. */\nexport function logAccountCoverage(label: string, report: AccountCoverageReport): void {\n console.log(`\\n── Account coverage: ${label} ──`);\n console.log(\n `Compiled static accounts (${report.staticAccounts.length}) — programs, fee payer, and uncompressed:`\n );\n report.staticAccounts.forEach((a, i) => console.log(` [${i}] ${a}`));\n\n console.log(`\\nCaller-supplied LUTs (${report.lutUsage.size}):`);\n if (report.lutUsage.size === 0) {\n console.log(\" (none)\");\n }\n for (const [lut, usage] of report.lutUsage) {\n const used = usage.writable.length + usage.readonly.length;\n console.log(` ${lut} size=${usage.size} used=${used}`);\n if (usage.writable.length > 0) {\n console.log(` writable (${usage.writable.length}): ${usage.writable.join(\", \")}`);\n }\n if (usage.readonly.length > 0) {\n console.log(` readonly (${usage.readonly.length}): ${usage.readonly.join(\", \")}`);\n }\n }\n\n console.log(\n `\\nReferenced addresses: ${report.referenced.length} ` +\n `(${report.programIds.length} program ID${report.programIds.length === 1 ? \"\" : \"s\"})`\n );\n\n console.log(`\\nReferenced but NOT in any caller LUT (${report.uncoveredByCallerLuts.length}):`);\n if (report.uncoveredByCallerLuts.length === 0) {\n console.log(\" (none — every referenced address is in at least one caller LUT)\");\n } else {\n for (const a of report.uncoveredByCallerLuts) {\n const tag = report.programIds.includes(a) ? \" [PROGRAM — must be static]\" : \"\";\n console.log(` ${a}${tag}`);\n }\n }\n\n console.log(\n `\\nCandidates to add to a LUT (excludes programs + fee payer; ${report.candidatesToAddToLut.length}):`\n );\n if (report.candidatesToAddToLut.length === 0) {\n console.log(\" (none — uncovered addresses are all programs or the fee payer)\");\n } else {\n report.candidatesToAddToLut.forEach((a) => console.log(` ${a}`));\n }\n}\n","// =============================================================================\n// Shared Anchor enum types + numeric enums + converters\n// =============================================================================\n\n// --- OracleType ---\n\nexport type AnchorOracleType =\n | { pyth: {} }\n | { switchboard: {} }\n | { perenaBank: {} }\n | { perenaTranche: {} }\n | { tpConsensusOracle: {} }\n | { pythSplStake: {} };\n\nexport enum OracleType {\n Pyth = 0,\n Switchboard = 1,\n PerenaBank = 2,\n PerenaTranche = 3,\n // LST priced from an SPL stake pool exchange rate × a Pyth SOL/USD feed\n // (capped at 1.1 × SOL/USD). The Pyth SOL feed is the primary oracle and the\n // SPL stake pool account is the secondary oracle.\n PythSplStake = 4,\n TPConsensusOracle = 5,\n}\n\nexport function oracleTypeToEnum(v: AnchorOracleType): OracleType {\n if (\"pyth\" in v) return OracleType.Pyth;\n if (\"switchboard\" in v) return OracleType.Switchboard;\n if (\"perenaBank\" in v) return OracleType.PerenaBank;\n if (\"perenaTranche\" in v) return OracleType.PerenaTranche;\n if (\"pythSplStake\" in v) return OracleType.PythSplStake;\n if (\"tpConsensusOracle\" in v) return OracleType.TPConsensusOracle;\n throw new Error(\"Unknown OracleType variant\");\n}\n\nexport function enumToOracleType(t: OracleType): AnchorOracleType {\n switch (t) {\n case OracleType.Pyth:\n return { pyth: {} };\n case OracleType.Switchboard:\n return { switchboard: {} };\n case OracleType.PerenaBank:\n return { perenaBank: {} };\n case OracleType.PerenaTranche:\n return { perenaTranche: {} };\n case OracleType.PythSplStake:\n return { pythSplStake: {} };\n case OracleType.TPConsensusOracle:\n return { tpConsensusOracle: {} };\n }\n}\n\n// --- ExternalLiquidityType ---\n\nexport type AnchorExternalLiquidityType = { none: {} } | { perenaWithdrawalQueue: {} };\n\nexport enum ExternalLiquidityType {\n None = 0,\n PerenaWithdrawalQueue = 1,\n}\n\nexport function ExternalLiquidityTypeToEnum(v: AnchorExternalLiquidityType): ExternalLiquidityType {\n if (\"none\" in v) return ExternalLiquidityType.None;\n if (\"perenaWithdrawalQueue\" in v) return ExternalLiquidityType.PerenaWithdrawalQueue;\n throw new Error(\"Unknown ExternalLiquidityType variant\");\n}\n\nexport function enumToExternalLiquidityType(t: ExternalLiquidityType): AnchorExternalLiquidityType {\n switch (t) {\n case ExternalLiquidityType.None:\n return { none: {} };\n case ExternalLiquidityType.PerenaWithdrawalQueue:\n return { perenaWithdrawalQueue: {} };\n }\n}\n\n// --- TokenProgram ---\n\nexport type AnchorTokenProgram = { spl: {} } | { token2022: {} };\n\nexport enum TokenProgram {\n Spl = 0,\n Token2022 = 1,\n}\n\nexport function tokenProgramToEnum(v: AnchorTokenProgram): TokenProgram {\n if (\"spl\" in v) return TokenProgram.Spl;\n if (\"token2022\" in v) return TokenProgram.Token2022;\n throw new Error(\"Unknown TokenProgram variant\");\n}\n\nexport function enumToTokenProgram(t: TokenProgram): AnchorTokenProgram {\n switch (t) {\n case TokenProgram.Spl:\n return { spl: {} };\n case TokenProgram.Token2022:\n return { token2022: {} };\n }\n}\n\n// --- LendingPlatform ---\n\nexport type AnchorLendingPlatform = { none: {} } | { marginfi: {} } | { kamino: {} };\n\nexport enum LendingPlatform {\n None = 0,\n Marginfi = 1,\n Kamino = 2,\n}\n\nexport function lendingPlatformToEnum(v: AnchorLendingPlatform): LendingPlatform {\n if (\"none\" in v) return LendingPlatform.None;\n if (\"marginfi\" in v) return LendingPlatform.Marginfi;\n if (\"kamino\" in v) return LendingPlatform.Kamino;\n throw new Error(\"Unknown LendingPlatform variant\");\n}\n\nexport function enumToLendingPlatform(t: LendingPlatform): AnchorLendingPlatform {\n switch (t) {\n case LendingPlatform.None:\n return { none: {} };\n case LendingPlatform.Marginfi:\n return { marginfi: {} };\n case LendingPlatform.Kamino:\n return { kamino: {} };\n }\n}\n","import { address, Address, Instruction, KeyPairSigner, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport { mints } from \"../services/mints/registry\";\nimport type { MintIdentifier } from \"../types\";\nimport {\n getInitializeMint2Instruction,\n getMintSize,\n TOKEN_PROGRAM_ADDRESS,\n} from \"@solana-program/token\";\nimport { TOKEN_2022_PROGRAM_ADDRESS } from \"@solana-program/token-2022\";\nimport { getCreateAccountInstruction } from \"@solana-program/system\";\nimport { signSendAndConfirmTransaction } from \"./transaction\";\nimport { type AnchorTokenProgram, tokenProgramToEnum, TokenProgram } from \"../types/enums\";\n\n/** Resolve a mint registry symbol or raw base58 address to a Kit {@link Address}. */\nexport function resolveTokenMint(token: MintIdentifier): Address {\n const known = mints.get(token);\n if (known) {\n return known.address;\n }\n\n return address(token as string);\n}\n\n/** Maps an `AnchorTokenProgram` value to its on-chain program address. */\nexport function resolveTokenProgram(tp: AnchorTokenProgram): Address {\n return tokenProgramToEnum(tp) === TokenProgram.Spl\n ? TOKEN_PROGRAM_ADDRESS\n : TOKEN_2022_PROGRAM_ADDRESS;\n}\n\n/**\n * Gets the token balance of an account (decimal-adjusted)\n *\n * @param tokenAccount - Token account to check\n * @returns Balance as a number (adjusted for decimals, e.g., 1000 USDC not 1000000000)\n */\nexport async function getTokenBalanceUi(\n rpc: Rpc<SolanaRpcApi>,\n tokenAccount: Address\n): Promise<number> {\n const response = await rpc\n .getTokenAccountBalance(tokenAccount, { commitment: \"confirmed\" })\n .send();\n return Number(response.value.uiAmount ?? 0);\n}\n\n/**\n * Gets the token balance of an account\n *\n * @param tokenAccount - Token account to check\n * @returns Balance as a number in base units\n */\nexport async function getTokenBalance(rpc: Rpc<SolanaRpcApi>, tokenAccount: Address): Promise<BN> {\n const response = await rpc\n .getTokenAccountBalance(tokenAccount, { commitment: \"confirmed\" })\n .send();\n return new BN(response.value.amount);\n}\n\n/**\n * Build instructions to create + initialize a new token mint.\n *\n * Prefer bundling these with the instruction that consumes the mint (e.g.\n * `create_token`) in the same transaction so simulation never races RPC\n * visibility of the newly created account.\n */\nexport async function getCreateMintInstructions(\n rpc: Rpc<SolanaRpcApi>,\n payer: KeyPairSigner,\n mintSigner: KeyPairSigner,\n authority: Address,\n decimals: number,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS\n): Promise<Instruction[]> {\n const space = getMintSize();\n const rent = (await rpc.getMinimumBalanceForRentExemption(BigInt(space)).send()) as bigint;\n\n return [\n getCreateAccountInstruction({\n payer,\n newAccount: mintSigner,\n lamports: rent,\n space,\n programAddress: tokenProgram,\n }),\n getInitializeMint2Instruction({\n mint: mintSigner.address,\n decimals,\n mintAuthority: authority,\n }),\n ];\n}\n\n/**\n * Creates a new token mint in its own transaction.\n *\n * @param rpc - Solana RPC client\n * @param payer - Payer for account creation rent\n * @param mintSigner - Keypair signer for the new mint account\n * @param authority - Mint authority address (does not need to be a signer)\n * @param decimals - Number of decimals for the mint\n * @param tokenProgram - Token program (defaults to SPL Token)\n */\nexport async function createMint(\n rpc: Rpc<SolanaRpcApi>,\n payer: KeyPairSigner,\n mintSigner: KeyPairSigner,\n authority: Address,\n decimals: number,\n tokenProgram: Address = TOKEN_PROGRAM_ADDRESS\n): Promise<void> {\n const instructions = await getCreateMintInstructions(\n rpc,\n payer,\n mintSigner,\n authority,\n decimals,\n tokenProgram\n );\n\n await signSendAndConfirmTransaction(rpc, payer, instructions, {\n additionalSigners: [mintSigner],\n });\n}\n","const SECONDS_PER_DAY = 86_400;\n\nexport interface PriceSnapshot {\n timestamp: number;\n price: number;\n}\n\n/**\n * Binary-search for the snapshot closest to (but not after) `targetTimestamp`.\n *\n * Assumes `snapshots` are sorted ascending by timestamp.\n * Returns `undefined` if no snapshot exists at or before the target.\n */\nexport function findNearestSnapshot(\n snapshots: PriceSnapshot[],\n targetTimestamp: number\n): PriceSnapshot | undefined {\n if (snapshots.length === 0) return undefined;\n\n let lo = 0;\n let hi = snapshots.length - 1;\n\n if (snapshots[lo].timestamp > targetTimestamp) return undefined;\n if (snapshots[hi].timestamp <= targetTimestamp) return snapshots[hi];\n\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (snapshots[mid].timestamp <= targetTimestamp) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n\n return snapshots[lo];\n}\n\n/**\n * Filter to only midnight-UTC snapshots (one per day).\n *\n * Midnight snapshots have no DynamoDB TTL and are retained forever, producing\n * a stable daily series that survives hourly data expiry.\n */\nexport function filterDailySnapshots(snapshots: PriceSnapshot[]): PriceSnapshot[] {\n return snapshots.filter((s) => s.timestamp % SECONDS_PER_DAY === 0);\n}\n","/**\n * Metaplex Token Metadata CPI helpers for building UpdateMetadataAccountV2\n * instruction data and CpiData for the CPI ref system.\n */\n\nimport {\n type Address,\n AccountRole,\n getAddressEncoder,\n getProgramDerivedAddress,\n} from \"@solana/kit\";\nimport { SYSTEM_PROGRAM_ADDRESS } from \"@solana-program/system\";\nimport { SYSVAR_RENT_ADDRESS } from \"@solana/sysvars\";\nimport {\n createUpdateMetadataAccountV2Instruction,\n createCreateMetadataAccountV3Instruction,\n Metadata,\n} from \"@metaplex-foundation/mpl-token-metadata\";\nimport type { Connection } from \"@solana/web3.js\";\nimport type { CpiData, CustomAccountMeta } from \"../types\";\nimport { CpiTypes } from \"../constants/generated/cpi\";\nimport { METAPLEX_TOKEN_METADATA_PROGRAM_ID } from \"../constants/general\";\nimport { toWeb3Pk } from \"./compat\";\n\nconst addressEncoder = getAddressEncoder();\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface UpdateMetadataDataV2 {\n name: string;\n symbol: string;\n uri: string;\n sellerFeeBasisPoints?: number;\n}\n\nexport interface UpdateMetadataParams {\n data?: UpdateMetadataDataV2;\n newUpdateAuthority?: Address;\n primarySaleHappened?: boolean;\n isMutable?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Serialization (via mpl-token-metadata SDK)\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize `UpdateMetadataAccountV2` instruction data using the Metaplex SDK.\n *\n * Uses `createUpdateMetadataAccountV2Instruction` from `@metaplex-foundation/mpl-token-metadata`\n * to build a full `TransactionInstruction`, then extracts the `.data` bytes. This avoids\n * manual Borsh serialization while keeping the result compatible with the CPI ref system.\n */\nexport function serializeUpdateMetadataAccountV2(\n metadataPda: Address,\n updateAuthority: Address,\n params: UpdateMetadataParams\n): Uint8Array {\n const ix = createUpdateMetadataAccountV2Instruction(\n {\n metadata: toWeb3Pk(metadataPda),\n updateAuthority: toWeb3Pk(updateAuthority),\n },\n {\n updateMetadataAccountArgsV2: {\n data: params.data\n ? {\n name: params.data.name,\n symbol: params.data.symbol,\n uri: params.data.uri,\n sellerFeeBasisPoints: params.data.sellerFeeBasisPoints ?? 0,\n creators: null,\n collection: null,\n uses: null,\n }\n : null,\n updateAuthority: params.newUpdateAuthority ? toWeb3Pk(params.newUpdateAuthority) : null,\n primarySaleHappened: params.primarySaleHappened ?? null,\n isMutable: params.isMutable ?? null,\n },\n }\n );\n\n return new Uint8Array(ix.data);\n}\n\n// ---------------------------------------------------------------------------\n// PDA Derivation\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// On-chain reader\n// ---------------------------------------------------------------------------\n\n/**\n * Display fields read out of the on-chain Metaplex metadata account, with\n * Metaplex's right-side null padding stripped.\n */\nexport interface OnchainTokenMetadata {\n name: string;\n symbol: string;\n uri: string;\n}\n\nfunction trimMetadataString(s: string): string {\n return s.replace(/\\0/g, \"\").trim();\n}\n\n/**\n * Fetches the Metaplex Token-Metadata account for `mint` and decodes the\n * three display fields. Returns `null` when the metadata account doesn't\n * exist (e.g. token was created without `update_token_metadata` ever firing).\n *\n * Throws on RPC errors so callers can choose between retry and fallback.\n *\n * Token-2022 mints with the metadata extension stored on the mint itself\n * are NOT covered here — every LYC mint goes through Metaplex via\n * `update_token_metadata`, so there's no second source to read.\n */\nexport async function fetchTokenMetadata(\n connection: Connection,\n mint: Address\n): Promise<OnchainTokenMetadata | null> {\n const metadataPda = await deriveMetadataPda(mint);\n const accountInfo = await connection.getAccountInfo(toWeb3Pk(metadataPda));\n if (!accountInfo) return null;\n const [decoded] = Metadata.fromAccountInfo(accountInfo);\n return {\n name: trimMetadataString(decoded.data.name),\n symbol: trimMetadataString(decoded.data.symbol),\n uri: trimMetadataString(decoded.data.uri),\n };\n}\n\n/**\n * Derive the Metaplex metadata PDA for a mint.\n *\n * Seeds: `[\"metadata\", METAPLEX_PROGRAM_ID, mint]`\n */\nexport async function deriveMetadataPda(mint: Address): Promise<Address> {\n const [pda] = await getProgramDerivedAddress({\n programAddress: METAPLEX_TOKEN_METADATA_PROGRAM_ID,\n seeds: [\n Buffer.from(\"metadata\"),\n addressEncoder.encode(METAPLEX_TOKEN_METADATA_PROGRAM_ID),\n addressEncoder.encode(mint),\n ],\n });\n return pda;\n}\n\n// ---------------------------------------------------------------------------\n// CpiData Builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build a `CpiData` for `UpdateMetadataAccountV2` that can be passed\n * into `createCpiRefs()` and then to the `update_token_metadata` instruction.\n *\n * The Token PDA is the update authority and will be PDA-signed on-chain.\n *\n * Metaplex account order:\n * 0. metadata (writable)\n * 1. update_authority (Token PDA — signer set on-chain via invoke_signed)\n *\n * @example\n * ```typescript\n * const cpiData = await buildUpdateMetadataCpiData({\n * mint: yTokenMint,\n * updateAuthority: tokenPda,\n * data: { name: \"ySOL\", symbol: \"ySOL\", uri: \"https://...\" },\n * });\n * const { accounts, refs } = createCpiRefs([cpiData]);\n * ```\n */\nexport async function buildUpdateMetadataCpiData(params: {\n mint: Address;\n updateAuthority: Address;\n data?: UpdateMetadataDataV2;\n newUpdateAuthority?: Address;\n primarySaleHappened?: boolean;\n isMutable?: boolean;\n}): Promise<CpiData> {\n const metadataPda = await deriveMetadataPda(params.mint);\n\n const accounts: CustomAccountMeta[] = [\n { address: metadataPda, role: AccountRole.WRITABLE },\n { address: params.updateAuthority, role: AccountRole.READONLY },\n ];\n\n const data = serializeUpdateMetadataAccountV2(metadataPda, params.updateAuthority, {\n data: params.data,\n newUpdateAuthority: params.newUpdateAuthority,\n primarySaleHappened: params.primarySaleHappened,\n isMutable: params.isMutable,\n });\n\n return {\n cpiType: CpiTypes.MPL_UPDATE_METADATA,\n programId: METAPLEX_TOKEN_METADATA_PROGRAM_ID,\n accounts,\n data,\n };\n}\n\n/**\n * Build a `CpiData` for `CreateMetadataAccountV3` that can be passed\n * into `createCpiRefs()` and then to the `update_token_metadata` instruction.\n *\n * Use this when no Metaplex metadata account exists yet for the mint.\n * The Token PDA is both the mint authority (PDA-signed on-chain) and the\n * update authority. The admin keypair is the payer and must be included in\n * remaining_accounts.\n *\n * Metaplex account order:\n * 0. metadata (writable)\n * 1. mint (writable)\n * 2. mint_authority / Token PDA (PDA-signed on-chain)\n * 3. payer / admin (writable, signer)\n * 4. update_authority / Token PDA (readonly)\n * 5. system_program (readonly)\n * 6. rent sysvar (readonly)\n */\nexport async function buildCreateMetadataCpiData(params: {\n mint: Address;\n mintAuthority: Address;\n payer: Address;\n updateAuthority: Address;\n data: UpdateMetadataDataV2;\n}): Promise<CpiData> {\n const metadataPda = await deriveMetadataPda(params.mint);\n\n const ix = createCreateMetadataAccountV3Instruction(\n {\n metadata: toWeb3Pk(metadataPda),\n mint: toWeb3Pk(params.mint),\n mintAuthority: toWeb3Pk(params.mintAuthority),\n payer: toWeb3Pk(params.payer),\n updateAuthority: toWeb3Pk(params.updateAuthority),\n },\n {\n createMetadataAccountArgsV3: {\n data: {\n name: params.data.name,\n symbol: params.data.symbol,\n uri: params.data.uri,\n sellerFeeBasisPoints: params.data.sellerFeeBasisPoints ?? 0,\n creators: null,\n collection: null,\n uses: null,\n },\n isMutable: true,\n collectionDetails: null,\n },\n }\n );\n\n const accounts: CustomAccountMeta[] = [\n { address: metadataPda, role: AccountRole.WRITABLE },\n { address: params.mint, role: AccountRole.WRITABLE },\n { address: params.mintAuthority, role: AccountRole.READONLY },\n { address: params.payer, role: AccountRole.WRITABLE },\n { address: params.updateAuthority, role: AccountRole.READONLY },\n { address: SYSTEM_PROGRAM_ADDRESS, role: AccountRole.READONLY },\n { address: SYSVAR_RENT_ADDRESS, role: AccountRole.READONLY },\n ];\n\n return {\n cpiType: CpiTypes.MPL_CREATE_METADATA,\n programId: METAPLEX_TOKEN_METADATA_PROGRAM_ID,\n accounts,\n data: new Uint8Array(ix.data),\n };\n}\n","/**\n * Recursively converts `bigint` values to decimal strings so values with\n * on-chain raw amounts are JSON-serializable.\n */\nexport function serializeForJson<T>(value: T): unknown {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n if (value === null || value === undefined) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((item) => serializeForJson(item));\n }\n if (typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [\n key,\n serializeForJson(entry),\n ])\n );\n }\n return value;\n}\n","export * from \"./accounts\";\nexport * from \"./data\";\nexport * from \"./compat\";\nexport * from \"./cpi\";\nexport * from \"./instruction\";\nexport * from \"./numbers\";\nexport * from \"./rpc\";\nexport * from \"./jsonRpcFetch\";\nexport * from \"./asyncConcurrency\";\nexport * from \"./anchor\";\nexport * from \"./solana\";\nexport * from \"./transaction\";\nexport * from \"./transactionSplitter\";\nexport * from \"./txAccountCoverage\";\nexport * from \"./jito\";\nexport * from \"./general\";\nexport * from \"./retry\";\nexport * from \"./token\";\nexport * from \"./timeSeries\";\nexport * from \"./metadata\";\nexport * from \"./json\";\nexport * from \"./priorityFee\";\n","import { AssociatedTokenSeeds } from \"@solana-program/token\";\nimport { AccountRole, Address, Instruction } from \"@solana/kit\";\nimport type { TransactionCacheInvalidation } from \"./general\";\n\nexport type CustomAccountMeta = {\n address: Address;\n role: AccountRole;\n isRequiredAta?: AssociatedTokenSeeds;\n};\n\nexport interface CpiData {\n cpiType: number;\n programId: Address;\n accounts: CustomAccountMeta[];\n /** Instruction data for the given CPI. if not provided, it implies the program should provide it internally. Can pass new UInt8Array() if no data is expected */\n data?: Uint8Array;\n lookupTables?: Address[];\n postSuccessCacheInvalidations?: TransactionCacheInvalidation[];\n /**\n * Top-level instructions that must run before the host transaction's CPI\n * dispatcher (e.g. createATA for intermediate-mint accounts a multi-hop\n * Jupiter route will write into). The host bundler is responsible for\n * placing these before the CPI but after lending-platform pre-instructions.\n */\n preInstructions?: Instruction[];\n}\n","import { Address } from \"@solana/kit\";\nimport type { DataCache } from \"../services/dataCache\";\n\nexport type Environment = \"local\" | \"test\" | \"prod\";\n\n/**\n * Remote deployment tiers only (`test` | `prod`). `local` is dev/Surfpool and is excluded from\n * types that describe on-chain deployed program tiers (e.g. operator keypair paths per cluster).\n */\nexport type DeployedEnv = Exclude<Environment, \"local\">;\n\n/** A mint address or token symbol (case-insensitive) */\nexport type MintIdentifier = string | Address;\n\n/**\n * Cache entries to clear after a successful transaction.\n *\n * Kamino entries target lending SDK caches; `lycToken` / `lycYieldingBank` clear\n * long-yield-carry program DataCache entries; `splAta` clears the SPL ATA existence\n * cache for one address (must match `SPL_ATA_CACHE_CATEGORY` in\n * `services/baseAccountClient.ts`); `perena` clears one entry from a Perena client\n * DataCache after the transaction confirms.\n */\nexport type TransactionCacheInvalidation =\n | {\n client: \"kamino\";\n category: string;\n id: Address;\n }\n | {\n client: \"lycToken\";\n tokenPda: Address;\n }\n | {\n client: \"lycYieldingBank\";\n yieldingBankPda: Address;\n }\n | {\n client: \"splAta\";\n ata: Address;\n }\n | {\n client: \"perena\";\n dataCache: DataCache;\n category: string;\n id: Address;\n };\n","/**\n * Generic CPI-related types for instruction building.\n *\n * Protocol-specific args types belong in their respective packages\n * (e.g., perena-helpers, jupiter-helpers).\n */\n\nimport { CpiMapping } from \"../utils/cpi/refs\";\n\n// ============================================================================\n// CPI References\n// ============================================================================\n\n/**\n * References for CPI invocations.\n *\n * Matches Rust `CpiRefs` struct in common/src/cpi/refs.rs.\n */\nexport interface CpiRefs {\n /** Account indices per CPI (first account of each CPI = program) */\n accounts: CpiMapping;\n /** Index into CPI_REGISTRY for each CPI slot */\n types: Buffer;\n /** Packed CPI args buffer built by CpiArgsBuilder */\n args: Buffer;\n}\n\n/**\n * Top-level references for an instruction.\n *\n * Matches Rust `InstructionRefs` struct in common/src/accounts/refs.rs.\n *\n * @property cpi - CPI refs (accounts, types, args)\n * @property tracked - Indices of accounts to access directly\n */\nexport interface InstructionRefs {\n /** CPI account mapping, type indices, and packed args */\n cpi: CpiRefs;\n /** Indices of accounts to access directly */\n tracked: Buffer;\n}\n","export * from \"./solana\";\nexport * from \"./general\";\nexport * from \"./cpi\";\nexport * from \"./enums\";\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { TransactionPlan } from \"../utils/transaction\";\n\n/**\n * Shared base for SDK instruction/transaction builders.\n *\n * `getIx(args)` is intentionally explicit: callers must provide the fully\n * resolved instruction inputs. Higher-level `getTx()` paths should derive those\n * inputs locally, then call `getIx(args)` without persisting them on the\n * builder instance.\n */\nexport abstract class BaseIXBuilderService<\n TContext,\n TIxArgs,\n TTxArgs = TIxArgs,\n TTxResult = TransactionPlan,\n> {\n constructor(protected readonly context: TContext) {}\n\n abstract getIx(args: TIxArgs): Promise<Instruction>;\n\n abstract getTx(args: TTxArgs): Promise<TTxResult>;\n}\n\n/**\n * Helper for single-instruction builders whose transaction output is a standard\n * `TransactionPlan`.\n */\nexport abstract class SingleInstructionBuilderService<\n TContext,\n TIxArgs,\n TTxArgs = TIxArgs,\n TTxPlan extends TransactionPlan = TransactionPlan,\n> extends BaseIXBuilderService<TContext, TIxArgs, TTxArgs, TTxPlan> {\n protected async deriveIxArgs(txArgs: TTxArgs): Promise<TIxArgs> {\n return txArgs as unknown as TIxArgs;\n }\n\n protected async buildPreambleInstructions(\n _args: TIxArgs,\n _txArgs: TTxArgs\n ): Promise<Instruction[]> {\n return [];\n }\n\n protected async buildLookupTables(\n _args: TIxArgs,\n _txArgs: TTxArgs\n ): Promise<readonly Address[] | undefined> {\n return undefined;\n }\n\n protected async buildPlanExtras(\n _args: TIxArgs,\n _txArgs: TTxArgs\n ): Promise<Omit<TTxPlan, \"instructions\" | \"lookupTables\"> | undefined> {\n return undefined;\n }\n\n async getTx(txArgs: TTxArgs): Promise<TTxPlan> {\n const args = await this.deriveIxArgs(txArgs);\n const preambleInstructions = await this.buildPreambleInstructions(args, txArgs);\n const instruction = await this.getIx(args);\n const lookupTables = await this.buildLookupTables(args, txArgs);\n const extras = await this.buildPlanExtras(args, txArgs);\n\n return {\n instructions: [...preambleInstructions, instruction],\n ...(lookupTables?.length ? { lookupTables: [...lookupTables] } : {}),\n ...(extras ?? {}),\n } as TTxPlan;\n }\n}\n","import type { Address } from \"@solana/kit\";\n\n/**\n * Parameters for requesting a swap quote.\n */\nexport interface SwapQuoteParams {\n /** Input token mint address */\n inputMint: Address;\n /** Output token mint address */\n outputMint: Address;\n /** Amount to swap in smallest units (e.g., lamports, not SOL) */\n amount: number;\n /** Slippage tolerance in basis points (e.g., 500 = 5%) */\n slippageBps?: number;\n /**\n * If true, restrict the quote to direct routes (no intermediate hops).\n * Useful for CPI flows where intermediate-mint ATAs (e.g. WSOL) wouldn't\n * exist for a PDA caller. Backends that don't multi-hop ignore this.\n */\n onlyDirectRoutes?: boolean;\n /**\n * Optional backend-specific route account budget. Jupiter uses this to\n * decide whether larger multi-hop routes are eligible.\n */\n maxAccounts?: number;\n /**\n * DEX labels to exclude from routing, merged with any client-level default\n * exclusions. Backends without venue routing (Perena) ignore this.\n */\n excludeDexes?: string[];\n}\n\n/**\n * Parameters for sizing a swap so realized output is at least a target, without\n * exceeding a maximum input spend (base units). Backends may use oracle math\n * (Perena) or exact-out routing (Jupiter), etc.\n */\nexport interface SwapQuoteCoveringMinOutputParams {\n inputMint: Address;\n outputMint: Address;\n /** Minimum output amount required (smallest units of `outputMint`). */\n minOutputAmount: bigint;\n /** Maximum input amount allowed (smallest units of `inputMint`). */\n maxInputAmount: bigint;\n slippageBps?: number;\n}\n\n/**\n * Normalized swap quote returned by any swap client.\n *\n * @typeParam TRawQuote - Platform-specific quote type (e.g., Jupiter's QuoteResponse)\n */\nexport interface SwapQuote<TRawQuote = unknown> {\n /** Input token mint address */\n inputMint: Address;\n /** Output token mint address */\n outputMint: Address;\n /** Input amount in smallest units */\n inputAmount: bigint;\n /** Expected output amount in smallest units */\n outputAmount: bigint;\n /** Price impact as a percentage (e.g., 0.5 = 0.5%) */\n priceImpactPct: number;\n /** Platform-specific quote data (e.g., Jupiter's QuoteResponse) */\n rawQuote: TRawQuote;\n}\n\n/**\n * Options for building a swap instruction.\n */\nexport interface SwapInstructionOptions {\n /** Whether to automatically wrap/unwrap SOL (default: false for CPI) */\n wrapAndUnwrapSol?: boolean;\n /**\n * Real signer that pays for any pre-instructions the swap client needs\n * (e.g. createATA for intermediate-mint accounts on a multi-hop route).\n * The swap authority (`userPublicKey`) is typically a PDA and cannot pay.\n * When omitted, the swap client skips emitting pre-instructions.\n */\n payer?: Address;\n}\n","import type { Address } from \"@solana/kit\";\nimport type {\n SwapQuoteParams,\n SwapQuote,\n SwapInstructionOptions,\n SwapQuoteCoveringMinOutputParams,\n} from \"./types\";\nimport { CpiData } from \"../../types\";\n\n/**\n * Base interface for swap clients.\n *\n * Implementations of this interface provide a unified API for interacting\n * with different DEX aggregators (Jupiter, Raydium, etc.) for CPI swaps\n * in addition to direct integration with other swap-like programs, like USD* mint/burn.\n *\n * @typeParam TRawQuote - Platform-specific quote type\n *\n * @example\n * ```typescript\n * const client: SwapClient = new JupiterSwapClient(rpc);\n * const quote = await client.getQuote({ inputMint, outputMint, amount });\n * const { data, accounts, programId } = await client.getSwapCpiData(quote, userPda);\n * ```\n */\nexport interface SwapClient<TRawQuote = unknown> {\n /**\n * Get a swap quote for the given parameters.\n *\n * @param params - Quote parameters (mints, amount, slippage)\n * @returns Normalized swap quote with expected output amount\n */\n getQuote(params: SwapQuoteParams): Promise<SwapQuote<TRawQuote>>;\n\n /**\n * Size a swap so expected output is at least {@link SwapQuoteCoveringMinOutputParams.minOutputAmount}\n * while spending no more than {@link SwapQuoteCoveringMinOutputParams.maxInputAmount} input.\n *\n * Implementations use backend-specific mechanics (e.g. Perena oracle linearization,\n * Jupiter `ExactOut` quotes).\n */\n getQuoteCoveringMinOutput(\n params: SwapQuoteCoveringMinOutputParams\n ): Promise<SwapQuote<TRawQuote>>;\n\n /**\n * Build the swap instruction for CPI.\n *\n * @param quote - Quote from getQuote()\n * @param userPublicKey - Address that will execute the swap (can be a PDA)\n * @param options - Optional settings (e.g., wrapAndUnwrapSol)\n * @returns Instruction data and accounts for CPI\n */\n getSwapCpiData(\n quote: SwapQuote<TRawQuote>,\n userPublicKey: Address,\n options?: SwapInstructionOptions\n ): Promise<CpiData>;\n}\n","import type { Address } from \"@solana/kit\";\nimport type { SwapClient } from \"./swapClientBase\";\n\n/**\n * Swap client with explicit routable mint metadata for aggregators.\n *\n * Composite clients (e.g. one that delegates to several backends) typically\n * implement only {@link SwapClient}.\n */\nexport interface RoutableSwapClient<TRawQuote = unknown> extends SwapClient<TRawQuote> {\n /**\n * Mints that may appear on the input side of a supported swap (see\n * {@link swapClientCanRoute}).\n */\n readonly inputMints: readonly Address[];\n /**\n * Mints that may appear on the output side of a supported swap.\n * For symmetric protocols, this is often the same array as `inputMints`.\n */\n readonly outputMints: readonly Address[];\n /**\n * Extra constraint when `inputMints` / `outputMints` alone would admit invalid\n * pairs.\n *\n * A naive rule “`inputMint` ∈ `inputMints` and `outputMint` ∈ `outputMints`”\n * is equivalent to allowing **every** directed edge in the complete bipartite\n * graph between those two name sets. That is wrong for Perena: USDC→USD* and\n * USD*→USDT are supported, so USDC must be allowed as an input and USDT as an\n * output — which would also admit USDC→USDT, which Perena does not support.\n * `routeAnchorMints` (e.g. USD* and USD*-J) requires at least one side of the\n * swap to touch the bank/junior tranche so yielding↔yielding legs are excluded.\n *\n * Empty means no such constraint (and empty `inputMints`/`outputMints` mean\n * wildcard routing for clients like Jupiter).\n */\n readonly routeAnchorMints: readonly Address[];\n}\n","import type { Address } from \"@solana/kit\";\nimport type { RoutableSwapClient } from \"./routableSwapClient\";\n\n/**\n * Whether a routable swap client can quote a swap from `inputMint` to `outputMint`.\n *\n * - **Wildcard** (`inputMints` and `outputMints` both empty): any distinct pair\n * (Jupiter-style fallback).\n * - Otherwise: `inputMint` must be in `inputMints` and `outputMint` in `outputMints`.\n * When `routeAnchorMints` is non-empty, at least one of the two mints must be an\n * anchor — see {@link RoutableSwapClient} (two name sets alone are not enough for\n * protocols like Perena).\n */\nexport function swapClientCanRoute(\n client: RoutableSwapClient,\n inputMint: Address,\n outputMint: Address\n): boolean {\n if (inputMint === outputMint) {\n return false;\n }\n\n if (client.inputMints.length === 0 && client.outputMints.length === 0) {\n return true;\n }\n\n if (!client.inputMints.includes(inputMint) || !client.outputMints.includes(outputMint)) {\n return false;\n }\n\n if (client.routeAnchorMints.length === 0) {\n return true;\n }\n\n return client.routeAnchorMints.some((m) => m === inputMint || m === outputMint);\n}\n","export * from \"./types\";\nexport * from \"./swapClientBase\";\nexport * from \"./routableSwapClient\";\nexport * from \"./swapRouting\";\n","import type { Address } from \"@solana/kit\";\n\n/**\n * Dynamic protocol information for a token asset.\n *\n * This info is fetched from the protocol and may change over time\n * based on governance, utilization, or other factors.\n */\nexport interface TokenProtocolInfo {\n /** The source mint this info applies to */\n sourceMint: Address;\n /** Minting/deposit fee in basis points */\n mintFeeBps: number;\n /** Redemption/burn fee in basis points */\n redemptionFeeBps: number;\n /** Maximum deposit amount (undefined = no limit) */\n depositLimit?: bigint;\n /** Maximum redemption amount (undefined = no limit) */\n redemptionLimit?: bigint;\n}\n","import type { Address } from \"@solana/kit\";\nimport type { TokenProtocolInfo } from \"./types\";\n\n/**\n * Interface for token protocol clients.\n *\n * This interface provides information about protocol capabilities,\n * supported mints, fees, and limits. It's separate from SwapClient\n * to maintain single responsibility - SwapClient handles quotes and\n * instructions, TokenProtocolClient handles protocol info.\n *\n * Clients like PerenaClient can implement both interfaces.\n *\n * @example\n * ```typescript\n * // Check if direct minting is possible\n * const supported = await client.getSupportedSourceMints();\n * if (supported.includes(inputMint)) {\n * // Direct mint via token protocol\n * const quote = await client.getQuote({ inputMint, outputMint, amount });\n * } else {\n * // Need to swap to a supported mint first\n * const swapQuote = await jupiterClient.getQuote({ inputMint, outputMint: supported[0], amount });\n * }\n *\n * // Get protocol info for fee/limit checks\n * const info = await client.getProtocolInfo(sourceMint);\n * console.log(`Mint fee: ${info.mintFeeBps} bps`);\n * ```\n */\nexport interface TokenProtocolClient {\n /**\n * Get mints that can directly convert to the output mint.\n *\n * These are the \"preferred\" mints that don't require a swap first.\n * For USD*, this might be [USDC]. For ONyc, this might be [USDC, USDG].\n *\n * @returns Array of mint addresses that can directly mint the output\n */\n getSupportedSourceMints(): Promise<Address[]>;\n\n /**\n * Get current protocol info for a source mint.\n *\n * Returns dynamic information including fees and limits.\n * This data is fetched from the protocol and may change over time.\n *\n * @param sourceMint - The source mint to get info for\n * @returns Protocol info including fees and limits\n * @throws Error if sourceMint is not supported\n */\n getProtocolInfo(sourceMint: Address): Promise<TokenProtocolInfo>;\n}\n","export * from \"./types\";\nexport * from \"./tokenProtocolClientBase\";\n","import type { Rpc, SolanaRpcApi, TransactionSigner, Instruction, Signature } from \"@solana/kit\";\nimport {\n signSendAndConfirmTransaction,\n type SendTransactionOptionsWithPostSuccess,\n type TransactionPlan,\n} from \"../utils/transaction\";\n\n/**\n * Reusable transaction sender that wraps `signSendAndConfirmTransaction`.\n *\n * Oversized transactions are split and submitted as an atomic Jito bundle\n * (via the user's RPC when it proxies `sendBundle`) when `jitoTipLamports > 0`.\n * For Surfpool / local validators, pass `sendOversizedAsSequentialTransactions`\n * to send each split as a normal transaction instead (not atomic).\n *\n * Designed to be extended with:\n * - Retry logic with configurable backoff\n * - Priority fee estimation\n * - Transaction batching\n *\n * Any consumer (backend services, CLI tools, scripts) can instantiate this\n * directly — it has no framework dependency (no NestJS, no decorators).\n */\nexport class TransactionSender {\n constructor(\n private readonly rpc: Rpc<SolanaRpcApi>,\n private readonly signer: TransactionSigner\n ) {}\n\n async send(\n instructionsOrPlan: Instruction[] | TransactionPlan,\n options?: SendTransactionOptionsWithPostSuccess\n ): Promise<Signature> {\n return signSendAndConfirmTransaction(this.rpc, this.signer, instructionsOrPlan, options);\n }\n}\n","export * from \"./baseAccountClient\";\nexport * from \"./baseIxBuilderService\";\nexport * from \"./dataCache\";\nexport * from \"./lutManager\";\nexport * from \"./mints\";\nexport * from \"./swap\";\nexport * from \"./token\";\nexport * from \"./transactionSender\";\n","export * from \"./utils\";\nexport * from \"./types\";\nexport * from \"./constants\";\nexport * from \"./services\";\n","import { address, Address } from \"@solana/kit\";\nimport { MintIdentifier } from \"common\";\n\nexport interface PythFeed {\n account: Address;\n feedId: string;\n}\n\n// https://docs.pyth.network/price-feeds/core/push-feeds/solana\nexport const PYTH_FEEDS: Record<MintIdentifier, PythFeed> = {\n // Standard assets\n SOL: {\n account: address(\"7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE\"),\n feedId: \"ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d\",\n },\n WETH: {\n account: address(\"42amVS4KgzR9rA28tkVYqVXjq9Qa8dcZQMbH5EYFX6XC\"),\n feedId: \"ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace\",\n },\n WBTC: {\n account: address(\"9gNX5vguzarZZPjTnE1hWze3s6UsZ7dsU3UnAmKPnMHG\"),\n feedId: \"c9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33\",\n },\n CBBTC: {\n account: address(\"4cSM2e6rvbGQUFiJbqytoVMi5GgghSMr8LwVrT9VPSPo\"),\n feedId: \"e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43\",\n },\n JLP: {\n account: address(\"2TTGSRSezqFzeLUH8JwRUbtN66XLLaymfYsWRTMjfiMw\"),\n feedId: \"c811abc82b4bad1f9bd711a2773ccaa935b03ecef974236942cec5e0eb845a3a\",\n },\n SPYx: {\n account: address(\"9owhtgrdLiUMAH9JKxYFt5pUY4Luy4EzzLhdcWPVuDyy\"),\n feedId: \"19e09bb805456ada3979a7d1cbb4b6d63babc3a0f8e8a9509f68afa5c4c11cd5\",\n },\n QQQx: {\n account: address(\"EwssJrQ7UVz6itHEaQQsKWikhZ3iHddyxRhmR7pTvwt5\"),\n feedId: \"9695e2b96ea7b3859da9ed25b7a46a920a776e2fdae19a7bcfdf2b219230452d\",\n },\n // LSTs\n JupSOL: {\n account: address(\"D7UqeBmCEmhGXGYfi2y9RfoCa7t1Xw5iZLBeYZ3sxFSe\"),\n feedId: \"f8d8d6b6c866c8b2624fb5b679ae846738725e5fc887fa8e927c8d8645018a2b\",\n },\n // Stablecoins\n USDC: {\n account: address(\"Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX\"),\n feedId: \"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a\",\n },\n USDT: {\n account: address(\"HT2PLQBcG5EiCcNSaMHAjSgd9F98ecpATbk4Sk5oYuM\"),\n feedId: \"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b\",\n },\n CASH: {\n account: address(\"F23Xi7VQw1pdre26VmuKnjRcDcrhpqGtHkGdKdSdbM8w\"),\n feedId: \"df3320ef0f4617337b8dbb924f2aaa4f9db08f522a5435b44f9066c1ac4c7f95\",\n },\n PYUSD: {\n account: address(\"9zXQxpYH3kYhtoybmZfUNNCRVuud7fY9jswTg1hLyT8k\"),\n feedId: \"0xc1da1b73d7f01e7ddd54b3766cf7fcd644395ad14f70aa706ec5384c59e76692\",\n },\n USDG: {\n account: address(\"6JkZmXGgWnzsyTQaqRARzP64iFYnpMNT4siiuUDUaB8s\"),\n feedId: \"0xdaa58c6a3ce7d4b9c46c32a6e646012c17c4a2b24c08dd8c5e476118b855a7da\",\n },\n USDS: {\n account: address(\"DyYBBWEi9xZvgNAeMDCiFnmC1U9gqgVsJDXkL5WETpoX\"),\n feedId: \"0x77f0971af11cc8bac224917275c1bf55f2319ed5c654a1ca955c82fa2d297ea1\",\n },\n // Yield bearing assets\n PST: {\n account: address(\"CBGwQddTeYn3KdvxGWtU95fqCcavzHK9XPFBLENDF5JR\"),\n feedId: \"675e36f84a6be779ed793c71eb5c03151e1866c125767f46933626e0610af84d\",\n },\n};\n","import { MintIdentifier } from \"common\";\n\ninterface SwitchboardFeed {\n feedId: string;\n feedHash: string;\n}\n\n// https://beta.ondemand.switchboard.xyz/solana/mainnet\nexport const SWITCHBOARD_PRICE_FEED_IDS: Record<MintIdentifier, SwitchboardFeed> = {\n SOL: {\n feedId: \"4Hmd6PdjVA9auCoScE12iaBogfwS4ZXQ6VZoBeqanwWW\",\n feedHash: \"0x1f42dfb21efb24828b99fbe70e6d139cd665aafcbb1706bccd8f2a9b12562db6\",\n },\n};\n","import { DataCache, MintIdentifier, PRICE_STALENESS_SECONDS } from \"common\";\nimport { PriceResult } from \"../types\";\n\n/** Optional per-fetch context passed through {@link PriceBase.fetchPrices}. */\nexport interface PriceFetchContext {\n /** RPC URL for feeds that need on-chain reads (e.g. custom SPL-stake oracles). */\n rpcUrl?: string;\n}\n\nexport abstract class PriceBase {\n dataCache!: DataCache;\n\n constructor() {\n this.dataCache = new DataCache({\n defaultTtlMs: PRICE_STALENESS_SECONDS * 1000,\n });\n }\n\n protected abstract internalFetchPrices(\n mints: MintIdentifier[],\n context?: PriceFetchContext\n ): Promise<Record<MintIdentifier, PriceResult>>;\n\n public async fetchPrices(\n mints: MintIdentifier[],\n bypassCache?: boolean,\n context?: PriceFetchContext\n ): Promise<Record<MintIdentifier, PriceResult>> {\n if (!mints.length) {\n return {};\n }\n\n if (bypassCache) {\n return await this.internalFetchPrices(mints, context);\n }\n\n const { data } = await this.dataCache.getDataBatch<PriceResult>(\n async () => {\n const prices = await this.internalFetchPrices(mints, context);\n return mints.map((mint) => prices[mint] ?? null);\n },\n \"prices\",\n mints\n );\n return Object.fromEntries(mints.map((mint, i) => [mint, data[i] ?? 0]));\n }\n}\n","import { Address } from \"@solana/kit\";\nimport { getBatches } from \"common\";\nimport { retry } from \"ts-retry\";\nimport { PriceBase, type PriceFetchContext } from \"./priceBase\";\nimport { PriceResult } from \"../types\";\n\nexport class JupiterPrices extends PriceBase {\n private async getJupPriceData(mints: Address[]) {\n const batches = getBatches(mints, 50);\n\n const results = await Promise.all(\n batches.map((batch) =>\n retry(\n async () => {\n const res = await (\n await fetch(\n \"https://lite-api.jup.ag/price/v3?ids=\" + batch.map((x) => x.toString()).join(\",\")\n )\n ).json();\n\n if (!res || typeof res !== \"object\") {\n throw new Error(\"Failed to get mint prices using Jupiter\");\n }\n\n return res;\n },\n { maxTry: 6, delay: 250 }\n )\n )\n );\n\n return Object.assign({}, ...results);\n }\n\n async internalFetchPrices(\n mints: Address[],\n _context?: PriceFetchContext\n ): Promise<Record<Address, PriceResult>> {\n if (mints.length == 0) {\n return {};\n }\n\n const priceData = await this.getJupPriceData(mints);\n const sortedPrices: { [key: string]: any } = {};\n\n for (const mint of mints) {\n const key = mint.toString();\n if (priceData.hasOwnProperty(key)) {\n sortedPrices[key] = priceData[key];\n }\n }\n\n const prices: Record<string, PriceResult> = Object.fromEntries(\n mints.map((mint) => [\n mint,\n sortedPrices !== null &&\n typeof sortedPrices === \"object\" &&\n typeof sortedPrices[mint.toString()] === \"object\" &&\n \"usdPrice\" in sortedPrices[mint.toString()]\n ? { realtimePrice: parseFloat(sortedPrices[mint.toString()].usdPrice as string) }\n : { realtimePrice: 0 },\n ])\n );\n\n return prices;\n }\n}\n","import { address } from \"@solana/kit\";\n\n/** SPL stake pool account for dfdvSOL (DeFi Development Corp LST). */\nexport const DFDVSOL_STAKE_POOL = address(\"pyZMBjpWsVjKANAYK5mpNbKiws2krjRPZ2N2UYCSnbP\");\n","export * from \"./pyth\";\nexport * from \"./splStake\";\nexport * from \"./switchboard\";\n","import { address, type Address } from \"@solana/kit\";\n\n/**\n * Perena Bankineco Program ID (prod)\n */\nexport const PERENA_PROGRAM_ID: Address = address(\"save8RQVPMWNTzU18t3GBvBkN9hT7jsGjiCQ28FpD9H\");\n","import { BN } from \"@anchor-lang/core\";\n\n/**\n * Inner arguments for Perena mint CPI.\n *\n * Matches Rust `PerenaMintArgs` in perena_helpers/src/cpi/mint.rs.\n * Borsh size: 16 bytes (2 × u64 LE).\n */\nexport interface PerenaMintArgs {\n /** Amount of yielding tokens to deposit (e.g., USDC amount) */\n amountYieldingDeposit: bigint | BN | number;\n /** Minimum USD* to receive (slippage protection) */\n minBankMintMinted: bigint | BN | number;\n}\n\n/**\n * Get raw borsh bytes for Perena mint CPI args.\n *\n * Returns a 16-byte `Uint8Array` (2 × u64 LE) — no length prefix.\n * Pass the result to `CpiArgsBuilder.add()` or `serializeArgs()`.\n *\n * @example\n * ```typescript\n * const cpiArgs = new CpiArgsBuilder()\n * .add(getPerenaMintArgs({ amountYieldingDeposit: 1_000_000, minBankMintMinted: 900_000 }))\n * .build();\n * ```\n */\nexport function getPerenaMintArgs(data: PerenaMintArgs): Uint8Array {\n const buf = Buffer.alloc(16);\n buf.writeBigUInt64LE(BigInt(data.amountYieldingDeposit.toString()), 0);\n buf.writeBigUInt64LE(BigInt(data.minBankMintMinted.toString()), 8);\n return buf;\n}\n","import { BN } from \"@anchor-lang/core\";\n\n/**\n * Inner arguments for Perena burn CPI.\n *\n * Matches Rust `PerenaBurnArgs` in perena_helpers/src/cpi/burn.rs.\n * Borsh size: 16 bytes (2 × u64 LE).\n */\nexport interface PerenaBurnArgs {\n /** Amount of USD* to burn */\n amountToBurn: bigint | BN | number;\n /** Minimum yielding tokens to receive (slippage protection) */\n minimumYieldingWithdrawn: bigint | BN | number;\n}\n\n/**\n * Get raw borsh bytes for Perena burn CPI args.\n *\n * Returns a 16-byte `Uint8Array` (2 × u64 LE) — no length prefix.\n * Pass the result to `CpiArgsBuilder.add()` or `serializeArgs()`.\n *\n * @example\n * ```typescript\n * const cpiArgs = new CpiArgsBuilder()\n * .add(getPerenaBurnArgs({ amountToBurn: 1_000_000, minimumYieldingWithdrawn: 900_000 }))\n * .build();\n * ```\n */\nexport function getPerenaBurnArgs(data: PerenaBurnArgs): Uint8Array {\n const buf = Buffer.alloc(16);\n buf.writeBigUInt64LE(BigInt(data.amountToBurn.toString()), 0);\n buf.writeBigUInt64LE(BigInt(data.minimumYieldingWithdrawn.toString()), 8);\n return buf;\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { numToU64Bytes } from \"common\";\n\n/**\n * Inner arguments for Perena request_unstake_junior CPI.\n *\n * Matches the Anchor `request_unstake_junior` instruction args.\n * Borsh size: 9 bytes (1 × u64 LE + 1 × u8).\n */\nexport interface PerenaRequestUnstakeArgs {\n /** Number of junior shares to lock in the withdrawal queue */\n shares: BN | number;\n /** Queue slot id (0–255) — unique per user per bank */\n queueId: number;\n}\n\n/**\n * Get raw borsh bytes for Perena request_unstake_junior CPI args.\n *\n * Returns a 9-byte `Uint8Array` (u64 LE + u8) — no length prefix.\n */\nexport function getPerenaRequestUnstakeArgs(data: PerenaRequestUnstakeArgs): Uint8Array {\n const sharesBytes = numToU64Bytes(data.shares);\n const buf = Buffer.alloc(9);\n Buffer.from(sharesBytes).copy(buf, 0);\n buf.writeUInt8(data.queueId, 8);\n return buf;\n}\n","export * from \"./mint\";\nexport * from \"./burn\";\nexport * from \"./requestUnstake\";\n","import { BN } from \"@anchor-lang/core\";\nimport type { Address } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport {\n UsdStarClient,\n BankinecoAction,\n type YieldingToBankMintQuoteRes,\n type BankMintToYieldingQuoteRes,\n type FetchUnstakeFeeRes,\n type TrancheCpiAccounts,\n type WithdrawalQueueEntry,\n} from \"@perena/bankineco-sdk\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { SYSTEM_PROGRAM_ADDRESS } from \"@solana-program/system\";\nimport { PERENA_PROGRAM_ID } from \"./constants\";\nimport {\n RoutableSwapClient,\n SwapQuoteParams,\n SwapQuote,\n SwapQuoteCoveringMinOutputParams,\n SwapInstructionOptions,\n CpiTypes,\n mints,\n toCustomAccountMeta,\n DataCache,\n type TransactionCacheInvalidation,\n type TokenProtocolClient,\n type TokenProtocolInfo,\n toCustomAccountMetaFromWeb3AccountMeta,\n CpiData,\n CustomAccountMeta,\n fromWeb3Pk,\n getAtaAddress,\n numToU64Bytes,\n} from \"common\";\nimport { getPerenaBurnArgs, getPerenaMintArgs, getPerenaRequestUnstakeArgs } from \"./cpi\";\n\nconst ACTIVE_WITHDRAWAL_QUEUES_CACHE_CATEGORY = \"activeWithdrawalQueues\";\n/**\n * Raw quote data from Perena SDK.\n *\n * Discriminated by `operation`:\n * - `mint`: yielding → USD* (e.g. USDC → USD*)\n * - `burn`: USD* → yielding (e.g. USD* → USDC)\n * - `stake`: USD* → USD*-J\n * - `unstake`: USD*-J → USD* or yielding (instant, single-tx)\n * - `request_unstake`: USD*-J → withdrawal queue (lockup period)\n * - `fulfill_unstake`: withdrawal queue → USD* or yielding (after lockup)\n */\nexport type PerenaRawQuote =\n | { operation: \"mint\"; yieldingMint: Address; sdkQuote: YieldingToBankMintQuoteRes }\n | { operation: \"burn\"; yieldingMint: Address; sdkQuote: BankMintToYieldingQuoteRes }\n | { operation: \"stake\" }\n | { operation: \"unstake\"; targetMint?: Address; unstakeFee: FetchUnstakeFeeRes }\n | {\n operation: \"request_unstake\";\n targetMint?: Address;\n unstakeFee: FetchUnstakeFeeRes;\n queueId: number;\n payer: Address;\n }\n | {\n operation: \"fulfill_unstake\";\n withdrawalQueue: Address;\n queuePayer: Address;\n owner: Address;\n targetMint?: Address;\n };\n\n/** Perena-specific swap quote with typed rawQuote */\nexport type PerenaSwapQuote = SwapQuote<PerenaRawQuote>;\n\n/** Parameters for building a request_unstake_junior CPI. */\nexport interface RequestUnstakeParams {\n /** Number of junior shares to lock */\n shares: BN | number;\n /** Queue slot id (0–255), unique per user per bank */\n queueId: number;\n /** Address that acts as the user/signer for the unstake */\n userPublicKey: Address;\n /** Address that pays rent for the withdrawal queue PDA (often same as user) */\n payer: Address;\n /** Optional yielding mint to receive upon fulfillment. Defaults to USD*. */\n targetMint?: Address;\n}\n\n/** Parameters for building a fulfill_unstake_junior CPI. */\nexport interface FulfillUnstakeParams {\n /** Address of the withdrawal queue PDA */\n withdrawalQueue: Address;\n /** The signer executing the fulfillment (queue owner or fulfiller) */\n signer: Address;\n /** The original payer who funded the queue rent (receives refund) */\n queuePayer: Address;\n /** The queue owner (needed to derive owner_bank_mint_ata) */\n owner: Address;\n /** Optional yielding mint — if the queue's target_mint is a yielding mint */\n targetMint?: Address;\n}\n\n/**\n * Perena USD* client implementing RoutableSwapClient and TokenProtocolClient.\n *\n * Provides a unified API for:\n * - Minting and burning USD*\n * - Querying protocol capabilities and info (YieldProtocolClient interface)\n *\n * @example\n * ```typescript\n * import { PerenaClient } from \"perena-helpers\";\n * import { defaultMints } from \"common/services/mints\";\n *\n * const client = new PerenaClient(rpcUrl);\n * const usdc = defaultMints.get(\"USDC\")!;\n * const usdStar = defaultMints.get(\"USD*\")!;\n *\n * // Mint: USDC → USD*\n * const mintQuote = await client.getQuote({\n * inputMint: usdc.address,\n * outputMint: usdStar.address,\n * amount: 10_000_000, // 10 USDC\n * slippageBps: 100,\n * });\n *\n * // Burn: USD* → USDC\n * const burnQuote = await client.getQuote({\n * inputMint: usdStar.address,\n * outputMint: usdc.address,\n * amount: 10_000_000, // 10 USD*\n * slippageBps: 100,\n * });\n *\n * // Get CPI accounts for instruction\n * const { accounts, programId } = await client.getSwapCpiData(\n * mintQuote,\n * userPda\n * );\n * ```\n */\nexport class PerenaClient implements RoutableSwapClient<PerenaRawQuote>, TokenProtocolClient {\n readonly sdkClient: UsdStarClient;\n private readonly cache: DataCache;\n\n /**\n * The bank mint (USD*).\n */\n public readonly bankMint: Address;\n\n /**\n * The junior tranche token (USD*-J).\n */\n public readonly juniorMint: Address;\n\n /**\n * Mints that can appear on either side of a Perena-routed swap (USD*, USD*-J,\n * and idle vault yielding mints). Same reference as {@link outputMints}.\n */\n public readonly inputMints: readonly Address[];\n\n /**\n * Same as {@link inputMints} — Perena routes are symmetric in terms of\n * allowed mints; {@link routeAnchorMints} encodes the “must touch USD* or USD*-J” rule.\n */\n public readonly outputMints: readonly Address[];\n\n /**\n * A valid route must involve at least one of USD* or USD*-J (prevents e.g. USDC↔USDT).\n */\n public readonly routeAnchorMints: readonly Address[];\n\n /**\n * Creates a new Perena client.\n *\n * @param rpcUrl - Solana RPC URL\n */\n constructor(rpcUrl: string) {\n this.sdkClient = UsdStarClient.new({\n env: \"prod\",\n rpcUrl,\n });\n this.cache = new DataCache({\n defaultTtlMs: 60_000 * 5, // 5 minute default\n });\n\n const usdStar = mints.get(\"USD*\");\n if (!usdStar) {\n throw new Error(\"USD* mint not found in registry\");\n }\n this.bankMint = usdStar.address;\n\n const usdStarJ = mints.get(\"USD*-J\");\n if (!usdStarJ) {\n throw new Error(\"USD*-J mint not found in registry\");\n }\n this.juniorMint = usdStarJ.address;\n\n const yieldingMints = Object.keys(this.sdkClient.idleVaultIndices) as Address[];\n const routable = Object.freeze<Address[]>([this.bankMint, this.juniorMint, ...yieldingMints]);\n this.inputMints = routable;\n this.outputMints = routable;\n this.routeAnchorMints = Object.freeze([this.bankMint, this.juniorMint]);\n }\n\n /**\n * Get mints that can directly mint USD*.\n */\n async getSupportedSourceMints(): Promise<Address[]> {\n return Object.keys(this.sdkClient.idleVaultIndices).map((key) => key as Address);\n }\n\n /**\n * Get current protocol info for a source mint.\n * @param sourceMint - The source mint to get info for (i.e. USDC, USDT, etc.)\n * @returns Protocol info including fees and limits\n * @throws Error if sourceMint is not supported by Perena\n */\n async getProtocolInfo(sourceMint: Address): Promise<TokenProtocolInfo> {\n const supportedSourceMints = await this.getSupportedSourceMints();\n if (!supportedSourceMints.includes(sourceMint)) {\n throw new Error(`Source mint ${sourceMint} is not supported by Perena`);\n }\n\n const { data } = await this.cache.getDataOrThrow<TokenProtocolInfo>(\n async () => {\n const vault = this.sdkClient.getVault(new PublicKey(sourceMint));\n const vaultInfo = await this.sdkClient.bankineco.pg.account.vaultGenState.fetch(vault);\n return {\n sourceMint,\n mintFeeBps: vaultInfo.config.mintingFeeBps,\n redemptionFeeBps: vaultInfo.config.burningFeeBps,\n depositLimit: BigInt(0),\n redemptionLimit: BigInt(vaultInfo.accounting.yieldingReserveAmount.toString()),\n };\n },\n \"yieldProtocolInfo\",\n sourceMint\n );\n\n return data;\n }\n\n /**\n * Get the latest USD* price in UI units (e.g. dollars).\n *\n * @returns The current bank mint price as a number\n */\n async getLatestBankMintUiPrice(): Promise<number> {\n const { data } = await this.cache.getDataOrThrow<number>(\n () => this.sdkClient.latestBankMintUiPrice(),\n \"bankMintUiPrice\",\n \"latest\"\n );\n\n return data;\n }\n\n /**\n * Get the latest USD*-J price in UI units (e.g. dollars).\n *\n * @returns The current junior mint price as a number\n */\n async getLatestJuniorMintUiPrice(): Promise<number> {\n const { data } = await this.cache.getDataOrThrow<number>(\n () => this.sdkClient.latestJuniorMintUiPrice(),\n \"juniorMintUiPrice\",\n \"latest\"\n );\n\n return data;\n }\n\n /**\n * Size a USD* burn so the routed yielding output (e.g. USDC) is at least\n * `minYieldingOut` base units, without scanning inputs.\n *\n * Perena's `bankMintToYieldingQuote` is linear in the burn amount for fixed\n * oracles: bank-mint price, yielding price, burn fee bps, and decimal\n * rescales are all proportional in `amountToBurn`. We take **one** reference\n * quote at exactly 1.0 bank-mint token (10^decimals base units) to read the\n * effective `yieldingOut / bankMintIn` rate implied by the current prices,\n * then `ceil(need * refIn / refOut)` and re-quote once at that input so the\n * returned {@link PerenaSwapQuote} matches the CPI.\n */\n /**\n * @deprecated Prefer {@link getQuoteCoveringMinOutput} — same behavior with generic param names.\n */\n async getQuoteCoveringYieldingOut(params: {\n inputMint: Address;\n outputMint: Address;\n minYieldingOut: bigint;\n maxBankMintIn: bigint;\n slippageBps?: number;\n }): Promise<PerenaSwapQuote> {\n return this.getQuoteCoveringMinOutput({\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n minOutputAmount: params.minYieldingOut,\n maxInputAmount: params.maxBankMintIn,\n slippageBps: params.slippageBps,\n });\n }\n\n async getQuoteCoveringMinOutput(\n params: SwapQuoteCoveringMinOutputParams\n ): Promise<PerenaSwapQuote> {\n if (params.inputMint !== this.bankMint) {\n throw new Error(\"getQuoteCoveringMinOutput only supports burning USD* into a yielding mint\");\n }\n const need = params.minOutputAmount;\n if (need <= BigInt(0)) {\n throw new Error(\"getQuoteCoveringMinOutput: minOutputAmount must be positive\");\n }\n const maxIn = params.maxInputAmount;\n if (maxIn <= BigInt(0)) {\n throw new Error(\"getQuoteCoveringMinOutput: maxInputAmount must be positive\");\n }\n\n const vault = this.sdkClient.getVault(new PublicKey(params.outputMint));\n const refInBn = mints.get(\"USD*\")!.fromUiAmount(1);\n const oneBankMint = BigInt(refInBn.toString());\n const refSdk = await this.sdkClient.bankMintToYieldingQuote(refInBn, vault);\n const refOut = BigInt(refSdk.amount.toString());\n if (refOut === BigInt(0)) {\n throw new Error(\"Perena reference burn quote returned zero yielding output\");\n }\n\n const maxSdk = await this.sdkClient.bankMintToYieldingQuote(new BN(maxIn.toString()), vault);\n if (BigInt(maxSdk.amount.toString()) < need) {\n throw new Error(\n \"Perena: bank mint holding cannot cover the yielding output required for this unwind\"\n );\n }\n\n /** `ceil(targetOut * oneBankMint / refOut)` — inverting the reference rate from oracle pricing. */\n const scaleInput = (targetOut: bigint): bigint => {\n const numer = targetOut * oneBankMint + refOut - BigInt(1);\n return numer / refOut;\n };\n\n let inputRaw = scaleInput(need);\n if (inputRaw > maxIn) {\n inputRaw = maxIn;\n }\n if (inputRaw < BigInt(1)) {\n inputRaw = BigInt(1);\n }\n\n const slippageBps = params.slippageBps ?? 100;\n const quoteAt = async (inAmt: bigint): Promise<PerenaSwapQuote> => {\n if (inAmt > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"getQuoteCoveringMinOutput: burn input exceeds Number.MAX_SAFE_INTEGER\");\n }\n return this.getQuote({\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n amount: Number(inAmt),\n slippageBps,\n });\n };\n\n let quote = await quoteAt(inputRaw);\n let out = BigInt(quote.outputAmount.toString());\n if (out < need && inputRaw < maxIn) {\n inputRaw = (need * inputRaw + out - BigInt(1)) / out;\n if (inputRaw > maxIn) {\n inputRaw = maxIn;\n }\n quote = await quoteAt(inputRaw);\n out = BigInt(quote.outputAmount.toString());\n }\n\n // Integer rounding inside the Perena SDK can leave the output 1 base unit\n // short even after proportional re-scaling. Bump the input by 1 and\n // re-quote once more before giving up.\n if (out < need && inputRaw < maxIn) {\n inputRaw += BigInt(1);\n if (inputRaw > maxIn) {\n inputRaw = maxIn;\n }\n quote = await quoteAt(inputRaw);\n out = BigInt(quote.outputAmount.toString());\n }\n\n if (out < need) {\n throw new Error(\n \"Perena: sized burn quote still below required yielding output (rounding); try larger holding or refresh oracles\"\n );\n }\n\n return quote;\n }\n\n /**\n * Get a quote for minting/burning USD* or staking/unstaking USD*-J.\n *\n * The operation is determined by the mints:\n * - outputMint is USD*: mint (yielding → USD*)\n * - inputMint is USD*: burn (USD* → yielding)\n * - outputMint is USD*-J: stake (USD* → USD*-J)\n * - inputMint is USD*-J: unstake (USD*-J → USD* or yielding)\n *\n * @param params - Quote parameters\n * @returns Normalized swap quote\n * @throws Error if the mint pair is not supported\n */\n async getQuote(params: SwapQuoteParams): Promise<PerenaSwapQuote> {\n const isJuniorInput = params.inputMint === this.juniorMint;\n const isJuniorOutput = params.outputMint === this.juniorMint;\n\n if (isJuniorOutput) {\n if (params.inputMint !== this.bankMint) {\n throw new Error(\"Invalid Perena quote: can only stake USD* into USD*-J\");\n }\n return this.getStakeQuote(params);\n }\n\n if (isJuniorInput) {\n return this.getUnstakeQuote(params);\n }\n\n const isMint = params.outputMint === this.bankMint;\n const isBurn = params.inputMint === this.bankMint;\n\n if (!isMint && !isBurn) {\n throw new Error(\n \"Invalid Perena quote: either inputMint or outputMint must be USD* or USD*-J\"\n );\n }\n\n if (isMint && isBurn) {\n throw new Error(\"Invalid Perena quote: cannot swap USD* to USD*\");\n }\n\n const yieldingMint = isMint ? params.inputMint : params.outputMint;\n const yieldingMintPubkey = new PublicKey(yieldingMint);\n const vault = this.sdkClient.getVault(yieldingMintPubkey);\n const amount = new BN(params.amount);\n\n const vaultInfo = await this.sdkClient.bankineco.pg.account.vaultGenState.fetch(vault);\n const feeBps = isMint ? vaultInfo.config.mintingFeeBps : vaultInfo.config.burningFeeBps;\n const priceImpactPct = feeBps / 100;\n\n if (isMint) {\n const sdkQuote = await this.sdkClient.yieldingToBankMintQuote(amount, vault);\n\n return {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n inputAmount: BigInt(params.amount),\n outputAmount: BigInt(sdkQuote.amount.toString()),\n priceImpactPct,\n rawQuote: { operation: \"mint\", yieldingMint, sdkQuote },\n };\n } else {\n const sdkQuote = await this.sdkClient.bankMintToYieldingQuote(amount, vault);\n\n return {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n inputAmount: BigInt(params.amount),\n outputAmount: BigInt(sdkQuote.amount.toString()),\n priceImpactPct,\n rawQuote: { operation: \"burn\", yieldingMint, sdkQuote },\n };\n }\n }\n\n /**\n * Quote for staking USD* → USD*-J.\n *\n * Shares minted = amount × bankMintPrice / sharePrice.\n * Staking has no fee; the on-chain conversion is deterministic.\n */\n private async getStakeQuote(params: SwapQuoteParams): Promise<PerenaSwapQuote> {\n const trancheState = await this.sdkClient.fetchTrancheState(true);\n const bankState = await this.sdkClient.bankineco.pg.account.bankState.fetch(\n this.sdkClient.bank\n );\n\n const amount = new BN(params.amount);\n const sharesOut = amount.mul(bankState.mint.price).div(trancheState.accounting.sharePrice);\n\n return {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n inputAmount: BigInt(params.amount),\n outputAmount: BigInt(sharesOut.toString()),\n priceImpactPct: 0,\n rawQuote: { operation: \"stake\" },\n };\n }\n\n /**\n * Quote for unstaking USD*-J → USD* or yielding mint.\n *\n * Uses `fetchUnstakeFee` with `early: true` because instant unstake\n * always applies the early fee.\n */\n private async getUnstakeQuote(params: SwapQuoteParams): Promise<PerenaSwapQuote> {\n const isToYielding = params.outputMint !== this.bankMint;\n const targetMintPk = isToYielding ? new PublicKey(params.outputMint) : undefined;\n\n const unstakeFee = await this.sdkClient.fetchUnstakeFee({\n amount: new BN(params.amount),\n early: true,\n targetMint: targetMintPk,\n });\n\n const totalFee = unstakeFee.feeAmount.add(unstakeFee.burningFeeAmount);\n const grossOutput = unstakeFee.amountAfterFee.add(totalFee);\n const feePct = grossOutput.isZero() ? 0 : (totalFee.toNumber() / grossOutput.toNumber()) * 100;\n\n return {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n inputAmount: BigInt(params.amount),\n outputAmount: BigInt(unstakeFee.amountAfterFee.toString()),\n priceImpactPct: feePct,\n rawQuote: {\n operation: \"unstake\",\n targetMint: isToYielding ? params.outputMint : undefined,\n unstakeFee,\n },\n };\n }\n\n /**\n * Get CPI accounts for a Perena instruction.\n *\n * Account order matches the IDL for the respective instruction.\n *\n * @param quote - Quote from getQuote()\n * @param userPublicKey - Address that will execute the swap (can be a PDA)\n * @param options - Options on building the CPI\n * @returns CPI accounts, program ID, and serialized instruction data\n */\n async getSwapCpiData(\n quote: PerenaSwapQuote,\n userPublicKey: Address,\n _options?: SwapInstructionOptions\n ): Promise<CpiData> {\n const { operation } = quote.rawQuote;\n\n switch (operation) {\n case \"mint\":\n case \"burn\":\n return this.getMintBurnCpiData(quote, userPublicKey);\n case \"stake\":\n return await this.getStakeCpiData(quote, userPublicKey);\n case \"unstake\":\n return await this.getInstantUnstakeCpiData(quote, userPublicKey);\n case \"request_unstake\": {\n const rq = quote.rawQuote as Extract<PerenaRawQuote, { operation: \"request_unstake\" }>;\n return await this.getRequestUnstakeCpiData({\n shares: new BN(quote.inputAmount.toString()),\n queueId: rq.queueId,\n userPublicKey,\n payer: rq.payer,\n targetMint: rq.targetMint,\n });\n }\n case \"fulfill_unstake\": {\n const fq = quote.rawQuote as Extract<PerenaRawQuote, { operation: \"fulfill_unstake\" }>;\n return await this.getFulfillUnstakeCpiData({\n withdrawalQueue: fq.withdrawalQueue,\n signer: fq.owner,\n queuePayer: fq.queuePayer,\n owner: fq.owner,\n targetMint: fq.targetMint,\n });\n }\n }\n }\n\n /**\n * Derive the withdrawal queue PDA for a given user and queue slot.\n */\n deriveWithdrawalQueue(user: Address, queueId: number): Address {\n return fromWeb3Pk(\n this.sdkClient.bankineco.withdrawalQueuePDA(this.sdkClient.bank, new PublicKey(user), queueId)\n );\n }\n\n /**\n * Fetch all active withdrawal queue PDAs owned by `user`.\n *\n * \"Active\" means the queue account exists, is owned by Perena, and currently\n * holds a non-zero locked amount.\n */\n async getActiveWithdrawalQueues(user: Address): Promise<Address[]> {\n const { data } = await this.cache.getDataOrThrow<Address[]>(\n async () => {\n const userPublicKey = new PublicKey(user);\n const queueInfos: WithdrawalQueueEntry[] =\n await this.sdkClient.fetchAllWithdrawalQueues(userPublicKey);\n\n return queueInfos\n .filter((queueInfo) => queueInfo.amount.gt(new BN(0)))\n .map((queueInfo) => fromWeb3Pk(queueInfo.address));\n },\n ACTIVE_WITHDRAWAL_QUEUES_CACHE_CATEGORY,\n user\n );\n return data;\n }\n\n /**\n * Cache invalidation descriptor for the active-withdrawal-queues snapshot of\n * one owner. Use this when a transaction may create, consume, or otherwise\n * mutate Perena withdrawal queues outside this exact client instance.\n */\n getActiveWithdrawalQueuesCacheInvalidation(owner: Address): TransactionCacheInvalidation {\n return this.getActiveWithdrawalQueuesInvalidation(owner);\n }\n\n private getActiveWithdrawalQueuesInvalidation(owner: Address): TransactionCacheInvalidation {\n return {\n client: \"perena\",\n dataCache: this.cache,\n category: ACTIVE_WITHDRAWAL_QUEUES_CACHE_CATEGORY,\n id: owner,\n };\n }\n\n /**\n * Build CPI data for mint_w_yielding_gen or burn_for_yielding_gen.\n */\n private async getMintBurnCpiData(\n quote: PerenaSwapQuote,\n userPublicKey: Address\n ): Promise<CpiData> {\n const raw = quote.rawQuote as Extract<PerenaRawQuote, { operation: \"mint\" | \"burn\" }>;\n const isMint = raw.operation === \"mint\";\n const action = isMint ? BankinecoAction.Mint : BankinecoAction.Burn;\n\n const cpiAccounts = await this.sdkClient.getMintAndBurnCpiAccounts(\n new PublicKey(raw.yieldingMint),\n action,\n new PublicKey(userPublicKey)\n );\n\n const accounts: CustomAccountMeta[] = [\n toCustomAccountMeta(userPublicKey, false, undefined, false),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.bankState),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.vaultState),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.oracleState),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.yieldingMint),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.bankMint),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.yieldingUserTa),\n {\n ...toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.bankMintUserTa),\n isRequiredAta: {\n mint: fromWeb3Pk(cpiAccounts.bankMint.pubkey),\n owner: userPublicKey,\n tokenProgram: mints.get(\"USD*\")!.tokenProgram,\n },\n },\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.yieldingVaultAta),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.teamState),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.feeTeamAta),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.systemProgram),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.tokenProgram),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.yieldingMintProgram),\n toCustomAccountMetaFromWeb3AccountMeta(cpiAccounts.associatedTokenProgram),\n ...(cpiAccounts.remainingAccounts ?? []).map(\n (meta: { pubkey: PublicKey; isWritable: boolean; isSigner: boolean }) =>\n toCustomAccountMeta(\n meta.pubkey.toBase58() as Address,\n meta.isWritable,\n undefined,\n meta.isSigner\n )\n ),\n ];\n\n return {\n cpiType: isMint ? CpiTypes.PERENA_MINT : CpiTypes.PERENA_BURN,\n accounts,\n programId: PERENA_PROGRAM_ID,\n data: isMint\n ? getPerenaMintArgs({\n amountYieldingDeposit: quote.inputAmount,\n minBankMintMinted: quote.outputAmount,\n })\n : getPerenaBurnArgs({\n amountToBurn: quote.inputAmount,\n minimumYieldingWithdrawn: quote.outputAmount,\n }),\n };\n }\n\n /**\n * Build CPI data for stake_junior.\n *\n * Account order matches the IDL:\n * user, tranche_state, bank_state, bank_mint, junior_mint,\n * user_bank_mint_ata, user_junior_mint_ata, junior_escrow_ata,\n * system_program, token_program, associated_token_program\n */\n private async getStakeCpiData(quote: PerenaSwapQuote, userPublicKey: Address): Promise<CpiData> {\n const userPk = new PublicKey(userPublicKey);\n const trancheAccounts = await this.sdkClient.getStakeCpiAccounts(userPk);\n\n const { bankMint, juniorMint, tokenProgram } = trancheAccounts;\n const userBankMintAta = await getAtaAddress(\n fromWeb3Pk(bankMint),\n userPublicKey,\n fromWeb3Pk(tokenProgram)\n );\n const userJuniorMintAta = await getAtaAddress(\n fromWeb3Pk(juniorMint),\n userPublicKey,\n fromWeb3Pk(tokenProgram)\n );\n\n const accounts: CustomAccountMeta[] = [\n toCustomAccountMeta(userPublicKey, true, undefined, false),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.trancheState), true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.bankState)),\n toCustomAccountMeta(fromWeb3Pk(bankMint)),\n toCustomAccountMeta(fromWeb3Pk(juniorMint), true),\n toCustomAccountMeta(userBankMintAta, true),\n {\n ...toCustomAccountMeta(userJuniorMintAta, true),\n isRequiredAta: {\n mint: this.juniorMint,\n owner: userPublicKey,\n tokenProgram: mints.get(\"USD*-J\")!.tokenProgram,\n },\n },\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.juniorEscrowAta), true),\n toCustomAccountMeta(SYSTEM_PROGRAM_ADDRESS),\n toCustomAccountMeta(fromWeb3Pk(tokenProgram)),\n toCustomAccountMeta(ASSOCIATED_TOKEN_PROGRAM_ADDRESS),\n ];\n\n return {\n cpiType: CpiTypes.PERENA_STAKE,\n accounts,\n programId: PERENA_PROGRAM_ID,\n data: numToU64Bytes(quote.inputAmount),\n };\n }\n\n /**\n * Build CPI data for instant_unstake_junior.\n *\n * Account order matches the IDL:\n * user, tranche_state, bank_state, bank_mint, target_mint, junior_mint,\n * user_junior_mint_ata, owner_bank_mint_ata, junior_escrow_ata,\n * locked_junior_shares_ata, token_program,\n * [vault_state, vault_oracle_state, vault_team_state, yielding_mint,\n * yielding_vault_ata, owner_yielding_ta, vault_fee_team_ata,\n * yielding_mint_program] (optional, when unstaking to a yielding mint)\n */\n private async getInstantUnstakeCpiData(\n quote: PerenaSwapQuote,\n userPublicKey: Address\n ): Promise<CpiData> {\n const raw = quote.rawQuote as Extract<PerenaRawQuote, { operation: \"unstake\" }>;\n const userPk = new PublicKey(userPublicKey);\n\n const targetMintPk = raw.targetMint ? new PublicKey(raw.targetMint) : undefined;\n const trancheAccounts = await this.sdkClient.getUnstakeCpiAccounts(userPk, targetMintPk);\n\n const { bankMint, juniorMint, tokenProgram } = trancheAccounts;\n const userJuniorMintAta = await getAtaAddress(\n fromWeb3Pk(juniorMint),\n userPublicKey,\n fromWeb3Pk(tokenProgram)\n );\n const ownerBankMintAta = await getAtaAddress(\n fromWeb3Pk(bankMint),\n userPublicKey,\n fromWeb3Pk(tokenProgram)\n );\n const targetMintAddress: Address = raw.targetMint ?? this.bankMint;\n\n const accounts: CustomAccountMeta[] = [\n toCustomAccountMeta(userPublicKey, false, undefined, false),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.trancheState), true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.bankState), true),\n toCustomAccountMeta(fromWeb3Pk(bankMint), true),\n toCustomAccountMeta(targetMintAddress),\n toCustomAccountMeta(fromWeb3Pk(juniorMint), true),\n toCustomAccountMeta(userJuniorMintAta, true),\n {\n ...toCustomAccountMeta(ownerBankMintAta, true),\n isRequiredAta: {\n mint: fromWeb3Pk(bankMint),\n owner: userPublicKey,\n tokenProgram: mints.get(\"USD*\")!.tokenProgram,\n },\n },\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.juniorEscrowAta), true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.lockedJuniorSharesAta), true),\n toCustomAccountMeta(fromWeb3Pk(tokenProgram)),\n ];\n\n this.pushYieldingRedemptionAccounts(accounts, trancheAccounts, userPublicKey);\n\n return {\n cpiType: CpiTypes.PERENA_INSTANT_UNSTAKE,\n accounts,\n programId: PERENA_PROGRAM_ID,\n data: numToU64Bytes(quote.inputAmount),\n };\n }\n\n /**\n * Build CPI data for request_unstake_junior.\n *\n * Account order matches the IDL:\n * user, payer, withdrawal_queue, tranche_state, bank_state, bank_mint,\n * target_mint, junior_mint, user_junior_mint_ata, locked_junior_shares_ata,\n * system_program, token_program\n */\n async getRequestUnstakeCpiData(params: RequestUnstakeParams): Promise<CpiData> {\n const userPk = new PublicKey(params.userPublicKey);\n const targetMintPk = params.targetMint ? new PublicKey(params.targetMint) : undefined;\n const trancheAccounts = await this.sdkClient.getUnstakeCpiAccounts(userPk, targetMintPk);\n\n const { bankMint, juniorMint, tokenProgram } = trancheAccounts;\n const userJuniorMintAta = await getAtaAddress(\n fromWeb3Pk(juniorMint),\n params.userPublicKey,\n fromWeb3Pk(tokenProgram)\n );\n const targetMintAddress: Address = params.targetMint ?? this.bankMint;\n const withdrawalQueue = this.deriveWithdrawalQueue(params.userPublicKey, params.queueId);\n\n const accounts: CustomAccountMeta[] = [\n toCustomAccountMeta(params.userPublicKey, false, undefined, false),\n toCustomAccountMeta(params.payer, true, undefined, true),\n toCustomAccountMeta(withdrawalQueue, true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.trancheState)),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.bankState)),\n toCustomAccountMeta(fromWeb3Pk(bankMint)),\n toCustomAccountMeta(targetMintAddress),\n toCustomAccountMeta(fromWeb3Pk(juniorMint)),\n toCustomAccountMeta(userJuniorMintAta, true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.lockedJuniorSharesAta), true),\n toCustomAccountMeta(SYSTEM_PROGRAM_ADDRESS),\n toCustomAccountMeta(fromWeb3Pk(tokenProgram)),\n ];\n\n return {\n cpiType: CpiTypes.PERENA_REQUEST_UNSTAKE,\n accounts,\n programId: PERENA_PROGRAM_ID,\n data: getPerenaRequestUnstakeArgs({\n shares: params.shares,\n queueId: params.queueId,\n }),\n postSuccessCacheInvalidations: [\n this.getActiveWithdrawalQueuesInvalidation(params.userPublicKey),\n ],\n };\n }\n\n /**\n * Build CPI data for fulfill_unstake_junior.\n *\n * Account order matches the IDL:\n * signer, queue_payer, withdrawal_queue, tranche_state, bank_state,\n * bank_mint, junior_mint, owner_bank_mint_ata, junior_escrow_ata,\n * locked_junior_shares_ata, token_program,\n * [vault_state, vault_oracle_state, vault_team_state, yielding_mint,\n * yielding_vault_ata, owner_yielding_ta, vault_fee_team_ata,\n * yielding_mint_program] (optional, when fulfilling to a yielding mint)\n */\n async getFulfillUnstakeCpiData(params: FulfillUnstakeParams): Promise<CpiData> {\n const ownerPk = new PublicKey(params.owner);\n const targetMintPk = params.targetMint ? new PublicKey(params.targetMint) : undefined;\n const trancheAccounts = await this.sdkClient.getUnstakeCpiAccounts(ownerPk, targetMintPk);\n\n const { bankMint, juniorMint, tokenProgram } = trancheAccounts;\n const ownerBankMintAta = await getAtaAddress(\n fromWeb3Pk(bankMint),\n params.owner,\n fromWeb3Pk(tokenProgram)\n );\n\n const accounts: CustomAccountMeta[] = [\n toCustomAccountMeta(params.signer, false, undefined, false),\n toCustomAccountMeta(params.queuePayer, true),\n toCustomAccountMeta(params.withdrawalQueue, true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.trancheState), true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.bankState), true),\n toCustomAccountMeta(fromWeb3Pk(bankMint), true),\n toCustomAccountMeta(fromWeb3Pk(juniorMint), true),\n {\n ...toCustomAccountMeta(ownerBankMintAta, true),\n isRequiredAta: {\n mint: fromWeb3Pk(bankMint),\n owner: params.owner,\n tokenProgram: mints.get(\"USD*\")!.tokenProgram,\n },\n },\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.juniorEscrowAta), true),\n toCustomAccountMeta(fromWeb3Pk(trancheAccounts.lockedJuniorSharesAta), true),\n toCustomAccountMeta(fromWeb3Pk(tokenProgram)),\n ];\n\n this.pushYieldingRedemptionAccounts(accounts, trancheAccounts, params.owner);\n\n return {\n cpiType: CpiTypes.PERENA_FULFILL_UNSTAKE,\n accounts,\n programId: PERENA_PROGRAM_ID,\n data: new Uint8Array(0),\n postSuccessCacheInvalidations: [this.getActiveWithdrawalQueuesInvalidation(params.owner)],\n };\n }\n\n /**\n * Appends the 8 yielding-redemption account slots that `instant_unstake_junior`\n * and `fulfill_unstake_junior` expect after `token_program`.\n *\n * When a yielding mint is involved, real accounts are pushed. Otherwise Anchor\n * still requires all 8 slots to be present — each set to the program ID as the\n * `Option<Account>` sentinel for `None`.\n */\n private pushYieldingRedemptionAccounts(\n accounts: CustomAccountMeta[],\n trancheAccounts: TrancheCpiAccounts,\n owner: Address\n ): void {\n const yr = trancheAccounts.yieldingRedemption;\n if (yr) {\n accounts.push(\n toCustomAccountMeta(fromWeb3Pk(yr.vaultState), true),\n toCustomAccountMeta(fromWeb3Pk(yr.vaultOracleState)),\n toCustomAccountMeta(fromWeb3Pk(yr.vaultTeamState), true),\n toCustomAccountMeta(fromWeb3Pk(yr.yieldingMint)),\n toCustomAccountMeta(fromWeb3Pk(yr.yieldingVaultAta), true),\n {\n ...toCustomAccountMeta(fromWeb3Pk(yr.ownerYieldingTa), true),\n isRequiredAta: {\n mint: fromWeb3Pk(yr.yieldingMint),\n owner,\n tokenProgram: fromWeb3Pk(yr.yieldingMintProgram),\n },\n },\n toCustomAccountMeta(fromWeb3Pk(yr.vaultFeeTeamAta), true),\n toCustomAccountMeta(fromWeb3Pk(yr.yieldingMintProgram))\n );\n } else {\n const sentinel = PERENA_PROGRAM_ID;\n for (let i = 0; i < 8; i++) {\n accounts.push(toCustomAccountMeta(sentinel));\n }\n }\n\n if (trancheAccounts.remainingAccounts) {\n for (const meta of trancheAccounts.remainingAccounts) {\n accounts.push(\n toCustomAccountMeta(\n meta.pubkey.toBase58() as Address,\n meta.isWritable,\n undefined,\n meta.isSigner\n )\n );\n }\n }\n }\n}\n","import type { Address } from \"@solana/kit\";\nimport type { PerenaClient } from \"./client\";\nimport { fromWeb3Pk, getAtaAddress, mints } from \"common\";\n\n/**\n * Derives the ATA that holds locked junior shares during unstaking, owned\n * by the tranche state PDA.\n */\nexport async function getLockedJuniorSharesAta(perenaClient: PerenaClient): Promise<Address> {\n const trancheOwner = fromWeb3Pk(\n perenaClient.sdkClient.bankineco.tranchePDA(perenaClient.sdkClient.bank)\n );\n return getAtaAddress(perenaClient.juniorMint, trancheOwner, mints.get(\"USD*\")!.tokenProgram);\n}\n","import type { Address } from \"@solana/kit\";\nimport {\n CpiTypes,\n DEFAULT_PUBLIC_KEY,\n dedupeOrderedAddresses,\n filterSpecificAccounts,\n getAtaAddress,\n mints,\n wholeTokenAmount,\n type CpiData,\n} from \"common\";\nimport { PerenaClient } from \"./client\";\n\n/**\n * Extract Perena withdrawal queue accounts referenced by request/fulfill-unstake\n * CPI data.\n */\nexport function getPerenaWithdrawalQueueAddressesFromCpiData(\n cpiData: readonly CpiData[]\n): Address[] {\n return cpiData\n .filter(\n (cpi) =>\n cpi.cpiType === CpiTypes.PERENA_REQUEST_UNSTAKE ||\n cpi.cpiType === CpiTypes.PERENA_FULFILL_UNSTAKE\n )\n .map((cpi) => cpi.accounts[2]?.address)\n .filter((address): address is Address => address !== undefined);\n}\n\nexport async function getGeneralLookupTableAccountsForPerena(\n perenaClient: PerenaClient\n): Promise<Address[]> {\n const bankMintInfo = mints.get(\"USD*\");\n const juniorMintInfo = mints.get(\"USD*-J\");\n const usdcMintInfo = mints.get(\"USDC\");\n if (!bankMintInfo || !juniorMintInfo || !usdcMintInfo) {\n throw new Error(\"USD*, USD*-J, and USDC must exist in the mint registry\");\n }\n\n const dummyUser = DEFAULT_PUBLIC_KEY;\n const bankMintUserAta = await getAtaAddress(\n bankMintInfo.address,\n dummyUser,\n bankMintInfo.tokenProgram\n );\n const juniorMintUserAta = await getAtaAddress(\n juniorMintInfo.address,\n dummyUser,\n juniorMintInfo.tokenProgram\n );\n const usdcMintUserAta = await getAtaAddress(\n usdcMintInfo.address,\n dummyUser,\n usdcMintInfo.tokenProgram\n );\n\n const allAccounts: Address[] = [];\n\n const stakeQuote = await perenaClient.getQuote({\n inputMint: bankMintInfo.address,\n outputMint: juniorMintInfo.address,\n amount: wholeTokenAmount(bankMintInfo.decimals),\n slippageBps: 50,\n });\n const stakeCpi = await perenaClient.getSwapCpiData(stakeQuote, dummyUser);\n allAccounts.push(\n ...filterSpecificAccounts(\n stakeCpi.accounts.map((account) => account.address),\n [DEFAULT_PUBLIC_KEY, bankMintUserAta, juniorMintUserAta]\n )\n );\n\n const mintQuote = await perenaClient.getQuote({\n inputMint: usdcMintInfo.address,\n outputMint: bankMintInfo.address,\n amount: wholeTokenAmount(usdcMintInfo.decimals),\n slippageBps: 50,\n });\n const mintCpi = await perenaClient.getSwapCpiData(mintQuote, dummyUser);\n allAccounts.push(\n ...filterSpecificAccounts(\n mintCpi.accounts.map((account) => account.address),\n [DEFAULT_PUBLIC_KEY, usdcMintUserAta, bankMintUserAta]\n )\n );\n\n const burnQuote = await perenaClient.getQuote({\n inputMint: bankMintInfo.address,\n outputMint: usdcMintInfo.address,\n amount: wholeTokenAmount(bankMintInfo.decimals),\n slippageBps: 50,\n });\n const burnCpi = await perenaClient.getSwapCpiData(burnQuote, dummyUser);\n allAccounts.push(\n ...filterSpecificAccounts(\n burnCpi.accounts.map((account) => account.address),\n [DEFAULT_PUBLIC_KEY, bankMintUserAta, usdcMintUserAta]\n )\n );\n\n return dedupeOrderedAddresses(allAccounts);\n}\n","export * from \"./constants\";\nexport * from \"./client\";\nexport * from \"./accounts\";\nexport * from \"./cpi\";\nexport * from \"./utils\";\n","import { Address } from \"@solana/kit\";\nimport {\n createRpcWithRetry,\n fromUiAmount,\n MintIdentifier,\n redactRpcUrlForLog,\n toUiAmount,\n} from \"common\";\nimport { pythRequest } from \"../utils\";\nimport { PythFeed } from \"../constants/pyth\";\n\n/**\n * Upper bound on the LST/SOL exchange rate, expressed as a multiple of SOL/USD.\n * Mirrors Kamino/Scope's SPL-stake LST pricing (and the on-chain Rust\n * `SPL_STAKE_PRICE_CAP_MULTIPLIER`): the price is capped at `1.1 × SOL/USD` so a\n * corrupted or manipulated stake pool exchange rate can never value the LST\n * above 1.1 SOL.\n */\nexport const SPL_STAKE_PRICE_CAP_MULTIPLIER = 1.1;\n\n// Byte offsets into an SPL stake pool account (no discriminator; Borsh layout\n// of `spl_stake_pool::state::StakePool`). Verified on-chain: `token_program_id`\n// lands on the SPL Token program at offset 226, so these two u64s are correct.\n// account_type(1) + manager(32) + staker(32) + stake_deposit_authority(32)\n// + stake_withdraw_bump_seed(1) + validator_list(32) + reserve_stake(32)\n// + pool_mint(32) + manager_fee_account(32) + token_program_id(32) = 258\nconst STAKE_POOL_TOTAL_LAMPORTS_OFFSET = 258;\nconst STAKE_POOL_POOL_TOKEN_SUPPLY_OFFSET = 266;\n\nexport interface SplStakeLstConfig {\n /** The LST mint (the stake pool's pool token). */\n mint: MintIdentifier;\n /** The SPL stake pool account. */\n stakePool: Address;\n /** The Pyth SOL/USD feed used to convert the SOL-denominated rate to USD. */\n pythSolFeed: PythFeed;\n}\n\ninterface PythPriceResponse {\n parsed: Array<{\n price: {\n price: number;\n expo: number;\n };\n }>;\n}\n\nfunction errorWithCause(message: string, cause: unknown): Error {\n const err = new Error(message);\n (err as { cause?: unknown }).cause = cause;\n return err;\n}\n\n/** Convert a raw Pyth price + exponent into a UI number (mirrors `pyth.ts`). */\nfunction deriveValue(price: number, exponent: number): number {\n if (exponent > 0) return Number(fromUiAmount(Number(price), exponent));\n if (exponent < 0) return toUiAmount(BigInt(price), Math.abs(exponent));\n return Number(price);\n}\n\n/**\n * Read the LST/SOL exchange rate from an SPL stake pool account:\n * `rate = total_lamports / pool_token_supply` — how much SOL one LST is\n * redeemable for. The underlying SOL and the LST mint both use 9 decimals, so\n * the raw ratio is the dimensionless SOL-per-LST rate.\n */\nasync function fetchStakeRate(rpcUrl: string, stakePool: Address): Promise<number> {\n const rpc = createRpcWithRetry(rpcUrl);\n const redactedRpcUrl = redactRpcUrlForLog(rpcUrl);\n let response;\n\n try {\n response = await rpc.getAccountInfo(stakePool, { encoding: \"base64\" }).send();\n } catch (err) {\n throw errorWithCause(\n `SPL stake pool getAccountInfo failed (stakePool=${stakePool}, rpc=${redactedRpcUrl})`,\n err\n );\n }\n\n const { value } = response;\n if (!value) {\n throw new Error(\n `SPL stake pool account not found (stakePool=${stakePool}, rpc=${redactedRpcUrl})`\n );\n }\n\n const data = Buffer.from(value.data[0], \"base64\");\n const totalLamports = data.readBigUInt64LE(STAKE_POOL_TOTAL_LAMPORTS_OFFSET);\n const poolTokenSupply = data.readBigUInt64LE(STAKE_POOL_POOL_TOKEN_SUPPLY_OFFSET);\n if (poolTokenSupply === BigInt(0)) {\n throw new Error(\n `SPL stake pool has zero pool token supply (stakePool=${stakePool}, rpc=${redactedRpcUrl})`\n );\n }\n\n return Number(totalLamports) / Number(poolTokenSupply);\n}\n\n/** Fetch the latest SOL/USD realtime price from Pyth Hermes. */\nasync function fetchSolUsd(feedId: string): Promise<number> {\n let resp: Response;\n try {\n resp = await pythRequest([feedId]);\n } catch (err) {\n throw errorWithCause(`Pyth SOL/USD request failed before response (feedId=${feedId})`, err);\n }\n\n if (resp.status !== 200) {\n const body = await resp.text().catch(() => \"<failed to read response body>\");\n throw new Error(\n `Pyth SOL/USD request failed status=${resp.status} feedId=${feedId} body=${body}`\n );\n }\n\n let json: PythPriceResponse;\n try {\n json = (await resp.json()) as PythPriceResponse;\n } catch (err) {\n throw errorWithCause(`Pyth SOL/USD response JSON parse failed (feedId=${feedId})`, err);\n }\n\n const price = json.parsed[0].price;\n return deriveValue(price.price, price.expo);\n}\n\n/**\n * Price an SPL-stake LST in USD, matching Kamino/Scope and the on-chain Rust\n * `PythSplStake` oracle:\n *\n * price = min(stake_rate × SOL/USD, 1.1 × SOL/USD)\n */\nexport async function getSplStakeLstUiPrice(\n rpcUrl: string,\n config: SplStakeLstConfig\n): Promise<number> {\n const [rate, solUsd] = await Promise.all([\n fetchStakeRate(rpcUrl, config.stakePool),\n fetchSolUsd(config.pythSolFeed.feedId),\n ]);\n\n return Math.min(rate * solUsd, SPL_STAKE_PRICE_CAP_MULTIPLIER * solUsd);\n}\n","import { PerenaClient } from \"perena-helpers\";\nimport { OracleService } from \"../oracle\";\nimport { fromWeb3Pk, getMainnetRpcUrl, mints, OracleType, fetchWithRetry } from \"common\";\nimport { getSplStakeLstUiPrice, SplStakeLstConfig } from \"../feeds/splStake\";\nimport { PYTH_FEEDS } from \"../constants/pyth\";\nimport { DFDVSOL_STAKE_POOL } from \"../constants/splStake\";\n\nexport async function pythRequest(feedIds: string[]) {\n return await fetchWithRetry(\n `https://hermes.pyth.network/v2/updates/price/latest?${feedIds\n .map((x) => `ids%5B%5D=${x}`)\n .join(\"&\")}`\n );\n}\n\n/**\n * Register the Perena USD* oracle on an OracleService instance.\n */\n/** Static Perena oracle account addresses (PDAs; independent of RPC endpoint). */\nconst perenaOracleAccounts = new PerenaClient(getMainnetRpcUrl());\n\nexport function registerUsdStarOracle(oracle: OracleService): void {\n oracle.registerCustomOracle(\"USD*\", {\n priceFetcher: (rpcUrl) => new PerenaClient(rpcUrl).getLatestBankMintUiPrice(),\n oracle: fromWeb3Pk(perenaOracleAccounts.sdkClient.bank),\n oracleType: OracleType.PerenaBank,\n });\n}\n\n/**\n * Register the Perena USD*-J oracle on an OracleService instance.\n */\nexport function registerUsdStarJuniorOracle(oracle: OracleService): void {\n oracle.registerCustomOracle(\"USD*-J\", {\n priceFetcher: (rpcUrl) => new PerenaClient(rpcUrl).getLatestJuniorMintUiPrice(),\n oracle: fromWeb3Pk(perenaOracleAccounts.sdkClient.tranche),\n oracleType: OracleType.PerenaTranche,\n });\n}\n\n/**\n * Register an SPL-stake LST oracle (e.g. dfdvSOL) on an OracleService instance.\n *\n * Prices the LST as `min(stake_rate × SOL/USD, 1.1 × SOL/USD)`, matching\n * Kamino/Scope and the on-chain `PythSplStake` oracle. The primary oracle is\n * the Pyth SOL/USD feed; the SPL stake pool account is the secondary oracle.\n */\nexport function registerSplStakeLstOracle(oracle: OracleService, config: SplStakeLstConfig): void {\n oracle.registerCustomOracle(config.mint, {\n priceFetcher: (rpcUrl) => getSplStakeLstUiPrice(rpcUrl, config),\n oracle: config.pythSolFeed.account,\n oracleType: OracleType.PythSplStake,\n secondaryOracle: config.stakePool,\n });\n}\n\n/**\n * Register the dfdvSOL oracle on an OracleService instance.\n */\nexport function registerDfdvSolOracle(oracle: OracleService): void {\n const dfdvSol = mints.get(\"dfdvSOL\")!;\n registerSplStakeLstOracle(oracle, {\n mint: dfdvSol.address,\n stakePool: DFDVSOL_STAKE_POOL,\n pythSolFeed: PYTH_FEEDS.SOL,\n });\n}\n","export * from \"./general\";\n","import { Address } from \"@solana/kit\";\nimport { PriceBase, type PriceFetchContext } from \"./priceBase\";\nimport { PYTH_FEEDS } from \"../constants\";\nimport {\n createRecord,\n findKeyIgnoreCase,\n fromUiAmount,\n mints as mintRegistry,\n toUiAmount,\n} from \"common\";\nimport { retry } from \"ts-retry\";\nimport { PriceResult } from \"../types\";\nimport { pythRequest } from \"../utils\";\n\nexport class PythPrices extends PriceBase {\n private deriveValue = (price: number, exponent: number) => {\n if (exponent > 0) {\n return Number(fromUiAmount(Number(price), exponent));\n } else if (exponent < 0) {\n return toUiAmount(BigInt(price), Math.abs(exponent));\n } else {\n return Number(price);\n }\n };\n\n private findFeed(symbol: string) {\n const key = findKeyIgnoreCase(PYTH_FEEDS, symbol);\n return key ? PYTH_FEEDS[key] : undefined;\n }\n\n protected async internalFetchPrices(\n mints: Address[],\n _context?: PriceFetchContext\n ): Promise<Record<Address, PriceResult>> {\n const feedIds = mints.map((mint) => {\n const symbol = mintRegistry.get(mint)?.symbol;\n const feed = symbol ? this.findFeed(symbol) : undefined;\n if (!feed) {\n throw new Error(`No Pyth feed configured for mint ${mint.toString()}`);\n }\n return feed.feedId;\n });\n\n const prices: PriceResult[] = await retry(\n async () => {\n const resp = await pythRequest(feedIds);\n const status = resp.status;\n if (status !== 200) {\n const body = await resp.text().catch(() => \"<failed to read response body>\");\n throw new Error(\n `Pyth price request failed status=${status} statusText=${resp.statusText} feedIds=${feedIds.join(\",\")} body=${body}`\n );\n }\n\n const json = await resp.json();\n const prices = (json as any).parsed.map((x: any) => {\n return {\n realtimePrice: this.deriveValue(x.price.price, x.price.expo),\n emaPrice: this.deriveValue(x.ema_price.price, x.ema_price.expo),\n };\n });\n\n return prices;\n },\n {\n maxTry: 5,\n delay: 250,\n }\n );\n\n return createRecord(\n mints.map((x) => x.toString()),\n prices\n );\n }\n}\n","import { Address } from \"@solana/kit\";\nimport { PriceBase, type PriceFetchContext } from \"./priceBase\";\nimport { PriceResult } from \"../types\";\n\nexport class SwitchboardPrices extends PriceBase {\n protected async internalFetchPrices(\n mints: Address[],\n _context?: PriceFetchContext\n ): Promise<Record<Address, PriceResult>> {\n // TODO\n return {};\n }\n}\n","import { Address } from \"@solana/kit\";\nimport { mints as mintRegistry, MintIdentifier, OracleType } from \"common\";\nimport { PriceBase, type PriceFetchContext } from \"./priceBase\";\nimport { PriceResult } from \"../types\";\n\nexport interface CustomOracle {\n /** Receives the RPC URL for the active environment on each fetch. */\n priceFetcher: (rpcUrl: string) => Promise<number>;\n oracle: Address;\n oracleType: OracleType;\n /** Optional secondary oracle account for composite oracle types (e.g. the\n * SPL stake pool account for `PythSplStake`). */\n secondaryOracle?: Address;\n}\n\nexport class CustomPrices extends PriceBase {\n private customOracles: Map<MintIdentifier, CustomOracle> = new Map();\n\n private getLookupKeys(mint: MintIdentifier): MintIdentifier[] {\n const symbol = mintRegistry.get(mint)?.symbol;\n const address = mintRegistry.get(mint)?.address;\n\n return [mint, symbol, address].filter((key): key is MintIdentifier => key !== undefined);\n }\n\n /**\n * Register a custom price fetcher for a given mint.\n *\n * @param mint - The mint identifier\n * @param fetcher - An async function that returns the current price\n */\n registerCustomOracle(mint: MintIdentifier, oracle: CustomOracle): void {\n this.customOracles.set(mint, oracle);\n }\n\n /**\n * Check if a custom price fetcher is registered for a given mint.\n */\n hasCustomOracle(mint: MintIdentifier): boolean {\n return this.getLookupKeys(mint).some((key) => this.customOracles.has(key));\n }\n\n protected async internalFetchPrices(\n mints: MintIdentifier[],\n context?: PriceFetchContext\n ): Promise<Record<MintIdentifier, PriceResult>> {\n const rpcUrl = context?.rpcUrl;\n if (!rpcUrl) {\n throw new Error(\"Custom oracle price fetch requires an RPC URL\");\n }\n\n const entries = await Promise.all(\n mints.map(async (mint) => {\n const oracle = this.getCustomOracle(mint);\n if (!oracle) {\n return [mint, { realtimePrice: 0 }] as const;\n }\n const price = await oracle.priceFetcher(rpcUrl);\n return [mint, { realtimePrice: price }] as const;\n })\n );\n\n return Object.fromEntries(entries);\n }\n\n getCustomOracle(mint: MintIdentifier) {\n for (const key of this.getLookupKeys(mint)) {\n const oracle = this.customOracles.get(key);\n if (oracle) {\n return oracle;\n }\n }\n\n return undefined;\n }\n}\n","import { address } from \"@solana/kit\";\nimport {\n mints as mintRegistry,\n OracleType,\n getRpcUrl,\n ENVIRONMENT,\n findKeyIgnoreCase,\n type Environment,\n type MintIdentifier,\n} from \"common\";\nimport { PYTH_FEEDS } from \"./constants/pyth\";\nimport { SWITCHBOARD_PRICE_FEED_IDS } from \"./constants/switchboard\";\nimport { JupiterPrices } from \"./feeds/jupiter\";\nimport { PythPrices } from \"./feeds/pyth\";\nimport { SwitchboardPrices } from \"./feeds/switchboard\";\nimport { CustomOracle, CustomPrices } from \"./feeds/custom\";\nimport { type PriceResult } from \"./types\";\nimport { registerUsdStarOracle, registerUsdStarJuniorOracle, registerDfdvSolOracle } from \"./utils\";\n\nexport class OracleService {\n private jupiter: JupiterPrices;\n private pyth: PythPrices;\n private switchboard: SwitchboardPrices;\n private custom: CustomPrices;\n\n constructor() {\n this.jupiter = new JupiterPrices();\n this.pyth = new PythPrices();\n this.switchboard = new SwitchboardPrices();\n this.custom = new CustomPrices();\n }\n\n /**\n * Register a custom oracle for a given mint.\n * Custom-registered mints take priority over all other oracle sources.\n */\n registerCustomOracle(mint: MintIdentifier, oracle: CustomOracle): void {\n this.custom.registerCustomOracle(mint, oracle);\n }\n\n getOracleData(mint: MintIdentifier) {\n const customOracle = this.custom.getCustomOracle(mint);\n if (customOracle) {\n return {\n oracle: customOracle.oracle,\n oracleType: customOracle.oracleType,\n secondaryOracle: customOracle.secondaryOracle,\n };\n }\n\n const symbol = mintRegistry.get(mint)?.symbol;\n const pythSymbol = symbol ? findKeyIgnoreCase(PYTH_FEEDS, symbol) : undefined;\n const switchboardSymbol = symbol\n ? findKeyIgnoreCase(SWITCHBOARD_PRICE_FEED_IDS, symbol)\n : undefined;\n\n return {\n oracle: pythSymbol\n ? PYTH_FEEDS[pythSymbol].account\n : address(SWITCHBOARD_PRICE_FEED_IDS[switchboardSymbol!].feedId),\n oracleType: pythSymbol ? OracleType.Pyth : OracleType.Switchboard,\n secondaryOracle: undefined,\n };\n }\n\n clearCache(): void {\n this.jupiter.dataCache.clearAllCache();\n this.pyth.dataCache.clearAllCache();\n this.switchboard.dataCache.clearAllCache();\n this.custom.dataCache.clearAllCache();\n }\n\n async fetchPrices(\n mints: MintIdentifier[],\n mode?: \"realtime\" | \"ema\",\n bypassCache?: boolean,\n environment: Environment = ENVIRONMENT\n ): Promise<Record<MintIdentifier, number>> {\n if (!mints.length) {\n return {};\n }\n\n const rpcUrl = getRpcUrl(environment);\n\n const customMints: MintIdentifier[] = [];\n const pythMints: MintIdentifier[] = [];\n const switchboardMints: MintIdentifier[] = [];\n const jupiterMints: MintIdentifier[] = [];\n\n for (const mint of mints) {\n if (this.custom.hasCustomOracle(mint)) {\n customMints.push(mint);\n } else {\n const symbol = mintRegistry.get(mint)?.symbol;\n if (symbol && findKeyIgnoreCase(PYTH_FEEDS, symbol)) {\n pythMints.push(mint);\n } else if (symbol && findKeyIgnoreCase(SWITCHBOARD_PRICE_FEED_IDS, symbol)) {\n switchboardMints.push(mint);\n } else {\n jupiterMints.push(mint);\n }\n }\n }\n\n const [customPrices, pythPrices, switchboardPrices, jupiterPrices] = await Promise.all([\n customMints.length ? this.custom.fetchPrices(customMints, bypassCache, { rpcUrl }) : {},\n pythMints.length ? this.pyth.fetchPrices(pythMints, bypassCache) : {},\n switchboardMints.length ? this.switchboard.fetchPrices(switchboardMints, bypassCache) : {},\n jupiterMints.length ? this.jupiter.fetchPrices(jupiterMints, bypassCache) : {},\n ]);\n\n const toNumber = (result: PriceResult): number =>\n mode === \"realtime\" ? result.realtimePrice : (result.emaPrice ?? result.realtimePrice);\n\n const prices: Record<MintIdentifier, number> = {};\n for (const mint of mints) {\n const price = toNumber(\n (customPrices as Record<MintIdentifier, PriceResult>)[mint] ??\n (pythPrices as Record<MintIdentifier, PriceResult>)[mint] ??\n (switchboardPrices as Record<MintIdentifier, PriceResult>)[mint] ??\n (jupiterPrices as Record<MintIdentifier, PriceResult>)[mint]\n );\n const isStablecoin = mintRegistry.get(mint)?.assetType === \"Stablecoin\";\n prices[mint] = isStablecoin ? Math.min(price, 1) : price;\n }\n\n return prices;\n }\n}\n\nexport const oracle = new OracleService();\n\nregisterUsdStarOracle(oracle);\nregisterUsdStarJuniorOracle(oracle);\nregisterDfdvSolOracle(oracle);\n","export { OracleService, oracle } from \"./oracle\";\nexport * from \"./constants\";\nexport { type PriceResult } from \"./types\";\nexport { registerSplStakeLstOracle, registerDfdvSolOracle } from \"./utils\";\nexport { getSplStakeLstUiPrice, type SplStakeLstConfig } from \"./feeds/splStake\";\n","import { Address, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport { createRpcWithFailover, TransactionCacheInvalidation } from \"common\";\nimport { LendingPlatformData, LpAccountsBase, LpInstructionsBase } from \"../../data\";\nimport type { FlashLoanBase } from \"../flashLoan/flashLoanBase\";\nimport type { OutstandingIncentive } from \"../../types\";\n\n/**\n * A platform-agnostic lending client — the base class instantiated against\n * any concrete `LendingPlatformData` subclass. Use this when a function\n * doesn't care about the underlying platform (Kamino, Marginfi, etc.) and\n * just needs to call the shared abstract surface.\n */\nexport type AnyLendingPlatformClient = LendingPlatformClientBase<LendingPlatformData>;\n\n/**\n * Abstract base class for lending platform clients.\n * Provides a unified interface for interacting with different lending protocols.\n *\n * @typeParam T - The platform-specific data class extending LendingPlatformData\n */\nexport abstract class LendingPlatformClientBase<T extends LendingPlatformData> {\n public rpc!: Rpc<SolanaRpcApi>;\n public data!: T;\n public abstract accounts: LpAccountsBase<T>;\n public abstract ix: LpInstructionsBase<T>;\n\n constructor(rpcUrl: string, rpcUrls: string[] = [rpcUrl]) {\n this.rpc = createRpcWithFailover(rpcUrls);\n }\n\n applyPostSuccessCacheInvalidations(invalidations: TransactionCacheInvalidation[]) {\n this.ix.applyPostSuccessCacheInvalidations(invalidations);\n }\n\n /** Refreshes cached platform data for the specified pools */\n abstract refreshData(pools: Address[]): Promise<void>;\n\n /**\n * Returns this platform's flash-loan client. Implementations should throw\n * if the platform doesn't expose a flash-loan facility.\n */\n abstract getFlashLoan(): FlashLoanBase<T>;\n\n /**\n * Returns the platform-specific \"repay full obligation debt\" sentinel for\n * the repay CPI's amount field, or `null` if the platform has no such\n * sentinel and callers must compute the exact debt amount themselves.\n * Used by `rebalance_token` on full-position moves to clear obligation\n * debt exactly without leaving interest-accrual dust.\n */\n abstract getRepayAllSentinel(): BN | null;\n\n /**\n * Returns the first user-account ID that can be used in `pool` for `user`.\n *\n * Implementations may reuse an existing inactive account or return the first\n * never-before-used ID, depending on the platform's account model.\n *\n * `excludeUserAccounts`, when provided, lists protocol user-account\n * addresses that must NOT be returned even if they look reusable on-chain\n * (e.g. zero deposits + zero borrows). Callers managing multiple\n * higher-level positions over the same `(pool, user)` pair use this to\n * ensure each position gets its own distinct user account, even when\n * sibling positions are temporarily inactive on-chain.\n */\n abstract getAvailableUserAccountId(\n pool: Address,\n user: Address,\n excludeUserAccounts?: readonly Address[]\n ): Promise<number>;\n\n /**\n * Returns the protocol user account's currently claimable rewards, excluding\n * zero balances. Entries may include claim metadata required by the platform\n * to harvest that specific reward.\n *\n * `minUiAmount` filters out dust: rewards whose UI-denominated balance is\n * below this threshold are omitted, so callers don't pay transaction fees to\n * harvest economically negligible amounts. Defaults to `0` (no filtering).\n */\n abstract getOutstandingIncentives(\n userAccount: Address,\n minUiAmount?: number,\n log?: (msg: string) => void\n ): Promise<OutstandingIncentive[]>;\n}\n","/**\n * `DataCache` category keys for `LendingPlatformData` and platform implementations.\n * Prefer `data.poolCatKey` / `data.reserveCatKey` / `data.userAccountCatKey` when you have a data\n * instance so subclasses stay consistent; import these constants for static references or other packages.\n */\nexport const LENDING_PLATFORM_DATA_CACHE_CATEGORY_POOL = \"pool\";\nexport const LENDING_PLATFORM_DATA_CACHE_CATEGORY_RESERVE = \"reserve\";\nexport const LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT = \"userAccount\";\n","import { type Address, type Rpc, type SolanaRpcApi } from \"@solana/kit\";\nimport { ReserveBase, UserPositionBase } from \"..\";\nimport { createRpcWithFailover, DataCache, CacheTtlConfig, getSlot } from \"common\";\nimport { LendingPlatform } from \"../../types\";\nimport {\n LENDING_PLATFORM_DATA_CACHE_CATEGORY_POOL,\n LENDING_PLATFORM_DATA_CACHE_CATEGORY_RESERVE,\n LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT,\n} from \"../../constants/cache\";\n\n/**\n * Abstract base class for fetching and caching lending platform data.\n * Provides a unified interface for accessing markets, reserves, and user positions\n * across different lending protocols with built-in TTL-based caching.\n */\nexport abstract class LendingPlatformData {\n protected rpc!: Rpc<SolanaRpcApi>;\n protected cache!: DataCache;\n\n public poolCatKey = LENDING_PLATFORM_DATA_CACHE_CATEGORY_POOL;\n public reserveCatKey = LENDING_PLATFORM_DATA_CACHE_CATEGORY_RESERVE;\n public userAccountCatKey = LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT;\n\n constructor(rpcUrl: string, cacheTtlConfig?: CacheTtlConfig, rpcUrls: string[] = [rpcUrl]) {\n this.rpc = createRpcWithFailover(rpcUrls);\n this.cache = new DataCache(cacheTtlConfig);\n }\n\n /** Returns the platform identifier for this data provider */\n abstract platform(): LendingPlatform;\n\n /** Loads and caches data for the specified lending pools/markets */\n abstract load(pools: Address[]): Promise<void>;\n\n clearCache() {\n this.cache.clearAllCache();\n }\n\n clearCacheEntry(category: string, id: string) {\n this.cache.clearCacheEntry(category, id);\n }\n\n /** Returns the current slot, cached to reduce RPC calls */\n async getSlot() {\n const { data } = await this.cache.getDataOrThrow<bigint>(\n async () => await getSlot(this.rpc),\n \"slot\",\n \"slot\"\n );\n return data;\n }\n\n /** Fetches a single user position by address if it exists */\n abstract maybeFetchUserPositionInPool(\n pool: Address,\n userPosition: Address\n ): Promise<UserPositionBase | null>;\n\n /** Fetches multiple user positions by their addresses */\n abstract fetchUserPositionsInPool(\n pool: Address,\n userPositions: Address[]\n ): Promise<UserPositionBase[]>;\n\n /** Fetches all positions owned by a user in a specific pool */\n abstract fetchAllUserPositionsForUserInPool(\n pool: Address,\n user: Address\n ): Promise<UserPositionBase[]>;\n\n /** Fetches reserve data by reserve address */\n abstract fetchReserve(pool: Address, reserve: Address): Promise<ReserveBase | null>;\n\n /** Fetches reserve data by the underlying token mint */\n abstract fetchReserveByMint(pool: Address, mint: Address): Promise<ReserveBase | null>;\n}\n","import { address } from \"@solana/kit\";\nimport { LendingPlatformAccounts } from \"../types\";\n\nexport const KAMINO_FARMS_PROGRAM_ID = address(\"FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr\");\nexport const KAMINO_SCOPE_PROGRAM_ID = address(\"HFn8GnPADiny6XqUoWE8uRPPxb29ikn4yTuPa9MF2fWJ\");\n\nexport const KAMINO_MAIN_MARKET = address(\"7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF\");\nexport const SOL_RESERVE = address(\"d4A2prbA2whesmvHaL88BH6Ewn5N4bTSU2Ze8P6Bc4Q\");\nexport const USDC_RESERVE = address(\"D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59\");\n\nexport const KAMINO_ACCOUNTS: LendingPlatformAccounts = {\n [KAMINO_MAIN_MARKET]: [\n {\n address: SOL_RESERVE,\n mintSymbol: \"SOL\",\n },\n {\n address: address(\"37Jk2zkz23vkAYBT66HM2gaqJuNg2nYLsCreQAVt5MWK\"),\n mintSymbol: \"cbBTC\",\n },\n {\n address: address(\"febGYTnFX4GbSGoFHFeJXUHgNaK53fB23uDins9Jp1E\"),\n mintSymbol: \"wETH\",\n },\n {\n address: address(\"DGQZWCY17gGtBUgdaFs1VreJWsodkjFxndPsskwFKGpp\"),\n mintSymbol: \"JupSOL\",\n },\n {\n address: address(\"CkgQnPbuHHwSv2mNdAKH79TKSqC6jsyttK9yh4MPH6z3\"),\n mintSymbol: \"dfdvSOL\",\n },\n {\n address: USDC_RESERVE,\n mintSymbol: \"USDC\",\n },\n {\n address: address(\"2gc9Dm1eB6UgVYFBUN9bWks6Kes9PbWSaPaa9DqyvEiN\"),\n mintSymbol: \"PYUSD\",\n },\n {\n address: address(\"ApQkX32ULJUzszZDe986aobLDLMNDoGQK8tRm6oD6SsA\"),\n mintSymbol: \"CASH\",\n },\n {\n address: address(\"ESCkPWKHmgNE7Msf77n9yzqJd5kQVWWGy3o5Mgxhvavp\"),\n mintSymbol: \"USDG\",\n },\n {\n address: address(\"BHUi32TrEsfN2U821G4FprKrR4hTeK4LCWtA3BFetuqA\"),\n mintSymbol: \"USDS\",\n },\n {\n address: address(\"H3t6qZ1JkguCNTi9uzVKqQ7dvt2cum4XiXWom6Gn5e5S\"),\n mintSymbol: \"USDT\",\n },\n ],\n /// xStocks Market\n [address(\"5wJeMrUYECGq41fxRESKALVcHnNX26TAWy4W98yULsua\")]: [\n {\n address: address(\"2jerdAXR8r2B6z3P7P6VgSiePQX7wqcpbEqdDbm8mgeB\"),\n mintSymbol: \"QQQx\",\n },\n {\n address: address(\"UvXjBuC7YZYaGB9Rn1PpBD1GySmjzunXgE8Zev9ua8d\"),\n mintSymbol: \"SPYx\",\n },\n {\n address: address(\"97zoywd8mPZsGTg8q1wdD2Wgkdrs2tqusp1Qqcxbyj7E\"),\n mintSymbol: \"USDC\",\n },\n ],\n // Bitcoin Market\n // [address(\"GMqmFygF5iSm5nkckYU6tieggFcR42SyjkkhK5rswFRs\")]: [\n // {\n // address: address(\"2Xd86oYAuhiKtQMVJBuWvJYxrSippreb46PmehGszpPQ\"),\n // mintSymbol: \"wBTC\"\n // },\n // {\n // address: address(\"9FRZvAsjDJ6WM8BJ2S45h9PoDCLAq8DNY9zZDX7MyGzT\"),\n // mintSymbol: \"USDC\"\n // }\n // ]\n};\n","/** Maximum value for `targetUtilizationRateBps` (100% LTV utilization). */\nexport const MAX_TARGET_UTILIZATION_RATE_BPS = 10_000;\n\n/**\n * Maximum unwind-trigger utilization: `target + maxDeviationAbove`.\n * Mirrors `MAX_LENDING_POSITION_UPPER_UTIL_BPS` in the on-chain program.\n */\nexport const MAX_LENDING_POSITION_UPPER_UTIL_BPS = 10_500;\n","export * from \"./cache\";\nexport * from \"./kamino\";\nexport * from \"./lendingPosition\";\n","import { Address } from \"@solana/kit\";\n\nexport interface KaminoExtraFarmData {\n market: Address;\n debtMint: Address;\n collMint: Address;\n farm: Address;\n rewardPayerTokenMint: Address;\n collReserve: Address;\n debtReserve: Address;\n}\n","import { Address } from \"@solana/kit\";\n\n/** Supported lending platforms */\nexport enum LendingPlatform {\n Kamino,\n}\n\nexport interface OutstandingIncentiveClaimAccounts {\n farm: Address;\n userFarm: Address;\n}\n\n/**\n * Represents a hypothetical change to a user's position.\n * Used for simulating APY changes before executing transactions.\n * Values are in UI units (token amounts, not raw).\n */\nexport interface PositionBalanceChange {\n /** Change in collateral amount (positive = deposit, negative = withdraw) */\n collateralChange?: number;\n /** Change in debt amount (positive = borrow, negative = repay) */\n debtChange?: number;\n}\n\n/** A claimable lending-platform incentive balance for a specific claim path. */\nexport interface OutstandingIncentive {\n mint: Address;\n /** Claimable balance in the reward token's raw base units. */\n amount: number;\n /** Decimals of the reward token mint (0 if unknown). */\n decimals: number;\n /** Claimable balance in UI units (`amount / 10 ** decimals`). */\n uiAmount: number;\n claimAccounts?: OutstandingIncentiveClaimAccounts;\n}\n\nexport interface SupportedReserve {\n address: Address;\n mintSymbol: string;\n}\n\n/** Pool mapped to supported reserves */\nexport type LendingPlatformAccounts = Record<Address, SupportedReserve[]>;\n","export * from \"./kamino\";\nexport * from \"./general\";\n","import type { Address } from \"@solana/kit\";\nimport { KAMINO_ACCOUNTS } from \"../constants\";\n\n/**\n * Returns all lending pool addresses that list a reserve matching the\n * given mint symbol (case-insensitive).\n *\n * Useful for resolving which pool(s) a collateral token is eligible for\n * when the caller hasn't specified a pool explicitly.\n */\nexport function getEligiblePools(mintSymbol: string): Address[] {\n const needle = mintSymbol.toUpperCase();\n const pools: Address[] = [];\n\n for (const pool of Object.keys(KAMINO_ACCOUNTS)) {\n const reserves = KAMINO_ACCOUNTS[pool as Address];\n if (reserves.some((r) => r.mintSymbol.toUpperCase() === needle)) {\n pools.push(pool as Address);\n }\n }\n\n return pools;\n}\n\n/**\n * Returns all mint symbols listed in a given lending pool.\n *\n * Callers can cross-reference with the common mint registry's `assetType`\n * to filter for stablecoins, LSTs, etc.\n */\nexport function getBorrowableMintsForPool(pool: Address): string[] {\n const reserves = KAMINO_ACCOUNTS[pool];\n if (!reserves) {\n throw new Error(`getBorrowableMintsForPool: unknown pool ${pool}`);\n }\n return reserves.map((r) => r.mintSymbol);\n}\n","import { type Address } from \"@solana/kit\";\nimport { type TransactionCacheInvalidation } from \"common\";\nimport { LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT } from \"../constants/cache\";\n\nexport function getLendingUserAccountCacheInvalidation(\n userAccount: Address\n): TransactionCacheInvalidation {\n return {\n client: \"kamino\",\n category: LENDING_PLATFORM_DATA_CACHE_CATEGORY_USER_ACCOUNT,\n id: userAccount,\n };\n}\n","import {\n calculateCurrentRewardPerToken,\n RewardInfo,\n SECONDS_IN_A_DAY,\n} from \"@kamino-finance/farms-sdk\";\nimport { BN } from \"@anchor-lang/core\";\nimport { LendingMarket, PROGRAM_ID } from \"@kamino-finance/klend-sdk\";\nimport { Address } from \"@solana/kit\";\nimport {\n createRpcWithRetry,\n currentUnixSeconds,\n DAYS_PER_YEAR,\n fetchWithRetry,\n fromUiAmount,\n mints,\n toUiAmount,\n} from \"common\";\nimport Decimal from \"decimal.js\";\nimport { KaminoReserveData } from \"../data\";\nimport { KaminoExtraFarmData } from \"../types\";\n\ninterface KaminoResources {\n \"mainnet-beta\": { extraFarms: KaminoExtraFarmData[] };\n}\n\n/**\n * Fetches extra farm configurations from Kamino's CDN.\n */\nexport async function fetchExtraFarms(): Promise<KaminoExtraFarmData[]> {\n const cdnRes = await fetchWithRetry(\"https://cdn.kamino.finance/resources.json\");\n const allResources = (await cdnRes.json()) as KaminoResources;\n return allResources[\"mainnet-beta\"][\"extraFarms\"];\n}\n\n/**\n * Fetches all Kamino lending markets from on-chain program accounts.\n * @returns Array of market objects with address, name, and decoded state\n */\nexport async function getAllKaminoMarkets(rpcUrl: string) {\n const rpc = createRpcWithRetry(rpcUrl);\n\n const accounts = await rpc\n .getProgramAccounts(PROGRAM_ID, {\n filters: [\n {\n dataSize: BigInt(LendingMarket.layout.span + 8), // +8 for discriminator\n },\n ],\n encoding: \"base64\",\n })\n .send();\n\n return accounts.map((account) => {\n const market = LendingMarket.decode(Buffer.from(account.account.data[0], \"base64\"));\n const name = Buffer.from(market.name).toString(\"utf8\").replace(/\\0/g, \"\");\n return {\n address: account.pubkey,\n name,\n state: market,\n };\n });\n}\n\n/**\n * Calculates the APY for a farm reward based on current reward emissions and total staked amount.\n * Converts daily reward rate to annualized percentage yield using compound interest formula.\n *\n * @param reserveMint - The mint address of the reserve's underlying token\n * @param rewardInfo - Farm reward configuration containing emission rate and token info\n * @param totalStakedRaw - Total amount staked in the farm (raw units as string)\n * @param stakedTokenDecimals - Decimal places for the staked token\n * @param exchangeRate - Exchange rate between staked shares and underlying tokens\n * @param rewardMintPrice - USD price of the reward token (used for non-stablecoin rewards)\n * @param requiresPairReserve - If the Kamino incentive requires a pair reserve in order to be eligible\n * @returns Annualized percentage yield as a decimal (e.g., 0.05 = 5% APY)\n */\nexport function calculateRewardAPY(\n reserveMint: Address,\n rewardInfo: RewardInfo,\n totalStakedRaw: string,\n stakedTokenDecimals: number,\n exchangeRate: number,\n rewardMintPrice: number,\n requiresPairReserve: boolean\n): number {\n let totalStaked = new Decimal(toUiAmount(BigInt(totalStakedRaw), stakedTokenDecimals));\n if (!requiresPairReserve) {\n totalStaked = totalStaked.div(exchangeRate);\n }\n if (totalStaked.isZero()) return 0;\n\n const rewardPerTokenPerSecond = calculateCurrentRewardPerToken(\n rewardInfo,\n new Decimal(currentUnixSeconds())\n );\n\n if (!rewardPerTokenPerSecond) return 0;\n\n const divisor = new Decimal(10)\n .pow(new Decimal(rewardInfo.rewardsPerSecondDecimals.toString()))\n .mul(new Decimal(10).pow(new Decimal(rewardInfo.token.decimals.toString())));\n\n const adjustedRewardPerToken = new Decimal(rewardPerTokenPerSecond).div(divisor);\n let dailyRewards = adjustedRewardPerToken.mul(SECONDS_IN_A_DAY);\n\n if (\n mints.get(rewardInfo.token.mint)?.assetType !== \"Stablecoin\" &&\n rewardInfo.token.mint !== reserveMint\n ) {\n dailyRewards = dailyRewards.mul(new Decimal(rewardMintPrice));\n }\n\n const dailyRate = dailyRewards.div(totalStaked);\n const apy = Decimal.pow(dailyRate.plus(1), DAYS_PER_YEAR).minus(1);\n\n return apy.toNumber();\n}\n\n/**\n * Converts a liquidity (underlying token) amount to collateral (cToken) amount\n * using the reserve's estimated exchange rate.\n *\n * Kamino's withdraw V2 instruction expects the amount in cTokens, so this\n * conversion is needed when the caller specifies a liquidity amount to withdraw.\n *\n * @param reserveData - The reserve to use for the exchange rate\n * @param liquidityBaseUnits - Amount in liquidity base units (e.g., USDC smallest unit)\n * @returns Amount in collateral base units (cTokens), floored to avoid overdrawing\n */\nexport function liquidityToCollateral(\n reserveData: KaminoReserveData,\n liquidityBaseUnits: number\n): number {\n const exchangeRate = reserveData.rawData\n .getEstimatedCollateralExchangeRate(reserveData.slot, 0)\n .toNumber();\n return Math.floor(liquidityBaseUnits * exchangeRate);\n}\n\n/**\n * Converts a collateral (cToken) amount back to liquidity base units using the\n * same estimated exchange rate as Kamino's reserve math.\n *\n * @param reserveData - The reserve to use for the exchange rate\n * @param collateralBaseUnits - Amount in collateral base units (cTokens)\n * @returns Amount in liquidity base units, floored to preserve withdraw safety\n */\nexport function collateralToLiquidity(\n reserveData: KaminoReserveData,\n collateralBaseUnits: number\n): number {\n const exchangeRate = reserveData.rawData\n .getEstimatedCollateralExchangeRate(reserveData.slot, 0)\n .toNumber();\n return Math.floor(collateralBaseUnits / exchangeRate);\n}\n\n/**\n * Normalizes a requested liquidity withdraw amount to the actual liquidity that\n * Kamino can redeem after converting through collateral shares.\n *\n * Kamino withdraws collateral shares, not raw liquidity. Because the liquidity\n * -> collateral conversion floors, a requested liquidity amount may redeem\n * slightly less liquidity in practice. Round-tripping through collateral shares\n * lets callers pre-snap to the realizable liquidity amount.\n *\n * @param reserveData - Source reserve used for the withdraw\n * @param liquidityBaseUnits - Requested liquidity amount in base units\n * @returns Realizable liquidity amount after liquidity -> collateral -> liquidity\n */\nexport function normalizeLiquidityWithdrawAmount(\n reserveData: KaminoReserveData,\n liquidityBaseUnits: BN | number\n): BN {\n const requestedBaseUnits =\n typeof liquidityBaseUnits === \"number\" ? liquidityBaseUnits : liquidityBaseUnits.toNumber();\n const collateralBaseUnits = liquidityToCollateral(reserveData, requestedBaseUnits);\n return new BN(collateralToLiquidity(reserveData, collateralBaseUnits));\n}\n\n/**\n * Smallest liquidity (underlying) base-unit withdraw request such that, after Kamino's\n * liquidity→collateral→liquidity rounding ({@link normalizeLiquidityWithdrawAmount}),\n * the **realized** liquidity is still at least `minLiquidityOut`.\n *\n * Used for `burn_token` withdraw CPI sizing: the on-chain program credits `unlent_amount`\n * from the actual token balance delta; if the requested withdraw floors below the burn's\n * `collateral_to_user`, the instruction fails with `InsufficientUnlentCollateral`.\n */\nexport function minLiquidityWithdrawForPayout(\n reserveData: KaminoReserveData,\n minLiquidityOut: BN\n): BN {\n const min = new BN(minLiquidityOut.toString());\n\n if (normalizeLiquidityWithdrawAmount(reserveData, min).gte(min)) {\n return min;\n }\n\n let hi = min.clone();\n let expanded = false;\n for (let i = 0; i < 64; i++) {\n hi = hi.muln(2);\n if (normalizeLiquidityWithdrawAmount(reserveData, hi).gte(min)) {\n expanded = true;\n break;\n }\n }\n if (!expanded) {\n throw new Error(\n `minLiquidityWithdrawForPayout: could not bracket min out ${minLiquidityOut.toString()}`\n );\n }\n\n let loBn = min.clone();\n let hiBn = hi.clone();\n while (loBn.lt(hiBn)) {\n const mid = loBn.add(hiBn).shrn(1);\n const realized = normalizeLiquidityWithdrawAmount(reserveData, mid);\n if (realized.gte(min)) {\n hiBn = mid;\n } else {\n loBn = mid.addn(1);\n }\n }\n return loBn;\n}\n\n/**\n * Normalizes a requested UI liquidity withdraw amount to the realizable UI\n * liquidity amount after Kamino rounds through collateral shares.\n *\n * @param reserveData - Source reserve used for the withdraw\n * @param uiAmount - Requested liquidity amount in UI units\n * @returns Realizable liquidity amount in UI units\n */\nexport function normalizeLiquidityWithdrawUiAmount(\n reserveData: KaminoReserveData,\n uiAmount: number\n): number {\n const requestedBaseUnits = fromUiAmount(uiAmount, reserveData.mint.mintDecimals);\n const normalizedBaseUnits = normalizeLiquidityWithdrawAmount(reserveData, requestedBaseUnits);\n return toUiAmount(normalizedBaseUnits, reserveData.mint.mintDecimals);\n}\n","import { LendingPlatform } from \"../types\";\nimport { KaminoClient } from \"../services\";\n\n/**\n * Get a lending platform client. Markets are loaded lazily on first use.\n */\nexport function getLpClient(\n lendingPlatform: LendingPlatform,\n rpcUrl: string,\n rpcUrls: string[] = [rpcUrl]\n) {\n if (lendingPlatform === LendingPlatform.Kamino) {\n return new KaminoClient(rpcUrl, rpcUrls);\n } else {\n throw new Error(\"Lending platform not yet supported\");\n }\n}\n","/**\n * LTV utilization math (same definition as `ReservesManager.calcLtvUtilizationRateBps` /\n * Kamino `borrowedValueUsd / borrowLimit`):\n *\n * ```\n * ltvUtilization = debtUsd / (collateralUsd × maxLtv)\n * ```\n *\n * **Assumptions:** debt USD fixed; only collateral USD moves. Liquidation uses a one-collateral sketch\n * (`debt ≤ collateral × liquidationThreshold`). Real obligations are multi-asset.\n */\n\nfunction clampUnitInterval(x: number): number {\n if (x <= 0) return 0;\n if (x >= 1) return 1;\n return x;\n}\n\nfunction assertLtv(ltv: number): void {\n if (!(ltv > 0) || ltv > 1) {\n throw new RangeError(\"ltv must be in (0, 1] (e.g. 0.8 for 80% max LTV)\");\n }\n}\n\nfunction assertLiquidationThreshold(t: number): void {\n if (!(t > 0) || t > 1) {\n throw new RangeError(\"liquidationThreshold must be in (0, 1] (e.g. 0.85)\");\n }\n}\n\nfunction maxLtvUtilBeforeCollUsdMultiplierInternal(params: {\n collateralUsdMultiplier: number;\n ltv: number;\n targetMaxBorrowUtilizationAfter?: number;\n liquidationThreshold?: number;\n}): number {\n const {\n collateralUsdMultiplier: mult,\n ltv,\n liquidationThreshold,\n targetMaxBorrowUtilizationAfter = 1,\n } = params;\n\n assertLtv(ltv);\n if (!(mult > 0)) {\n throw new RangeError(\"collateralUsdMultiplier must be positive\");\n }\n\n if (liquidationThreshold !== undefined) {\n assertLiquidationThreshold(liquidationThreshold);\n return clampUnitInterval((mult * liquidationThreshold) / ltv);\n }\n\n if (!(targetMaxBorrowUtilizationAfter > 0) || targetMaxBorrowUtilizationAfter > 1) {\n throw new RangeError(\n \"targetMaxBorrowUtilizationAfter must be in (0, 1] (1 = 100% of borrow limit)\"\n );\n }\n\n return clampUnitInterval(mult * targetMaxBorrowUtilizationAfter);\n}\n\n/**\n * If collateral drops X% (positive `drawdownPercent`), what **current** LTV utilization (decimal) stays\n * within the constraint? With `liquidationThreshold`, caps so that after the drop the sketch stays solvent:\n * `target ≤ (1 − drawdown/100) × liquidationThreshold / maxLtv`.\n *\n * Without `liquidationThreshold`, caps so post-drop utilization ≤ `targetMaxBorrowUtilizationAfter` (default 1).\n */\nexport function maxLtvUtilBeforeCollDrawdown(params: {\n drawdownPercent: number;\n ltv: number;\n targetMaxBorrowUtilizationAfter?: number;\n liquidationThreshold?: number;\n}): number {\n if (!(params.drawdownPercent >= 0)) {\n throw new RangeError(\"drawdownPercent must be non-negative (e.g. 30 for a 30% drop)\");\n }\n const collateralUsdMultiplier = 1 - params.drawdownPercent / 100;\n if (!(collateralUsdMultiplier > 0)) {\n throw new RangeError(\n \"drawdownPercent must be less than 100 so collateral USD remains positive\"\n );\n }\n return maxLtvUtilBeforeCollUsdMultiplierInternal({\n collateralUsdMultiplier,\n ltv: params.ltv,\n targetMaxBorrowUtilizationAfter: params.targetMaxBorrowUtilizationAfter,\n liquidationThreshold: params.liquidationThreshold,\n });\n}\n\n/**\n * LTV utilization after collateral **USD** moves by `collateralPricePctChg`, with debt USD unchanged.\n *\n * `collateralPricePctChg`: signed percent on collateral price, e.g. `10` = +10% rally, `-30` = −30% crash.\n * Formula: `newUtil = currentUtil / (1 + collateralPricePctChg/100)`.\n */\nexport function ltvUtilAfterCollateralPricePctChg(\n currentLtvUtilization: number,\n collateralPricePctChg: number\n): number {\n if (!(currentLtvUtilization >= 0) || currentLtvUtilization > 1) {\n throw new RangeError(\"currentLtvUtilization must be in [0, 1]\");\n }\n const mult = 1 + collateralPricePctChg / 100;\n if (!(mult > 0)) {\n throw new RangeError(\n \"collateralPricePctChg must be greater than -100 so collateral USD stays positive\"\n );\n }\n return currentLtvUtilization / mult;\n}\n\n/**\n * If you sit at **target** utilization and collateral **rallies** `rallyPercentPositive` (e.g. `25` = +25%),\n * utilization falls. This returns how far **below** target it lands — the width of `maxDeviationBelowTarget`\n * that lines up with that rally for carry-style triggers.\n *\n * Equivalent to: `target − ltvUtilAfterCollateralPricePctChg(target, rallyPercentPositive)`.\n */\nexport function ltvUtilDeltaBelowTargForRallyPct(\n targetLtvUtilization: number,\n rallyPercentPositive: number\n): number {\n if (!(targetLtvUtilization > 0) || targetLtvUtilization > 1) {\n throw new RangeError(\"targetLtvUtilization must be in (0, 1]\");\n }\n if (!Number.isFinite(rallyPercentPositive) || rallyPercentPositive <= 0) {\n throw new RangeError(\"rallyPercentPositive must be finite and positive\");\n }\n const after = ltvUtilAfterCollateralPricePctChg(targetLtvUtilization, rallyPercentPositive);\n return targetLtvUtilization - after;\n}\n\n/**\n * If you sit at **target** utilization and collateral **falls** `dropPercentPositive` (e.g. `20` = −20%),\n * utilization rises. This returns how far **above** target it lands — the width of `maxDeviationAboveTarget`\n * that lines up with that drop for carry-style triggers.\n *\n * Equivalent to: `ltvUtilAfterCollateralPricePctChg(target, -dropPercentPositive) − target`.\n */\nexport function ltvUtilDeltaAboveTargForDropPct(\n targetLtvUtilization: number,\n dropPercentPositive: number\n): number {\n if (!(targetLtvUtilization > 0) || targetLtvUtilization > 1) {\n throw new RangeError(\"targetLtvUtilization must be in (0, 1]\");\n }\n if (\n !Number.isFinite(dropPercentPositive) ||\n dropPercentPositive <= 0 ||\n dropPercentPositive >= 100\n ) {\n throw new RangeError(\"dropPercentPositive must be in (0, 100)\");\n }\n const after = ltvUtilAfterCollateralPricePctChg(targetLtvUtilization, -dropPercentPositive);\n return after - targetLtvUtilization;\n}\n","import { Scope } from \"@kamino-finance/scope-sdk\";\nimport { OraclePrices } from \"@kamino-finance/scope-sdk/dist/@codegen/scope/accounts\";\nimport { Address, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { currentUnixSeconds, DEFAULT_PUBLIC_KEY } from \"common\";\nimport { KaminoReserveData } from \"../data/reserve/kamino\";\n\ntype OracleMappings = {\n refPrice: number[];\n priceTypes: number[];\n priceInfoAccounts: Address[];\n generic: number[][];\n};\n\nconst ORACLE_TYPE_MOST_RECENT_OF = 28;\nconst ORACLE_TYPE_CAPPED_FLOORED = 33;\nconst MOST_RECENT_OF_UNUSED = 512;\n\n/**\n * Recursively collects a token and all its Scope dependency tokens.\n *\n * Handles three dependency mechanisms:\n * - `refPrice`: ScopeTwap and similar read from a single reference index\n * - `generic` (MostRecentOf): stores up to 4 source token indices as u16 LE\n * - `generic` (CappedFloored): stores sourceEntry, capEntry, floorEntry\n */\nexport function collectTokenDependencies(\n token: number,\n mappings: OracleMappings,\n result: Set<number>,\n depth = 0\n): void {\n if (result.has(token) || depth > 5) return;\n\n const isValidDep = (dep: number) =>\n dep !== undefined &&\n dep !== token &&\n dep < mappings.priceInfoAccounts.length &&\n mappings.priceInfoAccounts[dep] !== DEFAULT_PUBLIC_KEY;\n\n const recurse = (dep: number) => collectTokenDependencies(dep, mappings, result, depth + 1);\n\n if (mappings.priceTypes[token] === ORACLE_TYPE_MOST_RECENT_OF) {\n const raw = mappings.generic[token];\n if (raw?.length >= 8) {\n for (let i = 0; i < 4; i++) {\n const src = raw[i * 2] | (raw[i * 2 + 1] << 8);\n if (src !== MOST_RECENT_OF_UNUSED && isValidDep(src)) {\n recurse(src);\n }\n }\n }\n } else if (mappings.priceTypes[token] === ORACLE_TYPE_CAPPED_FLOORED) {\n const raw = mappings.generic[token];\n if (raw?.length >= 7) {\n const sourceEntry = raw[0] | (raw[1] << 8);\n if (isValidDep(sourceEntry)) recurse(sourceEntry);\n\n // borsh Option<u16>: 1-byte tag (0=None,1=Some) + u16 value\n if (raw[2] === 1) {\n const capEntry = raw[3] | (raw[4] << 8);\n if (isValidDep(capEntry)) recurse(capEntry);\n }\n const floorOffset = raw[2] === 1 ? 5 : 3;\n if (raw[floorOffset] === 1) {\n const floorEntry = raw[floorOffset + 1] | (raw[floorOffset + 2] << 8);\n if (isValidDep(floorEntry)) recurse(floorEntry);\n }\n }\n }\n\n const dep = mappings.refPrice[token];\n if (isValidDep(dep)) {\n recurse(dep);\n }\n\n result.add(token);\n}\n\n/**\n * Checks if a reserve's Scope price chain has any stale entries by comparing\n * each entry's `unixTimestamp` against the reserve's configured max price age.\n * @param reserveData - The reserve to check\n * @param oraclePrices - The fetched Scope OraclePrices account\n * @param bufferSeconds - Lookahead buffer (same semantics as KaminoReserveData.requiresRefresh)\n */\nexport function isScopePriceStale(\n reserveData: KaminoReserveData,\n oraclePrices: OraclePrices,\n bufferSeconds = 10\n): boolean {\n const SCOPE_CHAIN_END = 65535; // U16_MAX — terminates the price chain\n const tokenInfo = reserveData.rawData.state.config.tokenInfo;\n const { priceChain, twapChain } = tokenInfo.scopeConfiguration;\n const isTwapEnabled = tokenInfo.maxTwapDivergenceBps.toNumber() > 0;\n\n const now = currentUnixSeconds();\n\n const isChainStale = (chain: number[], maxAge: number) => {\n for (const index of chain) {\n if (index === SCOPE_CHAIN_END) break;\n const datedPrice = oraclePrices.prices[index];\n if (!datedPrice || now - datedPrice.unixTimestamp.toNumber() > maxAge - bufferSeconds) {\n return true;\n }\n }\n return false;\n };\n\n const spotMaxAge = tokenInfo.maxAgePriceSeconds.toNumber();\n if (isChainStale(priceChain, spotMaxAge)) return true;\n\n if (isTwapEnabled) {\n const twapMaxAge = tokenInfo.maxAgeTwapSeconds.toNumber();\n if (isChainStale(twapChain, twapMaxAge)) return true;\n }\n\n return false;\n}\n\nconst ORACLE_TYPE_PYTH_PULL = 21;\nconst ORACLE_TYPE_PYTH_PULL_EMA = 22;\nconst SCOPE_CHAIN_END = 65535;\n\n/**\n * Returns the external PythPull / PythPullEMA oracle accounts from the Scope\n * dependency tree for the given Kamino reserves. These are the accounts whose\n * data Scope reads during RefreshPriceList — streaming them on a localnet fork\n * keeps Scope prices fresh.\n *\n * Only Pyth accounts are returned. Switchboard and other oracle types are\n * intentionally excluded because their on-chain data format can produce corrupt\n * values when streamed through Surfpool's account mirroring.\n */\nexport async function getScopePythAccounts(\n rpc: Rpc<SolanaRpcApi>,\n reserves: KaminoReserveData[]\n): Promise<Address[]> {\n const scope = new Scope(\"mainnet-beta\", rpc as any);\n const accounts = new Set<string>();\n\n for (const reserve of reserves) {\n const scopeFeed = reserve.getOracleAccounts().scope;\n if (!scopeFeed) continue;\n\n const [configAddr] = await scope.getSingleFeedConfiguration({ prices: scopeFeed });\n const mappings = await scope.getOracleMappings({ config: configAddr });\n\n const { priceChain, twapChain } = reserve.rawData.state.config.tokenInfo.scopeConfiguration;\n const chainTokens = new Set<number>();\n for (const chain of [priceChain, twapChain]) {\n for (const index of chain) {\n if (index === SCOPE_CHAIN_END) break;\n chainTokens.add(index);\n }\n }\n\n const allTokens = new Set<number>();\n for (const token of chainTokens) {\n collectTokenDependencies(token, mappings, allTokens);\n }\n\n for (const token of allTokens) {\n const type = mappings.priceTypes[token];\n if (type === ORACLE_TYPE_PYTH_PULL || type === ORACLE_TYPE_PYTH_PULL_EMA) {\n const account = mappings.priceInfoAccounts[token];\n if (account && account !== DEFAULT_PUBLIC_KEY) {\n accounts.add(account);\n }\n }\n }\n }\n\n return [...accounts] as Address[];\n}\n","export * from \"./accounts\";\nexport * from \"./cache\";\nexport * from \"./kamino\";\nexport * from \"./lendingPlatform\";\nexport * from \"./math\";\nexport * from \"./scope\";\n","import { type Address } from \"@solana/kit\";\nimport {\n KaminoMarket,\n KaminoObligation,\n DEFAULT_RECENT_SLOT_DURATION_MS,\n PROGRAM_ID,\n DEFAULT_PUBLIC_KEY,\n KaminoReserve,\n KlendPrices,\n VanillaObligation,\n userMetadataPda,\n} from \"@kamino-finance/klend-sdk\";\nimport { Scope } from \"@kamino-finance/scope-sdk\";\nimport { Farms, FarmState, UserFarm } from \"@kamino-finance/farms-sdk\";\nimport { LendingPlatformData } from \"./lpDataBase\";\nimport { KaminoReserveData, KaminoUserPositionData, KaminoIncentiveDataArgs } from \"..\";\nimport { KAMINO_FARMS_PROGRAM_ID } from \"../../constants\";\nimport { LendingPlatform } from \"../../types\";\nimport { fetchExtraFarms } from \"../../utils\";\nimport { OraclePrices } from \"@kamino-finance/scope-sdk/dist/@codegen/scope/accounts\";\nimport { CacheTtlConfig, currentUnixSeconds } from \"common\";\nimport Decimal from \"decimal.js\";\n\n/** Cache configuration for Kamino data with optional market-specific TTL */\nexport interface KaminoCacheConfig extends CacheTtlConfig {\n marketsTtlMs?: number;\n}\n\n/** Internal type for tracking farm addresses and their type (collateral vs debt) */\ninterface FarmEntry {\n address: Address;\n isDebtFarm: boolean;\n}\n\n/**\n * Data provider for Kamino Lend protocol.\n * Handles fetching and caching of markets, reserves, obligations, farms, and prices.\n * Supports both standard reserve farms and \"extra\" farms (paired collateral/debt incentives).\n */\nexport class KaminoData extends LendingPlatformData {\n farms!: Farms;\n private scope!: Scope;\n\n constructor(rpcUrl: string, cacheConfig?: KaminoCacheConfig, rpcUrls: string[] = [rpcUrl]) {\n const ttlConfig: CacheTtlConfig = {\n defaultTtlMs: 90_000,\n categoryTtlMs: {\n ...cacheConfig?.categoryTtlMs,\n markets: 60_000 * 5,\n farms: 60_000 * 5,\n extraFarms: Number.MAX_SAFE_INTEGER,\n scopeOraclePrices: 30_000,\n scopeConfig: 60_000 * 5,\n },\n };\n super(rpcUrl, ttlConfig, rpcUrls);\n this.farms = new Farms(this.rpc, KAMINO_FARMS_PROGRAM_ID);\n this.scope = new Scope(\"mainnet-beta\", this.rpc as any);\n }\n\n platform(): LendingPlatform {\n return LendingPlatform.Kamino;\n }\n\n /**\n * Warms the market cache for the requested pools. Single-pool calls reuse the\n * normal lazy fetch path; multi-pool calls use Kamino's batched loader.\n */\n async load(pools: Address[]): Promise<void> {\n if (pools.length === 0) return;\n\n if (pools.length === 1) {\n await this.fetchMarket(pools[0]);\n return;\n }\n\n const { data: markets, fromCache } = await this.cache.getDataBatch<KaminoMarket>(\n async () => {\n const marketsData = await KaminoMarket.loadMultiple(\n this.rpc,\n pools,\n DEFAULT_RECENT_SLOT_DURATION_MS,\n PROGRAM_ID,\n true\n );\n return pools.map((pool) => marketsData.get(pool) ?? null);\n },\n this.poolCatKey,\n pools\n );\n\n if (!fromCache) {\n await Promise.all(markets.map(async (market) => await market.loadReserves()));\n }\n }\n\n /** Fetches a market by address, loading from cache if available */\n async fetchMarket(market: Address): Promise<KaminoMarket> {\n const { data, fromCache } = await this.cache.getDataOrThrow<KaminoMarket>(\n async () =>\n await KaminoMarket.load(\n this.rpc,\n market,\n DEFAULT_RECENT_SLOT_DURATION_MS,\n PROGRAM_ID,\n true\n ),\n this.poolCatKey,\n market\n );\n if (!fromCache) {\n await data.loadReserves();\n }\n return data;\n }\n\n /** Fetches all oracle prices for assets in the specified market */\n async fetchPrices(pool: Address) {\n const market = await this.fetchMarket(pool);\n const { data } = await this.cache.getDataOrThrow<KlendPrices>(\n async () => await market.getAllPrices(),\n \"prices\",\n \"queryAll\"\n );\n return data;\n }\n\n /** Fetches an obligation (user position) by address */\n async fetchObligation(\n market: KaminoMarket,\n obligation: Address\n ): Promise<KaminoObligation | null> {\n const { data } = await this.cache.getData<KaminoObligation>(\n async () => await market.getObligationByAddress(obligation),\n this.userAccountCatKey,\n obligation,\n { cacheNull: false }\n );\n return data;\n }\n\n /** Batch fetches farm states by their addresses */\n async fetchFarms(farms: Address[]) {\n const { data } = await this.cache.getDataBatch<FarmState>(\n async () => (await this.farms.getAllFarmStatesByPubkeys(farms)).map((x) => x.farmState),\n \"userFarms\",\n farms\n );\n return data;\n }\n\n private async fetchExtraFarms() {\n const { data } = await this.cache.getDataOrThrow(\n async () => await fetchExtraFarms(),\n \"extraFarms\",\n \"mainnet-beta\"\n );\n return data;\n }\n\n /**\n * Collects all farm incentives for a reserve, including both standard\n * collateral/debt farms and extra paired farms from Kamino CDN config.\n */\n private async fetchFarmsForReserve(\n pool: Address,\n reserve: Address\n ): Promise<KaminoIncentiveDataArgs[]> {\n const market = await this.fetchMarket(pool);\n const reserveData = market.getReserveByAddress(reserve);\n if (!reserveData) {\n throw new Error(`Unable to find reserve ${reserve}`);\n }\n\n const farms: FarmEntry[] = [];\n\n const farmCollateral = reserveData.state.farmCollateral;\n const farmDebt = reserveData.state.farmDebt;\n\n if (farmCollateral && farmCollateral !== DEFAULT_PUBLIC_KEY) {\n farms.push({ address: farmCollateral, isDebtFarm: false });\n }\n if (farmDebt && farmDebt !== DEFAULT_PUBLIC_KEY) {\n farms.push({ address: farmDebt, isDebtFarm: true });\n }\n\n const extraFarmsData = (await this.fetchExtraFarms()).filter(\n (x) => x.collReserve === reserve || x.debtReserve === reserve\n );\n const extraFarmEntries: FarmEntry[] = extraFarmsData.map((x) => ({\n address: x.farm,\n isDebtFarm: x.debtReserve === reserve,\n }));\n\n const allFarmEntries = [...farms, ...extraFarmEntries];\n const allFarmAddresses = allFarmEntries.map((f) => f.address);\n\n if (!allFarmAddresses.length) {\n return [];\n }\n\n const farmStates = await this.fetchFarms(allFarmAddresses);\n const result: KaminoIncentiveDataArgs[] = [];\n\n farmStates.forEach((farmState, i) => {\n const farmEntry = allFarmEntries[i];\n const isExtraFarm = i >= farms.length;\n const extraFarmIndex = i - farms.length;\n\n farmState.rewardInfos.forEach((rewardInfo, rewardIndex) => {\n if (rewardInfo.rewardsVault === DEFAULT_PUBLIC_KEY) {\n return;\n }\n\n result.push({\n data: {\n key: farmEntry.address,\n farmState,\n },\n rewardIndex,\n requiresPairReserve: isExtraFarm ? extraFarmsData[extraFarmIndex].debtReserve : undefined,\n isDebtFarm: farmEntry.isDebtFarm,\n });\n });\n });\n\n return result;\n }\n\n async fetchUserActiveIncentives(user: Address, specificFarm?: Address) {\n let { data } = await this.cache.getDataOrThrow<UserFarm[]>(\n async () => {\n return Array.from(\n (\n await this.farms.getAllFarmsForUserMultiState(user, new Decimal(currentUnixSeconds()))\n ).values()\n ).flat();\n },\n \"userFarms\",\n user\n );\n\n if (specificFarm) {\n data = data.filter((x) => x.farm === specificFarm);\n }\n\n return data;\n }\n\n async maybeFetchUserPositionInPool(\n pool: Address,\n userPosition: Address\n ): Promise<KaminoUserPositionData | null> {\n const market = await this.fetchMarket(pool);\n const obligation = await this.fetchObligation(market, userPosition);\n return obligation ? KaminoUserPositionData.loadData(obligation) : null;\n }\n\n async fetchUserPositionsInPool(\n pool: Address,\n userPositions: Address[]\n ): Promise<KaminoUserPositionData[]> {\n const market = await this.fetchMarket(pool);\n const { data } = await this.cache.getDataBatch<KaminoObligation>(\n async () => await market.getMultipleObligationsByAddress(userPositions),\n this.userAccountCatKey,\n userPositions\n );\n return data.map((obligation) => KaminoUserPositionData.loadData(obligation));\n }\n\n async fetchAllUserPositionsForUserInPool(\n pool: Address,\n user: Address\n ): Promise<KaminoUserPositionData[]> {\n const market = await this.fetchMarket(pool);\n const { data } = await this.cache.getDataOrThrow<KaminoObligation[]>(\n async () => await market.getAllUserObligations(user, \"confirmed\"),\n \"obligationsBatch\",\n user\n );\n return data.map((obligation) => KaminoUserPositionData.loadData(obligation));\n }\n\n async fetchReserve(pool: Address, reserve: Address): Promise<KaminoReserveData> {\n const market = await this.fetchMarket(pool);\n const reserveData = market.getReserveByAddress(reserve);\n if (!reserveData) {\n throw new Error(`Unable to find reserve ${reserve}`);\n }\n return this.mapReserve(market, reserveData);\n }\n\n async fetchReserveByMint(pool: Address, mint: Address): Promise<KaminoReserveData> {\n const market = await this.fetchMarket(pool);\n const reserveData = market.getReserveByMint(mint);\n if (!reserveData) {\n throw new Error(`Unable to find reserve by mint ${mint}`);\n }\n return this.mapReserve(market, reserveData);\n }\n\n private async mapReserve(\n market: KaminoMarket,\n reserve: KaminoReserve\n ): Promise<KaminoReserveData> {\n return KaminoReserveData.loadData(\n market,\n reserve,\n await this.fetchFarmsForReserve(market.address, reserve.address),\n await this.fetchPrices(market.address),\n await this.getSlot()\n );\n }\n\n /**\n * Fetches and caches the Scope OraclePrices account for a given price feed.\n * @returns The deserialized OraclePrices, or null if the account doesn't exist\n */\n async fetchScopeOraclePrices(priceFeed: Address): Promise<OraclePrices | null> {\n const { data } = await this.cache.getData<OraclePrices>(\n async () => await this.scope.getSingleOraclePrices({ prices: priceFeed }),\n \"scopeOraclePrices\",\n priceFeed\n );\n return data;\n }\n\n /**\n * Resolves and caches the Scope Configuration account address for a given OraclePrices account.\n * The first call per price feed does a getProgramAccounts lookup; subsequent calls use cache.\n */\n async fetchScopeConfigAddress(priceFeed: Address): Promise<Address> {\n const { data } = await this.cache.getDataOrThrow<Address>(\n async () => {\n const [configAddr] = await this.scope.getSingleFeedConfiguration({\n prices: priceFeed,\n });\n return configAddr;\n },\n \"scopeConfig\",\n priceFeed\n );\n return data;\n }\n}\n","export * from \"./kamino\";\nexport * from \"./lpDataBase\";\n","import { Address } from \"@solana/kit\";\nimport { PositionBalanceChange } from \"../../types\";\n\n/**\n * Categorizes when an incentive reward applies:\n * - LendingOnly: Only for lending\n * - BorrowingOnly: Only for borroweing\n * - Pair: Requires both collateral and debt in specific reserves\n */\nexport enum IncentiveType {\n LendingOnly = \"Lending\",\n BorrowingOnly = \"Borrowing\",\n Pair = \"Pair\",\n}\n\ninterface IncentiveConfig {\n rewardMint: Address;\n incentiveType: IncentiveType;\n /** If set, this incentive only applies when paired with this reserve */\n requiresPairReserve?: Address;\n}\n\n/**\n * Abstract base class for token reward incentives on lending reserves.\n * Incentives can apply to deposits, borrows, or paired positions.\n */\nexport abstract class TokenIncentiveBase {\n constructor(\n public address: Address,\n public config: IncentiveConfig\n ) {}\n\n /** Returns true if the incentive is currently active and emitting rewards */\n abstract active(): boolean;\n\n /** Returns the current APY from this incentive */\n abstract apy(): number;\n\n /** Simulates the APY after a hypothetical position change after changing total collateral deposits or debt borrows */\n abstract simulateNewAPY(args: PositionBalanceChange): number;\n}\n","import { Address } from \"@solana/kit\";\nimport Decimal from \"decimal.js\";\nimport { BN } from \"@anchor-lang/core\";\nimport { IncentiveType, TokenIncentiveBase } from \"./incentiveBase\";\nimport {\n FarmAndKey,\n FarmState,\n RewardInfo,\n calculateCurrentRewardPerToken,\n} from \"@kamino-finance/farms-sdk\";\nimport { currentUnixSeconds } from \"common\";\nimport { PositionBalanceChange } from \"../../types\";\nimport { calculateRewardAPY } from \"../../utils\";\nimport { KaminoReserve, KlendPrices } from \"@kamino-finance/klend-sdk\";\n\n/** Arguments for constructing a KaminoIncentiveData instance */\nexport interface KaminoIncentiveDataArgs {\n data: FarmAndKey;\n /** Index of the reward within the farm's rewardInfos array */\n rewardIndex: number;\n /** If set, this incentive requires a paired position with this reserve */\n requiresPairReserve?: Address;\n /** True if this is a debt farm (rewards borrowers), false for collateral farm */\n isDebtFarm: boolean;\n}\n\n/**\n * Kamino-specific incentive data for farm rewards.\n * Handles both collateral farms (reward lenders) and debt farms (reward borrowers),\n * as well as paired incentives that require specific collateral/debt combinations.\n */\nexport class KaminoIncentiveData extends TokenIncentiveBase {\n public rawReserve!: KaminoReserve;\n public rawFarm!: FarmState;\n public rewardInfo!: RewardInfo;\n public isDebtFarm!: boolean;\n\n private exchangeRate!: number;\n private rewardMintPrice!: number;\n\n /**\n * Creates a KaminoIncentiveData instance from farm and reserve data.\n * Determines the incentive type and calculates current exchange rates.\n */\n static loadData(\n args: KaminoIncentiveDataArgs,\n reserve: KaminoReserve,\n prices: KlendPrices,\n slot: bigint\n ): KaminoIncentiveData {\n const {\n data: { key, farmState },\n rewardIndex,\n requiresPairReserve,\n isDebtFarm,\n } = args;\n\n const rewardInfo = farmState.rewardInfos[rewardIndex];\n\n const data = new KaminoIncentiveData(key, {\n rewardMint: rewardInfo.token.mint,\n incentiveType: isDebtFarm\n ? IncentiveType.BorrowingOnly\n : requiresPairReserve\n ? IncentiveType.Pair\n : IncentiveType.LendingOnly,\n requiresPairReserve,\n });\n data.rawReserve = reserve;\n data.rawFarm = farmState;\n data.rewardInfo = farmState.rewardInfos[rewardIndex];\n data.isDebtFarm = isDebtFarm;\n\n const collateralExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0).toNumber();\n const debtExchangeRate = reserve.getEstimatedCumulativeBorrowRate(slot, 0).toNumber();\n data.exchangeRate = isDebtFarm ? debtExchangeRate : collateralExchangeRate;\n\n const rewardMint = rewardInfo.token.mint;\n const scope = prices.scope.spot[rewardMint];\n const pyth = prices.pyth.spot[rewardMint];\n const swb = prices.switchboard.spot[rewardMint];\n\n // TODO: need to fetch the price if kamino doesn't provide it\n data.rewardMintPrice = scope\n ? scope.price.toNumber()\n : pyth\n ? pyth.price.toNumber()\n : swb\n ? swb.price.toNumber()\n : 0;\n\n return data;\n }\n\n /**\n * Checks if the incentive is currently active.\n * An incentive is active if rewards are available, the schedule has started,\n * and there is a non-zero emission rate.\n */\n active(): boolean {\n const rewardsAvailable = this.rewardInfo.rewardsAvailable.gtn(0);\n const hasStarted =\n this.rewardInfo.rewardScheduleCurve.points[0].tsStart.toNumber() < currentUnixSeconds();\n const rewardPerTokenPerSecond = calculateCurrentRewardPerToken(\n this.rewardInfo,\n new Decimal(currentUnixSeconds())\n );\n\n return rewardsAvailable && hasStarted && rewardPerTokenPerSecond > 0;\n }\n\n /** Calculates the current APY based on total staked amount and reward emission rate */\n apy(): number {\n const { totalStaked, stakedTokenDecimals } = this.getStakedTokenData();\n return calculateRewardAPY(\n this.rawReserve.getLiquidityMint(),\n this.rewardInfo,\n totalStaked.toString(),\n stakedTokenDecimals,\n this.exchangeRate,\n this.rewardMintPrice,\n Boolean(this.config.requiresPairReserve)\n );\n }\n\n /**\n * Simulates the APY after a hypothetical position change.\n * Useful for calculating expected rewards before executing a transaction.\n */\n simulateNewAPY(args: PositionBalanceChange): number {\n const changeInUnderlying = this.isDebtFarm\n ? (args.debtChange ?? 0)\n : (args.collateralChange ?? 0);\n\n if (changeInUnderlying === 0) {\n return this.apy();\n }\n\n const { totalStaked, stakedTokenDecimals } = this.getStakedTokenData();\n const changeInShares = changeInUnderlying / this.exchangeRate;\n const changeInSharesRaw = new BN(\n Math.round(changeInShares * Math.pow(10, stakedTokenDecimals))\n );\n const newTotalStakedRaw = new BN(totalStaked.toString()).add(changeInSharesRaw);\n\n return calculateRewardAPY(\n this.rawReserve.getLiquidityMint(),\n this.rewardInfo,\n newTotalStakedRaw.toString(),\n stakedTokenDecimals,\n this.exchangeRate,\n this.rewardMintPrice,\n Boolean(this.config.requiresPairReserve)\n );\n }\n\n /**\n * Returns staking metrics for APY calculation.\n * Falls back to reserve decimals if farm token decimals are not set.\n */\n protected getStakedTokenData() {\n return {\n totalStaked: this.rawFarm.totalStakedAmount,\n stakedTokenDecimals:\n this.rawFarm.token.decimals.toNumber() ||\n (this.config.requiresPairReserve ? 6 : this.rawReserve.getMintDecimals()),\n };\n }\n}\n","export * from \"./incentiveBase\";\nexport * from \"./kamino\";\n","import type { Address } from \"@solana/kit\";\nimport { PRICE_STALENESS_SECONDS, sum } from \"common\";\nimport { IncentiveType, TokenIncentiveBase } from \"../incentive\";\nimport { PositionBalanceChange } from \"../../types\";\n\ntype IncentiveSide = \"supply\" | \"borrow\";\n\n/** Token mint information for a reserve's underlying asset */\ninterface ReserveMint {\n mint: Address;\n mintDecimals: number;\n mintTokenProgram: Address;\n price?: number;\n emaPrice?: number;\n}\n\n/** Risk and fee parameters for a reserve */\ninterface ReserveConfig {\n ltvPct: number;\n liquidationThresholdPct: number;\n borrowFeePct: number;\n flashLoanFeePct: number;\n /** E-mode configurations for enhanced LTV with specific debt reserves */\n emodes?: EmodeConfig[];\n}\n\n/** Aggregated metrics for deposit/borrow activity */\ninterface ReserveInteractionInfo {\n /** In UI amounts, e.g. 1.234 */\n totalAmount: number;\n /** In UI amounts, e.g. 1.234 */\n limit: number;\n apy: number;\n}\n\ninterface ReserveState {\n utilizationRatePct: number;\n availableLiquidity: number;\n}\n\n/** E-mode (efficiency mode) configuration for enhanced collateral ratios */\ninterface EmodeConfig {\n id?: number;\n debtReserve?: Address;\n ltvPct: number;\n liquidationThresholdPct: number;\n}\n\n/**\n * Abstract base class representing a lending reserve (asset pool).\n * Contains normalized data about deposits, borrows, rates, and incentives.\n */\nexport abstract class ReserveBase {\n private createdAt = Date.now();\n\n constructor(\n public address: Address,\n public mint: ReserveMint,\n public config: ReserveConfig,\n public deposits: ReserveInteractionInfo,\n public borrows: ReserveInteractionInfo,\n private state: ReserveState,\n public incentives?: TokenIncentiveBase[]\n ) {}\n\n private normalizeLtvPct(ltvPct: number): number {\n return ltvPct <= 1 ? ltvPct : ltvPct / 100;\n }\n\n /** Returns the cached price, or undefined if stale */\n get mintPrice(): number | undefined {\n if (this.mint.price === undefined) {\n return undefined;\n }\n const ageMs = Date.now() - this.createdAt;\n if (ageMs > PRICE_STALENESS_SECONDS * 1000) {\n return undefined;\n }\n return this.mint.price;\n }\n\n /** Returns the cached EMA price, or undefined if stale/missing */\n get mintEmaPrice(): number | undefined {\n if (this.mint.emaPrice === undefined) {\n return undefined;\n }\n const ageMs = Date.now() - this.createdAt;\n if (ageMs > PRICE_STALENESS_SECONDS * 1000) {\n return undefined;\n }\n return this.mint.emaPrice;\n }\n\n /** Returns oracle account addresses used for price feeds */\n abstract getOracleAccounts(): Record<string, Address | undefined>;\n\n /**\n * Returns the reserve LTV in decimal form, where `0.5 = 50%`.\n */\n get ltvPct(): number {\n return this.normalizeLtvPct(this.config.ltvPct);\n }\n\n /**\n * Returns e-mode configs with `ltvPct` normalized to decimal form, where\n * `0.5 = 50%`.\n */\n get emodes(): EmodeConfig[] | undefined {\n return this.config.emodes?.map((emode) => ({\n ...emode,\n ltvPct: this.normalizeLtvPct(emode.ltvPct),\n }));\n }\n\n utilizationRatePct(): number {\n return this.state.utilizationRatePct;\n }\n\n /** Returns borrowable liquidity, accounting for both available balance and borrow limits, in UI amount (e.g. 1.234) */\n liquidityAvailable(): number {\n return Math.min(this.state.availableLiquidity, this.borrows.limit - this.borrows.totalAmount);\n }\n\n /**\n * Returns the total supply APY including base rate and eligible supply-side\n * incentives (types `LendingOnly` and `Pair`). Borrow-side incentives are\n * excluded here — they reward borrowers, not lenders.\n * @param usingDebtReserve - When specified, includes paired incentives requiring this debt reserve\n */\n supplyAPY(usingDebtReserve?: Address) {\n return this.deposits.apy + this.sumEligibleIncentivesAPY(\"supply\", usingDebtReserve);\n }\n\n /** Simulates supply APY after a position change */\n abstract simulateNewSupplyAPY(args: PositionBalanceChange, usingDebtReserve?: Address): number;\n\n /**\n * Returns the effective borrow APY (base rate minus eligible borrow-side\n * incentive rebates, i.e. `BorrowingOnly`). Lender-side incentives are\n * excluded — they are paid to lenders and do not offset borrower cost.\n * @param usingSupplyReserve - When specified, includes paired incentives requiring this collateral\n */\n borrowAPY(usingSupplyReserve?: Address) {\n return this.borrows.apy - this.sumEligibleIncentivesAPY(\"borrow\", usingSupplyReserve);\n }\n\n /** Simulates borrow APY after a position change */\n abstract simulateNewBorrowAPY(args: PositionBalanceChange, usingSupplyReserve?: Address): number;\n\n /** Sums APY from incentives eligible for the given side and paired reserve */\n protected sumEligibleIncentivesAPY(side: IncentiveSide, usingPairReserve?: Address) {\n return sum(this.getEligibleIncentives(side, usingPairReserve).map((x) => x.apy()));\n }\n\n /** Sums the new simulated APY from incentives eligible for the given side and paired reserve */\n protected simulateNewEligbleIncentivesAPY(\n args: PositionBalanceChange,\n side: IncentiveSide,\n usingPairReserve?: Address\n ) {\n return sum(\n this.getEligibleIncentives(side, usingPairReserve).map((x) => x.simulateNewAPY(args))\n );\n }\n\n /**\n * Filters incentives eligible for the given side (supply vs borrow) and\n * paired reserve.\n *\n * Side filter:\n * - `supply`: `LendingOnly` and `Pair` (collateral-farm incentives,\n * optionally gated on a specific debt reserve).\n * - `borrow`: `BorrowingOnly` (debt-farm incentives, optionally gated on a\n * specific collateral reserve via `requiresPairReserve`).\n *\n * Pair filter: incentives with `requiresPairReserve` only apply when that\n * reserve matches the caller's pair.\n */\n protected getEligibleIncentives(\n side: IncentiveSide,\n usingPairReserve?: Address\n ): TokenIncentiveBase[] {\n return (this.incentives ?? []).filter((x) => {\n const sideMatches =\n side === \"borrow\"\n ? x.config.incentiveType === IncentiveType.BorrowingOnly\n : x.config.incentiveType !== IncentiveType.BorrowingOnly;\n if (!sideMatches) return false;\n return !x.config.requiresPairReserve || x.config.requiresPairReserve === usingPairReserve;\n });\n }\n\n canDeposit(amount: number): boolean {\n return amount <= this.deposits.limit;\n }\n\n abstract canWithdraw(amount: number): boolean;\n\n canBorrow(amount: number) {\n return amount <= this.borrows.limit;\n }\n}\n","import { Address } from \"@solana/kit\";\nimport {\n isNotNullPubkey,\n KaminoMarket,\n KaminoReserve,\n KlendPrices,\n} from \"@kamino-finance/klend-sdk\";\nimport Decimal from \"decimal.js\";\nimport { currentUnixSeconds, fromUiAmount, fromWeb3Pk, toUiAmount } from \"common\";\nimport { ReserveBase } from \"./reserveBase\";\nimport { KaminoIncentiveData, KaminoIncentiveDataArgs } from \"../incentive\";\nimport { PositionBalanceChange } from \"../../types\";\n\n/** Supported oracle types for Kamino price feeds */\nexport type OracleType = \"pythPrice\" | \"switchboardPrice\" | \"switchboardTwap\" | \"scope\";\n\nexport type ReserveOracleAccounts = Record<OracleType, Address | undefined>;\n\n/**\n * Kamino-specific reserve data implementation.\n * Wraps KaminoReserve with normalized accessors and oracle account resolution.\n */\nexport class KaminoReserveData extends ReserveBase {\n public rawData!: KaminoReserve;\n slot!: bigint;\n\n /**\n * Creates a KaminoReserveData instance from raw SDK types.\n * Extracts and normalizes configuration, rates, limits, and incentives.\n */\n static loadData(\n market: KaminoMarket,\n reserve: KaminoReserve,\n reserveFarms: KaminoIncentiveDataArgs[],\n prices: KlendPrices,\n slot: bigint\n ): KaminoReserveData {\n const stats = reserve.stats;\n const state = reserve.state;\n const config = state.config;\n\n const mintDecimals = reserve.getMintDecimals();\n const price = reserve.getOracleMarketPrice().toNumber();\n\n const allElevationGroups = config.elevationGroups\n .map((id) => market.getElevationGroup(id))\n .filter(\n (group) =>\n group !== undefined &&\n group.debtReserve !== reserve.address &&\n group.maxReservesAsCollateral === 1\n );\n\n const data = new KaminoReserveData(\n reserve.address,\n {\n mint: reserve.getLiquidityMint(),\n mintDecimals,\n mintTokenProgram: reserve.getLiquidityTokenProgram(),\n price,\n },\n {\n ltvPct: stats.loanToValue,\n liquidationThresholdPct: stats.liquidationThreshold,\n borrowFeePct: reserve.getBorrowFee().toNumber(),\n flashLoanFeePct: reserve.getFlashLoanFee().toNumber(),\n emodes: allElevationGroups.map((x) => ({\n id: x.id,\n debtReserve: x.debtReserve,\n ltvPct: x.ltvPct,\n liquidationThresholdPct: x.liquidationThresholdPct,\n })),\n },\n {\n totalAmount: reserve.getDepositTvl().toNumber() / price,\n limit: toUiAmount(config.depositLimit, mintDecimals),\n apy: reserve.totalSupplyAPY(slot),\n },\n {\n totalAmount: reserve.getBorrowTvl().toNumber() / price,\n limit: toUiAmount(config.borrowLimit, mintDecimals),\n apy: reserve.totalBorrowAPY(slot),\n },\n {\n utilizationRatePct: reserve.calculateUtilizationRatio(),\n availableLiquidity: toUiAmount(\n BigInt(reserve.getLiquidityAvailableAmount().toFixed(0)),\n mintDecimals\n ),\n },\n reserveFarms\n .map((x) => KaminoIncentiveData.loadData(x, reserve, prices, slot))\n .filter((x) => x.active() || [state.farmCollateral, state.farmDebt].includes(x.address))\n );\n\n data.rawData = reserve;\n data.slot = slot;\n\n return data;\n }\n\n /** Checks if TWAP price validation is enabled for this reserve */\n protected isTwapEnabled() {\n return this.rawData.state.config.tokenInfo.maxTwapDivergenceBps.toNumber() > 0;\n }\n\n /**\n * Determines if the reserve's on-chain price data is stale and needs refreshing.\n */\n requiresRefresh() {\n return true;\n }\n\n /**\n * Returns all configured oracle account addresses for this reserve.\n * Only includes accounts that are actually enabled.\n */\n getOracleAccounts(): ReserveOracleAccounts {\n const tokenInfo = this.rawData.state.config.tokenInfo;\n\n const pythAccount = tokenInfo.pythConfiguration.price;\n const switchboardPrice = tokenInfo.switchboardConfiguration.priceAggregator;\n const switchboardTwap = tokenInfo.switchboardConfiguration.twapAggregator;\n const scope = tokenInfo.scopeConfiguration.priceFeed;\n\n const pythEnabled = isNotNullPubkey(pythAccount);\n const switchboardEnabled = isNotNullPubkey(switchboardPrice);\n const switchboardTwapEnabled =\n switchboardEnabled && this.isTwapEnabled() && isNotNullPubkey(switchboardTwap);\n const scopeEnabled = isNotNullPubkey(scope);\n\n return {\n pythPrice: pythEnabled ? pythAccount : undefined,\n switchboardPrice: switchboardEnabled ? switchboardPrice : undefined,\n switchboardTwap: switchboardTwapEnabled ? switchboardTwap : undefined,\n scope: scopeEnabled ? scope : undefined,\n };\n }\n\n /**\n * Simulates the supply APY after a position balance change.\n * Uses the SDK's calcSimulatedSupplyAPR which accounts for utilization changes.\n */\n simulateNewSupplyAPY(args: PositionBalanceChange, usingDebtReserve?: Address): number {\n const collateralChange = args.collateralChange ?? 0;\n if (!collateralChange) {\n return this.supplyAPY(usingDebtReserve);\n }\n\n const simulatedAPR = this.rawData.calcSimulatedSupplyAPR(\n new Decimal(fromUiAmount(collateralChange, this.mint.mintDecimals).toNumber()),\n collateralChange > 0 ? \"deposit\" : \"withdraw\",\n this.slot,\n 0\n );\n\n return simulatedAPR + this.simulateNewEligbleIncentivesAPY(args, \"supply\", usingDebtReserve);\n }\n\n /**\n * Simulates the borrow APY after a position balance change.\n * Uses the SDK's calcSimulatedBorrowAPR which accounts for utilization changes.\n */\n simulateNewBorrowAPY(args: PositionBalanceChange, usingSupplyReserve?: Address): number {\n const debtChange = args.debtChange ?? 0;\n if (!debtChange) {\n return this.borrowAPY(usingSupplyReserve);\n }\n\n const simulatedAPR = this.rawData.calcSimulatedBorrowAPR(\n new Decimal(fromUiAmount(debtChange, this.mint.mintDecimals).toNumber()),\n debtChange > 0 ? \"borrow\" : \"repay\",\n this.slot,\n 0\n );\n\n return simulatedAPR - this.simulateNewEligbleIncentivesAPY(args, \"borrow\", usingSupplyReserve);\n }\n\n canWithdraw(amount: number): boolean {\n const capCapacity = this.rawData.getDepositWithdrawalCapCapacity();\n const capCurrent = this.rawData.getDepositWithdrawalCapCurrent(this.slot);\n return this.hasCapacity(amount, capCapacity, capCurrent);\n }\n\n canBorrow(amount: number): boolean {\n const capCapacity = this.rawData.getDebtWithdrawalCapCapacity();\n const capCurrent = this.rawData.getDebtWithdrawalCapCurrent(this.slot);\n return amount <= this.borrows.limit && this.hasCapacity(amount, capCapacity, capCurrent);\n }\n\n private hasCapacity(amount: number, capCapacity: Decimal, capCurrent: Decimal) {\n if (!capCapacity.isZero()) {\n const remainingCap = toUiAmount(\n BigInt(capCapacity.minus(capCurrent).toFixed(0)),\n this.mint.mintDecimals\n );\n if (amount > remainingCap) {\n return false;\n }\n }\n return true;\n }\n}\n","export * from \"./kamino\";\nexport * from \"./reserveBase\";\n","import type { Address } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport { fromUiAmount, toUiAmount } from \"common\";\n\n/** Represents a single asset position (deposit or borrow) within an obligation */\nexport interface PositionInfo {\n reserve: Address;\n mint: Address;\n amount: BN;\n valueUsd: number;\n}\n\n/**\n * Base class representing a user's lending position.\n * Contains aggregated data about deposits, borrows, and health metrics.\n */\nexport class UserPositionBase {\n constructor(\n public address: Address,\n /** Current utilization as a ratio of borrowed value to borrow limit (0-1) */\n public utilizationRate: number,\n public deposits: PositionInfo[],\n public borrows: PositionInfo[],\n /** Loan-to-value ratio (if applicable based on elevation group) */\n public ltv?: number,\n /** Liquidation threshold percentage (if applicable) */\n public liquidationThreshold?: number,\n /**\n * Obligation-level max borrow capacity in USD (`borrowedUsd / utilizationRate`).\n * Each platform loader must set this from that protocol's position health model.\n */\n public borrowLimitUsd?: number\n ) {}\n\n /** Aggregate borrowed USD for headroom; prefers per-borrow breakdown when present. */\n private userPositionBorrowedValueUsd(): number {\n const fromBorrows = this.borrows.reduce((sum, borrow) => sum + borrow.valueUsd, 0);\n if (fromBorrows > 0) {\n return fromBorrows;\n }\n if (this.borrowLimitUsd !== undefined && this.utilizationRate > 0) {\n return this.borrowLimitUsd * this.utilizationRate;\n }\n return 0;\n }\n\n /**\n * Max additional debt UI amount before the platform rejects the borrow.\n * Uses obligation `borrowLimitUsd − borrowedUsd`, floored to base units with a\n * one-unit buffer so simulation-time refresh cannot overshoot. Returns `undefined`\n * when `borrowLimitUsd` was not set by the platform loader.\n */\n getMaxAdditionalBorrowUiAmount(debtPriceUsd: number, debtDecimals: number): number | undefined {\n if (this.borrowLimitUsd === undefined) {\n return undefined;\n }\n\n const borrowedValueUsd = this.userPositionBorrowedValueUsd();\n const headroomUsd = Math.max(0, this.borrowLimitUsd - borrowedValueUsd);\n if (headroomUsd <= 0 || !(debtPriceUsd > 0)) {\n return 0;\n }\n\n const headroomUi = headroomUsd / debtPriceUsd;\n const maxBaseUnits = fromUiAmount(headroomUi, debtDecimals);\n const safeBaseUnits = BN.max(maxBaseUnits.subn(1), new BN(0));\n return toUiAmount(safeBaseUnits, debtDecimals);\n }\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { KaminoObligation } from \"@kamino-finance/klend-sdk\";\nimport { PositionInfo, UserPositionBase } from \"./userPositionBase\";\n\n/**\n * Kamino-specific user position data.\n * Extracts deposit/borrow positions and health metrics from a KaminoObligation.\n */\nexport class KaminoUserPositionData extends UserPositionBase {\n public rawData!: KaminoObligation;\n\n /** Creates a KaminoUserPositionData from a raw KaminoObligation */\n static loadData(obligation: KaminoObligation): KaminoUserPositionData {\n const deposits: PositionInfo[] = [];\n obligation.deposits.forEach((deposit, mint) => {\n deposits.push({\n reserve: deposit.reserveAddress,\n mint,\n amount: new BN(deposit.amount.toFixed(0)),\n valueUsd: deposit.marketValueRefreshed.toNumber(),\n });\n });\n\n const borrows: PositionInfo[] = [];\n obligation.borrows.forEach((borrow, mint) => {\n borrows.push({\n reserve: borrow.reserveAddress,\n mint,\n amount: new BN(borrow.amount.toFixed(0)),\n valueUsd: borrow.marketValueRefreshed.toNumber(),\n });\n });\n\n const borrowedValueUsd = obligation.refreshedStats.userTotalBorrow.toNumber();\n const borrowLimitUsd = obligation.refreshedStats.borrowLimit.toNumber();\n const utilizationRate = borrowLimitUsd > 0 ? borrowedValueUsd / borrowLimitUsd : 0;\n\n const data = new KaminoUserPositionData(\n obligation.obligationAddress,\n utilizationRate,\n deposits,\n borrows,\n undefined,\n undefined,\n borrowLimitUsd\n );\n\n data.rawData = obligation;\n\n return data;\n }\n\n /**\n * Determines if the obligation needs a refresh_obligation instruction.\n */\n requiresRefresh(): boolean {\n return true;\n }\n}\n","export * from \"./kamino\";\nexport * from \"./userPositionBase\";\n","import { BN } from \"@anchor-lang/core\";\nimport { Address, Instruction, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { LendingPlatformData } from \"../platform\";\nimport {\n CpiData,\n CustomAccountMeta,\n toCustomAccountMeta,\n TransactionCacheInvalidation,\n} from \"common\";\nimport { LpAccountsBase } from \"../accounts\";\nimport { RefreshPrerequisiteTarget } from \"./types\";\n\n/** Parameters for deposit, withdraw, and borrow operations */\nexport interface LendingOperationParams {\n user: Address;\n payer: Address;\n pool: Address;\n reserve: Address;\n userAccount: Address;\n /**\n * UI-unit amount, or `\"all\"` (withdraw-only) to encode the platform's\n * \"withdraw all\" sentinel (Kamino: `u64::MAX` collateral amount) so the\n * obligation's deposit is fully drained on-chain — no dust left behind\n * from off-chain cToken/liquidity rate drift.\n *\n * If neither this nor {@link baseUnitAmount} is provided, the amount is\n * implied to be derived in the program.\n */\n uiAmount?: number | \"all\";\n /**\n * Exact liquidity base units for the operation (e.g. lamports for SOL). Prefer over\n * {@link uiAmount} when float round-trips would undershoot on-chain requirements.\n * Pass `\"all\"` (withdraw-only) for the same sentinel semantics as {@link uiAmount}.\n */\n baseUnitAmount?: BN | \"all\";\n txId: string;\n}\n\n/** Parameters for repay operations, with option for full repayment */\nexport interface RepayOperationParams extends LendingOperationParams {\n /** Repay amount in UI units. The withdraw-only `\"all\"` sentinel is not valid here. */\n uiAmount?: number;\n /** Exact repay amount in liquidity base units. */\n baseUnitAmount?: BN;\n /** When true, repays the entire debt balance regardless of `amount` */\n full?: boolean;\n}\n\n/** CPI data split into instruction-level prerequisite CPIs and main operation CPIs. */\nexport interface SplitLpOperationCpiData {\n prerequisiteCpis: CpiData[];\n cpis: CpiData[];\n allCpis: CpiData[];\n}\n\n/** Split CPI data plus flattened post-success cache invalidations from all nested CPIs. */\nexport interface LendingOperationCpiBundle extends SplitLpOperationCpiData {\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\n/** Whether a reserve is used as collateral or debt for a user account */\nexport type ReserveRole = \"collateral\" | \"debt\";\n\n/** Tracks a reserve's pool and which user accounts reference it (with roles) */\nexport interface TxReserveInfo {\n pool: Address;\n userAccounts: Map<string, Set<ReserveRole>>;\n}\n\n/**\n * Abstract base class for lending platform instruction builders.\n * Provides a unified interface for building CPI data for different lending protocols.\n * Each platform implementation provides the account metas needed to construct CPI calls.\n *\n * @typeParam T - The platform-specific data class extending LendingPlatformData\n */\nexport abstract class LpInstructionsBase<T extends LendingPlatformData> {\n rpc: Rpc<SolanaRpcApi>;\n rpcUrl: string;\n data: T;\n public abstract programId: Address;\n public abstract lookupTable: Address;\n public accounts: LpAccountsBase<T>;\n\n /** Tracks which reserves (and their pools/roles) are involved in each transaction */\n protected txReserves = new Map<string, Map<string, TxReserveInfo>>();\n\n /**\n * Per-txId per-obligation set of debt reserves that the caller has flagged\n * as being fully repaid earlier in the same transaction. Subsequent\n * `RefreshObligation` builds for that obligation must NOT include these\n * reserves in the borrow accounts list — by execution time the borrow row\n * has been removed from the obligation, and Kamino's `handler_refresh_obligation`\n * checks the passed account count against the live obligation state and\n * fails with `InvalidAccountInput` (klend error 6006) on a mismatch.\n *\n * Set via {@link markObligationDebtCleared}, read via {@link getTxObligationClearedDebt}.\n */\n protected txClearedDebt = new Map<string, Map<string, Set<string>>>();\n\n constructor(rpc: Rpc<SolanaRpcApi>, rpcUrl: string, data: T, accounts: LpAccountsBase<T>) {\n this.rpc = rpc;\n this.rpcUrl = rpcUrl;\n this.data = data;\n this.accounts = accounts;\n }\n\n emptyAccountMeta() {\n return toCustomAccountMeta(this.programId);\n }\n\n clearCacheEntry(category: string, id: string) {\n this.data.clearCacheEntry(category, id);\n }\n\n protected getCacheInvalidation(invalidation: {\n category: string;\n id: Address;\n }): TransactionCacheInvalidation {\n return {\n client: \"kamino\",\n ...invalidation,\n };\n }\n\n applyPostSuccessCacheInvalidations(invalidations: TransactionCacheInvalidation[]) {\n for (const invalidation of invalidations) {\n if (invalidation.client !== \"kamino\") {\n continue;\n }\n this.clearCacheEntry(invalidation.category, invalidation.id);\n }\n }\n\n protected getCpiData(\n cpiType: number,\n accounts: CustomAccountMeta[],\n data?: Uint8Array,\n programId?: Address,\n postSuccessCacheInvalidations?: TransactionCacheInvalidation[]\n ): CpiData {\n return {\n programId: programId ?? this.programId,\n cpiType,\n data,\n accounts,\n lookupTables: [this.lookupTable],\n postSuccessCacheInvalidations,\n };\n }\n\n protected createSplitOperationCpiData(\n prerequisiteCpis: CpiData[],\n cpis: CpiData[]\n ): SplitLpOperationCpiData {\n return {\n prerequisiteCpis,\n cpis,\n allCpis: [...prerequisiteCpis, ...cpis],\n };\n }\n\n protected buildLendingOperationCpiBundle(\n cpiData: SplitLpOperationCpiData\n ): LendingOperationCpiBundle {\n return {\n prerequisiteCpis: cpiData.prerequisiteCpis,\n cpis: cpiData.cpis,\n allCpis: [...cpiData.prerequisiteCpis, ...cpiData.cpis],\n postSuccessCacheInvalidations: [...cpiData.prerequisiteCpis, ...cpiData.cpis].flatMap(\n (cpi) => cpi.postSuccessCacheInvalidations ?? []\n ),\n };\n }\n\n async getInitAndDepositCpiBundle(\n params: LendingOperationParams,\n userAccountId: number\n ): Promise<LendingOperationCpiBundle> {\n return this.buildLendingOperationCpiBundle(\n await this.getInitAndDepositCpiData(params, userAccountId)\n );\n }\n\n async getInitBorrowPositionCpiBundle(\n params: LendingOperationParams,\n collReserve: Address\n ): Promise<LendingOperationCpiBundle> {\n return this.buildLendingOperationCpiBundle(\n await this.getInitBorrowPositionCpiData(params, collReserve)\n );\n }\n\n async getDepositCpiBundle(params: LendingOperationParams): Promise<LendingOperationCpiBundle> {\n return this.buildLendingOperationCpiBundle(await this.getDepositCpiData(params));\n }\n\n async getWithdrawCpiBundle(params: LendingOperationParams): Promise<LendingOperationCpiBundle> {\n return this.buildLendingOperationCpiBundle(await this.getWithdrawCpiData(params));\n }\n\n async getBorrowCpiBundle(params: LendingOperationParams): Promise<LendingOperationCpiBundle> {\n return this.buildLendingOperationCpiBundle(await this.getBorrowCpiData(params));\n }\n\n async getRepayCpiBundle(params: RepayOperationParams): Promise<LendingOperationCpiBundle> {\n return this.buildLendingOperationCpiBundle(await this.getRepayCpiData(params));\n }\n\n /**\n * Registers a reserve as being used in a transaction.\n * When userAccount and role are provided, also tracks the collateral/debt role\n * for that specific user account.\n */\n protected registerTxReserve(\n txId: string,\n pool: Address,\n reserve: Address,\n userAccount?: Address,\n role?: ReserveRole\n ) {\n if (!this.txReserves.has(txId)) {\n this.txReserves.set(txId, new Map());\n }\n const txMap = this.txReserves.get(txId)!;\n if (!txMap.has(reserve)) {\n txMap.set(reserve, { pool, userAccounts: new Map() });\n }\n if (userAccount && role) {\n const entry = txMap.get(reserve)!;\n if (!entry.userAccounts.has(userAccount)) {\n entry.userAccounts.set(userAccount, new Set());\n }\n entry.userAccounts.get(userAccount)!.add(role);\n }\n }\n\n /**\n * Returns the collateral and debt reserves registered in the tx cache\n * for a specific user account (obligation).\n */\n protected getTxUserAccountReserves(\n txId: string,\n userAccount: Address\n ): { collateral: Address[]; debt: Address[] } {\n const collateral: Address[] = [];\n const debt: Address[] = [];\n const txMap = this.txReserves.get(txId);\n if (!txMap) return { collateral, debt };\n for (const [reserve, info] of txMap) {\n const roles = info.userAccounts.get(userAccount);\n if (roles?.has(\"collateral\")) collateral.push(reserve as Address);\n if (roles?.has(\"debt\")) debt.push(reserve as Address);\n }\n return { collateral, debt };\n }\n\n /**\n * Mark that `reserve` will be fully repaid for `userAccount` earlier in the\n * `txId` flow, so subsequent obligation-refresh builders drop it from the\n * borrow accounts they emit. Call after building a \"repay all\" CPI; it has\n * no effect on the repay itself.\n */\n markObligationDebtCleared(txId: string, userAccount: Address, reserve: Address) {\n if (!this.txClearedDebt.has(txId)) {\n this.txClearedDebt.set(txId, new Map());\n }\n const obligationMap = this.txClearedDebt.get(txId)!;\n if (!obligationMap.has(userAccount)) {\n obligationMap.set(userAccount, new Set());\n }\n obligationMap.get(userAccount)!.add(reserve);\n }\n\n /** Returns the set of debt reserves marked cleared for `(txId, userAccount)`. */\n protected getTxObligationClearedDebt(txId: string, userAccount: Address): Set<Address> {\n return (this.txClearedDebt.get(txId)?.get(userAccount) ?? new Set()) as Set<Address>;\n }\n\n /**\n * Clears the transaction cache for a given transaction or all transactions.\n * Call after finishing building a transaction to free memory.\n */\n clearTransactionCache(txId?: string) {\n if (txId) {\n this.txReserves.delete(txId);\n this.txClearedDebt.delete(txId);\n } else {\n this.txReserves.clear();\n this.txClearedDebt.clear();\n }\n }\n\n /**\n * Returns standalone instructions that must be executed at the top level\n * BEFORE the the main CPIs. Should be called after all CPI methods for this\n * txId have been invoked.\n */\n abstract getPreInstructions(txId: string): Promise<Instruction[]>;\n\n /**\n * Returns prerequisite CPIs needed before reading refreshed account state for\n * a batch of lending positions outside a normal deposit/withdraw/borrow/repay\n * flow.\n */\n async getPrerequisiteCpisForRefresh(_targets: RefreshPrerequisiteTarget[]): Promise<CpiData[]> {\n return [];\n }\n\n /** Returns CPI data for initializing a user's lending account */\n abstract getInitUserAccountCpiData(\n pool: Address,\n user: Address,\n feePayer: Address,\n id: number\n ): Promise<SplitLpOperationCpiData>;\n\n /**\n * Returns CPI data for initializing a lending position end-to-end: the user\n * account itself plus any per-reserve accessory accounts (e.g. Kamino\n * obligation farm user states for the collateral and debt reserves). Called\n * at position-creation time so subsequent deposit/borrow flows don't need\n * to init these inline.\n *\n * Default: delegates to {@link getInitUserAccountCpiData}. Platforms with\n * per-reserve accessory accounts override this to add their inits.\n */\n async getInitLendingPositionCpiData(params: {\n pool: Address;\n user: Address;\n payer: Address;\n userAccountId: number;\n collateralReserve: Address;\n debtReserve: Address;\n }): Promise<SplitLpOperationCpiData> {\n return this.getInitUserAccountCpiData(\n params.pool,\n params.user,\n params.payer,\n params.userAccountId\n );\n }\n\n /** Returns CPI data for initializing user account, incentive account (if necessary) and depositing */\n abstract getInitAndDepositCpiData(\n params: LendingOperationParams,\n userAccountId: number\n ): Promise<SplitLpOperationCpiData>;\n\n /** Returns CPI data for initializing a new borrow position */\n abstract getInitBorrowPositionCpiData(\n params: LendingOperationParams,\n collReserve: Address\n ): Promise<SplitLpOperationCpiData>;\n\n /** Returns deposit CPI data split into optional prerequisite CPIs and main CPIs. */\n abstract getDepositCpiData(params: LendingOperationParams): Promise<SplitLpOperationCpiData>;\n\n /** Returns withdraw CPI data split into optional prerequisite CPIs and main CPIs. */\n abstract getWithdrawCpiData(params: LendingOperationParams): Promise<SplitLpOperationCpiData>;\n\n /** Returns borrow CPI data split into optional prerequisite CPIs and main CPIs. */\n abstract getBorrowCpiData(params: LendingOperationParams): Promise<SplitLpOperationCpiData>;\n\n /** Returns repay CPI data split into optional prerequisite CPIs and main CPIs. */\n abstract getRepayCpiData(params: RepayOperationParams): Promise<SplitLpOperationCpiData>;\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { address, Address, getAddressEncoder, Instruction, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { Scope } from \"@kamino-finance/scope-sdk\";\nimport {\n DEFAULT_PUBLIC_KEY,\n lendingMarketAuthPda,\n PROGRAM_ID,\n userMetadataPda,\n VanillaObligation,\n} from \"@kamino-finance/klend-sdk\";\nimport {\n accountExists,\n CpiData,\n CpiTypes,\n dedupeOrderedAddresses,\n getAtaAddress,\n IX_SYSVAR_META,\n LOCALNET_URL,\n mints,\n numToU64Bytes,\n RENT_SYSVAR_META,\n SYSTEM_PROGRAM_META,\n toCustomAccountMeta,\n U64_MAX_BN,\n} from \"common\";\nimport {\n LendingOperationParams,\n LpInstructionsBase,\n RepayOperationParams,\n SplitLpOperationCpiData,\n} from \"./lpInstructionsBase\";\nimport { RefreshPrerequisiteTarget } from \"./types\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { getTreasuryVaultPDA } from \"@kamino-finance/farms-sdk\";\nimport { KAMINO_FARMS_PROGRAM_ID } from \"../../constants\";\nimport { KaminoData } from \"../platform\";\nimport { collectTokenDependencies, liquidityToCollateral } from \"../../utils\";\nimport { KaminoAccounts } from \"../accounts\";\n\n/**\n * Instruction builder for Kamino Lend protocol.\n * Provides methods to build CPI account metas for lending operations.\n */\nexport class KaminoInstructions extends LpInstructionsBase<KaminoData> {\n declare accounts: KaminoAccounts;\n programId = PROGRAM_ID;\n lookupTable = address(\"bzdjSeDDPEdsGpK73oevQ87x4Sm6QRsnzupPLQEaFFN\");\n\n constructor(rpc: Rpc<SolanaRpcApi>, rpcUrl: string, data: KaminoData, accounts: KaminoAccounts) {\n super(rpc, rpcUrl, data, accounts);\n }\n\n clearTransactionCache(txId?: string) {\n super.clearTransactionCache(txId);\n }\n\n // ================ CPI Data ================\n\n private getUserAccountCacheInvalidations(userAccount: Address) {\n return [\n this.getCacheInvalidation({\n category: this.data.userAccountCatKey,\n id: userAccount,\n }),\n ];\n }\n\n private async getInitUserMetadataCpiData(\n user: Address,\n payer: Address,\n userLookupTable?: Address\n ): Promise<CpiData | undefined> {\n const [userMetadataAddress] = await userMetadataPda(user, this.programId);\n if (await accountExists(this.rpc, userMetadataAddress)) return;\n\n return this.getCpiData(\n CpiTypes.K_INIT_USER_METADATA,\n [\n toCustomAccountMeta(user, false, undefined, true),\n toCustomAccountMeta(payer, true, undefined, true),\n toCustomAccountMeta(userMetadataAddress, true),\n this.emptyAccountMeta(),\n RENT_SYSVAR_META,\n SYSTEM_PROGRAM_META,\n ],\n new Uint8Array(getAddressEncoder().encode(userLookupTable ?? DEFAULT_PUBLIC_KEY))\n );\n }\n\n override async getInitLendingPositionCpiData(params: {\n pool: Address;\n user: Address;\n payer: Address;\n userAccountId: number;\n collateralReserve: Address;\n debtReserve: Address;\n }): Promise<SplitLpOperationCpiData> {\n const userInit = await this.getInitUserAccountCpiData(\n params.pool,\n params.user,\n params.payer,\n params.userAccountId\n );\n const obligation = await this.accounts.getUserAccountAddress(\n params.pool,\n params.user,\n params.userAccountId\n );\n\n const farmCpis: CpiData[] = [];\n const farmTargets: Array<[Address, \"collateral\" | \"debt\"]> = [\n [params.collateralReserve, \"collateral\"],\n [params.debtReserve, \"debt\"],\n ];\n for (const [reserve, mode] of farmTargets) {\n const reserveData = await this.data.fetchReserve(params.pool, reserve);\n const reserveFarm =\n mode === \"collateral\"\n ? reserveData.rawData.state.farmCollateral\n : reserveData.rawData.state.farmDebt;\n if (!reserveFarm || reserveFarm === DEFAULT_PUBLIC_KEY) continue;\n\n const farmAccounts = await this.accounts.getFarmAccounts(\n params.pool,\n reserve,\n obligation,\n mode\n );\n if (await accountExists(this.rpc, farmAccounts.userFarm.address)) continue;\n\n farmCpis.push(\n await this.getInitObligationFarmsForReserveCpiData(\n params.user,\n params.payer,\n obligation,\n params.pool,\n reserve,\n mode\n )\n );\n }\n\n return this.createSplitOperationCpiData(userInit.prerequisiteCpis, [\n ...userInit.cpis,\n ...farmCpis,\n ]);\n }\n\n async getInitUserAccountCpiData(\n pool: Address,\n user: Address,\n payer: Address,\n id: number,\n userLookupTable?: Address\n ): Promise<SplitLpOperationCpiData> {\n const market = await this.data.fetchMarket(pool);\n const obligationPda = await this.accounts.getUserAccountAddress(pool, user, id);\n const userMetadataAddress = await this.accounts.getUserMetadataAddress(user);\n const tag = VanillaObligation.tag;\n\n const initMetadataCpi = await this.getInitUserMetadataCpiData(user, payer, userLookupTable);\n const obligationAlreadyInit = await accountExists(this.rpc, obligationPda);\n return this.createSplitOperationCpiData(\n [],\n [\n ...(initMetadataCpi ? [initMetadataCpi] : []),\n ...(obligationAlreadyInit\n ? []\n : [\n this.getCpiData(\n CpiTypes.K_INIT_OBLIGATION,\n [\n toCustomAccountMeta(user),\n toCustomAccountMeta(payer, true),\n toCustomAccountMeta(obligationPda, true),\n toCustomAccountMeta(market.address),\n toCustomAccountMeta(DEFAULT_PUBLIC_KEY),\n toCustomAccountMeta(DEFAULT_PUBLIC_KEY),\n toCustomAccountMeta(userMetadataAddress),\n RENT_SYSVAR_META,\n SYSTEM_PROGRAM_META,\n ],\n new Uint8Array([tag, id])\n ),\n ]),\n ]\n );\n }\n\n private async getInitObligationFarmsForReserveCpiData(\n user: Address,\n payer: Address,\n obligation: Address,\n pool: Address,\n reserve: Address,\n farmMode: \"collateral\" | \"debt\"\n ): Promise<CpiData> {\n const farmAccounts = await this.accounts.getFarmAccounts(pool, reserve, obligation, farmMode);\n return this.getCpiData(\n CpiTypes.K_INIT_USER_FARM,\n [\n toCustomAccountMeta(payer, true),\n toCustomAccountMeta(user),\n toCustomAccountMeta(obligation, true),\n toCustomAccountMeta((await lendingMarketAuthPda(pool))[0]),\n toCustomAccountMeta(reserve, true),\n farmAccounts.farm,\n farmAccounts.userFarm,\n toCustomAccountMeta(pool),\n toCustomAccountMeta(KAMINO_FARMS_PROGRAM_ID),\n RENT_SYSVAR_META,\n SYSTEM_PROGRAM_META,\n ],\n new Uint8Array([farmMode === \"collateral\" ? 0 : 1])\n );\n }\n\n /**\n * Returns CPI accounts for refreshing a reserve's state.\n * Includes the market, reserve, and all configured oracle accounts.\n */\n private async getRefreshReserveCpiData(pool: Address, reserve: Address): Promise<CpiData> {\n const reserveData = await this.data.fetchReserve(pool, reserve);\n const oracleAccounts = reserveData.getOracleAccounts();\n return this.getCpiData(\n CpiTypes.K_REFRESH_RESERVE,\n [\n toCustomAccountMeta(reserve, true),\n toCustomAccountMeta(pool),\n ...Object.values(oracleAccounts).map((x) =>\n x === undefined ? this.emptyAccountMeta() : toCustomAccountMeta(x)\n ),\n ],\n new Uint8Array()\n );\n }\n\n private async getRefreshObligationCpiData(\n txId: string,\n pool: Address,\n obligation: Address\n ): Promise<CpiData> {\n const obligationData = await this.data.maybeFetchUserPositionInPool(pool, obligation);\n\n const cached = this.getTxUserAccountReserves(txId, obligation);\n // Drop debt reserves the caller has flagged as fully repaid earlier in\n // the same tx (via `markObligationDebtCleared`). The on-chain obligation\n // will no longer list them by the time this RefreshObligation runs;\n // including them here would trip Kamino's account-count check\n // (`expected_remaining_accounts != actual_remaining_accounts`,\n // InvalidAccountInput / klend 6006).\n const cleared = this.getTxObligationClearedDebt(txId, obligation);\n const collateralReserves = [\n ...new Set([...(obligationData?.deposits.map((x) => x.reserve) ?? []), ...cached.collateral]),\n ];\n // Drop any debt reserves a prior CPI in this tx already cleared via the\n // repay-all sentinel — at execution time the obligation no longer carries\n // that borrow, and klend rejects the mismatched accounts count\n // (`InvalidAccountInput`, error 6006).\n const debtReserves = [\n ...new Set([...(obligationData?.borrows.map((x) => x.reserve) ?? []), ...cached.debt]),\n ].filter((r) => !cleared.has(r));\n\n return this.getCpiData(\n CpiTypes.K_REFRESH_OBLIGATION,\n [\n toCustomAccountMeta(pool),\n toCustomAccountMeta(obligation, true),\n ...collateralReserves.map((x) => toCustomAccountMeta(x)),\n ...debtReserves.map((x) => toCustomAccountMeta(x)),\n ],\n new Uint8Array()\n );\n }\n\n private getRefreshObligationCpiDataFromReserves({\n pool,\n userAccount,\n collateralReserves,\n debtReserves,\n }: RefreshPrerequisiteTarget): CpiData {\n return this.getCpiData(\n CpiTypes.K_REFRESH_OBLIGATION,\n [\n toCustomAccountMeta(pool),\n toCustomAccountMeta(userAccount, true),\n ...dedupeOrderedAddresses(collateralReserves).map((x) => toCustomAccountMeta(x)),\n ...dedupeOrderedAddresses(debtReserves).map((x) => toCustomAccountMeta(x)),\n ],\n new Uint8Array()\n );\n }\n\n override async getPrerequisiteCpisForRefresh(\n targets: RefreshPrerequisiteTarget[]\n ): Promise<CpiData[]> {\n const reserveRefreshes: Array<{ pool: Address; reserve: Address }> = [];\n const seenReserveRefreshes = new Set<string>();\n const obligationRefreshes = new Map<string, RefreshPrerequisiteTarget>();\n\n for (const target of targets) {\n for (const reserve of dedupeOrderedAddresses([\n ...target.collateralReserves,\n ...target.debtReserves,\n ])) {\n const reserveRefreshKey = `${target.pool}:${reserve}`;\n if (seenReserveRefreshes.has(reserveRefreshKey)) {\n continue;\n }\n seenReserveRefreshes.add(reserveRefreshKey);\n reserveRefreshes.push({ pool: target.pool, reserve });\n }\n\n if (target.userAccount === DEFAULT_PUBLIC_KEY) {\n continue;\n }\n\n const obligationKey = `${target.pool}:${target.userAccount}`;\n if (obligationRefreshes.has(obligationKey)) {\n continue;\n }\n obligationRefreshes.set(obligationKey, {\n pool: target.pool,\n userAccount: target.userAccount,\n collateralReserves: dedupeOrderedAddresses(target.collateralReserves),\n debtReserves: dedupeOrderedAddresses(target.debtReserves),\n });\n }\n\n const prerequisiteCpis: CpiData[] = [];\n for (const { pool, reserve } of reserveRefreshes) {\n prerequisiteCpis.push(await this.getRefreshReserveCpiData(pool, reserve));\n }\n\n for (const obligationRefresh of obligationRefreshes.values()) {\n let obligationData = null;\n try {\n obligationData = await this.data.maybeFetchUserPositionInPool(\n obligationRefresh.pool,\n obligationRefresh.userAccount\n );\n } catch {\n obligationData = null;\n }\n\n if (!obligationData) {\n continue;\n }\n\n prerequisiteCpis.push(\n this.getRefreshObligationCpiDataFromReserves({\n pool: obligationRefresh.pool,\n userAccount: obligationRefresh.userAccount,\n collateralReserves: obligationData.deposits.map((deposit) => deposit.reserve),\n debtReserves: obligationData.borrows.map((borrow) => borrow.reserve),\n })\n );\n }\n\n return prerequisiteCpis;\n }\n\n private async getRefreshUserFarmCpiData(\n signer: Address,\n pool: Address,\n reserve: Address,\n obligation: Address,\n userFarm: Address,\n farm: Address,\n mode: \"collateral\" | \"debt\"\n ): Promise<CpiData> {\n const details = await this.accounts.reserveInteractionDetails(\n signer,\n pool,\n reserve,\n obligation\n );\n return this.getCpiData(\n CpiTypes.K_REFRESH_USER_FARM,\n [\n details.signer,\n details.obligation!,\n details.lendingMarketAuthority,\n details.reserve,\n toCustomAccountMeta(farm, true),\n toCustomAccountMeta(userFarm, true),\n details.lendingMarket,\n details.farmsProgram,\n RENT_SYSVAR_META,\n SYSTEM_PROGRAM_META,\n ],\n new Uint8Array([mode === \"collateral\" ? 0 : 1])\n );\n }\n\n /**\n * Checks if refresh CPIs are needed for the given reserve and obligation.\n * Also registers all involved reserves in the txReserves cache for getPreInstructions.\n *\n * The instruction `reserve` (collateral vs debt) is also listed on the obligation;\n * `dedupeOrderedAddresses` ensures one RefreshReserve CPI per reserve pubkey.\n */\n private async getRefreshCpisIfNeeded(\n txId: string,\n pool: Address,\n reserve: Address,\n obligation: Address\n ): Promise<CpiData[]> {\n const cpis: CpiData[] = [];\n const cached = this.getTxUserAccountReserves(txId, obligation);\n\n const refreshReserve = async (reserveAddr: Address) => {\n cpis.push(await this.getRefreshReserveCpiData(pool, reserveAddr));\n this.registerTxReserve(txId, pool, reserveAddr);\n };\n\n const obligationData = await this.data.maybeFetchUserPositionInPool(pool, obligation);\n\n if (obligationData) {\n const needsFullObligationRefresh =\n obligationData.requiresRefresh() || cached.collateral.length > 0 || cached.debt.length > 0;\n\n if (needsFullObligationRefresh) {\n const additional = [\n ...obligationData.deposits.map((d) => d.reserve),\n ...obligationData.borrows.map((b) => b.reserve),\n ...cached.collateral,\n ...cached.debt,\n ];\n for (const addr of dedupeOrderedAddresses([reserve, ...additional])) {\n await refreshReserve(addr);\n }\n cpis.push(await this.getRefreshObligationCpiData(txId, pool, obligation));\n } else {\n await refreshReserve(reserve);\n }\n } else {\n const additional = [...new Set([...cached.collateral, ...cached.debt])];\n for (const addr of dedupeOrderedAddresses([reserve, ...additional])) {\n await refreshReserve(addr);\n }\n cpis.push(await this.getRefreshObligationCpiData(txId, pool, obligation));\n }\n\n return cpis;\n }\n\n async getPreInstructions(txId: string): Promise<Instruction[]> {\n const reserveEntries = this.txReserves.get(txId);\n if (!reserveEntries) return [];\n\n const SCOPE_CHAIN_END = 65535;\n\n // Collect scope feed -> token indices, then merge feeds that share the\n // same Scope Configuration into a single RefreshPriceList instruction.\n // Scope's on-chain handler rejects a RefreshPriceList that is preceded by\n // non-Scope instructions, so emitting multiple ixs only works when they\n // are consecutive with nothing in between — grouping by config avoids the\n // problem entirely.\n const scopeFeeds = new Map<string, Set<number>>();\n\n if (reserveEntries) {\n for (const [reserve, { pool }] of reserveEntries) {\n const reserveData = await this.data.fetchReserve(pool, reserve as Address);\n if (!reserveData.requiresRefresh()) continue;\n\n const scopeFeed = reserveData.getOracleAccounts().scope;\n if (!scopeFeed) continue;\n\n if (!scopeFeeds.has(scopeFeed)) {\n scopeFeeds.set(scopeFeed, new Set());\n }\n const tokens = scopeFeeds.get(scopeFeed)!;\n\n const { priceChain, twapChain } =\n reserveData.rawData.state.config.tokenInfo.scopeConfiguration;\n for (const chain of [priceChain, twapChain]) {\n for (const index of chain) {\n if (index === SCOPE_CHAIN_END) break;\n tokens.add(index);\n }\n }\n }\n }\n\n // Resolve each feed's config, then merge token indices by config address.\n // Scope's on-chain handler rejects a RefreshPriceList that is preceded by\n // a RefreshPriceList from a different Configuration account, so we can only\n // emit one instruction per transaction. On deployed environments crankers\n // keep prices fresh, so skipping additional configs is safe.\n const configTokens = new Map<string, Set<number>>();\n for (const [feed, chainTokens] of scopeFeeds) {\n const configAddr = await this.data.fetchScopeConfigAddress(feed as Address);\n if (!configTokens.has(configAddr)) {\n configTokens.set(configAddr, new Set());\n }\n const merged = configTokens.get(configAddr)!;\n for (const t of chainTokens) merged.add(t);\n }\n\n const scope = new Scope(\"mainnet-beta\", this.rpc);\n const isLocalnet = this.rpcUrl === LOCALNET_URL;\n\n // Take only the first config to avoid the cross-config Scope rejection.\n const [firstEntry] = configTokens;\n if (!firstEntry) return [];\n const [configAddr, chainTokens] = firstEntry;\n\n let tokens: number[];\n if (isLocalnet) {\n // On localnet there are no crankers keeping Scope prices fresh, so we\n // must resolve the full dependency graph (CappedFloored sources, etc.)\n // and refresh in topological order.\n const mappings = await scope.getOracleMappings({ config: address(configAddr) });\n const allTokens = new Set<number>();\n for (const token of chainTokens) {\n collectTokenDependencies(token, mappings, allTokens);\n }\n tokens = [...allTokens];\n } else {\n tokens = [...chainTokens];\n }\n\n const ix = await scope.refreshPriceListIx({ config: address(configAddr) }, tokens);\n return ix ? [ix] : [];\n }\n\n async getClaimIncentiveCpiData(\n user: Address,\n payer: Address,\n pool: Address,\n reserve: Address,\n obligation: Address,\n farm: Address,\n userFarm: Address,\n mint: Address\n ): Promise<CpiData[]> {\n const tokenProgram = mints.get(mint)?.tokenProgram ?? TOKEN_PROGRAM_ADDRESS;\n const reserveData = await this.data.fetchReserve(pool, reserve);\n\n const [farmState] = await this.data.fetchFarms([farm]);\n\n const rewardIndex = farmState.rewardInfos.findIndex((r) => r.token.mint === mint);\n if (rewardIndex === -1) {\n throw new Error(`Reward mint ${mint} not found on farm ${farm}`);\n }\n\n const rewardInfo = farmState.rewardInfos[rewardIndex];\n const treasuryVault = await getTreasuryVaultPDA(\n KAMINO_FARMS_PROGRAM_ID,\n farmState.globalConfig,\n mint\n );\n const scopePrices =\n farmState.scopePrices === DEFAULT_PUBLIC_KEY\n ? KAMINO_FARMS_PROGRAM_ID\n : farmState.scopePrices;\n\n const mode =\n reserveData.rawData.state.farmCollateral === farm\n ? \"collateral\"\n : reserveData.rawData.state.farmDebt === farm\n ? \"debt\"\n : undefined;\n const refreshIx = mode\n ? await this.getRefreshUserFarmCpiData(user, pool, reserve, obligation, userFarm, farm, mode)\n : undefined;\n\n // Kfarms HarvestReward requires `owner` (account[0]) to equal\n // `UserState.owner`, which for both klend obligation farms and direct/extra\n // farms is the lyc-token PDA — `user` here. The CPI dispatcher signs for it\n // via `invoke_signed` with the token PDA seeds. Passing the manager fails\n // with HarvestingNotPermissionlessPayerMismatch (0x17b2).\n return [\n ...(refreshIx ? [refreshIx] : []),\n this.getCpiData(\n CpiTypes.K_HARVEST_REWARD,\n [\n toCustomAccountMeta(user, true),\n toCustomAccountMeta(userFarm, true),\n toCustomAccountMeta(farm, true),\n toCustomAccountMeta(farmState.globalConfig),\n toCustomAccountMeta(mint),\n toCustomAccountMeta(await getAtaAddress(mint, user, tokenProgram), true, {\n owner: user,\n mint,\n tokenProgram,\n }),\n toCustomAccountMeta(rewardInfo.rewardsVault, true),\n toCustomAccountMeta(treasuryVault, true),\n toCustomAccountMeta(farmState.farmVaultsAuthority),\n toCustomAccountMeta(scopePrices),\n toCustomAccountMeta(tokenProgram),\n ],\n numToU64Bytes(rewardIndex),\n KAMINO_FARMS_PROGRAM_ID\n ),\n ];\n }\n\n async getRequestElevationGroupCpiData(\n elevationGroup: number,\n user: Address,\n obligation: Address,\n pool: Address,\n txId: string\n ): Promise<CpiData> {\n // Kamino's request_elevation_group handler validates the trailing\n // remaining accounts against the obligation's *current* deposit + borrow\n // reserves — the same `expected_remaining_accounts != actual_remaining_accounts`\n // count check that RefreshObligation enforces (see\n // `getRefreshObligationCpiData`); a mismatch throws InvalidAccountInput\n // (klend 6006). Passing only the three fixed accounts (as we used to)\n // works for an empty obligation but fails the moment it holds a deposit\n // — e.g. the flash-rebalance destination, which has the just-moved\n // collateral deposited before this elevation request runs.\n //\n // Mirror the refresh path: append the obligation's collateral then debt\n // reserves, combining on-chain state with reserves registered earlier in\n // this same tx (the destination deposit isn't reflected on-chain yet at\n // build time). Kamino marks these WRITABLE.\n const obligationData = await this.data.maybeFetchUserPositionInPool(pool, obligation);\n const cached = this.getTxUserAccountReserves(txId, obligation);\n const cleared = this.getTxObligationClearedDebt(txId, obligation);\n const collateralReserves = [\n ...new Set([...(obligationData?.deposits.map((x) => x.reserve) ?? []), ...cached.collateral]),\n ];\n const debtReserves = [\n ...new Set([...(obligationData?.borrows.map((x) => x.reserve) ?? []), ...cached.debt]),\n ].filter((r) => !cleared.has(r));\n\n return this.getCpiData(\n CpiTypes.K_REQUEST_ELEVATION_GROUP,\n [\n toCustomAccountMeta(user),\n toCustomAccountMeta(obligation, true),\n toCustomAccountMeta(pool),\n ...collateralReserves.map((x) => toCustomAccountMeta(x, true)),\n ...debtReserves.map((x) => toCustomAccountMeta(x, true)),\n ],\n new Uint8Array([elevationGroup])\n );\n }\n\n async getInitAndDepositCpiData(\n params: LendingOperationParams,\n userAccountId: number\n ): Promise<SplitLpOperationCpiData> {\n const initCpis: CpiData[] = [];\n\n if (!(await accountExists(this.rpc, params.userAccount))) {\n initCpis.push(\n ...(\n await this.getInitUserAccountCpiData(\n params.pool,\n params.user,\n params.payer,\n userAccountId\n )\n ).allCpis,\n await this.getRefreshObligationCpiData(params.txId, params.pool, params.userAccount)\n );\n }\n\n const reserveData = await this.data.fetchReserve(params.pool, params.reserve);\n const farmCollateral = reserveData.rawData.state.farmCollateral;\n if (farmCollateral && farmCollateral !== DEFAULT_PUBLIC_KEY) {\n const farmAccounts = await this.accounts.getFarmAccounts(\n params.pool,\n params.reserve,\n params.userAccount,\n \"collateral\"\n );\n if (!(await accountExists(this.rpc, farmAccounts.userFarm.address))) {\n initCpis.push(\n await this.getInitObligationFarmsForReserveCpiData(\n params.user,\n params.payer,\n params.userAccount,\n params.pool,\n params.reserve,\n \"collateral\"\n )\n );\n }\n }\n\n const depositCpis = await this.getDepositCpiData(params);\n return this.createSplitOperationCpiData(\n [...initCpis, ...depositCpis.prerequisiteCpis],\n depositCpis.cpis\n );\n }\n\n async getInitBorrowPositionCpiData(\n params: LendingOperationParams,\n collReserve: Address\n ): Promise<SplitLpOperationCpiData> {\n const initCpis: CpiData[] = [];\n\n const reserveData = await this.data.fetchReserve(params.pool, params.reserve);\n const farmDebt = reserveData.rawData.state.farmDebt;\n if (farmDebt && farmDebt !== DEFAULT_PUBLIC_KEY) {\n const farmAccounts = await this.accounts.getFarmAccounts(\n params.pool,\n params.reserve,\n params.userAccount,\n \"debt\"\n );\n if (!(await accountExists(this.rpc, farmAccounts.userFarm.address))) {\n initCpis.push(\n await this.getInitObligationFarmsForReserveCpiData(\n params.user,\n params.payer,\n params.userAccount,\n params.pool,\n params.reserve,\n \"debt\"\n )\n );\n }\n }\n\n const debtReserveData = await this.data.fetchReserve(params.pool, params.reserve);\n const market = await this.data.fetchMarket(params.pool);\n const requestedBorrowBaseUnits =\n params.baseUnitAmount && params.baseUnitAmount !== \"all\"\n ? params.baseUnitAmount\n : typeof params.uiAmount === \"number\"\n ? new BN(Math.floor(params.uiAmount * Math.pow(10, debtReserveData.mint.mintDecimals)))\n : undefined;\n\n const collReserveData = await this.data.fetchReserve(params.pool, collReserve);\n const availableElevationGroups = collReserveData.config.emodes?.filter(\n (x) => x.debtReserve === params.reserve\n );\n if (availableElevationGroups?.length) {\n // Greedily prefer the highest-LTV e-mode group, but only enter one that\n // actually has borrow capacity for this debt+collateral pair right now.\n // Kamino rejects entry into a group whose debt cap is exhausted or\n // disabled (ElevationGroupBorrowLimitExceeded, klend 6101); the cap lives\n // on the collateral reserve, indexed per group. `getLiquidityAvailable…`\n // folds the emode cap together with the reserve's global / utilization /\n // daily caps and returns 0 for a maxed/zeroed group. When none qualify we\n // fall back to no e-mode (group 0) — LYC sizing uses the base (non-emode)\n // LTV, so the borrow always fits there.\n const sortedGroups = [...availableElevationGroups]\n .filter((g) => g.id !== undefined)\n .sort((a, b) => b.ltvPct - a.ltvPct);\n\n let selectedGroup: number | undefined;\n for (const group of sortedGroups) {\n const [available] = debtReserveData.rawData.getLiquidityAvailableForDebtReserveGivenCaps(\n market,\n [group.id!],\n [collReserve]\n );\n const hasCapacity = requestedBorrowBaseUnits\n ? available.gte(requestedBorrowBaseUnits.toString())\n : available.gt(0);\n if (hasCapacity) {\n selectedGroup = group.id!;\n break;\n }\n }\n\n if (selectedGroup !== undefined) {\n // RequestElevationGroup requires the obligation to be refreshed in the\n // current slot (klend ObligationStale / 6017). A preceding CPI in this\n // group — e.g. the destination collateral deposit in a flash rebalance —\n // dirties the obligation, so refresh it (and its reserves) immediately\n // before the elevation request. Refreshing against `collReserve` scopes\n // the RefreshObligation to the obligation's current deposits; the borrow\n // below emits its own refresh afterward, re-freshening the obligation\n // that RequestElevationGroup itself leaves stale.\n initCpis.push(\n ...(await this.getRefreshCpisIfNeeded(\n params.txId,\n params.pool,\n collReserve,\n params.userAccount\n ))\n );\n initCpis.push(\n await this.getRequestElevationGroupCpiData(\n selectedGroup,\n params.user,\n params.userAccount,\n params.pool,\n params.txId\n )\n );\n }\n }\n\n const borrowCpis = await this.getBorrowCpiData(params);\n return this.createSplitOperationCpiData(\n [...initCpis, ...borrowCpis.prerequisiteCpis],\n borrowCpis.cpis\n );\n }\n\n async getDepositCpiData(params: LendingOperationParams): Promise<SplitLpOperationCpiData> {\n const refreshCpis = await this.getRefreshCpisIfNeeded(\n params.txId,\n params.pool,\n params.reserve,\n params.userAccount\n );\n const details = await this.accounts.reserveInteractionDetails(\n params.user,\n params.pool,\n params.reserve,\n params.userAccount,\n typeof params.uiAmount === \"number\" ? params.uiAmount : undefined,\n params.baseUnitAmount instanceof BN ? params.baseUnitAmount : undefined\n );\n const farms = await this.accounts.getFarmAccounts(\n params.pool,\n params.reserve,\n params.userAccount,\n \"collateral\"\n );\n\n this.registerTxReserve(\n params.txId,\n params.pool,\n params.reserve,\n params.userAccount,\n \"collateral\"\n );\n\n return this.createSplitOperationCpiData(refreshCpis, [\n this.getCpiData(\n CpiTypes.K_DEPOSIT,\n [\n details.signer,\n details.obligation!,\n details.lendingMarket,\n details.lendingMarketAuthority,\n details.reserve,\n details.reserveLiquidityMint,\n details.reserveLiquiditySupply,\n details.reserveCollateralMint,\n details.reserveCollateralSupply,\n details.userLiquidityTa,\n this.emptyAccountMeta(),\n details.collateralMintTokenProgram,\n details.liquidityMintTokenProgram,\n IX_SYSVAR_META,\n farms.userFarm,\n farms.farm,\n details.farmsProgram,\n ],\n details.baseUnitAmount ? numToU64Bytes(details.baseUnitAmount) : undefined,\n undefined,\n this.getUserAccountCacheInvalidations(params.userAccount)\n ),\n ]);\n }\n\n async getWithdrawCpiData(params: LendingOperationParams): Promise<SplitLpOperationCpiData> {\n const refreshCpis = await this.getRefreshCpisIfNeeded(\n params.txId,\n params.pool,\n params.reserve,\n params.userAccount\n );\n const withdrawAll = params.uiAmount === \"all\" || params.baseUnitAmount === \"all\";\n const details = await this.accounts.reserveInteractionDetails(\n params.user,\n params.pool,\n params.reserve,\n params.userAccount,\n typeof params.uiAmount === \"number\" ? params.uiAmount : undefined,\n params.baseUnitAmount instanceof BN ? params.baseUnitAmount : undefined\n );\n const farms = await this.accounts.getFarmAccounts(\n params.pool,\n params.reserve,\n params.userAccount,\n \"collateral\"\n );\n\n let collateralBytes: Uint8Array | undefined;\n if (withdrawAll) {\n // Kamino's `WithdrawObligationCollateralAndRedeemReserveCollateralV2`\n // treats `collateral_amount = u64::MAX` as \"withdraw the obligation's\n // entire deposit on this reserve\" — clears dust regardless of off-chain\n // cToken/liquidity rate drift.\n collateralBytes = numToU64Bytes(U64_MAX_BN);\n } else if (details.baseUnitAmount) {\n const reserveData = await this.data.fetchReserve(params.pool, params.reserve);\n // +1 cToken so the on-chain redemption always realizes at least the\n // requested liquidity amount despite the floor in the exchange rate\n // conversion and minor rate drift between fetch and execution.\n const collateralAmount =\n liquidityToCollateral(reserveData, details.baseUnitAmount.toNumber()) + 1;\n collateralBytes = numToU64Bytes(collateralAmount);\n }\n\n this.registerTxReserve(\n params.txId,\n params.pool,\n params.reserve,\n params.userAccount,\n \"collateral\"\n );\n\n return this.createSplitOperationCpiData(refreshCpis, [\n this.getCpiData(\n CpiTypes.K_WITHDRAW,\n [\n details.signer,\n details.obligation!,\n details.lendingMarket,\n details.lendingMarketAuthority,\n details.reserve,\n details.reserveLiquidityMint,\n details.reserveCollateralSupply,\n details.reserveCollateralMint,\n details.reserveLiquiditySupply,\n details.userLiquidityTa,\n this.emptyAccountMeta(),\n details.collateralMintTokenProgram,\n details.liquidityMintTokenProgram,\n IX_SYSVAR_META,\n farms.userFarm,\n farms.farm,\n details.farmsProgram,\n ],\n collateralBytes,\n undefined,\n this.getUserAccountCacheInvalidations(params.userAccount)\n ),\n ]);\n }\n\n async getBorrowCpiData(params: LendingOperationParams): Promise<SplitLpOperationCpiData> {\n const refreshCpis = await this.getRefreshCpisIfNeeded(\n params.txId,\n params.pool,\n params.reserve,\n params.userAccount\n );\n const details = await this.accounts.reserveInteractionDetails(\n params.user,\n params.pool,\n params.reserve,\n params.userAccount,\n typeof params.uiAmount === \"number\" ? params.uiAmount : undefined\n );\n const farms = await this.accounts.getFarmAccounts(\n params.pool,\n params.reserve,\n params.userAccount,\n \"debt\"\n );\n\n this.registerTxReserve(params.txId, params.pool, params.reserve, params.userAccount, \"debt\");\n return this.createSplitOperationCpiData(refreshCpis, [\n this.getCpiData(\n CpiTypes.K_BORROW,\n [\n details.signer,\n details.obligation!,\n details.lendingMarket,\n details.lendingMarketAuthority,\n details.reserve,\n details.reserveLiquidityMint,\n details.reserveLiquiditySupply,\n details.reserveFeeVault,\n details.userLiquidityTa,\n this.emptyAccountMeta(),\n details.liquidityMintTokenProgram,\n IX_SYSVAR_META,\n farms.userFarm,\n farms.farm,\n details.farmsProgram,\n ],\n details.baseUnitAmount ? numToU64Bytes(details.baseUnitAmount) : undefined,\n undefined,\n this.getUserAccountCacheInvalidations(params.userAccount)\n ),\n ]);\n }\n\n async getRepayCpiData(params: RepayOperationParams): Promise<SplitLpOperationCpiData> {\n this.registerTxReserve(params.txId, params.pool, params.reserve, params.userAccount, \"debt\");\n const refreshCpis = await this.getRefreshCpisIfNeeded(\n params.txId,\n params.pool,\n params.reserve,\n params.userAccount\n );\n const details = await this.accounts.reserveInteractionDetails(\n params.user,\n params.pool,\n params.reserve,\n params.userAccount,\n typeof params.uiAmount === \"number\" ? params.uiAmount : undefined\n );\n const farms = await this.accounts.getFarmAccounts(\n params.pool,\n params.reserve,\n params.userAccount,\n \"debt\"\n );\n\n // \"all\" never carries a repay amount — full repayment goes through `full`\n // (U64_MAX); a non-BN amount falls back to the derived reserve amount.\n const repayAmountBytes = params.full\n ? numToU64Bytes(U64_MAX_BN)\n : params.baseUnitAmount instanceof BN\n ? numToU64Bytes(params.baseUnitAmount)\n : details.baseUnitAmount\n ? numToU64Bytes(details.baseUnitAmount)\n : undefined;\n\n return this.createSplitOperationCpiData(refreshCpis, [\n this.getCpiData(\n CpiTypes.K_REPAY,\n [\n details.signer,\n details.obligation!,\n details.lendingMarket,\n details.reserve,\n details.reserveLiquidityMint,\n details.reserveLiquiditySupply,\n details.userLiquidityTa,\n details.liquidityMintTokenProgram,\n IX_SYSVAR_META,\n farms.userFarm,\n farms.farm,\n details.lendingMarketAuthority,\n details.farmsProgram,\n ],\n repayAmountBytes,\n undefined,\n this.getUserAccountCacheInvalidations(params.userAccount)\n ),\n ]);\n }\n}\n","import { Address } from \"@solana/kit\";\n\nexport interface RefreshPrerequisiteTarget {\n pool: Address;\n userAccount: Address;\n collateralReserves: Address[];\n debtReserves: Address[];\n}\n","export * from \"./kamino\";\nexport * from \"./lpInstructionsBase\";\nexport * from \"./types\";\n","import { Address } from \"@solana/kit\";\nimport { LendingPlatformData } from \"../platform\";\n\nexport abstract class LpAccountsBase<T extends LendingPlatformData> {\n data!: T;\n\n constructor(data: T) {\n this.data = data;\n }\n\n abstract getUserAccountAddress(pool: Address, user: Address, id: number): Promise<Address>;\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { Address } from \"@solana/kit\";\nimport { KaminoData } from \"../platform\";\nimport {\n DEFAULT_PUBLIC_KEY,\n lendingMarketAuthPda,\n obligationFarmStatePda,\n PROGRAM_ID,\n userMetadataPda,\n VanillaObligation,\n} from \"@kamino-finance/klend-sdk\";\nimport { getAtaAddress, fromUiAmount, toCustomAccountMeta } from \"common\";\nimport { AssociatedTokenSeeds, TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { KAMINO_FARMS_PROGRAM_ID } from \"../../constants\";\nimport { LpAccountsBase } from \"./lpAccountsBase\";\n\nexport class KaminoAccounts extends LpAccountsBase<KaminoData> {\n async getUserAccountAddress(pool: Address, user: Address, id: number): Promise<Address> {\n const market = await this.data.fetchMarket(pool);\n const obligationType = new VanillaObligation(market.programId, id);\n return await obligationType.toPda(pool, user);\n }\n\n async getUserMetadataAddress(user: Address) {\n return (await userMetadataPda(user, PROGRAM_ID))[0];\n }\n\n /**\n * Gets the obligation farm accounts for a reserve.\n */\n async getFarmAccounts(\n pool: Address,\n reserve: Address,\n obligation: Address,\n farmMode: \"collateral\" | \"debt\"\n ) {\n const emptyFarms = {\n userFarm: toCustomAccountMeta(PROGRAM_ID),\n farm: toCustomAccountMeta(PROGRAM_ID),\n };\n\n const reserveData = await this.data.fetchReserve(pool, reserve);\n if (!reserveData) {\n return emptyFarms;\n }\n\n const farmAddress =\n farmMode === \"collateral\"\n ? reserveData.rawData.state.farmCollateral\n : reserveData.rawData.state.farmDebt;\n\n if (!farmAddress || farmAddress === DEFAULT_PUBLIC_KEY) {\n return emptyFarms;\n }\n\n const obligationFarmUserState = await obligationFarmStatePda(farmAddress, obligation);\n return {\n userFarm: toCustomAccountMeta(obligationFarmUserState, true),\n farm: toCustomAccountMeta(farmAddress, true),\n };\n }\n\n /**\n * Returns the obligationFarmUserState PDA addresses for all active farms\n * (collateral and debt) on a reserve. The farm addresses themselves live on\n * the Kamino LUTs; only the user-specific state needs the per-token LUT.\n */\n async getUserFarmAddresses(\n pool: Address,\n reserve: Address,\n obligation: Address\n ): Promise<Address[]> {\n const addresses: Address[] = [];\n for (const mode of [\"collateral\", \"debt\"] as const) {\n const { farm, userFarm } = await this.getFarmAccounts(pool, reserve, obligation, mode);\n if (farm.address !== PROGRAM_ID) {\n addresses.push(userFarm.address);\n }\n }\n return addresses;\n }\n\n /**\n * Get all relevant account metas needed for interacting with the Kamino lending market.\n */\n async reserveInteractionDetails(\n user: Address,\n pool: Address,\n reserve: Address,\n obligation?: Address,\n amount?: number,\n baseUnitAmountOverride?: BN\n ) {\n const reserveData = await this.data.fetchReserve(pool, reserve);\n const liquidityMint = reserveData.mint.mint;\n const liquidityMintTokenProgram = reserveData.mint.mintTokenProgram;\n\n const collateralMint = reserveData.rawData.state.collateral.mintPubkey;\n const collateralMintTokenProgram = TOKEN_PROGRAM_ADDRESS;\n\n const userLiquidityTaSeeds: AssociatedTokenSeeds = {\n mint: liquidityMint,\n owner: user,\n tokenProgram: liquidityMintTokenProgram,\n };\n const userLiquidityTa = await getAtaAddress(liquidityMint, user, liquidityMintTokenProgram);\n\n const userCollateralTaSeeds: AssociatedTokenSeeds = {\n mint: collateralMint,\n owner: user,\n tokenProgram: collateralMintTokenProgram,\n };\n const userCollateralTa = await getAtaAddress(collateralMint, user, collateralMintTokenProgram);\n\n const reserveLiquiditySupply = reserveData.rawData.state.liquidity.supplyVault;\n const reserveCollateralSupply = reserveData.rawData.state.collateral.supplyVault;\n\n return {\n baseUnitAmount:\n baseUnitAmountOverride !== undefined\n ? baseUnitAmountOverride\n : amount !== undefined\n ? fromUiAmount(amount, reserveData.mint.mintDecimals)\n : undefined,\n signer: toCustomAccountMeta(user, true),\n obligation: obligation ? toCustomAccountMeta(obligation, true) : undefined,\n reserve: toCustomAccountMeta(reserve, true),\n reserveFeeVault: toCustomAccountMeta(reserveData.rawData.state.liquidity.feeVault, true),\n reserveLiquidityMint: toCustomAccountMeta(liquidityMint),\n reserveLiquiditySupply: toCustomAccountMeta(reserveLiquiditySupply, true),\n reserveCollateralMint: toCustomAccountMeta(collateralMint, true),\n reserveCollateralSupply: toCustomAccountMeta(reserveCollateralSupply, true),\n lendingMarket: toCustomAccountMeta(pool),\n lendingMarketAuthority: toCustomAccountMeta((await lendingMarketAuthPda(pool))[0]),\n userLiquidityTa: toCustomAccountMeta(userLiquidityTa, true, userLiquidityTaSeeds),\n userCollateralTa: toCustomAccountMeta(userCollateralTa, true, userCollateralTaSeeds),\n liquidityMintTokenProgram: toCustomAccountMeta(liquidityMintTokenProgram),\n collateralMintTokenProgram: toCustomAccountMeta(collateralMintTokenProgram),\n farmsProgram: toCustomAccountMeta(KAMINO_FARMS_PROGRAM_ID),\n };\n }\n}\n","export * from \"./kamino\";\nexport * from \"./lpAccountsBase\";\n","export * from \"./platform\";\nexport * from \"./reserve\";\nexport * from \"./userPosition\";\nexport * from \"./incentive\";\nexport * from \"./instructions\";\nexport * from \"./accounts\";\n","import { BN } from \"@anchor-lang/core\";\nimport type { Address, Instruction } from \"@solana/kit\";\nimport { LendingPlatformData } from \"../../data/platform\";\n\n/** Parameters for building a flash-borrow instruction. */\nexport interface FlashBorrowParams {\n /** Authority that signs the transfer of the borrowed liquidity. */\n user: Address;\n pool: Address;\n reserve: Address;\n /** Amount to borrow, in the reserve liquidity mint's base units. */\n amountBaseUnits: BN;\n /** Destination ATA for the borrowed liquidity. Defaults to `user`'s ATA for the mint. */\n destinationAta?: Address;\n}\n\n/** Parameters for building a flash-repay instruction, paired with a prior flash-borrow. */\nexport interface FlashRepayParams extends FlashBorrowParams {\n /** Top-level transaction index of the matching flash-borrow instruction. */\n borrowIxIndex: number;\n /** Source ATA for the repay. Defaults to the destination ATA used on the flash-borrow. */\n userSourceLiquidity?: Address;\n}\n\n/**\n * Abstract base for lending-platform flash-loan instruction builders.\n * Flash loans are composed of a top-level borrow and repay pair that must live\n * in the same transaction; the repay references the borrow by instruction index.\n *\n * @typeParam T - The platform-specific data class extending LendingPlatformData\n */\nexport abstract class FlashLoanBase<T extends LendingPlatformData> {\n data!: T;\n\n constructor(data: T) {\n this.data = data;\n }\n\n /** Builds the top-level flash-borrow instruction. */\n abstract getFlashBorrowIx(params: FlashBorrowParams): Promise<Instruction>;\n\n /**\n * Builds the top-level flash-repay instruction. Must be paired with a\n * flash-borrow at `borrowIxIndex` in the same transaction.\n */\n abstract getFlashRepayIx(params: FlashRepayParams): Promise<Instruction>;\n\n /**\n * Returns the maximum amount that can be flash-borrowed from `reserve`, in\n * the reserve liquidity mint's base units.\n */\n abstract getAvailableFlashBorrowAmount(pool: Address, reserve: Address): Promise<BN>;\n\n /**\n * Returns `reserve`'s flash-loan fee rate as a fraction of the borrowed\n * amount (e.g. `0.003` for 0.3%).\n */\n abstract getFlashLoanFeeRate(pool: Address, reserve: Address): Promise<number>;\n}\n","import { BN } from \"@anchor-lang/core\";\nimport Decimal from \"decimal.js\";\nimport { type Address, type Instruction, none } from \"@solana/kit\";\nimport {\n getBorrowFlashLoanInstruction,\n getRepayFlashLoanInstruction,\n lendingMarketAuthPda,\n PROGRAM_ID,\n} from \"@kamino-finance/klend-sdk\";\nimport { createSignerFromAddress, getAtaAddress, mints } from \"common\";\nimport { KaminoData } from \"../../data/platform\";\nimport { KaminoReserveData } from \"../../data/reserve\";\nimport { FlashBorrowParams, FlashLoanBase, FlashRepayParams } from \"./flashLoanBase\";\n\n/**\n * Drop the `signer` field from any account meta, leaving the address + role\n * intact. The Kamino codegen attaches a placeholder `NoopSigner` to the\n * `userTransferAuthority` meta to satisfy its TS types; if we keep it, Kit's\n * dedup conflicts with the real fee-payer `KeyPairSigner` whenever the\n * placeholder address matches the fee payer (or appears twice — borrow +\n * repay — in the same tx). Stripping it lets `addSignersToTransactionMessage`\n * re-attach the real signer at compile time.\n */\nfunction stripAccountSigners(ix: Instruction): Instruction {\n if (!ix.accounts) return ix;\n return {\n ...ix,\n accounts: ix.accounts.map((account) => {\n if (!(\"signer\" in account)) return account;\n const { signer: _signer, ...rest } = account as { signer: unknown } & typeof account;\n return rest;\n }),\n };\n}\n\nexport class KaminoFlashLoan extends FlashLoanBase<KaminoData> {\n async getFlashBorrowIx(params: FlashBorrowParams): Promise<Instruction> {\n const { reserve, lendingMarketAuthority, destinationAta } =\n await this.resolveSharedAccounts(params);\n\n return stripAccountSigners(\n getBorrowFlashLoanInstruction({\n userTransferAuthority: createSignerFromAddress(params.user),\n lendingMarketAuthority,\n lendingMarketAddress: params.pool,\n reserve: reserve.rawData,\n amountLamports: new Decimal(params.amountBaseUnits.toString()),\n destinationAta,\n referrerAccount: none(),\n referrerTokenState: none(),\n programId: PROGRAM_ID,\n })\n );\n }\n\n async getAvailableFlashBorrowAmount(pool: Address, reserve: Address): Promise<BN> {\n const reserveData = await this.data.fetchReserve(pool, reserve);\n return new BN(reserveData.rawData.getLiquidityAvailableAmount().toFixed(0));\n }\n\n async getFlashLoanFeeRate(pool: Address, reserve: Address): Promise<number> {\n const reserveData = await this.data.fetchReserve(pool, reserve);\n return reserveData.config.flashLoanFeePct;\n }\n\n async getFlashRepayIx(params: FlashRepayParams): Promise<Instruction> {\n const { reserve, lendingMarketAuthority, destinationAta } =\n await this.resolveSharedAccounts(params);\n\n return stripAccountSigners(\n getRepayFlashLoanInstruction({\n borrowIxIndex: params.borrowIxIndex,\n userTransferAuthority: createSignerFromAddress(params.user),\n lendingMarketAuthority,\n lendingMarketAddress: params.pool,\n reserve: reserve.rawData,\n amountLamports: new Decimal(params.amountBaseUnits.toString()),\n userSourceLiquidity: params.userSourceLiquidity ?? destinationAta,\n referrerAccount: none(),\n referrerTokenState: none(),\n programId: PROGRAM_ID,\n })\n );\n }\n\n private async resolveSharedAccounts(params: FlashBorrowParams): Promise<{\n reserve: KaminoReserveData;\n lendingMarketAuthority: Address;\n destinationAta: Address;\n }> {\n const reserve = await this.data.fetchReserve(params.pool, params.reserve);\n const [lendingMarketAuthority] = await lendingMarketAuthPda(params.pool);\n\n const liquidityMint = reserve.mint.mint;\n const tokenProgram = mints.get(liquidityMint)?.tokenProgram;\n if (!tokenProgram) {\n throw new Error(`Unsupported liquidity mint for flash loan: ${liquidityMint}`);\n }\n\n const destinationAta =\n params.destinationAta ?? (await getAtaAddress(liquidityMint, params.user, tokenProgram));\n\n return { reserve, lendingMarketAuthority, destinationAta };\n }\n}\n","import { Address } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport { Obligation } from \"@kamino-finance/klend-sdk\";\nimport { getRpcUrl, ENVIRONMENT, U64_MAX_BN } from \"common\";\nimport { LendingPlatformClientBase } from \"./lpClientBase\";\nimport { KaminoData, KaminoUserPositionData } from \"../../data\";\nimport { KaminoAccounts } from \"../../data/accounts\";\nimport { KaminoInstructions } from \"../../data/instructions\";\nimport { KaminoFlashLoan } from \"../flashLoan/kamino\";\nimport type { OutstandingIncentive } from \"../../types\";\n\n/**\n * Client for interacting with Kamino Lend protocol.\n * Provides access to data, accounts, and instruction builders for lending operations.\n */\nexport class KaminoClient extends LendingPlatformClientBase<KaminoData> {\n accounts: KaminoAccounts;\n ix: KaminoInstructions;\n\n constructor(rpcUrl: string = getRpcUrl(ENVIRONMENT), rpcUrls: string[] = [rpcUrl]) {\n super(rpcUrl, rpcUrls);\n this.data = new KaminoData(rpcUrl, undefined, rpcUrls);\n this.accounts = new KaminoAccounts(this.data);\n this.ix = new KaminoInstructions(this.rpc, rpcUrl, this.data, this.accounts);\n }\n\n async refreshData(pools: Address[]) {\n this.data.clearCache();\n await this.data.load(pools);\n }\n\n getFlashLoan(): KaminoFlashLoan {\n return new KaminoFlashLoan(this.data);\n }\n\n /**\n * Kamino's `RepayObligationLiquidityV2` interprets `u64::MAX` as \"repay\n * the obligation's full debt for this reserve\" — letting the on-chain\n * handler clear interest-accrual dust between the off-chain quote and\n * settlement. The flash-borrow over-borrows by a slippage buffer to fund\n * this; the post-repay surplus is swept into the yielding bank.\n */\n override getRepayAllSentinel(): BN {\n return U64_MAX_BN;\n }\n\n async getAvailableUserAccountId(\n pool: Address,\n user: Address,\n excludeUserAccounts: readonly Address[] = []\n ): Promise<number> {\n const positions = await this.data.fetchAllUserPositionsForUserInPool(pool, user);\n const positionsByAddress = new Map(positions.map((position) => [position.address, position]));\n const excludeSet = new Set(excludeUserAccounts);\n\n for (let userAccountId = 0; ; userAccountId++) {\n const userAccount = await this.accounts.getUserAccountAddress(pool, user, userAccountId);\n if (excludeSet.has(userAccount)) {\n continue;\n }\n const existingPosition = positionsByAddress.get(userAccount);\n\n if (!existingPosition || this.isInactiveUserAccount(existingPosition)) {\n return userAccountId;\n }\n }\n }\n\n /**\n * Returns claimable rewards across all kamino farms tied to this obligation:\n *\n * - **Obligation farms** (klend reserve `farmCollateral`/`farmDebt`):\n * UserState.owner = obligation owner (the lyc-token PDA),\n * UserState.delegatee = the obligation itself.\n * - **Direct/extra farms** (e.g. paired-reserve incentives): the lyc-token\n * PDA stakes directly in the farms program.\n * UserState.owner = UserState.delegatee = lyc-token PDA.\n *\n * The farms SDK filters UserStates by memcmp against `owner` (offset 48),\n * so we query by the obligation's owner and then accept any UserState whose\n * `delegatee` is either the obligation or the owner itself. In both cases\n * `userFarm.userStateAddress` is the correct UserState account for the\n * `HarvestReward` CPI; deriving via `obligationFarmStatePda` would be wrong\n * for direct farms (different seed scheme).\n */\n async getOutstandingIncentives(\n userAccount: Address,\n minUiAmount = 0,\n log?: (msg: string) => void\n ): Promise<OutstandingIncentive[]> {\n const obligationOwner = await this.fetchObligationOwner(userAccount);\n if (!obligationOwner) {\n log?.(` [getOutstandingIncentives] no obligation owner found for ${userAccount}`);\n return [];\n }\n const allOwnerFarms = await this.data.fetchUserActiveIncentives(obligationOwner);\n log?.(\n ` [getOutstandingIncentives] found ${allOwnerFarms.length} farm(s) owned by ${obligationOwner.slice(0, 6)}…`\n );\n const userFarms = allOwnerFarms.filter(\n (uf) => uf.userState.delegatee === userAccount || uf.userState.delegatee === obligationOwner\n );\n const filteredOut = allOwnerFarms.length - userFarms.length;\n if (filteredOut > 0) {\n log?.(\n ` [getOutstandingIncentives] ${filteredOut} farm(s) skipped — delegatee matched neither userAccount (${userAccount.slice(0, 6)}…) nor owner`\n );\n }\n if (userFarms.length === 0) {\n log?.(` [getOutstandingIncentives] no matching farms for userAccount`);\n return [];\n }\n\n // Reward token decimals live on the FarmState, not on the pending-reward\n // entry, so fetch the (cached) farm states to convert raw balances to UI\n // units for the dust filter.\n const farmStates = await this.data.fetchFarms(userFarms.map((uf) => uf.farm));\n const decimalsByFarmAndMint = new Map<string, number>();\n farmStates.forEach((farmState, i) => {\n const farm = userFarms[i].farm;\n for (const rewardInfo of farmState.rewardInfos) {\n decimalsByFarmAndMint.set(\n `${farm}:${rewardInfo.token.mint}`,\n rewardInfo.token.decimals.toNumber()\n );\n }\n });\n\n const incentives: OutstandingIncentive[] = [];\n\n for (const userFarm of userFarms) {\n log?.(\n ` [getOutstandingIncentives] farm ${userFarm.farm.slice(0, 6)}… userFarm ${userFarm.userStateAddress.slice(0, 6)}… delegatee ${userFarm.userState.delegatee.slice(0, 6)}… ${userFarm.pendingRewards.length} pending reward(s)`\n );\n for (const reward of userFarm.pendingRewards) {\n const amount = reward.cumulatedPendingRewards.toNumber();\n const decimals =\n decimalsByFarmAndMint.get(`${userFarm.farm}:${reward.rewardTokenMint}`) ?? 0;\n const uiAmount = amount / 10 ** decimals;\n if (amount <= 0) {\n log?.(` reward ${reward.rewardTokenMint.slice(0, 6)}… — skipped (amount=0)`);\n continue;\n }\n if (uiAmount < minUiAmount) {\n log?.(\n ` reward ${reward.rewardTokenMint.slice(0, 6)}… — skipped (uiAmount=${uiAmount.toFixed(4)} < minUiAmount=${minUiAmount})`\n );\n continue;\n }\n log?.(\n ` reward ${reward.rewardTokenMint.slice(0, 6)}… — claimable uiAmount=${uiAmount.toFixed(4)}`\n );\n incentives.push({\n mint: reward.rewardTokenMint,\n amount,\n decimals,\n uiAmount,\n claimAccounts: {\n farm: userFarm.farm,\n userFarm: userFarm.userStateAddress,\n },\n });\n }\n }\n\n return incentives;\n }\n\n /**\n * Reads the klend obligation account and returns its `owner` field (the\n * authority that opened the obligation — for LYC this is the lyc-token PDA).\n * Returns null when the account doesn't exist on-chain (stale protocolUserAcc).\n */\n private async fetchObligationOwner(userAccount: Address): Promise<Address | null> {\n const obligation = await Obligation.fetch(this.rpc, userAccount);\n return obligation ? (obligation.owner as Address) : null;\n }\n\n private isInactiveUserAccount(position: KaminoUserPositionData): boolean {\n return [...position.deposits, ...position.borrows].every((entry) => entry.amount.isZero());\n }\n}\n","export * from \"./kamino\";\nexport * from \"./lpClientBase\";\n","export * from \"./flashLoanBase\";\nexport * from \"./kamino\";\n","import { address, type Address } from \"@solana/kit\";\n\n/**\n * Jupiter V6 Aggregator Program ID\n */\nexport const JUPITER_V6_PROGRAM_ID: Address = address(\n \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\"\n);\n\n/**\n * Jupiter API base URL\n */\nexport const JUPITER_API_URL = \"https://lite-api.jup.ag\";\n\n/**\n * Default slippage in basis points (5%)\n */\nexport const DEFAULT_SLIPPAGE_BPS = 500;\n\n/**\n * Local/Surfpool max account budget for swap instructions.\n * Lower values improve compatibility with local validators.\n */\nexport const LOCAL_TEST_MAX_ACCOUNTS = 20;\n\n/**\n * DEXes to exclude in local/Surfpool tests.\n * Production/testnet deployments should not apply this list by default.\n */\nexport const LOCAL_TEST_EXCLUDED_DEXES = [\"GoonFi\", \"HumidiFi\", \"TesseraV\", \"1DEX\", \"Aquifer\"];\n\n/**\n * Venues excluded from ALL Jupiter quotes, in every environment. These\n * proprietary market-maker venues rotate their vault token accounts\n * off-chain, so quoted routes intermittently fail at execution with\n * \"Token account ... has wrong owner\". Not applied when a `dexes`\n * whitelist is set (the whitelist takes full control of routing).\n *\n * TODO(2026-07-06): Riptide was excluded after repeated wrong-owner failures\n * on PYUSD routes. It often quotes the best stable-pair price, so revisit\n * later and give it another chance if their account rotation has stabilized.\n */\nexport const ALWAYS_EXCLUDED_DEXES = [\"Riptide\"];\n","import type { Address, AccountMeta } from \"@solana/kit\";\nimport type { QuoteResponse } from \"@jup-ag/api\";\n\n/**\n * Parameters for getting a Jupiter quote\n */\nexport interface JupiterQuoteParams {\n /** Input token mint */\n inputMint: Address;\n /** Output token mint */\n outputMint: Address;\n /** Amount in smallest units (e.g., lamports for SOL) */\n amount: number | bigint;\n /** Slippage tolerance in basis points (default: 500 = 5%) */\n slippageBps?: number;\n /** Optional max accounts in swap instruction. Omitted lets Jupiter choose route complexity. */\n maxAccounts?: number;\n /**\n * Whitelist of DEX names to route through. When set, `excludeDexes` is ignored.\n * Useful for test environments where only specific DEXes have funded accounts\n * (e.g. `[\"Raydium\", \"Whirlpool\"]` on Surfpool).\n */\n dexes?: string[];\n /** DEXes to exclude from routing. Ignored when `dexes` is set. */\n excludeDexes?: string[];\n /** Only use direct routes (no intermediate hops) */\n onlyDirectRoutes?: boolean;\n /**\n * `ExactIn` (default): `amount` is input size. `ExactOut`: `amount` is desired output size.\n */\n swapMode?: \"ExactIn\" | \"ExactOut\";\n}\n\n/**\n * Default quote-policy overrides applied by `JupiterSwapClient`.\n *\n * Core swap identity fields (`inputMint`, `outputMint`, `amount`) remain\n * request-specific and are always supplied per quote call.\n */\nexport interface JupiterSwapClientConfig {\n /** Default quote options merged into every `getQuote()` call. */\n quoteDefaults?: Omit<Partial<JupiterQuoteParams>, \"inputMint\" | \"outputMint\" | \"amount\">;\n}\n\n/**\n * Parameters for building a Jupiter swap transaction\n */\nexport interface JupiterSwapParams {\n /** Quote response from getJupiterQuote */\n quote: QuoteResponse;\n /** Address that will execute the swap (can be a PDA for CPI) */\n userPublicKey: Address;\n /** Whether to wrap/unwrap SOL automatically (default: false for CPI) */\n wrapAndUnwrapSol?: boolean;\n /** Use dynamic compute unit limit (default: true) */\n dynamicComputeUnitLimit?: boolean;\n}\n\n/**\n * Extracted Jupiter instruction data for CPI\n */\nexport interface ExtractedJupiterInstruction {\n /** Serialized instruction data as Uint8Array */\n data: Uint8Array;\n /** Account metas with proper writability flags (Kit format) */\n accounts: AccountMeta[];\n /** Address lookup tables used by the transaction */\n lookupTables: Address[];\n}\n\n// Re-export QuoteResponse for convenience\nexport type { QuoteResponse } from \"@jup-ag/api\";\n","import type { Address, Transaction } from \"@solana/kit\";\nimport { getBase64Encoder, getTransactionDecoder } from \"@solana/kit\";\nimport { createJupiterApiClient } from \"@jup-ag/api\";\nimport type { QuoteResponse } from \"@jup-ag/api\";\nimport { JUPITER_API_URL, DEFAULT_SLIPPAGE_BPS, ALWAYS_EXCLUDED_DEXES } from \"./constants\";\nimport type { JupiterQuoteParams, JupiterSwapParams } from \"./types\";\n\n/**\n * Get a Jupiter swap quote.\n *\n * @param params - Quote parameters\n * @returns Quote response from Jupiter API\n *\n * @example\n * ```typescript\n * const quote = await getJupiterQuote({\n * inputMint: address(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"),\n * outputMint: address(\"So11111111111111111111111111111111111111112\"),\n * amount: 1000_000, // 1 USDC (6 decimals)\n * });\n * ```\n */\nexport async function getJupiterQuote(params: JupiterQuoteParams): Promise<QuoteResponse> {\n const jupiterApi = createJupiterApiClient({ basePath: JUPITER_API_URL });\n\n const amount = typeof params.amount === \"bigint\" ? Number(params.amount) : params.amount;\n const request = {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n amount,\n slippageBps: params.slippageBps ?? DEFAULT_SLIPPAGE_BPS,\n swapMode: params.swapMode,\n maxAccounts: params.maxAccounts,\n dexes: params.dexes,\n // When `dexes` is set it acts as a whitelist and `excludeDexes` is irrelevant.\n // Otherwise the caller's exclusions are merged with the global list.\n excludeDexes: params.dexes\n ? undefined\n : [...new Set([...ALWAYS_EXCLUDED_DEXES, ...(params.excludeDexes ?? [])])],\n onlyDirectRoutes: params.onlyDirectRoutes,\n };\n\n try {\n return await jupiterApi.quoteGet(request);\n } catch (err) {\n throw await enrichJupiterHttpError(err, request);\n }\n}\n\n/**\n * The OpenAPI client throws `ResponseError` with a generic message; the real reason\n * is usually in the HTTP body (e.g. no route, validation).\n */\nasync function enrichJupiterHttpError(\n err: unknown,\n request: Parameters<ReturnType<typeof createJupiterApiClient>[\"quoteGet\"]>[0]\n): Promise<Error> {\n if (!(err instanceof Error) || !(\"response\" in err)) {\n return err instanceof Error ? err : new Error(String(err));\n }\n const res = (err as { response?: Response }).response;\n if (!res || res.ok || typeof res.text !== \"function\") {\n return err;\n }\n let body = \"\";\n try {\n body = (await res.text()).slice(0, 2000);\n } catch {\n body = \"<failed to read response body>\";\n }\n return new Error(\n `Jupiter quoteGet http=${res.status} ${res.statusText} request=${JSON.stringify(request)} body=${body} (was: ${err.message})`\n );\n}\n\n/**\n * Build a Jupiter swap transaction from a quote.\n *\n * @param params - Swap parameters including quote and user public key\n * @returns Kit Transaction ready for signing or instruction extraction\n *\n * @example\n * ```typescript\n * const quote = await getJupiterQuote({ ... });\n * const tx = await buildJupiterSwapTransaction({\n * quote,\n * userPublicKey: myPdaAddress, // Can be a PDA for CPI\n * });\n * ```\n */\nexport async function buildJupiterSwapTransaction(params: JupiterSwapParams): Promise<Transaction> {\n const jupiterApi = createJupiterApiClient({ basePath: JUPITER_API_URL });\n\n const swapResult = await jupiterApi.swapPost({\n swapRequest: {\n quoteResponse: params.quote,\n userPublicKey: params.userPublicKey,\n wrapAndUnwrapSol: params.wrapAndUnwrapSol ?? false, // Default false for CPI\n dynamicComputeUnitLimit: params.dynamicComputeUnitLimit ?? true,\n },\n });\n\n // Jupiter returns a base64-encoded serialized transaction\n // In Kit, \"encoder\" converts string -> bytes, \"decoder\" converts bytes -> string\n const base64Encoder = getBase64Encoder();\n const transactionBytes = base64Encoder.encode(swapResult.swapTransaction);\n\n const transactionDecoder = getTransactionDecoder();\n return transactionDecoder.decode(transactionBytes);\n}\n\n/**\n * Convenience function to get quote and build transaction in one call.\n *\n * @param quoteParams - Quote parameters\n * @param userPublicKey - Address that will execute the swap\n * @param swapOptions - Additional swap options\n * @returns Quote response and Kit transaction\n *\n * @example\n * ```typescript\n * const { quote, transaction } = await getJupiterSwapTransaction(\n * {\n * inputMint: address(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"),\n * outputMint: address(\"So11111111111111111111111111111111111111112\"),\n * amount: 1000_000,\n * },\n * myPdaAddress\n * );\n * ```\n */\nexport async function getJupiterSwapTransaction(\n quoteParams: JupiterQuoteParams,\n userPublicKey: Address,\n swapOptions?: Omit<JupiterSwapParams, \"quote\" | \"userPublicKey\">\n): Promise<{ quote: QuoteResponse; transaction: Transaction }> {\n const quote = await getJupiterQuote(quoteParams);\n const transaction = await buildJupiterSwapTransaction({\n quote,\n userPublicKey,\n ...swapOptions,\n });\n\n return { quote, transaction };\n}\n","import type { Address, Instruction, Rpc, SolanaRpcApi, Transaction } from \"@solana/kit\";\nimport {\n decompileTransactionMessageFetchingLookupTables,\n getCompiledTransactionMessageDecoder,\n} from \"@solana/kit\";\nimport { CustomAccountMeta } from \"common\";\nimport { JUPITER_V6_PROGRAM_ID } from \"./constants\";\nimport type { ExtractedJupiterInstruction } from \"./types\";\n\n/**\n * Extract Jupiter instruction data and accounts from a Kit transaction.\n *\n * This function decompiles a Jupiter swap transaction, resolves any address lookup tables,\n * and extracts the instruction data and account metas needed for CPI calls.\n *\n * @param transaction - The Kit Transaction from Jupiter API\n * @param rpc - Solana RPC client to resolve lookup tables\n * @param jupiterProgramId - Jupiter program ID (default: JUPITER_V6_PROGRAM_ID)\n * @returns Jupiter instruction data and account metas with writability info\n * @throws Error if Jupiter instruction is not found in transaction\n *\n * @example\n * ```typescript\n * // Get transaction from Jupiter API\n * const jupiterTx = await buildJupiterSwapTransaction({ quote, userPublicKey });\n *\n * // Extract instruction for CPI\n * const { data, accounts } = await extractJupiterInstruction(jupiterTx, rpc);\n *\n * // Use in your program\n * await program.methods\n * .executeSwap({ jupiterSwapData: Array.from(data) })\n * .remainingAccounts(accounts)\n * .rpc();\n * ```\n */\nexport async function extractJupiterInstruction(\n transaction: Transaction,\n rpc: Rpc<SolanaRpcApi>,\n jupiterProgramId: Address = JUPITER_V6_PROGRAM_ID\n): Promise<ExtractedJupiterInstruction> {\n // Decode the message bytes to a CompiledTransactionMessage\n const messageDecoder = getCompiledTransactionMessageDecoder();\n const compiledMessage = messageDecoder.decode(transaction.messageBytes);\n\n // Extract lookup table addresses from the compiled message before decompiling\n const lookupTables: Address[] = (\n \"addressTableLookups\" in compiledMessage ? (compiledMessage.addressTableLookups ?? []) : []\n ).map((lookup) => lookup.lookupTableAddress);\n\n // Decompile the transaction message, fetching any lookup tables needed\n const decompiledMessage = await decompileTransactionMessageFetchingLookupTables(\n compiledMessage,\n rpc\n );\n\n // Find the Jupiter instruction\n const jupiterIx = decompiledMessage.instructions.find(\n (ix: Instruction) => ix.programAddress === jupiterProgramId\n );\n\n if (!jupiterIx) {\n throw new Error(\"Jupiter instruction not found in transaction\");\n }\n\n // Convert instruction accounts to AccountMeta format\n const accounts: CustomAccountMeta[] = (jupiterIx.accounts ?? []).map(\n (account: CustomAccountMeta) => ({\n address: account.address,\n role: account.role,\n })\n );\n\n // Return instruction data, accounts, and lookup tables\n return {\n data: new Uint8Array(jupiterIx.data ?? []),\n accounts,\n lookupTables,\n };\n}\n","import type { Address, Instruction, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport type { QuoteResponse } from \"@jup-ag/api\";\nimport { getCreateAtaIxIfNeeded, mints, type TransactionCacheInvalidation } from \"common\";\n\nexport interface JupiterRoutePreInstructionsResult {\n instructions: Instruction[];\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\n/**\n * Build idempotent createATA instructions for every intermediate-mint touched\n * by a Jupiter route that the swap authority (`user`) doesn't already have an\n * ATA for. Input/output mints are excluded — the caller is expected to have\n * already provisioned those (e.g. flash-borrow lands the input balance in\n * the user's destDebt ATA).\n *\n * Token programs are resolved via the {@link mints} registry first; unknown\n * mints fall back to an RPC `getMultipleAccounts` lookup that reads each\n * mint's `owner` (the SPL Token vs Token-2022 program).\n */\nexport async function getJupiterRoutePreInstructions(\n rpc: Rpc<SolanaRpcApi>,\n quote: QuoteResponse,\n user: Address,\n payer: Address\n): Promise<JupiterRoutePreInstructionsResult> {\n const intermediate = new Set<Address>();\n for (const step of quote.routePlan ?? []) {\n intermediate.add(step.swapInfo.inputMint as Address);\n intermediate.add(step.swapInfo.outputMint as Address);\n }\n intermediate.delete(quote.inputMint as Address);\n intermediate.delete(quote.outputMint as Address);\n if (!intermediate.size) {\n return { instructions: [], postSuccessCacheInvalidations: [] };\n }\n\n const tokenProgramByMint = new Map<Address, Address>();\n const unknown: Address[] = [];\n for (const mint of intermediate) {\n const info = mints.get(mint);\n if (info) {\n tokenProgramByMint.set(mint, info.tokenProgram);\n } else {\n unknown.push(mint);\n }\n }\n\n if (unknown.length) {\n const resp = await (\n rpc as Rpc<SolanaRpcApi> & {\n getMultipleAccounts: (\n addrs: Address[],\n config: { encoding: \"base64\" }\n ) => { send(): Promise<{ value: Array<{ owner: Address } | null> }> };\n }\n )\n .getMultipleAccounts(unknown, { encoding: \"base64\" })\n .send();\n for (let i = 0; i < unknown.length; i += 1) {\n const acct = resp.value[i];\n if (!acct) {\n throw new Error(\n `getJupiterRoutePreInstructions: route mint ${unknown[i]} not found on-chain`\n );\n }\n tokenProgramByMint.set(unknown[i], acct.owner);\n }\n }\n\n const instructions: Instruction[] = [];\n const postSuccessCacheInvalidations: TransactionCacheInvalidation[] = [];\n for (const mint of intermediate) {\n const tokenProgram = tokenProgramByMint.get(mint)!;\n const result = await getCreateAtaIxIfNeeded(rpc, payer, mint, user, tokenProgram);\n if (result.instruction) {\n instructions.push(result.instruction);\n postSuccessCacheInvalidations.push(...result.postSuccessCacheInvalidations);\n }\n }\n\n return { instructions, postSuccessCacheInvalidations };\n}\n","import { type Address, type Instruction, type Rpc, type SolanaRpcApi } from \"@solana/kit\";\nimport type { QuoteResponse } from \"@jup-ag/api\";\nimport { getJupiterQuote, buildJupiterSwapTransaction } from \"./api\";\nimport { extractJupiterInstruction } from \"./extract\";\nimport { getJupiterRoutePreInstructions } from \"./routePreInstructions\";\nimport { JUPITER_V6_PROGRAM_ID } from \"./constants\";\nimport type { JupiterSwapClientConfig } from \"./types\";\nimport {\n CpiTypes,\n CpiData,\n RoutableSwapClient,\n SwapQuoteParams,\n SwapQuote,\n SwapQuoteCoveringMinOutputParams,\n SwapInstructionOptions,\n} from \"common\";\n\n/** Jupiter-specific swap quote with typed rawQuote */\nexport type JupiterSwapQuote = SwapQuote<QuoteResponse>;\n\n/**\n * Jupiter swap client implementing RoutableSwapClient (see `common`).\n *\n * Provides a simplified API for getting quotes and building swap instructions\n * from Jupiter aggregator for use in CPI calls.\n *\n * @example\n * ```typescript\n * const client = new JupiterSwapClient(rpc);\n *\n * // Get a quote\n * const quote = await client.getQuote({\n * inputMint: USDC_MINT,\n * outputMint: WSOL_MINT,\n * amount: 10_000_000, // 10 USDC\n * slippageBps: 500, // 5%\n * });\n *\n * // Build instruction for CPI\n * const { data, accounts, programId } = await client.getSwapCpiData(\n * quote,\n * swapAuthorityPda\n * );\n *\n * // Use in your Anchor program\n * await program.methods\n * .executeSwap(Buffer.from(data))\n * .remainingAccounts(accounts.map(toWeb3AccountMeta))\n * .rpc();\n * ```\n */\nexport class JupiterSwapClient implements RoutableSwapClient<QuoteResponse> {\n /**\n * Empty lists mean any route for aggregate routing (Jupiter quotes arbitrary\n * pairs via the API).\n */\n readonly inputMints: readonly Address[] = [];\n readonly outputMints: readonly Address[] = [];\n readonly routeAnchorMints: readonly Address[] = [];\n\n /**\n * Creates a new Jupiter swap client.\n *\n * @param rpc - Solana RPC client for resolving address lookup tables\n * @param config - Optional default quote policy applied to every Jupiter quote\n */\n constructor(\n private rpc: Rpc<SolanaRpcApi>,\n private readonly config: JupiterSwapClientConfig = {}\n ) {}\n\n /**\n * Get a swap quote from Jupiter.\n *\n * @param params - Quote parameters\n * @returns Normalized swap quote with Jupiter's QuoteResponse as rawQuote\n */\n async getQuote(params: SwapQuoteParams): Promise<JupiterSwapQuote> {\n const excludeDexes = params.excludeDexes?.length\n ? [...new Set([...(this.config.quoteDefaults?.excludeDexes ?? []), ...params.excludeDexes])]\n : undefined;\n const rawQuote = await getJupiterQuote({\n ...(this.config.quoteDefaults ?? {}),\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n amount: params.amount,\n slippageBps: params.slippageBps,\n ...(params.maxAccounts !== undefined ? { maxAccounts: params.maxAccounts } : {}),\n ...(params.onlyDirectRoutes !== undefined\n ? { onlyDirectRoutes: params.onlyDirectRoutes }\n : {}),\n ...(excludeDexes ? { excludeDexes } : {}),\n });\n\n return {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n inputAmount: BigInt(rawQuote.inAmount),\n outputAmount: BigInt(rawQuote.outAmount),\n priceImpactPct: Number(rawQuote.priceImpactPct ?? 0),\n rawQuote,\n };\n }\n\n /**\n * Use Jupiter `ExactOut` quoting: desired output is `minOutputAmount`; reject if implied\n * input exceeds `maxInputAmount`.\n */\n async getQuoteCoveringMinOutput(\n params: SwapQuoteCoveringMinOutputParams\n ): Promise<JupiterSwapQuote> {\n const need = params.minOutputAmount;\n if (need <= BigInt(0)) {\n throw new Error(\"getQuoteCoveringMinOutput: minOutputAmount must be positive\");\n }\n const maxIn = params.maxInputAmount;\n if (maxIn <= BigInt(0)) {\n throw new Error(\"getQuoteCoveringMinOutput: maxInputAmount must be positive\");\n }\n if (need > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"getQuoteCoveringMinOutput: minOutputAmount exceeds Number.MAX_SAFE_INTEGER\");\n }\n\n const rawQuote = await getJupiterQuote({\n ...(this.config.quoteDefaults ?? {}),\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n amount: Number(need),\n slippageBps: params.slippageBps,\n swapMode: \"ExactOut\",\n });\n\n const inAmt = BigInt(rawQuote.inAmount);\n const outAmt = BigInt(rawQuote.outAmount);\n if (inAmt > maxIn) {\n throw new Error(\n \"Jupiter getQuoteCoveringMinOutput: exact-out route needs more input than maxInputAmount\"\n );\n }\n if (outAmt < need) {\n throw new Error(\"Jupiter getQuoteCoveringMinOutput: quoted output is below minOutputAmount\");\n }\n\n return {\n inputMint: params.inputMint,\n outputMint: params.outputMint,\n inputAmount: inAmt,\n outputAmount: outAmt,\n priceImpactPct: Number(rawQuote.priceImpactPct ?? 0),\n rawQuote,\n };\n }\n\n /**\n * Build Jupiter swap instruction for CPI.\n *\n * This fetches a swap transaction from Jupiter API, decompiles it,\n * and extracts the instruction data and accounts needed for CPI.\n *\n * @param quote - Quote from getQuote()\n * @param userPublicKey - Address executing the swap (typically a PDA)\n * @param options - Swap options\n * @returns Instruction data, accounts, and Jupiter program ID\n */\n async getSwapCpiData(\n quote: JupiterSwapQuote,\n userPublicKey: Address,\n options?: SwapInstructionOptions\n ): Promise<CpiData> {\n const transaction = await buildJupiterSwapTransaction({\n quote: quote.rawQuote,\n userPublicKey,\n wrapAndUnwrapSol: options?.wrapAndUnwrapSol ?? false,\n });\n\n const { data, accounts, lookupTables } = await extractJupiterInstruction(transaction, this.rpc);\n\n // When a `payer` is supplied we provision intermediate-mint ATAs for\n // multi-hop routes; the swap authority `userPublicKey` is typically a PDA\n // and can't pay the rent itself. With no payer we skip pre-instructions\n // (single-hop routes don't need them; multi-hop routes will then fail\n // at the CPI if intermediate ATAs are missing).\n let preInstructions: Instruction[] | undefined;\n let preInvalidations: NonNullable<CpiData[\"postSuccessCacheInvalidations\"]> | undefined;\n if (options?.payer) {\n const result = await getJupiterRoutePreInstructions(\n this.rpc,\n quote.rawQuote,\n userPublicKey,\n options.payer\n );\n if (result.instructions.length) {\n preInstructions = result.instructions;\n preInvalidations = result.postSuccessCacheInvalidations;\n }\n }\n\n return {\n cpiType: CpiTypes.JUPITER_SWAP,\n data,\n accounts,\n programId: JUPITER_V6_PROGRAM_ID,\n lookupTables,\n ...(preInstructions ? { preInstructions } : {}),\n ...(preInvalidations ? { postSuccessCacheInvalidations: preInvalidations } : {}),\n };\n }\n}\n","import type { Address } from \"@solana/kit\";\nimport type { SwapClient, SwapQuote } from \"common\";\n\nexport class ExactInQuoteExceedsMaxInputError extends Error {\n constructor(\n readonly inputAmount: bigint,\n readonly maxInputAmount: bigint\n ) {\n super(\n `sizeExactInForMinOutput: sized input (${inputAmount}) exceeds maxInputAmount (${maxInputAmount})`\n );\n this.name = \"ExactInQuoteExceedsMaxInputError\";\n }\n}\n\nexport interface SizeExactInForMinOutputParams {\n /** Input mint of the swap. */\n inputMint: Address;\n /** Output mint of the swap. */\n outputMint: Address;\n /** Minimum acceptable output amount (smallest units of `outputMint`). */\n minOutputAmount: bigint;\n /**\n * Maximum input amount the caller is willing to spend (smallest units of\n * `inputMint`). Throws if the sized input would exceed this.\n */\n maxInputAmount: bigint;\n /** Slippage tolerance applied by the swap, in basis points (e.g. 50 = 0.5%). */\n slippageBps: number;\n /**\n * Extra bps of headroom added on top of slippage when sizing the input.\n * The worst-case post-slippage output is pushed above `minOutputAmount`\n * by this much. Defaults to 0 (size to bare minimum).\n */\n safetyBufferBps?: number;\n /**\n * If true, restrict the quotes to direct routes (no intermediate hops).\n * Useful for CPI flows where intermediate-mint ATAs (e.g. WSOL) wouldn't\n * exist for a PDA caller. Defaults to false.\n */\n onlyDirectRoutes?: boolean;\n /** Optional route account budget forwarded to backends that support it. */\n maxAccounts?: number;\n /** DEX labels to exclude from routing, forwarded to backends that support it. */\n excludeDexes?: string[];\n}\n\nexport interface SizeExactInForMinOutputResult<TRawQuote = unknown> {\n /** ExactIn quote sized so the worst-case output covers `minOutputAmount`. */\n quote: SwapQuote<TRawQuote>;\n /** The sized input amount in `inputMint` base units (== `quote.inputAmount`). */\n inputAmount: bigint;\n /** The minimum output the caller can rely on after applying slippage. */\n worstCaseOutputAmount: bigint;\n}\n\n/**\n * Size an ExactIn swap so its **worst-case post-slippage output** covers\n * `minOutputAmount`.\n *\n * The ExactIn route graph is denser than ExactOut on most aggregators\n * (Jupiter included), so this is preferred when ExactOut hits\n * `NO_ROUTES_FOUND`. The trade-off: you over-spend input by the slippage\n * buffer; the unused output excess is the caller's to handle (e.g. sweep\n * to a sink account).\n *\n * Strategy:\n * 1. Probe quote at `minOutputAmount` input — gives us the route's\n * spot rate (`probeOut / probeIn`).\n * 2. Solve for the input `I` such that\n * `I × probeOut/probeIn × (1 − slippageBps/10000) ≥ minOutputAmount × (1 + safetyBufferBps/10000)`.\n * 3. Real ExactIn quote at the sized input.\n * 4. Verify the real quote's worst-case output still covers\n * `minOutputAmount` — guards against price impact at the larger size\n * diverging from the probe's spot rate.\n *\n * Throws if `inputAmount` exceeds `maxInputAmount`, if `slippageBps` is\n * out of range, or if the verification in step 4 fails.\n */\nexport async function sizeExactInForMinOutput<TRawQuote = unknown>(\n swap: SwapClient<TRawQuote>,\n params: SizeExactInForMinOutputParams\n): Promise<SizeExactInForMinOutputResult<TRawQuote>> {\n const {\n inputMint,\n outputMint,\n minOutputAmount,\n maxInputAmount,\n slippageBps,\n safetyBufferBps = 0,\n onlyDirectRoutes,\n maxAccounts,\n excludeDexes,\n } = params;\n\n if (minOutputAmount <= 0n) {\n throw new Error(\"sizeExactInForMinOutput: minOutputAmount must be positive\");\n }\n if (maxInputAmount <= 0n) {\n throw new Error(\"sizeExactInForMinOutput: maxInputAmount must be positive\");\n }\n if (slippageBps < 0 || slippageBps >= 10_000) {\n throw new Error(\"sizeExactInForMinOutput: slippageBps must be in [0, 10000)\");\n }\n if (safetyBufferBps < 0) {\n throw new Error(\"sizeExactInForMinOutput: safetyBufferBps must be non-negative\");\n }\n if (minOutputAmount > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"sizeExactInForMinOutput: minOutputAmount exceeds Number.MAX_SAFE_INTEGER\");\n }\n\n const probeQuote = await swap.getQuote({\n inputMint,\n outputMint,\n amount: Number(minOutputAmount),\n slippageBps,\n onlyDirectRoutes,\n maxAccounts,\n excludeDexes,\n });\n if (probeQuote.outputAmount <= 0n || probeQuote.inputAmount <= 0n) {\n throw new Error(\"sizeExactInForMinOutput: probe quote returned non-positive amounts\");\n }\n\n // I = ceil(minOutput × probeIn × (10000 + safetyBufferBps) /\n // (probeOut × (10000 - slippageBps)))\n const slippageBpsBig = BigInt(slippageBps);\n const safetyBpsBig = BigInt(safetyBufferBps);\n const sizingNumer = minOutputAmount * probeQuote.inputAmount * (10_000n + safetyBpsBig);\n const sizingDenom = probeQuote.outputAmount * (10_000n - slippageBpsBig);\n const inputAmount = (sizingNumer + sizingDenom - 1n) / sizingDenom;\n\n if (inputAmount > maxInputAmount) {\n throw new ExactInQuoteExceedsMaxInputError(inputAmount, maxInputAmount);\n }\n if (inputAmount > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"sizeExactInForMinOutput: sized input exceeds Number.MAX_SAFE_INTEGER\");\n }\n\n const quote = await swap.getQuote({\n inputMint,\n outputMint,\n amount: Number(inputAmount),\n slippageBps,\n onlyDirectRoutes,\n maxAccounts,\n excludeDexes,\n });\n\n const worstCaseOutputAmount = (quote.outputAmount * (10_000n - slippageBpsBig)) / 10_000n;\n if (worstCaseOutputAmount < minOutputAmount) {\n throw new Error(\n `sizeExactInForMinOutput: real-quote worst-case output (${worstCaseOutputAmount}) ` +\n `does not cover minOutputAmount (${minOutputAmount}) — likely price impact at sized input ` +\n `diverged from probe spot rate; raise safetyBufferBps`\n );\n }\n\n return { quote, inputAmount, worstCaseOutputAmount };\n}\n","export * from \"./constants\";\nexport * from \"./types\";\nexport * from \"./client\";\nexport * from \"./sizeExactInForMinOutput\";\nexport * from \"./routePreInstructions\";\n","import type { Address } from \"@solana/kit\";\nimport { DataCache, type Environment } from \"common\";\nimport { oracle, PriceResult } from \"oracle-service\";\nimport { ReserveBase } from \"../data\";\nimport { PositionBalanceChange } from \"../types\";\n\nexport interface ReservesPrices {\n supply: PriceResult;\n debt: PriceResult;\n}\n\nexport interface DebtAdjustmentOptions {\n /**\n * How the position changes when debt is adjusted.\n * `levered` models a loop / flash-loan rebalance where borrowed funds also\n * increase supplied collateral.\n * `debtOnly` models changes such as carry-position borrows where only debt\n * changes and supplied collateral stays constant.\n */\n positionChangeMode?: \"levered\" | \"debtOnly\";\n}\n\n/**\n * Manages a supply/debt reserve pair and provides calculations\n * for APY, simulations, and debt adjustments.\n */\nexport class ReservesManager {\n private cache = new DataCache();\n\n constructor(\n public supplyReserve: ReserveBase,\n public debtReserve: ReserveBase,\n private environment?: Environment\n ) {}\n\n /** Max LTV ratio (0-1), using e-mode override when the pair qualifies */\n get maxLtv(): number {\n const emode = this.supplyReserve.emodes?.find(\n (e) => e.debtReserve === this.debtReserve.address\n );\n return emode?.ltvPct ?? this.supplyReserve.ltvPct;\n }\n\n /**\n * Returns supply and debt token prices.\n * Uses reserve-embedded prices when available, otherwise fetches from oracle and caches the result.\n */\n async prices(): Promise<ReservesPrices> {\n const { data } = await this.cache.getDataOrThrow(\n async () => {\n const supplyRealtimePrice = this.supplyReserve.mintPrice;\n const debtRealtimePrice = this.debtReserve.mintPrice;\n const supplyEmaPrice = this.supplyReserve.mintEmaPrice;\n const debtEmaPrice = this.debtReserve.mintEmaPrice;\n\n const realtimeMintsToFetch = [\n ...(supplyRealtimePrice === undefined ? [this.supplyReserve.mint.mint] : []),\n ...(debtRealtimePrice === undefined ? [this.debtReserve.mint.mint] : []),\n ];\n const emaMintsToFetch = [\n ...(supplyEmaPrice === undefined ? [this.supplyReserve.mint.mint] : []),\n ...(debtEmaPrice === undefined ? [this.debtReserve.mint.mint] : []),\n ];\n\n const [realtime, ema] = await Promise.all([\n realtimeMintsToFetch.length\n ? oracle.fetchPrices(realtimeMintsToFetch, \"realtime\", undefined, this.environment)\n : ({} as Record<Address, number>),\n emaMintsToFetch.length\n ? oracle.fetchPrices(emaMintsToFetch, \"ema\", undefined, this.environment)\n : ({} as Record<Address, number>),\n ]);\n\n return {\n supply: {\n realtimePrice: supplyRealtimePrice ?? realtime[this.supplyReserve.mint.mint],\n emaPrice: supplyEmaPrice ?? ema[this.supplyReserve.mint.mint],\n },\n debt: {\n realtimePrice: debtRealtimePrice ?? realtime[this.debtReserve.mint.mint],\n emaPrice: debtEmaPrice ?? ema[this.debtReserve.mint.mint],\n },\n };\n },\n \"prices\",\n `${this.supplyReserve.mint.mint}:${this.debtReserve.mint.mint}`\n );\n return data;\n }\n\n /**\n * Net APY for the lending & borrowing position.\n * Accounts for eligible incentives based on the paired reserve relationship.\n */\n get netAPY(): number {\n return this.supplyReserve.supplyAPY(this.debtReserve.address) - this.debtReserve.borrowAPY();\n }\n\n /**\n * Simulates net APY after hypothetical position changes.\n * Accounts for eligible incentives based on the paired reserve relationship.\n */\n simulateNetAPY(args: PositionBalanceChange[]): number {\n return (\n this.supplyReserve.simulateNewSupplyAPY(\n args.find((x) => Boolean(x.collateralChange)) ?? { collateralChange: 0 },\n this.debtReserve.address\n ) -\n this.debtReserve.simulateNewBorrowAPY(\n args.find((x) => Boolean(x.debtChange)) ?? { debtChange: 0 }\n )\n );\n }\n\n /** Current LTV utilization rate in basis points (0-10000) given USD position values */\n calcLtvUtilizationRateBps(supplyUsd: number, debtUsd: number): number {\n if (supplyUsd <= 0) return 0;\n return (debtUsd / (supplyUsd * this.maxLtv)) * 10_000;\n }\n\n /**\n * Calculates the USD debt adjustment needed to reach a target LTV utilization rate.\n * Positive result = boost (increase leverage), negative = deleverage.\n */\n async calcDebtAdjustmentUsd(\n uiSupplyAmount: number,\n uiDebtAmount: number,\n targetLtvUtilizationRateBps: number,\n options: DebtAdjustmentOptions = {}\n ): Promise<number> {\n const { supply: supplyPrice, debt: debtPrice } = await this.prices();\n let supplyUsd = uiSupplyAmount * supplyPrice.realtimePrice;\n let debtUsd = uiDebtAmount * debtPrice.realtimePrice;\n\n const maxLtv = this.maxLtv;\n const targetUtilizationRate = targetLtvUtilizationRateBps / 10_000;\n const flFee = this.debtReserve.config.flashLoanFeePct / 100;\n const lpBorrowFee = this.debtReserve.config.borrowFeePct / 100;\n const positionChangeMode = options.positionChangeMode ?? \"levered\";\n\n const currentLtvUtilizationRate = supplyUsd > 0 ? debtUsd / (supplyUsd * maxLtv) : 0;\n const isBoost = currentLtvUtilizationRate < targetUtilizationRate;\n\n if (isBoost) {\n supplyUsd = uiSupplyAmount * (supplyPrice.emaPrice ?? supplyPrice.realtimePrice);\n debtUsd = uiDebtAmount * (debtPrice.emaPrice ?? debtPrice.realtimePrice);\n }\n\n if (positionChangeMode === \"debtOnly\") {\n const targetDebtDeltaUsd = targetUtilizationRate * maxLtv * supplyUsd - debtUsd;\n return isBoost ? targetDebtDeltaUsd / (1.0 + lpBorrowFee) : targetDebtDeltaUsd;\n }\n\n return isBoost\n ? (targetUtilizationRate * maxLtv * supplyUsd - debtUsd) /\n (1.0 + lpBorrowFee + flFee - targetUtilizationRate * maxLtv)\n : (targetUtilizationRate * maxLtv * supplyUsd - debtUsd) /\n (1.0 - targetUtilizationRate * maxLtv * (1.0 + flFee));\n }\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { type Address } from \"@solana/kit\";\nimport { fromUiAmount, toUiAmount, type Environment } from \"common\";\nimport type { PriceResult } from \"oracle-service\";\nimport { LendingPlatformData } from \"../../data/platform/lpDataBase\";\nimport { ReserveBase } from \"../../data/reserve/reserveBase\";\nimport { UserPositionBase } from \"../../data/userPosition/userPositionBase\";\nimport { MAX_LENDING_POSITION_UPPER_UTIL_BPS } from \"../../constants/lendingPosition\";\nimport { ReservesManager, type ReservesPrices } from \"../reservesManager\";\nimport type {\n CollateralPriceTriggerBand,\n CollateralPriceTriggerLevel,\n LendingPositionInspectMetrics,\n LendingPositionSelectedPrice,\n LendingPositionState,\n LendingPositionUtilizationPrices,\n LendingPositionUtilizationRatesBps,\n} from \"./types\";\n\n/**\n * Manages a leveraged lending position (collateral/debt pair): sizing decisions,\n * threshold triggers, and realtime/EMA-priced state. Wraps a {@link ReservesManager}.\n *\n * Generic across protocols — the constructor takes pool + user-account addresses\n * directly. SDK-specific subclasses may add convenience wrappers that derive\n * targets from their own on-chain config.\n */\nexport class LendingPositionManager {\n readonly reservesManager: ReservesManager;\n\n constructor(\n readonly lpData: LendingPlatformData,\n readonly pool: Address,\n readonly userAccount: Address,\n collateralReserve: ReserveBase,\n debtReserve: ReserveBase,\n environment?: Environment\n ) {\n this.reservesManager = new ReservesManager(collateralReserve, debtReserve, environment);\n }\n\n /**\n * Calculates the UI debt amount change needed to reach the target LTV utilization\n * rate. Positive values indicate borrowing; negative values indicate repaying.\n */\n async calcDebtChangeAmount(targetUtilizationRateBps: number): Promise<number> {\n const state = await this.getPositionState(\"realtime\");\n if (!state) return 0;\n\n return this.calcDebtChangeAmountFromState(state, targetUtilizationRateBps);\n }\n\n /**\n * Fetch current supply and debt position amounts in UI units.\n */\n async getLendingPositionAmounts(): Promise<{\n supplyUiAmount: number;\n debtUiAmount: number;\n }> {\n const state = await this.getPositionState(\"realtime\");\n if (!state) return { supplyUiAmount: 0, debtUiAmount: 0 };\n\n const supplyPrice = state.prices.supply.realtimePrice;\n const debtPrice = state.prices.debt.realtimePrice;\n\n return {\n supplyUiAmount: supplyPrice > 0 ? state.supplyUsd / supplyPrice : 0,\n debtUiAmount: debtPrice > 0 ? state.debtUsd / debtPrice : 0,\n };\n }\n\n /**\n * Calculates the utilization rate the source position must reach before a\n * collateral withdrawal so that, after the withdrawal, the position lands at\n * the desired target utilization rate.\n *\n * Units:\n * - current supply USD = supplied collateral before withdrawal\n * - withdrawn USD = collateral requested for the rebalance move\n * - post-withdraw target = desired utilization after collateral leaves the LP\n *\n * Formula:\n * pre_withdraw_target = post_withdraw_target * (current_supply - withdrawn) / current_supply\n *\n * The result is floored to stay conservatively at or below the requested\n * post-withdraw target once integer basis-point rounding is applied.\n */\n async calcPreWithdrawalTargetUtilizationRateBps(\n withdrawUiCollateralAmount: number,\n postWithdrawalTargetUtilizationRateBps: number\n ): Promise<number> {\n const state = await this.getPositionState(\"realtime\");\n if (!state) return 0;\n\n return this.calcPreWithdrawalTargetUtilizationRateBpsFromState(\n state,\n withdrawUiCollateralAmount,\n postWithdrawalTargetUtilizationRateBps\n );\n }\n\n /**\n * Calculates the UI debt amount change needed before a collateral withdrawal\n * so that the position lands at the desired utilization rate after the\n * withdrawal completes.\n */\n async calcDebtChangeAmountForCollateralWithdrawal(\n withdrawUiCollateralAmount: number,\n postWithdrawalTargetUtilizationRateBps: number\n ): Promise<number> {\n const state = await this.getPositionState(\"realtime\");\n if (!state) return 0;\n\n const preWithdrawalTargetUtilizationRateBps =\n this.calcPreWithdrawalTargetUtilizationRateBpsFromState(\n state,\n withdrawUiCollateralAmount,\n postWithdrawalTargetUtilizationRateBps\n );\n\n return this.calcDebtChangeAmountFromState(state, preWithdrawalTargetUtilizationRateBps);\n }\n\n /**\n * Calculates the utilization rate after withdrawing collateral while leaving\n * debt unchanged.\n */\n async calcPostWithdrawalUtilizationRateBps(withdrawUiCollateralAmount: number): Promise<number> {\n const state = await this.getPositionState(\"realtime\");\n if (!state) return 0;\n\n return this.calcPostWithdrawalUtilizationRateBpsFromState(state, withdrawUiCollateralAmount);\n }\n\n /**\n * For burn-token liquidity management: checks that a withdrawal of\n * `collateralWithdrawalUiAmount` (collateral mint UI units) leaves strictly\n * positive supplied collateral, matching the pre-withdraw math used in\n * {@link calcPreWithdrawalTargetUtilizationRateBps}.\n *\n * Returns realtime LTV utilization in basis points when eligible; null when the\n * obligation is missing, has no supply, prices are invalid, or the withdrawal\n * would consume the full (or more than the full) collateral position.\n */\n async getBurnUnwindEligibility(\n collateralWithdrawalUiAmount: number\n ): Promise<{ utilizationRateBps: number } | null> {\n if (!(collateralWithdrawalUiAmount > 0)) {\n return null;\n }\n const state = await this.getPositionState(\"realtime\");\n if (!state) {\n return null;\n }\n const collateralPrice = state.prices.supply.realtimePrice;\n if (!(collateralPrice > 0)) {\n return null;\n }\n const withdrawnCollateralUsd = collateralWithdrawalUiAmount * collateralPrice;\n if (!(withdrawnCollateralUsd < state.supplyUsd)) {\n return null;\n }\n const utilizationRateBps = this.reservesManager.calcLtvUtilizationRateBps(\n state.supplyUsd,\n state.debtUsd\n );\n return { utilizationRateBps };\n }\n\n /**\n * Returns the collateral price levels that would place the position exactly on\n * its lower and upper utilization trigger bands.\n *\n * The lower-band trigger uses EMA pricing (to mirror boost-trigger semantics),\n * while the upper-band trigger uses realtime pricing (to mirror unwind-trigger\n * semantics).\n */\n async getCollateralPriceTriggerBand(params: {\n lowerTargetUtilizationRateBps: number;\n upperTargetUtilizationRateBps: number;\n }): Promise<CollateralPriceTriggerBand> {\n const [lower, upper] = await Promise.all([\n this.getCollateralPriceTriggerLevel(\"ema\", params.lowerTargetUtilizationRateBps),\n this.getCollateralPriceTriggerLevel(\"realtime\", params.upperTargetUtilizationRateBps),\n ]);\n\n return { lower, upper };\n }\n\n async getUtilizationRatesBps(): Promise<LendingPositionUtilizationRatesBps | null> {\n const [realtimeState, emaState] = await Promise.all([\n this.getPositionState(\"realtime\"),\n this.getPositionState(\"ema\"),\n ]);\n if (!realtimeState || !emaState) {\n return null;\n }\n\n return {\n realtime: this.reservesManager.calcLtvUtilizationRateBps(\n realtimeState.supplyUsd,\n realtimeState.debtUsd\n ),\n ema: this.reservesManager.calcLtvUtilizationRateBps(emaState.supplyUsd, emaState.debtUsd),\n };\n }\n\n async getUtilizationPrices(): Promise<LendingPositionUtilizationPrices | null> {\n const [realtimeState, emaState] = await Promise.all([\n this.getPositionState(\"realtime\"),\n this.getPositionState(\"ema\"),\n ]);\n if (!realtimeState || !emaState) {\n return null;\n }\n\n return {\n realtime: {\n collateral: this.selectPrice(realtimeState.prices.supply, \"realtime\"),\n debt: this.selectPrice(realtimeState.prices.debt, \"realtime\"),\n },\n ema: {\n collateral: this.selectPrice(emaState.prices.supply, \"ema\"),\n debt: this.selectPrice(emaState.prices.debt, \"ema\"),\n },\n };\n }\n\n async getInspectMetrics(params: {\n lowerTargetUtilizationRateBps: number;\n upperTargetUtilizationRateBps: number;\n }): Promise<LendingPositionInspectMetrics | null> {\n const [utilizationRateBps, utilizationPrices, triggerBand] = await Promise.all([\n this.getUtilizationRatesBps(),\n this.getUtilizationPrices(),\n this.getCollateralPriceTriggerBand(params),\n ]);\n if (!utilizationRateBps || !utilizationPrices) {\n return null;\n }\n\n return { utilizationRateBps, utilizationPrices, triggerBand };\n }\n\n protected async getPositionState(mode: \"realtime\" | \"ema\"): Promise<LendingPositionState | null> {\n const position = await this.lpData.maybeFetchUserPositionInPool(this.pool, this.userAccount);\n if (!position) return null;\n\n const prices = await this.reservesManager.prices();\n const { supplyUsd, debtUsd } = this.calcPositionSupplyDebtUsd(position, prices, mode);\n return { prices, supplyUsd, debtUsd };\n }\n\n private calcPositionSupplyDebtUsd(\n position: UserPositionBase,\n prices: ReservesPrices,\n mode: \"realtime\" | \"ema\"\n ): { supplyUsd: number; debtUsd: number } {\n const { supplyReserve, debtReserve } = this.reservesManager;\n\n const deposit = position.deposits.find((d) => d.reserve === supplyReserve.address);\n const borrow = position.borrows.find((b) => b.reserve === debtReserve.address);\n\n const supplyAmount = deposit ? toUiAmount(deposit.amount, supplyReserve.mint.mintDecimals) : 0;\n const debtAmount = borrow ? toUiAmount(borrow.amount, debtReserve.mint.mintDecimals) : 0;\n\n return {\n supplyUsd: supplyAmount * this.selectPrice(prices.supply, mode).value,\n debtUsd: debtAmount * this.selectPrice(prices.debt, mode).value,\n };\n }\n\n private selectPrice(price: PriceResult, mode: \"realtime\" | \"ema\"): LendingPositionSelectedPrice {\n if (mode === \"realtime\") {\n return { value: price.realtimePrice, source: \"realtime\" };\n }\n\n if (price.emaPrice != null) {\n return { value: price.emaPrice, source: \"ema\" };\n }\n\n return { value: price.realtimePrice, source: \"ema_fallback_realtime\" };\n }\n\n private async getCollateralPriceTriggerLevel(\n mode: \"realtime\" | \"ema\",\n targetUtilizationRateBps: number\n ): Promise<CollateralPriceTriggerLevel | undefined> {\n this.assertValidTriggerBandUtilizationRateBps(\n targetUtilizationRateBps,\n \"targetUtilizationRateBps\"\n );\n if (targetUtilizationRateBps === 0) {\n return undefined;\n }\n\n const state = await this.getPositionState(mode);\n if (!state) {\n return undefined;\n }\n\n const currentCollateralPrice =\n mode === \"ema\"\n ? (state.prices.supply.emaPrice ?? state.prices.supply.realtimePrice)\n : state.prices.supply.realtimePrice;\n\n if (currentCollateralPrice <= 0 || state.debtUsd < 0 || this.reservesManager.maxLtv <= 0) {\n return undefined;\n }\n\n const uiSupplyAmount = state.supplyUsd / currentCollateralPrice;\n if (uiSupplyAmount <= 0) {\n return undefined;\n }\n\n const triggerCollateralPrice = this.calcCollateralPriceForTargetUtilization(\n state.debtUsd,\n uiSupplyAmount,\n targetUtilizationRateBps\n );\n\n if (!Number.isFinite(triggerCollateralPrice) || triggerCollateralPrice < 0) {\n return undefined;\n }\n\n return {\n currentCollateralPrice,\n triggerCollateralPrice,\n targetUtilizationRateBps,\n priceMode: mode,\n priceChangePct:\n ((triggerCollateralPrice - currentCollateralPrice) / currentCollateralPrice) * 100,\n };\n }\n\n /**\n * Solve for collateral price at a target utilization:\n * utilization = debtUsd / (collateralAmount * collateralPrice * maxLtv).\n */\n private calcCollateralPriceForTargetUtilization(\n debtUsd: number,\n uiSupplyAmount: number,\n targetUtilizationRateBps: number\n ): number {\n const targetUtilizationRate = targetUtilizationRateBps / 10_000;\n return debtUsd / (uiSupplyAmount * this.reservesManager.maxLtv * targetUtilizationRate);\n }\n\n private async calcDebtChangeAmountFromState(\n state: LendingPositionState,\n targetUtilizationRateBps: number\n ): Promise<number> {\n this.assertValidUtilizationRateBps(targetUtilizationRateBps, \"targetUtilizationRateBps\");\n\n if (state.prices.debt.realtimePrice <= 0) {\n throw new Error(\"Debt reserve realtime price must be positive\");\n }\n if (state.prices.supply.realtimePrice <= 0) {\n throw new Error(\"Collateral reserve realtime price must be positive\");\n }\n\n const debtAdjustmentUsd = await this.reservesManager.calcDebtAdjustmentUsd(\n state.supplyUsd / state.prices.supply.realtimePrice,\n state.debtUsd / state.prices.debt.realtimePrice,\n targetUtilizationRateBps,\n { positionChangeMode: \"debtOnly\" }\n );\n\n const debtChangeUiAmount = debtAdjustmentUsd / state.prices.debt.realtimePrice;\n const debtDecimals = this.reservesManager.debtReserve.mint.mintDecimals;\n\n let quantizedUiAmount = this.quantizeDebtChangeUiAmount(debtChangeUiAmount, debtDecimals);\n if (quantizedUiAmount > 0) {\n quantizedUiAmount = await this.capPositiveBorrowToProtocolHeadroom(quantizedUiAmount, state);\n }\n\n return debtChangeUiAmount < 0 ? -quantizedUiAmount : quantizedUiAmount;\n }\n\n /**\n * Quantize to the debt mint's base-unit precision. Borrows floor; repays round\n * away from zero so deleveraging does not undershoot.\n */\n private quantizeDebtChangeUiAmount(debtChangeUiAmount: number, debtDecimals: number): number {\n if (debtChangeUiAmount === 0) return 0;\n\n const absUi = Math.abs(debtChangeUiAmount);\n\n if (debtChangeUiAmount > 0) {\n if (!(absUi > 0)) return 0;\n const flooredBaseUnits = new BN(Math.floor(absUi * Math.pow(10, debtDecimals)));\n return toUiAmount(flooredBaseUnits, debtDecimals);\n }\n\n const roundedAmount = fromUiAmount(absUi, debtDecimals);\n let repayUi = toUiAmount(roundedAmount, debtDecimals);\n if (repayUi < absUi) {\n repayUi = toUiAmount(roundedAmount.addn(1), debtDecimals);\n }\n return repayUi;\n }\n\n /** Cap positive borrows to obligation headroom when the platform exposes it. */\n private async capPositiveBorrowToProtocolHeadroom(\n requestedUiAmount: number,\n state: LendingPositionState\n ): Promise<number> {\n const debtDecimals = this.reservesManager.debtReserve.mint.mintDecimals;\n const position = await this.lpData.maybeFetchUserPositionInPool(this.pool, this.userAccount);\n if (!position) {\n return requestedUiAmount;\n }\n\n const maxUi = position.getMaxAdditionalBorrowUiAmount(\n state.prices.debt.realtimePrice,\n debtDecimals\n );\n if (maxUi === undefined) {\n return requestedUiAmount;\n }\n return Math.min(requestedUiAmount, maxUi);\n }\n\n private calcPreWithdrawalTargetUtilizationRateBpsFromState(\n state: LendingPositionState,\n withdrawUiCollateralAmount: number,\n postWithdrawalTargetUtilizationRateBps: number\n ): number {\n if (withdrawUiCollateralAmount <= 0) {\n throw new Error(\"withdrawUiCollateralAmount must be greater than zero\");\n }\n this.assertValidUtilizationRateBps(\n postWithdrawalTargetUtilizationRateBps,\n \"postWithdrawalTargetUtilizationRateBps\"\n );\n\n const collateralPrice = state.prices.supply.realtimePrice;\n if (collateralPrice <= 0) {\n throw new Error(\"Collateral reserve realtime price must be positive\");\n }\n\n const withdrawnCollateralUsd = withdrawUiCollateralAmount * collateralPrice;\n if (withdrawnCollateralUsd >= state.supplyUsd) {\n throw new Error(\"withdrawUiCollateralAmount exceeds the current supplied collateral\");\n }\n\n const preWithdrawalTargetUtilizationRateBps = Math.floor(\n (postWithdrawalTargetUtilizationRateBps * (state.supplyUsd - withdrawnCollateralUsd)) /\n state.supplyUsd\n );\n\n return Math.max(\n 0,\n Math.min(postWithdrawalTargetUtilizationRateBps, preWithdrawalTargetUtilizationRateBps)\n );\n }\n\n private calcPostWithdrawalUtilizationRateBpsFromState(\n state: LendingPositionState,\n withdrawUiCollateralAmount: number\n ): number {\n if (withdrawUiCollateralAmount <= 0) {\n throw new Error(\"withdrawUiCollateralAmount must be greater than zero\");\n }\n\n const collateralPrice = state.prices.supply.realtimePrice;\n if (collateralPrice <= 0) {\n throw new Error(\"Collateral reserve realtime price must be positive\");\n }\n\n const withdrawnCollateralUsd = withdrawUiCollateralAmount * collateralPrice;\n if (withdrawnCollateralUsd >= state.supplyUsd) {\n throw new Error(\"withdrawUiCollateralAmount exceeds the current supplied collateral\");\n }\n\n return this.reservesManager.calcLtvUtilizationRateBps(\n state.supplyUsd - withdrawnCollateralUsd,\n state.debtUsd\n );\n }\n\n protected assertValidUtilizationRateBps(value: number, field: string) {\n if (!Number.isFinite(value) || value < 0 || value > 10_000) {\n throw new Error(`${field} must be between 0 and 10000`);\n }\n }\n\n /**\n * Unwind/boost trigger bands may exceed 100% LTV utilization (up to 10_500 bps\n * on-chain). Debt-sizing paths still use {@link assertValidUtilizationRateBps}.\n */\n protected assertValidTriggerBandUtilizationRateBps(value: number, field: string) {\n if (!Number.isFinite(value) || value < 0 || value > MAX_LENDING_POSITION_UPPER_UTIL_BPS) {\n throw new Error(`${field} must be between 0 and ${MAX_LENDING_POSITION_UPPER_UTIL_BPS}`);\n }\n }\n}\n","import { BN } from \"@anchor-lang/core\";\nimport type { Instruction } from \"@solana/kit\";\nimport { applyFeeCeil, type CpiData, fromUiAmount, getAtaAddress, toUiAmount } from \"common\";\nimport { sizeExactInForMinOutput } from \"jupiter-helpers\";\nimport { LendingPositionManager } from \"../lendingPosition/lendingPositionManager\";\nimport { ReservesManager } from \"../reservesManager\";\nimport type {\n DecreaseLeverageParams,\n DecreaseLeverageResult,\n FlashRebalanceContext,\n FlashRebalanceParams,\n FlashRebalanceResult,\n IncreaseLeverageParams,\n IncreaseLeverageResult,\n LeverageContext,\n LeverageSwapContext,\n} from \"./types\";\n\nconst DECREASE_LEVERAGE_SWAP_BUFFER_BPS = 5;\nconst DECREASE_LEVERAGE_SWAP_SLIPPAGE_BPS = 40;\nconst DECREASE_LEVERAGE_SWAP_MAX_ACCOUNTS = 30;\nconst FLASH_REBALANCE_SWAP_MAX_ACCOUNTS = 25;\n\n/**\n * Thrown by {@link LeverageService.buildFlashRebalance} when the quoted\n * destination-debt → source-debt swap breaches a caller-set bound. The quote's\n * total below-par gap is split into two components, each bounded separately:\n *\n * - `executionCostBps` — quote rate vs the oracle-fair cross rate: route fees\n * + price impact. Permanently lost value.\n * - `marketBasisBps` — oracle-fair cross rate vs 1:1: genuine USD price\n * difference between the two stables. Charged to the token's carry-vs-debt\n * difference by the $1-pinned books at conversion time, but reverses on\n * unwind if the basis persists.\n *\n * `reason` names which bound was breached; both measured components are\n * always populated for logging/telemetry.\n */\nexport class FlashRebalanceSwapCostExceededError extends Error {\n constructor(\n readonly reason: \"execution-cost\" | \"market-basis\",\n readonly executionCostBps: number,\n readonly marketBasisBps: number,\n readonly limitBps: number,\n readonly inputAmount: bigint,\n readonly outputAmount: bigint\n ) {\n super(\n `LeverageService.buildFlashRebalance: swap ${reason} exceeds ${limitBps} bps ` +\n `(execution cost ${executionCostBps.toFixed(2)} bps, market basis ${marketBasisBps.toFixed(2)} bps, ` +\n `in=${inputAmount} out=${outputAmount})`\n );\n this.name = \"FlashRebalanceSwapCostExceededError\";\n }\n}\n\n/**\n * Stateless service that sizes and builds lending-protocol CPIs for leverage\n * changes on a collateral/debt reserve pair.\n *\n * Inputs are generic lending-platform types (reserves, LP client, position\n * identifiers). No program-specific types.\n *\n * - **Increase leverage** → calculates borrow amount to reach target, builds\n * borrow CPIs.\n * - **Decrease leverage** → calculates repay amount to reach target, builds\n * repay CPIs, and assembles swap + repay CPI groups when the debt token must\n * be obtained via swap.\n */\nexport class LeverageService {\n /**\n * Calculate the borrow amount needed to reach the target utilization rate,\n * then build the borrow CPIs.\n */\n static async buildIncreaseLeverage(\n ctx: LeverageContext,\n params: IncreaseLeverageParams\n ): Promise<IncreaseLeverageResult> {\n const reserves = new ReservesManager(ctx.supplyReserve, ctx.debtReserve, ctx.environment);\n const mode = params.mode ?? \"debtOnly\";\n\n const debtAdjustmentUsd = await reserves.calcDebtAdjustmentUsd(\n params.currentSupplyUiAmount,\n params.currentDebtUiAmount,\n params.targetUtilizationRateBps,\n { positionChangeMode: mode }\n );\n\n const prices = await reserves.prices();\n const borrowUiAmount = Math.abs(debtAdjustmentUsd / prices.debt.realtimePrice);\n const borrowBaseUnits = fromUiAmount(borrowUiAmount, ctx.debtReserve.mint.mintDecimals);\n\n const { prerequisiteCpis, cpis, postSuccessCacheInvalidations } =\n await ctx.lendingIx.getBorrowCpiBundle({\n user: ctx.user,\n payer: ctx.payer,\n pool: ctx.pool,\n reserve: ctx.debtReserve.address,\n userAccount: ctx.userAccount,\n uiAmount: borrowUiAmount,\n txId: ctx.txId,\n });\n\n const preInstructions = await ctx.lendingIx.getPreInstructions(ctx.txId);\n\n return {\n borrowUiAmount,\n borrowBaseUnits,\n prerequisiteCpis,\n borrowCpis: cpis,\n preInstructions,\n postSuccessCacheInvalidations,\n };\n }\n\n /**\n * Calculate the repay amount needed to reach the target utilization rate,\n * build the repay CPIs, and assemble CPI groups with an optional swap\n * prepended when the caller's debt-token balance is insufficient.\n *\n * The returned `repayUiAmount` is always non-negative. When the position is\n * already at or below the target, the amount is zero and the CPI list is\n * sized for a zero repay.\n */\n static async buildDecreaseLeverage(\n ctx: LeverageContext,\n params: DecreaseLeverageParams\n ): Promise<DecreaseLeverageResult> {\n const reserves = new ReservesManager(ctx.supplyReserve, ctx.debtReserve, ctx.environment);\n const mode = params.mode ?? \"debtOnly\";\n\n const debtAdjustmentUsd = await reserves.calcDebtAdjustmentUsd(\n params.currentSupplyUiAmount,\n params.currentDebtUiAmount,\n params.targetUtilizationRateBps,\n { positionChangeMode: mode }\n );\n\n const prices = await reserves.prices();\n const debtDecimals = ctx.debtReserve.mint.mintDecimals;\n const repayUiAmount = Math.abs(debtAdjustmentUsd / prices.debt.realtimePrice);\n const calculatedRepayBaseUnits = fromUiAmount(repayUiAmount, debtDecimals);\n const repayBaseUnits = params.repayBaseUnitsOverride ?? calculatedRepayBaseUnits;\n\n // The repay CPI is always built without an embedded amount. On-chain, the\n // handler sources the final amount from `params.repay_amount` (manager /\n // non-swap path) or from the post-swap balance delta (swap path), then\n // forwards it to the repay CPI via `invoke_amount_cpi` (Skip sentinel).\n // Embedding the amount here would leak build-time estimates into a slot\n // that must reflect runtime state.\n //\n // Full deleverages pass `repayBaseUnitsOverride` so the Kamino CPI and SPL\n // transfer both use refreshed obligation debt instead of stale accounting.\n const { prerequisiteCpis, cpis } = await ctx.lendingIx.getRepayCpiData({\n user: ctx.user,\n payer: ctx.payer,\n pool: ctx.pool,\n reserve: ctx.debtReserve.address,\n userAccount: ctx.userAccount,\n txId: ctx.txId,\n ...(params.repayBaseUnitsOverride ? { baseUnitAmount: repayBaseUnits } : {}),\n });\n\n const preInstructions = await ctx.lendingIx.getPreInstructions(ctx.txId);\n\n const swapRequired = params.swapContext !== undefined;\n const assembledCpis = await this.assembleDecreaseLeverageCpis(\n repayBaseUnits,\n cpis,\n params.swapContext\n );\n\n return {\n repayUiAmount,\n repayBaseUnits,\n prerequisiteCpis,\n repayCpis: cpis,\n cpiDataGroups: assembledCpis.cpiDataGroups,\n swapRequired,\n preInstructions: [...preInstructions, ...assembledCpis.preInstructions],\n };\n }\n\n /**\n * Assemble repay CPI groups, prepending a swap group whenever the bank is\n * configured to source the debt mint via a swap. The on-chain handler\n * decides whether to actually invoke the swap (via `perform_swap`) based on\n * runtime balances; building it unconditionally keeps the tx resilient when\n * the bank's debt-token balance changes between build and send.\n */\n private static async assembleDecreaseLeverageCpis(\n repayBaseUnits: BN,\n repayCpis: CpiData[],\n swapContext?: LeverageSwapContext\n ): Promise<{ cpiDataGroups: CpiData[][]; preInstructions: Instruction[] }> {\n if (!swapContext) {\n return { cpiDataGroups: [repayCpis], preInstructions: [] };\n }\n\n // Quote the swap for the full repay amount rather than\n // `repay - debtHeld`, so the swap can cover the repay on its own if the\n // bank's debt-token balance has dropped since tx build time.\n const swapCpiData = await this.quoteDebtTopUpSwap(swapContext, repayBaseUnits);\n\n return {\n cpiDataGroups: [[swapCpiData], repayCpis],\n preInstructions: swapCpiData.preInstructions ?? [],\n };\n }\n\n /**\n * Quote a swap that converts a source asset into the debt mint,\n * covering at least `shortfall` base units.\n */\n private static async quoteDebtTopUpSwap(\n ctx: LeverageSwapContext,\n shortfall: BN\n ): Promise<CpiData> {\n const need = BigInt(shortfall.toString());\n if (need <= 0n) {\n throw new Error(\"LeverageService.quoteDebtTopUpSwap: shortfall must be positive\");\n }\n if (ctx.sourceBalanceBaseUnits <= 0n) {\n throw new Error(\"LeverageService.quoteDebtTopUpSwap: source balance is zero\");\n }\n\n const { quote } = await sizeExactInForMinOutput(ctx.swap, {\n inputMint: ctx.sourceMint,\n outputMint: ctx.debtMint,\n minOutputAmount: need,\n maxInputAmount: ctx.sourceBalanceBaseUnits,\n slippageBps: ctx.slippageBps ?? DECREASE_LEVERAGE_SWAP_SLIPPAGE_BPS,\n safetyBufferBps: DECREASE_LEVERAGE_SWAP_BUFFER_BPS,\n maxAccounts: DECREASE_LEVERAGE_SWAP_MAX_ACCOUNTS,\n excludeDexes: ctx.excludeDexes,\n });\n\n return ctx.swap.getSwapCpiData(quote, ctx.swapTarget, { payer: ctx.payer });\n }\n\n /**\n * Build a flash-loan-wrapped rebalance that moves collateral between two\n * lending positions without decreasing any carry positions.\n *\n * The flow assembled here (inside a single transaction):\n * 1. Top-level: flash-borrow source debt mint into the user's ATA.\n * 2. CPI: repay flash-borrowed amount on source → frees collateral.\n * 3. CPI: withdraw `collateralUiAmount` from source.\n * 4. CPI: deposit that collateral on destination.\n * 5. CPI: borrow destination debt mint (sized slightly above the swap\n * input needed to produce the flash repay, so post-slippage output\n * still covers it).\n * 6. CPI: exact-in swap destination debt → source debt; the entire borrow\n * is consumed and worst-case output is at least the flash repay amount.\n * 7. Top-level: flash-repay source debt mint.\n *\n * The exact-in over-borrow leaves a small **source-debt** excess in the\n * token PDA's ATA after the swap; the on-chain handler sweeps this excess\n * into the yielding bank before the top-level flash repay so exactly\n * `flashRepayAmountBaseUnits` remains for the repay.\n */\n static async buildFlashRebalance(\n ctx: FlashRebalanceContext,\n params: FlashRebalanceParams\n ): Promise<FlashRebalanceResult> {\n if (ctx.source.debtReserve.mint.mint === ctx.destination.debtReserve.mint.mint) {\n throw new Error(\n \"LeverageService.buildFlashRebalance: source and destination debt mints must differ\"\n );\n }\n const sourceDebtMint = ctx.source.debtReserve.address;\n const sourceDebtLiqMint = ctx.source.debtReserve.mint.mint;\n const sourceDebtDecimals = ctx.source.debtReserve.mint.mintDecimals;\n const destDebtLiqMint = ctx.destination.debtReserve.mint.mint;\n const destDebtDecimals = ctx.destination.debtReserve.mint.mintDecimals;\n\n const sourceRepayBaseUnits = await this.calcSourceRepayForWithdraw(ctx, params);\n if (sourceRepayBaseUnits.lten(0)) {\n throw new Error(\n \"LeverageService.buildFlashRebalance: source repay amount must be positive — use the simple rebalance path when no flash loan is needed\"\n );\n }\n const sourceRepayUiAmount = toUiAmount(sourceRepayBaseUnits, sourceDebtDecimals);\n\n const flashFeeRate = await ctx.flashLoan.getFlashLoanFeeRate(ctx.source.pool, sourceDebtMint);\n // For `withdrawAll`, the rebalance-token builder sends Kamino's\n // `u64::MAX` repay sentinel — Kamino computes the obligation's\n // *refreshed* debt at execution time, which exceeds the off-chain\n // principal snapshot by any unrealized interest accrual. Over-borrow by\n // 5 bps so the ATA always covers the refreshed debt; the surplus is\n // swept into the yielding bank by the rebalance handler's dust path.\n //\n // For partial rebalances the builder sends `flashBorrowAmount` as the\n // explicit repay amount — the on-chain repay matches the ATA balance\n // exactly, so no buffer is needed (over-borrowing would just bloat the\n // dust sweep and pay an unnecessary flash fee).\n const SOURCE_REPAY_OVERBORROW_BPS = 5n;\n const sourceRepayBigInt = BigInt(sourceRepayBaseUnits.toString());\n const flashBorrowBigInt = params.withdrawAll\n ? sourceRepayBigInt + (sourceRepayBigInt * SOURCE_REPAY_OVERBORROW_BPS) / 10_000n\n : sourceRepayBigInt;\n const flashFeeBigInt = applyFeeCeil(flashBorrowBigInt, flashFeeRate);\n const flashRepayBigInt = flashBorrowBigInt + flashFeeBigInt;\n const flashBorrowAmountBaseUnits = new BN(flashBorrowBigInt.toString());\n const flashFeeBaseUnits = new BN(flashFeeBigInt.toString());\n const flashRepayAmountBaseUnits = new BN(flashRepayBigInt.toString());\n\n const reserveBorrowCapacityBaseUnits = BigInt(\n fromUiAmount(\n ctx.destination.debtReserve.borrows.limit - ctx.destination.debtReserve.borrows.totalAmount,\n destDebtDecimals\n ).toString()\n );\n // Borrow capacity is calculated from current destination collateral only —\n // supply never moves in a debt-only rebalance.\n const utilizationBorrowCapacityBaseUnits = await this.calcDestinationBorrowCapacityForDeposit(\n ctx,\n { ...params, collateralUiAmount: 0 }\n );\n const maxDestinationBorrowBaseUnits = [\n params.maxDestinationBorrowBaseUnits,\n reserveBorrowCapacityBaseUnits,\n utilizationBorrowCapacityBaseUnits,\n ]\n .filter((amount): amount is bigint => amount !== undefined)\n .reduce((min, amount) => (amount < min ? amount : min));\n if (maxDestinationBorrowBaseUnits <= 0n) {\n throw new Error(\n \"LeverageService.buildFlashRebalance: destination reserve has no available borrow capacity\"\n );\n }\n // ExactIn-sized swap: routes through the dense ExactIn graph instead of\n // the sparser ExactOut graph (which often returns NO_ROUTES_FOUND on\n // Jupiter). We over-borrow slightly so the worst-case post-slippage\n // output still covers `flashRepayBigInt`; the post-swap source-debt\n // excess is swept on-chain into the yielding bank.\n const { quote: swapQuote } = await sizeExactInForMinOutput(ctx.swap, {\n inputMint: destDebtLiqMint,\n outputMint: sourceDebtLiqMint,\n minOutputAmount: flashRepayBigInt,\n maxInputAmount: maxDestinationBorrowBaseUnits,\n slippageBps: params.swapSlippageBps ?? 15,\n safetyBufferBps: params.swapBufferBps ?? 5,\n maxAccounts: FLASH_REBALANCE_SWAP_MAX_ACCOUNTS,\n });\n\n // Split the quote's below-par gap into market basis (oracle-fair cross\n // rate vs 1:1) and execution cost (quote vs that fair rate — route fees\n // + price impact), and bound each independently. The $1-pinned on-chain\n // books charge the *whole* gap to the token at conversion time, but only\n // the execution component is permanently lost; the basis component is\n // mark-to-market that reverses on unwind if the basis persists.\n if (params.maxSwapCostBps !== undefined || params.maxMarketBasisBps !== undefined) {\n const [sourcePrices, destPrices] = await Promise.all([\n new ReservesManager(\n ctx.source.supplyReserve,\n ctx.source.debtReserve,\n ctx.environment\n ).prices(),\n new ReservesManager(\n ctx.destination.supplyReserve,\n ctx.destination.debtReserve,\n ctx.environment\n ).prices(),\n ]);\n const fairOutPerIn = destPrices.debt.realtimePrice / sourcePrices.debt.realtimePrice;\n if (!Number.isFinite(fairOutPerIn) || fairOutPerIn <= 0) {\n throw new Error(\n `LeverageService.buildFlashRebalance: invalid oracle prices for swap cost check ` +\n `(source=${sourcePrices.debt.realtimePrice} dest=${destPrices.debt.realtimePrice})`\n );\n }\n const inUi = Number(swapQuote.inputAmount) / Math.pow(10, destDebtDecimals);\n const outUi = Number(swapQuote.outputAmount) / Math.pow(10, sourceDebtDecimals);\n const executionCostBps = (1 - outUi / inUi / fairOutPerIn) * 10_000;\n const marketBasisBps = (1 - fairOutPerIn) * 10_000;\n if (params.maxSwapCostBps !== undefined && executionCostBps > params.maxSwapCostBps) {\n throw new FlashRebalanceSwapCostExceededError(\n \"execution-cost\",\n executionCostBps,\n marketBasisBps,\n params.maxSwapCostBps,\n swapQuote.inputAmount,\n swapQuote.outputAmount\n );\n }\n if (\n params.maxMarketBasisBps !== undefined &&\n Math.abs(marketBasisBps) > params.maxMarketBasisBps\n ) {\n throw new FlashRebalanceSwapCostExceededError(\n \"market-basis\",\n executionCostBps,\n marketBasisBps,\n params.maxMarketBasisBps,\n swapQuote.inputAmount,\n swapQuote.outputAmount\n );\n }\n }\n\n const swapCpi = await ctx.swap.getSwapCpiData(swapQuote, ctx.user, { payer: ctx.payer });\n const destinationBorrowBaseUnits = new BN(swapQuote.inputAmount.toString());\n const destinationBorrowUiAmount = toUiAmount(destinationBorrowBaseUnits, destDebtDecimals);\n\n // Build the CPI bundles serially in execution order. The LP instruction\n // clients track reserve registrations per-obligation-per-txId; each\n // bundle's `getRefreshCpisIfNeeded` sees the cached reserves registered\n // by earlier calls on the same obligation. Running these in parallel\n // (Promise.all) would interleave non-deterministically and could cause\n // the later op's refresh to miss a reserve.\n //\n // Repay is built with NO uiAmount → the CPI data is a Skip sentinel.\n // On-chain, the rebalance_token handler fills the amount from\n // `flash_cpis.repay_amount` via `invoke_amount_cpi`, keeping the repay\n // amount authoritative from one top-level param instead of embedded in\n // a CPI we can't easily update after a quote refresh.\n const sourceRepay = await ctx.source.lendingIx.getRepayCpiData({\n user: ctx.user,\n payer: ctx.payer,\n pool: ctx.source.pool,\n reserve: sourceDebtMint,\n userAccount: ctx.source.userAccount,\n txId: ctx.txId,\n });\n\n // For a full repay the source debt row is removed from the obligation before\n // the destination borrow's RefreshObligation runs. Flag it now so that CPI's\n // accounts are built with 0 borrows; otherwise klend rejects the mismatched\n // account count with InvalidAccountInput (error 6006).\n // Partial rebalances leave the debt row intact — do not mark.\n if (params.withdrawAll) {\n ctx.source.lendingIx.markObligationDebtCleared(\n ctx.txId,\n ctx.source.userAccount,\n sourceDebtMint\n );\n }\n\n const destBorrow = await ctx.destination.lendingIx.getInitBorrowPositionCpiBundle(\n {\n user: ctx.user,\n payer: ctx.payer,\n pool: ctx.destination.pool,\n reserve: ctx.destination.debtReserve.address,\n userAccount: ctx.destination.userAccount,\n uiAmount: destinationBorrowUiAmount,\n txId: ctx.txId,\n },\n ctx.destination.supplyReserve.address\n );\n\n // The flash borrow/repay use the payer (a real top-level signer) as\n // `userTransferAuthority` because `ctx.user` (the obligation owner) is\n // typically a PDA and can't sign at the top level. The borrowed liquidity\n // still flows into the obligation owner's source-debt ATA — Kamino\n // requires the borrow's `userDestinationLiquidity` to equal the repay's\n // `userSourceLiquidity`, so both reference the same ATA. The on-chain\n // rebalance handler grants the payer SPL Approve over that ATA at the\n // end so the top-level flash repay's transfer can settle via delegation.\n const userSourceDebtAta = await getAtaAddress(\n sourceDebtLiqMint,\n ctx.user,\n ctx.source.debtReserve.mint.mintTokenProgram\n );\n\n const flashBorrowIx = await ctx.flashLoan.getFlashBorrowIx({\n user: ctx.payer,\n pool: ctx.source.pool,\n reserve: sourceDebtMint,\n amountBaseUnits: flashBorrowAmountBaseUnits,\n destinationAta: userSourceDebtAta,\n });\n\n const sourceIx = ctx.source.lendingIx;\n const destIx = ctx.destination.lendingIx;\n const sourcePreInstructions = await sourceIx.getPreInstructions(ctx.txId);\n const lendingPreInstructions =\n sourceIx === destIx\n ? sourcePreInstructions\n : [...sourcePreInstructions, ...(await destIx.getPreInstructions(ctx.txId))];\n\n // Lending-platform pre-instructions must come first (they prepare reserve\n // state the inner CPIs depend on). Swap-driven pre-instructions\n // (e.g. createATA for intermediate-mint hops in a Jupiter route) ride\n // immediately after — both must precede the host's other ATA setup so\n // they're in scope by the time the rebalance CPI dispatches the swap.\n const swapPreInstructions = swapCpi.preInstructions ?? [];\n const preInstructions = [...lendingPreInstructions, ...swapPreInstructions];\n\n const postSuccessCacheInvalidations = [\n ...destBorrow.postSuccessCacheInvalidations,\n ...(swapCpi.postSuccessCacheInvalidations ?? []),\n ];\n\n return {\n flashBorrowAmountBaseUnits,\n flashRepayAmountBaseUnits,\n flashFeeBaseUnits,\n sourceRepayUiAmount,\n destinationBorrowUiAmount,\n flashBorrowIx,\n sourceRepayCpis: [...sourceRepay.prerequisiteCpis, ...sourceRepay.cpis],\n destinationBorrowCpis: [...destBorrow.prerequisiteCpis, ...destBorrow.cpis],\n swapCpis: [swapCpi],\n preInstructions,\n postSuccessCacheInvalidations,\n };\n }\n\n /**\n * Build the top-level flash-repay instruction for a previously-built flash\n * rebalance, given the final transaction index of its `flashBorrowIx`.\n *\n * Split from {@link buildFlashRebalance} because `borrowIxIndex` depends on\n * the caller's full tx layout (pre-instructions + heap frame + ATA creations\n * + flash-borrow position), which in turn depends on the ATA list derived\n * from the plan's `remainingAccounts` — a chicken-and-egg the caller resolves\n * by assembling the preamble before calling this.\n */\n static async buildFlashRepayIx(\n ctx: FlashRebalanceContext,\n plan: Pick<FlashRebalanceResult, \"flashBorrowAmountBaseUnits\">,\n borrowIxIndex: number\n ): Promise<Instruction> {\n // The payer (top-level signer) authorizes the repay. Kamino enforces\n // that the borrow's `userDestinationLiquidity` matches the repay's\n // `userSourceLiquidity` — both must reference the obligation-owner's\n // source-debt ATA — so we explicitly route the repay through that ATA\n // rather than letting it default to the payer's. The on-chain\n // rebalance handler grants the payer SPL Approve over this ATA before\n // returning, so the top-level repay's transfer settles via delegation.\n const userSourceDebtAta = await getAtaAddress(\n ctx.source.debtReserve.mint.mint,\n ctx.user,\n ctx.source.debtReserve.mint.mintTokenProgram\n );\n return ctx.flashLoan.getFlashRepayIx({\n user: ctx.payer,\n pool: ctx.source.pool,\n reserve: ctx.source.debtReserve.address,\n amountBaseUnits: plan.flashBorrowAmountBaseUnits,\n borrowIxIndex,\n userSourceLiquidity: userSourceDebtAta,\n });\n }\n\n private static async calcSourceRepayForWithdraw(\n ctx: FlashRebalanceContext,\n params: FlashRebalanceParams\n ): Promise<BN> {\n const manager = new LendingPositionManager(\n ctx.source.lendingIx.data,\n ctx.source.pool,\n ctx.source.userAccount,\n ctx.source.supplyReserve,\n ctx.source.debtReserve,\n ctx.environment\n );\n if (params.withdrawAll) {\n const { debtUiAmount } = await manager.getLendingPositionAmounts();\n return fromUiAmount(debtUiAmount, ctx.source.debtReserve.mint.mintDecimals);\n }\n\n const debtChangeUi = await manager.calcDebtChangeAmountForCollateralWithdrawal(\n params.collateralUiAmount,\n params.sourceTargetUtilizationRateBps\n );\n // `calcDebtChangeAmountForCollateralWithdrawal` returns a signed UI delta:\n // negative → repay, positive → (under-leveraged) borrow. The flash path is\n // only relevant for the repay case.\n const repayUi = Math.max(0, -debtChangeUi);\n return fromUiAmount(repayUi, ctx.source.debtReserve.mint.mintDecimals);\n }\n\n private static async calcDestinationBorrowCapacityForDeposit(\n ctx: FlashRebalanceContext,\n params: FlashRebalanceParams\n ): Promise<bigint | undefined> {\n if (params.destinationMaxUtilizationRateBps === undefined) {\n return undefined;\n }\n\n const manager = new LendingPositionManager(\n ctx.destination.lendingIx.data,\n ctx.destination.pool,\n ctx.destination.userAccount,\n ctx.destination.supplyReserve,\n ctx.destination.debtReserve,\n ctx.environment\n );\n const current = await manager.getLendingPositionAmounts();\n const reserves = new ReservesManager(\n ctx.destination.supplyReserve,\n ctx.destination.debtReserve,\n ctx.environment\n );\n const debtAdjustmentUsd = await reserves.calcDebtAdjustmentUsd(\n current.supplyUiAmount + params.collateralUiAmount,\n current.debtUiAmount,\n params.destinationMaxUtilizationRateBps,\n { positionChangeMode: \"debtOnly\" }\n );\n const prices = await reserves.prices();\n if (debtAdjustmentUsd <= 0) {\n return 0n;\n }\n\n const debtUiAmount = debtAdjustmentUsd / prices.debt.realtimePrice;\n return BigInt(\n fromUiAmount(debtUiAmount, ctx.destination.debtReserve.mint.mintDecimals).toString()\n );\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type BN from \"bn.js\";\nimport type { CpiData, Environment, SwapClient, TransactionCacheInvalidation } from \"common\";\nimport type { LendingPlatformData } from \"../../data\";\nimport type { LpInstructionsBase } from \"../../data/instructions/lpInstructionsBase\";\nimport type { ReserveBase } from \"../../data/reserve/reserveBase\";\nimport type { FlashLoanBase } from \"../flashLoan\";\n\n/**\n * How the position changes when debt is adjusted.\n *\n * - `levered` — flash-loan loop where borrowed funds also increase supplied\n * collateral (e.g. multiply token).\n * - `debtOnly` — only debt changes, supplied collateral stays constant\n * (e.g. carry-position borrow/repay).\n */\nexport type LeverageChangeMode = \"levered\" | \"debtOnly\";\n\n/**\n * Shared context for leverage operations: the lending-platform client, reserves,\n * and position identity needed for both sizing and CPI construction.\n */\nexport interface LeverageContext {\n /** Lending-platform instruction client for building CPIs. */\n lendingIx: LpInstructionsBase<LendingPlatformData>;\n /** Collateral reserve. */\n supplyReserve: ReserveBase;\n /** Debt reserve. */\n debtReserve: ReserveBase;\n /** Account that owns the lending position (e.g. a token PDA). */\n user: Address;\n /** Transaction signer / fee payer. */\n payer: Address;\n /** Lending pool address. */\n pool: Address;\n /** Lending protocol user account (e.g. Kamino obligation). */\n userAccount: Address;\n /** Transaction identifier shared with the lending client for pre-instruction deduplication. */\n txId: string;\n /** Deployment environment used for oracle price fetches. */\n environment?: Environment;\n}\n\n/**\n * Inputs for an increase-leverage (borrow) operation.\n */\nexport interface IncreaseLeverageParams {\n /** Current supply position in UI units (e.g. 1.5 SOL). */\n currentSupplyUiAmount: number;\n /** Current debt position in UI units (e.g. 100 USDC). */\n currentDebtUiAmount: number;\n /** Target LTV utilization rate in basis points (0–10000). */\n targetUtilizationRateBps: number;\n /** Defaults to `debtOnly`. */\n mode?: LeverageChangeMode;\n}\n\n/**\n * Inputs for a decrease-leverage (repay) operation.\n */\nexport interface DecreaseLeverageParams {\n /** Current supply position in UI units. */\n currentSupplyUiAmount: number;\n /** Current debt position in UI units. */\n currentDebtUiAmount: number;\n /** Target LTV utilization rate in basis points (0–10000). */\n targetUtilizationRateBps: number;\n /** Defaults to `debtOnly`. */\n mode?: LeverageChangeMode;\n /**\n * When set, replaces the utilization-derived repay size for both the on-chain\n * `repay_amount` and the embedded Kamino repay CPI amount. Used for full\n * deleverages where refreshed obligation debt can exceed stale token accounting.\n */\n repayBaseUnitsOverride?: BN;\n /**\n * When the debt token must be obtained via a swap (source asset differs\n * from debt mint), provide swap context so the service can quote the swap\n * and prepend a swap CPI group when the on-hand balance is insufficient.\n */\n swapContext?: LeverageSwapContext;\n}\n\n/**\n * Context for quoting a swap that tops up the debt token before repay.\n */\nexport interface LeverageSwapContext {\n /** Swap client used to quote and build CPI data. */\n swap: SwapClient;\n /** Mint of the asset to sell (source of liquidity). */\n sourceMint: Address;\n /** Debt mint the repay requires. */\n debtMint: Address;\n /** Base units of the source asset available for the swap. */\n sourceBalanceBaseUnits: bigint;\n /** Address that executes the swap (e.g. a vault PDA). */\n swapTarget: Address;\n /** Real signer that can pay for swap route setup instructions. */\n payer?: Address;\n /** Slippage tolerance in basis points. Defaults to 40 for decrease-leverage swaps. */\n slippageBps?: number;\n /** DEX labels to exclude from swap routing (e.g. venues that failed a prior attempt). */\n excludeDexes?: string[];\n}\n\n/**\n * Result of an increase-leverage (borrow) operation.\n */\nexport interface IncreaseLeverageResult {\n /** Borrow amount in UI units. */\n borrowUiAmount: number;\n /** Borrow amount in debt-token base units. */\n borrowBaseUnits: BN;\n /** Prerequisite CPIs (e.g. obligation refresh) that precede the borrow. */\n prerequisiteCpis: CpiData[];\n /** Main borrow CPI descriptors. */\n borrowCpis: CpiData[];\n /** Top-level instructions that must execute before CPIs (e.g. Kamino LUT warmup). */\n preInstructions: Instruction[];\n /** Cache invalidations from the lending operation. */\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\n/**\n * Per-leg context for a flash-loan-wrapped rebalance leg (source or destination).\n */\nexport interface FlashRebalanceLegContext {\n /** Lending-platform instruction client for building CPIs on this leg. */\n lendingIx: LpInstructionsBase<LendingPlatformData>;\n /** Collateral (supply) reserve. */\n supplyReserve: ReserveBase;\n /** Debt reserve. */\n debtReserve: ReserveBase;\n /** Lending pool address. */\n pool: Address;\n /** Lending-protocol user account (e.g. Kamino obligation). */\n userAccount: Address;\n}\n\n/**\n * Shared context for a flash-loan-wrapped rebalance, moving collateral between\n * two lending positions without touching carry positions.\n */\nexport interface FlashRebalanceContext {\n /** Source position (collateral withdraws from here, debt temporarily repaid). */\n source: FlashRebalanceLegContext;\n /** Destination position (collateral deposits here, fresh debt borrowed). */\n destination: FlashRebalanceLegContext;\n /** Flash-loan client for the source debt mint's lending platform. */\n flashLoan: FlashLoanBase<LendingPlatformData>;\n /** Swap client used to quote the exact-in swap back to source debt mint. */\n swap: SwapClient;\n /** Account owning the lending positions (e.g. token PDA). */\n user: Address;\n /** Transaction signer / fee payer. */\n payer: Address;\n /** Transaction identifier shared with lending clients for pre-instruction dedup. */\n txId: string;\n /** Deployment environment — passed to oracle fetches so custom oracles (e.g. PythSplStake) use the correct RPC endpoint. */\n environment?: Environment;\n}\n\n/**\n * Inputs for a flash-loan-wrapped rebalance.\n */\nexport interface FlashRebalanceParams {\n /** Collateral amount in UI units; used to size the source repay for partial rebalances. */\n collateralUiAmount: number;\n /** Target LTV utilization rate (bps) the source should land at after the repay. */\n sourceTargetUtilizationRateBps: number;\n /**\n * Upper utilization bound (bps) the destination must stay under after the borrow.\n * This should mirror the on-chain post-rebalance guard.\n */\n destinationMaxUtilizationRateBps?: number;\n /** Slippage tolerance for the exact-in swap, in basis points. Defaults to 100. */\n swapSlippageBps?: number;\n /**\n * Extra safety margin (bps) added on top of `swapSlippageBps` when sizing\n * the destination borrow / swap input. The over-borrow makes the worst-case\n * post-slippage swap output exceed the flash repay by this much; the\n * excess is swept to the yielding bank on-chain. Defaults to 50.\n */\n swapBufferBps?: number;\n /**\n * Upper bound for how much destination debt mint the builder may borrow.\n * Defaults to the destination reserve's available borrow capacity.\n */\n maxDestinationBorrowBaseUnits?: bigint;\n /**\n * If true, the source-side repay uses the platform's \"repay all\" sentinel so\n * the obligation's full debt is cleared on-chain — caller still passes\n * `collateralUiAmount` (used for sizing the destination borrow / swap).\n * Set when rebalancing 100% of a position's debt.\n */\n withdrawAll?: boolean;\n /**\n * Maximum acceptable **execution cost** of the destination-debt →\n * source-debt swap quote, in bps, measured against the oracle-fair cross\n * rate (`destDebtUsd / sourceDebtUsd`): route fees + price impact only.\n * Genuine market basis between the two stables is excluded here — bound it\n * with {@link maxMarketBasisBps}. Exceeding this throws\n * `FlashRebalanceSwapCostExceededError` (reason `\"execution-cost\"`); the\n * cost is permanently lost value. Unset = no limit.\n */\n maxSwapCostBps?: number;\n /**\n * Maximum acceptable **market basis** between the two debt stables, in bps:\n * how far the oracle-fair cross rate sits from 1:1 (either direction).\n * Under the $1-pinned on-chain books the basis is charged to the token's\n * carry-vs-debt difference at conversion time (as mark-to-market that\n * reverses on unwind if the basis persists), and a large basis usually\n * means one leg is depegging. Exceeding this throws\n * `FlashRebalanceSwapCostExceededError` (reason `\"market-basis\"`).\n * Unset = no limit.\n */\n maxMarketBasisBps?: number;\n}\n\n/**\n * Result of a flash-loan-wrapped rebalance build.\n *\n * The caller wraps the on-chain rebalance instruction with the returned\n * {@link flashBorrowIx} and {@link flashRepayIx} at the top level.\n */\nexport interface FlashRebalanceResult {\n /** Flash-borrow amount in source-debt-mint base units. */\n flashBorrowAmountBaseUnits: BN;\n /** Flash-repay amount in source-debt-mint base units (borrow + fee). */\n flashRepayAmountBaseUnits: BN;\n /** Flash fee in source-debt-mint base units. */\n flashFeeBaseUnits: BN;\n /** Source repay amount in UI units (equals flash-borrow amount). */\n sourceRepayUiAmount: number;\n /** Destination borrow amount in UI units (quote's max input). */\n destinationBorrowUiAmount: number;\n /** Top-level flash-borrow instruction (goes before the rebalance ix). */\n flashBorrowIx: Instruction;\n /** Source repay CPI group (flash-borrowed tokens → source debt), prereqs prepended. */\n sourceRepayCpis: CpiData[];\n /** Destination borrow CPI group, prereqs prepended. */\n destinationBorrowCpis: CpiData[];\n /** Swap CPI descriptor (single Swap CPI, exact-in). */\n swapCpis: CpiData[];\n /** Hoisted top-level instructions (Kamino LUT warmup etc.), deduplicated across legs. */\n preInstructions: Instruction[];\n /** Cache invalidations for the lending operations. */\n postSuccessCacheInvalidations: TransactionCacheInvalidation[];\n}\n\n/**\n * Result of a decrease-leverage (repay) operation.\n */\nexport interface DecreaseLeverageResult {\n /** Repay amount in UI units. */\n repayUiAmount: number;\n /** Repay amount in debt-token base units. */\n repayBaseUnits: BN;\n /** Prerequisite CPIs (e.g. obligation refresh) that precede the repay. */\n prerequisiteCpis: CpiData[];\n /** Main repay CPI descriptors. */\n repayCpis: CpiData[];\n /**\n * Ordered CPI groups for the operation: `[swapGroup?, repayGroup]`.\n * When no swap is needed, contains a single repay group.\n */\n cpiDataGroups: CpiData[][];\n /** True when a swap CPI was prepended because on-hand debt was insufficient. */\n swapRequired: boolean;\n /** Top-level instructions that must execute before CPIs. */\n preInstructions: Instruction[];\n}\n","export * from \"./leverageService\";\nexport * from \"./types\";\n","import type { ReservesPrices } from \"../reservesManager\";\n\nexport interface LendingPositionState {\n prices: ReservesPrices;\n supplyUsd: number;\n debtUsd: number;\n}\n\nexport interface CollateralPriceTriggerLevel {\n currentCollateralPrice: number;\n triggerCollateralPrice: number;\n targetUtilizationRateBps: number;\n priceMode: \"realtime\" | \"ema\";\n priceChangePct: number;\n}\n\nexport interface CollateralPriceTriggerBand {\n lower?: CollateralPriceTriggerLevel;\n upper?: CollateralPriceTriggerLevel;\n}\n\nexport interface LendingPositionUtilizationRatesBps {\n realtime: number;\n ema: number;\n}\n\nexport interface LendingPositionSelectedPrice {\n value: number;\n source: \"realtime\" | \"ema\" | \"ema_fallback_realtime\";\n}\n\nexport interface LendingPositionUtilizationPrices {\n realtime: {\n collateral: LendingPositionSelectedPrice;\n debt: LendingPositionSelectedPrice;\n };\n ema: {\n collateral: LendingPositionSelectedPrice;\n debt: LendingPositionSelectedPrice;\n };\n}\n\nexport interface LendingPositionInspectMetrics {\n utilizationRateBps: LendingPositionUtilizationRatesBps;\n utilizationPrices: LendingPositionUtilizationPrices;\n triggerBand: CollateralPriceTriggerBand;\n}\n","export * from \"./lendingPositionManager\";\nexport * from \"./types\";\n","export * from \"./client\";\nexport * from \"./flashLoan\";\nexport * from \"./leverage\";\nexport * from \"./lendingPosition\";\nexport * from \"./reservesManager\";\n","export * from \"./services\";\nexport * from \"./data\";\nexport * from \"./constants\";\nexport * from \"./utils\";\nexport * from \"./types\";\n","/**\n * Per-asset carry trade price-band presets, split by volatility regime.\n *\n * Each preset defines three drawdown / rally buffers that control how aggressively a\n * lending position is utilized relative to its liquidation line:\n *\n * - `drawdownPctFromTargetToLiq` — collateral drawdown (%) that separates the **target**\n * utilization from the liquidation line. Larger = more conservative target.\n * - `drawdownPctFromUnwindToLiq` — collateral drawdown (%) that separates the **unwind\n * trigger** from the liquidation line. Smaller than target (closer to liquidation).\n * - `maxPriceChangeUpPercent` — max collateral **rally** (%) before the boost trigger fires,\n * prompting the position to borrow more and return to target.\n *\n * ## Usage\n *\n * Select the appropriate asset preset and volatility regime, then pass it to\n * `LycLendingPositionManager.getLendingAllocationConfigFromPriceBands(preset)`, which combines\n * the price-band params with pair-specific `maxLtv` and `liquidationThreshold` to produce\n * a `CarryLendingAllocationConfig` (target utilization + deviation bands in bps). The\n * resulting config is used to update the on-chain `LendingPositionConfig`, adapting the\n * position's risk envelope to the current market regime.\n *\n * ## Asset tiers (tightest → widest buffers)\n *\n * BTC → ETH → SOL → large-cap alts → small-cap alts\n *\n * Higher-volatility assets use wider buffers to avoid unnecessary unwinds during normal\n * price swings, while lower-volatility assets can afford tighter bands for better capital\n * efficiency.\n */\nimport type { CarryPriceBandPreset } from \"../../services/carry/carryAllocationConfig\";\n\nexport const VOLATILITY_REGIMES = [\"lowVol\", \"highVol\"] as const;\nexport type VolatilityRegime = (typeof VOLATILITY_REGIMES)[number];\n\nexport function isVolatilityRegime(s: string): s is VolatilityRegime {\n return VOLATILITY_REGIMES.includes(s as VolatilityRegime);\n}\n\nexport type CarryVolatilityPresets = {\n lowVol: CarryPriceBandPreset;\n highVol: CarryPriceBandPreset;\n};\n\nexport interface AssetPresetEntry {\n presets: CarryVolatilityPresets;\n defaultRegime: VolatilityRegime;\n}\n\nexport const STOCK_INDEX_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 8,\n drawdownPctFromUnwindToLiq: 5,\n maxPriceChangeUpPercent: 2,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 11,\n drawdownPctFromUnwindToLiq: 7,\n maxPriceChangeUpPercent: 3,\n },\n};\n\nexport const BTC_CARRY_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 12,\n drawdownPctFromUnwindToLiq: 8,\n maxPriceChangeUpPercent: 6,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 14,\n drawdownPctFromUnwindToLiq: 10,\n maxPriceChangeUpPercent: 8,\n },\n};\n\nexport const ETH_CARRY_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 14,\n drawdownPctFromUnwindToLiq: 10,\n maxPriceChangeUpPercent: 7,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 17,\n drawdownPctFromUnwindToLiq: 12,\n maxPriceChangeUpPercent: 10,\n },\n};\n\nexport const SOL_CARRY_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 16,\n drawdownPctFromUnwindToLiq: 12,\n maxPriceChangeUpPercent: 8,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 19,\n drawdownPctFromUnwindToLiq: 14,\n maxPriceChangeUpPercent: 11,\n },\n};\n\nexport const LST_CARRY_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 19,\n drawdownPctFromUnwindToLiq: 10,\n maxPriceChangeUpPercent: 8,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 22,\n drawdownPctFromUnwindToLiq: 12,\n maxPriceChangeUpPercent: 11,\n },\n};\n\nexport const LARGE_CAP_ALT_CARRY_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 22,\n drawdownPctFromUnwindToLiq: 16,\n maxPriceChangeUpPercent: 8,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 25,\n drawdownPctFromUnwindToLiq: 18,\n maxPriceChangeUpPercent: 10,\n },\n};\n\nexport const SMALL_CAP_ALT_CARRY_PRESETS: CarryVolatilityPresets = {\n lowVol: {\n drawdownPctFromTargetToLiq: 26,\n drawdownPctFromUnwindToLiq: 22,\n maxPriceChangeUpPercent: 10,\n },\n highVol: {\n drawdownPctFromTargetToLiq: 29,\n drawdownPctFromUnwindToLiq: 24,\n maxPriceChangeUpPercent: 12,\n },\n};\n\n/**\n * Maps collateral symbol (upper-cased) to its carry trade preset tier and\n * default volatility regime. Used by scripts and backend services to resolve\n * the correct price-band parameters when creating or reconfiguring lending\n * positions.\n */\nexport const ASSET_PRESETS: Record<string, AssetPresetEntry> = {\n WBTC: { presets: BTC_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n CBBTC: { presets: BTC_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n WETH: { presets: ETH_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n SOL: { presets: SOL_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n JUPSOL: { presets: LST_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n JITOSOL: { presets: LST_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n DFDVSOL: { presets: LST_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n SPYX: { presets: STOCK_INDEX_PRESETS, defaultRegime: \"lowVol\" },\n QQQX: { presets: STOCK_INDEX_PRESETS, defaultRegime: \"lowVol\" },\n LARGE_CAP: { presets: LARGE_CAP_ALT_CARRY_PRESETS, defaultRegime: \"lowVol\" },\n SMALL_CAP: { presets: SMALL_CAP_ALT_CARRY_PRESETS, defaultRegime: \"highVol\" },\n};\n\n/** Looks up the carry preset entry for a collateral symbol (case-insensitive). */\nexport function resolvePresets(collateralSymbol: string): AssetPresetEntry | undefined {\n return ASSET_PRESETS[collateralSymbol.toUpperCase()];\n}\n","import {\n ltvUtilDeltaBelowTargForRallyPct,\n maxLtvUtilBeforeCollDrawdown,\n ReservesManager,\n type ReserveBase,\n} from \"lending-platforms\";\nimport { mints } from \"common\";\nimport type { Address } from \"@solana/kit\";\nimport { resolvePresets, type VolatilityRegime } from \"../../constants/configs/carryTradePresets\";\n\n/** Maximum value for `targetUtilizationRateBps` (100% in basis points). */\nexport const MAX_TARGET_UTILIZATION_RATE_BPS = 10_000;\n\n/**\n * Maximum allowed value of `targetUtilizationRateBps + maxDeviationAboveTargetUtilBps`.\n * Mirrors `MAX_LENDING_POSITION_UPPER_UTIL_BPS` in the on-chain program.\n */\nexport const MAX_LENDING_POSITION_UPPER_UTIL_BPS = 10_500;\n\n/**\n * Floor for `maxDeviationAboveTargetUtilBps` in preset-based computation.\n *\n * When the raw target is high enough that the unwind-trigger gap would be\n * smaller than this, `computeCarryLendingAllocationConfig` pulls the target\n * down so the above-deviation is at least this wide. This prevents\n * near-zero unwind bands that would trigger constant rebalances.\n */\nexport const MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS = 200;\n\n/**\n * On-chain lending position tuning (see `LendingPositionConfig` in `long_yield_carry`).\n */\nexport type CarryLendingAllocationConfig = {\n targetUtilizationRateBps: number;\n maxDeviationAboveTargetUtilBps: number;\n maxDeviationBelowTargetUtilBps: number;\n};\n\nexport type ComputeCarryLendingAllocationConfigParams = {\n /**\n * Collateral drawdown buffer between the **target** utilization and liquidation (positive percent,\n * e.g. `25` for 25%). At target utilization, a collateral drop of this size reaches the liquidation\n * line: `target = (1 − drawdownPctFromTargetToLiq/100) × liquidationThreshold / maxLtv`.\n *\n * Must be greater than `drawdownPctFromUnwindToLiq` (the target sits further from liquidation than\n * the unwind trigger).\n */\n drawdownPctFromTargetToLiq: number;\n /**\n * Collateral drawdown buffer between the **unwind trigger** and liquidation (positive percent,\n * e.g. `10` for 10%). At the unwind trigger (`target + maxDeviationAbove`), a collateral drop of\n * this size reaches the liquidation line:\n * `unwindTrigger = (1 − drawdownPctFromUnwindToLiq/100) × liquidationThreshold / maxLtv`.\n *\n * Must be less than `drawdownPctFromTargetToLiq`.\n */\n drawdownPctFromUnwindToLiq: number;\n /**\n * Max collateral **appreciation** (positive percent, e.g. `25` for +25%). If you start exactly at\n * target utilization and collateral rallies this much (debt USD fixed), utilization reaches the\n * **boost** trigger: `target − maxDeviationBelow`.\n */\n maxPriceChangeUpPercent: number;\n /** Effective max LTV for the pair (decimal `0.8` = 80%), e.g. `ReservesManager.maxLtv`. */\n maxLtv: number;\n /** Collateral liquidation threshold (decimal `0.85` = 85%), from reserve config. */\n liquidationThreshold: number;\n};\n\n/** The price-band params without pair-specific LTV / liquidation fields. */\nexport type CarryPriceBandPreset = Omit<\n ComputeCarryLendingAllocationConfigParams,\n \"maxLtv\" | \"liquidationThreshold\"\n>;\n\n/**\n * Clamps a lending position config so it satisfies the on-chain constraints in\n * `require_valid_lending_position_config_bps`:\n *\n * - `targetUtilizationRateBps` is clamped to `[1, MAX_TARGET_UTILIZATION_RATE_BPS]`\n * - `maxDeviationAboveTargetUtilBps` is clamped so `target + above ≤ MAX_LENDING_POSITION_UPPER_UTIL_BPS`\n *\n * Throws only for inputs that indicate a bug (non-integer, negative deviation, target ≤ maxDevBelow).\n */\nexport function clampLendingPositionConfigBps(\n config: CarryLendingAllocationConfig\n): CarryLendingAllocationConfig {\n let { targetUtilizationRateBps, maxDeviationAboveTargetUtilBps, maxDeviationBelowTargetUtilBps } =\n config;\n\n if (!Number.isInteger(targetUtilizationRateBps) || targetUtilizationRateBps <= 0) {\n throw new Error(\"targetUtilizationRateBps must be a positive integer\");\n }\n for (const [name, v] of [\n [\"maxDeviationAboveTargetUtilBps\", maxDeviationAboveTargetUtilBps],\n [\"maxDeviationBelowTargetUtilBps\", maxDeviationBelowTargetUtilBps],\n ] as const) {\n if (!Number.isInteger(v) || v < 0) {\n throw new Error(`${name} must be a non-negative integer`);\n }\n }\n\n targetUtilizationRateBps = Math.min(targetUtilizationRateBps, MAX_TARGET_UTILIZATION_RATE_BPS);\n maxDeviationAboveTargetUtilBps = Math.min(\n maxDeviationAboveTargetUtilBps,\n MAX_LENDING_POSITION_UPPER_UTIL_BPS - targetUtilizationRateBps\n );\n\n if (targetUtilizationRateBps <= maxDeviationBelowTargetUtilBps) {\n throw new Error(\"targetUtilizationRateBps must be greater than maxDeviationBelowTargetUtilBps\");\n }\n\n return {\n targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps,\n };\n}\n\n/**\n * Builds `targetUtilizationRateBps` and deviation bands from drawdown-to-liquidation buffers.\n *\n * **Model:** debt USD fixed; only collateral USD moves. Both the target and the unwind trigger are\n * defined by how much collateral drawdown separates them from the liquidation line\n * (`liquidationThreshold / maxLtv`). The boost trigger (below target) is set by a rally percentage.\n *\n * `maxDeviationAbove = unwindTriggerBps − targetBps` (derived, not from a price-change input).\n */\nexport function computeCarryLendingAllocationConfig(\n params: ComputeCarryLendingAllocationConfigParams\n): CarryLendingAllocationConfig {\n const {\n drawdownPctFromTargetToLiq,\n drawdownPctFromUnwindToLiq,\n maxPriceChangeUpPercent,\n maxLtv,\n liquidationThreshold,\n } = params;\n\n if (\n !Number.isFinite(drawdownPctFromTargetToLiq) ||\n drawdownPctFromTargetToLiq <= 0 ||\n drawdownPctFromTargetToLiq >= 100\n ) {\n throw new RangeError(\"drawdownPctFromTargetToLiq must be in (0, 100)\");\n }\n if (\n !Number.isFinite(drawdownPctFromUnwindToLiq) ||\n drawdownPctFromUnwindToLiq < 0 ||\n drawdownPctFromUnwindToLiq >= 100\n ) {\n throw new RangeError(\"drawdownPctFromUnwindToLiq must be in [0, 100)\");\n }\n if (drawdownPctFromUnwindToLiq >= drawdownPctFromTargetToLiq) {\n throw new RangeError(\n \"drawdownPctFromUnwindToLiq must be less than drawdownPctFromTargetToLiq (unwind trigger is closer to liquidation than target)\"\n );\n }\n if (!Number.isFinite(maxPriceChangeUpPercent) || maxPriceChangeUpPercent <= 0) {\n throw new RangeError(\"maxPriceChangeUpPercent must be finite and positive\");\n }\n\n const targetDecimal = maxLtvUtilBeforeCollDrawdown({\n drawdownPercent: drawdownPctFromTargetToLiq,\n ltv: maxLtv,\n liquidationThreshold,\n });\n\n let targetUtilizationRateBps = Math.min(\n Math.floor(targetDecimal * 10_000),\n MAX_TARGET_UTILIZATION_RATE_BPS\n );\n if (targetUtilizationRateBps <= 0) {\n throw new RangeError(\n \"Computed target utilization rounds to zero; reduce drawdownPctFromTargetToLiq or check maxLtv / liquidationThreshold\"\n );\n }\n\n const unwindTriggerDecimal = maxLtvUtilBeforeCollDrawdown({\n drawdownPercent: drawdownPctFromUnwindToLiq,\n ltv: maxLtv,\n liquidationThreshold,\n });\n const unwindTriggerBps = Math.floor(unwindTriggerDecimal * 10_000);\n let maxDeviationAboveTargetUtilBps = Math.min(\n unwindTriggerBps - targetUtilizationRateBps,\n MAX_LENDING_POSITION_UPPER_UTIL_BPS - targetUtilizationRateBps\n );\n\n // If the above-deviation is below the minimum (e.g. because the target was\n // clamped to MAX_TARGET_UTILIZATION_RATE_BPS), pull the target down so the\n // unwind band is at least MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS wide.\n if (maxDeviationAboveTargetUtilBps < MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS) {\n maxDeviationAboveTargetUtilBps = MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS;\n targetUtilizationRateBps = Math.min(\n targetUtilizationRateBps,\n MAX_LENDING_POSITION_UPPER_UTIL_BPS - MIN_DEVIATION_ABOVE_TARGET_UTIL_BPS\n );\n }\n\n const t = targetUtilizationRateBps / 10_000;\n const maxBelowDecimal = ltvUtilDeltaBelowTargForRallyPct(t, maxPriceChangeUpPercent);\n const maxDeviationBelowTargetUtilBps = Math.floor(maxBelowDecimal * 10_000);\n\n return clampLendingPositionConfigBps({\n targetUtilizationRateBps,\n maxDeviationAboveTargetUtilBps,\n maxDeviationBelowTargetUtilBps,\n });\n}\n\n// =============================================================================\n// High-level preset resolution\n// =============================================================================\n\nexport interface ComputeConfigForCollateralArgs {\n /** Collateral mint address — used to look up the symbol from the mint registry. */\n collateralMint: Address;\n /** Collateral reserve — used to read `liquidationThresholdPct`. */\n collateralReserve: ReserveBase;\n /** Debt reserve — paired with collateral to determine `maxLtv` (including e-mode). */\n debtReserve: ReserveBase;\n /**\n * Override the volatility regime. When omitted, uses the asset's\n * `defaultRegime` from `ASSET_PRESETS`.\n */\n regime?: VolatilityRegime;\n}\n\n/**\n * Resolves the carry trade price-band preset for a collateral mint and\n * computes the lending position config (target utilization + deviation bands)\n * using the reserve pair's `maxLtv` and `liquidationThreshold`.\n *\n * Uses {@link ReservesManager} to derive `maxLtv` (including e-mode overrides)\n * and normalizes `liquidationThresholdPct` to a decimal.\n *\n * Throws if the collateral mint symbol is not in `ASSET_PRESETS`.\n */\nexport function computeConfigForCollateral(\n args: ComputeConfigForCollateralArgs\n): CarryLendingAllocationConfig {\n const { collateralMint, collateralReserve, debtReserve } = args;\n\n const mintInfo = mints.get(collateralMint);\n const symbol = mintInfo?.symbol ?? String(collateralMint);\n const entry = resolvePresets(symbol);\n if (!entry) {\n throw new Error(\n `computeConfigForCollateral: no carry preset found for collateral \"${symbol}\" (${collateralMint})`\n );\n }\n\n const regime = args.regime ?? entry.defaultRegime;\n const preset = entry.presets[regime];\n\n const rm = new ReservesManager(collateralReserve, debtReserve);\n const pct = collateralReserve.config.liquidationThresholdPct;\n const liquidationThreshold = pct <= 1 ? pct : pct / 100;\n\n return computeCarryLendingAllocationConfig({\n ...preset,\n maxLtv: rm.maxLtv,\n liquidationThreshold,\n });\n}\n","import { fromWeb3Pk, type Environment } from \"common\";\nimport {\n LendingPlatformData,\n LendingPositionManager,\n ReserveBase,\n type CollateralPriceTriggerBand,\n type LendingPositionInspectMetrics,\n} from \"lending-platforms\";\nimport { TokenLendingPositionData } from \"../../models/lycToken\";\nimport {\n computeCarryLendingAllocationConfig,\n type CarryLendingAllocationConfig,\n type CarryPriceBandPreset,\n} from \"./carryAllocationConfig\";\n\n/**\n * LYC-flavoured {@link LendingPositionManager}: adds carry-specific sizing\n * signals ({@link shouldIncreaseCarryPosition}, {@link shouldDecreaseCarryPosition})\n * and defaults utilization targets from the on-chain `LendingPositionConfig`.\n */\nexport class LycLendingPositionManager extends LendingPositionManager {\n constructor(\n lpData: LendingPlatformData,\n readonly lendingPosition: TokenLendingPositionData,\n collateralReserve: ReserveBase,\n debtReserve: ReserveBase,\n environment?: Environment\n ) {\n super(\n lpData,\n fromWeb3Pk(lendingPosition.pool),\n fromWeb3Pk(lendingPosition.protocolUserAcc),\n collateralReserve,\n debtReserve,\n environment\n );\n }\n\n static async create(\n lpData: LendingPlatformData,\n lendingPosition: TokenLendingPositionData,\n environment?: Environment\n ): Promise<LycLendingPositionManager> {\n const pool = fromWeb3Pk(lendingPosition.pool);\n const [collateralReserve, debtReserve] = await Promise.all([\n lpData.fetchReserve(pool, fromWeb3Pk(lendingPosition.collateralReserve)),\n lpData.fetchReserve(pool, fromWeb3Pk(lendingPosition.debtReserve)),\n ]);\n if (!collateralReserve || !debtReserve) {\n throw new Error(\"Failed to fetch reserves\");\n }\n return new LycLendingPositionManager(\n lpData,\n lendingPosition,\n collateralReserve,\n debtReserve,\n environment\n );\n }\n\n /**\n * Derives `targetUtilizationRateBps` and carry trigger deviations from drawdown-to-liquidation\n * buffers and a rally percentage, using this pair's {@link ReservesManager.maxLtv} and the\n * collateral reserve's **base** `liquidationThresholdPct` (normalized to a decimal).\n *\n * For custom `maxLtv` / `liquidationThreshold` (e.g. e-mode liquidation threshold), call\n * {@link computeCarryLendingAllocationConfig} directly.\n */\n getLendingAllocationConfigFromPriceBands(\n params: CarryPriceBandPreset\n ): CarryLendingAllocationConfig {\n const pct = this.reservesManager.supplyReserve.config.liquidationThresholdPct;\n const liquidationThreshold = pct <= 1 ? pct : pct / 100;\n return computeCarryLendingAllocationConfig({\n ...params,\n maxLtv: this.reservesManager.maxLtv,\n liquidationThreshold,\n });\n }\n\n /**\n * Returns true when the current LTV utilization (valued at EMA prices) has\n * fallen far enough below the target that the position should be boosted.\n */\n async shouldIncreaseCarryPosition(): Promise<boolean> {\n const state = await this.getPositionState(\"ema\");\n if (!state) return false;\n\n const { supplyUsd, debtUsd } = state;\n if (supplyUsd <= 0) return false;\n\n const currentUtilBps = this.reservesManager.calcLtvUtilizationRateBps(supplyUsd, debtUsd);\n return (\n currentUtilBps <=\n this.lendingPosition.config.targetUtilizationRateBps -\n this.lendingPosition.config.maxDeviationBelowTargetUtilBps\n );\n }\n\n /**\n * Returns true when the current LTV utilization (valued at realtime prices) has\n * risen far enough above the target that the position should be unwound.\n */\n async shouldDecreaseCarryPosition(): Promise<boolean> {\n const state = await this.getPositionState(\"realtime\");\n if (!state) return false;\n\n const { supplyUsd, debtUsd } = state;\n const currentUtilBps = this.reservesManager.calcLtvUtilizationRateBps(supplyUsd, debtUsd);\n return (\n currentUtilBps >=\n this.lendingPosition.config.targetUtilizationRateBps +\n this.lendingPosition.config.maxDeviationAboveTargetUtilBps\n );\n }\n\n override async calcDebtChangeAmount(\n targetUtilizationRateBps: number = this.lendingPosition.config.targetUtilizationRateBps\n ): Promise<number> {\n return super.calcDebtChangeAmount(targetUtilizationRateBps);\n }\n\n override async calcPreWithdrawalTargetUtilizationRateBps(\n withdrawUiCollateralAmount: number,\n postWithdrawalTargetUtilizationRateBps: number = this.lendingPosition.config\n .targetUtilizationRateBps\n ): Promise<number> {\n return super.calcPreWithdrawalTargetUtilizationRateBps(\n withdrawUiCollateralAmount,\n postWithdrawalTargetUtilizationRateBps\n );\n }\n\n override async calcDebtChangeAmountForCollateralWithdrawal(\n withdrawUiCollateralAmount: number,\n postWithdrawalTargetUtilizationRateBps: number = this.lendingPosition.config\n .targetUtilizationRateBps\n ): Promise<number> {\n return super.calcDebtChangeAmountForCollateralWithdrawal(\n withdrawUiCollateralAmount,\n postWithdrawalTargetUtilizationRateBps\n );\n }\n\n override async getCollateralPriceTriggerBand(): Promise<CollateralPriceTriggerBand> {\n return super.getCollateralPriceTriggerBand(this.configTriggerBandBps());\n }\n\n override async getInspectMetrics(): Promise<LendingPositionInspectMetrics | null> {\n return super.getInspectMetrics(this.configTriggerBandBps());\n }\n\n private configTriggerBandBps(): {\n lowerTargetUtilizationRateBps: number;\n upperTargetUtilizationRateBps: number;\n } {\n const {\n targetUtilizationRateBps,\n maxDeviationBelowTargetUtilBps,\n maxDeviationAboveTargetUtilBps,\n } = this.lendingPosition.config;\n return {\n lowerTargetUtilizationRateBps: targetUtilizationRateBps - maxDeviationBelowTargetUtilBps,\n upperTargetUtilizationRateBps: targetUtilizationRateBps + maxDeviationAboveTargetUtilBps,\n };\n }\n}\n","export * from \"./carryAllocationConfig\";\nexport * from \"./lycLendingPositionManager\";\n","export * from \"./errors\";\nexport * from \"./utils\";\nexport * from \"./constants\";\nexport * from \"./client\";\nexport * from \"./services\";\nexport * from \"./models\";\nexport * from \"./types\";\nexport * from \"./metrics\";\nexport * from \"./decoders\";\nexport type { ResolvedDecreaseCarryCpiPlan } from \"./utils\";\n","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","/**\n * Program IDL in camelCase format in order to be used in JS/TS.\n *\n * Note that this is only a type helper and is not the actual IDL. The original\n * IDL can be found at `target/idl/long_yield_carry.json`.\n */\nexport type LongYieldCarry = {\n \"address\": \"7YPAKESPJ7zJAvBuk45ZVziu6tXGKoNzg3p9YpvrH6pX\",\n \"metadata\": {\n \"name\": \"longYieldCarry\",\n \"version\": \"0.1.0\",\n \"spec\": \"0.1.0\",\n \"description\": \"Created with Anchor\"\n },\n \"instructions\": [\n {\n \"name\": \"burnToken\",\n \"docs\": [\n \"Burn long-yield-carry tokens and redeem collateral.\"\n ],\n \"discriminator\": [\n 185,\n 165,\n 216,\n 246,\n 144,\n 31,\n 70,\n 74\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Pays SOL rent when async-path PDAs are created; must authorize lamport debits.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The yToken mint. Mutable because the burn CPI decrements total supply.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"userTokenAccount\",\n \"docs\": [\n \"User's yToken ATA — source of the burn. The user is the authority.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"tokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"userCollateralAccount\",\n \"docs\": [\n \"User's collateral ATA — destination of the redeemed collateral.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's collateral reserve — source of the collateral payout, and\",\n \"the destination for the collateral withdrawal in the liquidity path.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"request\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"requestTokenAccount\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"tokenProgram\",\n \"docs\": [\n \"Token program for yToken operations (Burn).\"\n ]\n },\n {\n \"name\": \"collateralTokenProgram\",\n \"docs\": [\n \"Token program for collateral operations (Transfer).\"\n ]\n },\n {\n \"name\": \"associatedTokenProgram\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"burnTokenParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"cancelAsyncBurn\",\n \"docs\": [\n \"Cancel a timed-out FIFO-head async burn request while its epoch is still open.\"\n ],\n \"discriminator\": [\n 66,\n 63,\n 112,\n 221,\n 71,\n 95,\n 126,\n 145\n ],\n \"accounts\": [\n {\n \"name\": \"user\",\n \"signer\": true\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Validated against the payer stored on the request at creation time.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true\n },\n {\n \"name\": \"request\",\n \"writable\": true\n },\n {\n \"name\": \"mint\"\n },\n {\n \"name\": \"userTokenAccount\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"user\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"tokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"requestTokenAccount\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"tokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"epochRentRecipient\",\n \"docs\": [\n \"Must match `redemption_epoch.header.payer`.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"tokenProgram\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"claimIncentives\",\n \"docs\": [\n \"Claim lending-platform farm incentives and deposit them into the\",\n \"token's carry position via the yielding bank.\"\n ],\n \"discriminator\": [\n 79,\n 126,\n 77,\n 51,\n 253,\n 163,\n 193,\n 248\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"expectedIncentiveMint\"\n },\n {\n \"name\": \"tokenIncentiveAta\",\n \"docs\": [\n \"Token PDA's ATA for the reward mint — receives rewards from the claim CPI.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"incentiveTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"expectedIncentiveMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"yieldingBank\",\n \"docs\": [\n \"Required only on the debt-mint branch. Self-pointer check happens\",\n \"inline at the start of `settle_debt_branch`.\"\n ],\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"yieldingBankIncentiveAta\",\n \"docs\": [\n \"Yielding bank's ATA for the reward mint — receives the transfer on the\",\n \"debt-mint branch.\"\n ],\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yieldingBank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"incentiveTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"expectedIncentiveMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"incentiveOracle\",\n \"docs\": [\n \"`incentive_oracle_type`, which validates feed identity. Required on\",\n \"the debt-mint and collateral-mint branches.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"feeWallet\",\n \"docs\": [\n \"Required on the fee-wallet branch.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"feeWalletIncentiveAta\",\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"feeWallet\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"incentiveTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"expectedIncentiveMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"incentiveTokenProgram\"\n },\n {\n \"name\": \"associatedTokenProgram\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"claimIncentivesParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"closeCpiPlan\",\n \"docs\": [\n \"Close an orphaned CPI plan PDA and return its rent to the manager.\",\n \"\",\n \"CPI plan accounts normally auto-close via `close = manager` when\",\n \"`rebalance_token` succeeds. This instruction reclaims rent from any\",\n \"plans that were left open due to a failed or interrupted transaction.\"\n ],\n \"discriminator\": [\n 47,\n 118,\n 163,\n 160,\n 199,\n 31,\n 63,\n 26\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"docs\": [\n \"Receives the reclaimed rent. Must be the original payer of this CPI plan.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"cpiPlan\",\n \"writable\": true\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"collectFees\",\n \"docs\": [\n \"Collect accrued protocol fees from a token.\"\n ],\n \"discriminator\": [\n 164,\n 152,\n 207,\n 99,\n 30,\n 186,\n 19,\n 182\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Must match either the token's `curator()` or the program-level `PROTOCOL_ADMIN`.\",\n \"If the signer is `PROTOCOL_ADMIN`, the protocol fee bucket and wallet are used\",\n \"(even when that key is also the curator). Otherwise, when the signer is the\",\n \"curator only, the curator bucket and curator fee wallet are used.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"writable\": true\n },\n {\n \"name\": \"feeWallet\",\n \"docs\": [\n \"Fee wallet that receives the minted yTokens. Must match the\",\n \"`curator_fee_wallet()` wallet when signed by the curator, or\",\n \"`protocol_fee_wallet()` when signed by PROTOCOL_ADMIN.\"\n ]\n },\n {\n \"name\": \"feeWalletTokenAccount\",\n \"docs\": [\n \"Fee wallet's yToken ATA — created on first collection, reused thereafter\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"feeWallet\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"tokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"tokenProgram\"\n },\n {\n \"name\": \"associatedTokenProgram\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"collectInterest\",\n \"docs\": [\n \"Realize accrued yield from a carry position.\"\n ],\n \"discriminator\": [\n 238,\n 101,\n 253,\n 86,\n 160,\n 25,\n 16,\n 134\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"collateralOracle\",\n \"docs\": [\n \"Collateral oracle account — refreshed before slippage validation so the\",\n \"collateral USD value is checked against a fresh price.\"\n ]\n },\n {\n \"name\": \"secondaryCollateralOracle\",\n \"docs\": [\n \"Optional secondary oracle account for composite oracle types (the SPL\",\n \"stake pool account for `PythSplStake` collateral); omit otherwise.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"redemptionOracle\",\n \"docs\": [\n \"Oracle account for the yielding bank's default redemption mint —\",\n \"refreshed at the top of the handler so share accounting and the phase 4\",\n \"slippage check all use a live price basis that matches what the SDK\",\n \"planner read when sizing the swap input.\"\n ]\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's collateral ATA — final destination for the swapped collateral\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"ybCollateralTokenAccount\",\n \"docs\": [\n \"Yielding bank's collateral ATA — receives the swap output before the\",\n \"handler transfers the delta into the token's collateral ATA.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yieldingBank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"curatorFeeWalletCollateralAccount\",\n \"docs\": [\n \"Curator fee wallet's collateral ATA — receives the curator share of the performance fee.\",\n \"Address is the ATA of `token.roles.curator_fee_wallet()` for this collateral mint.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"protocolFeeWalletCollateralAccount\",\n \"docs\": [\n \"Protocol fee wallet's collateral ATA — receives the protocol share of the performance fee.\",\n \"Address is the ATA of `TokenRoles::protocol_fee_wallet()` for this collateral mint.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"ybRedemptionTokenAccount\",\n \"docs\": [\n \"YB's ATA for the default redemption mint — snapshotted before and after\",\n \"swap CPIs to verify only this asset was sold.\",\n \"default_redemption_mint and the yielding bank PDA.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"collateralTokenProgram\"\n },\n {\n \"name\": \"associatedTokenProgram\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"refs\",\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"createCpiPlan\",\n \"docs\": [\n \"Create a temporary zero-copy CPI plan account for a later instruction.\"\n ],\n \"discriminator\": [\n 176,\n 0,\n 30,\n 192,\n 57,\n 208,\n 40,\n 114\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"cpiPlan\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 99,\n 112,\n 105,\n 32,\n 112,\n 108,\n 97,\n 110\n ]\n },\n {\n \"kind\": \"arg\",\n \"path\": \"params.unique_id\"\n },\n {\n \"kind\": \"arg\",\n \"path\": \"params.created_ts\"\n }\n ]\n }\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"createCpiPlanParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"createToken\",\n \"docs\": [\n \"Create a new token and initialize its configuration.\"\n ],\n \"discriminator\": [\n 84,\n 52,\n 204,\n 228,\n 24,\n 140,\n 234,\n 75\n ],\n \"accounts\": [\n {\n \"name\": \"curator\",\n \"docs\": [\n \"Curator that will own this token. Must be in `WHITELISTED_CURATORS`.\",\n \"Pays for account rent.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"adminRole\",\n \"docs\": [\n \"Admin multisig. `None` means \\\"use the feature-gated default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"managerRole\",\n \"docs\": [\n \"Manager ops wallet. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curatorFeeWallet\",\n \"docs\": [\n \"Curator fee wallet. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cbControllerRole\",\n \"docs\": [\n \"Circuit-breaker activator. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"yToken mint — must be pre-created with its authority set to the token PDA\",\n \"and freeze authority set to None. This allows the caller to set mint metadata\",\n \"(name, symbol, icon) before registering the token with the program.\"\n ]\n },\n {\n \"name\": \"collateralMint\",\n \"docs\": [\n \"The underlying collateral mint (e.g. wSOL)\"\n ]\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's account for holding unlent collateral reserves\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n },\n {\n \"name\": \"tokenProgram\",\n \"docs\": [\n \"Token program for the yToken mint\"\n ]\n },\n {\n \"name\": \"collateralTokenProgram\",\n \"docs\": [\n \"Token program for the collateral mint\"\n ]\n },\n {\n \"name\": \"associatedTokenProgram\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"createTokenParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"createTokenLendingPosition\",\n \"docs\": [\n \"Register a new lending position for a token.\"\n ],\n \"discriminator\": [\n 32,\n 13,\n 223,\n 159,\n 125,\n 144,\n 219,\n 148\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"lpPosition\",\n \"accounts\": [\n {\n \"name\": \"userAccount\",\n \"docs\": [\n \"The lending position's user/authority account.\"\n ]\n },\n {\n \"name\": \"collateralReserve\",\n \"docs\": [\n \"The lending position's collateral reserve/bank account.\"\n ]\n },\n {\n \"name\": \"debtOracle\",\n \"docs\": [\n \"Oracle for the lending position's debt asset.\"\n ]\n }\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"createTokenLendingPositionParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"createYieldingBank\",\n \"docs\": [\n \"Create a new yielding bank for a base mint.\"\n ],\n \"discriminator\": [\n 123,\n 125,\n 211,\n 195,\n 102,\n 102,\n 90,\n 7\n ],\n \"accounts\": [\n {\n \"name\": \"curator\",\n \"docs\": [\n \"Curator that will own this yielding bank. Must be in `WHITELISTED_CURATORS`.\",\n \"Pays for account rent.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"adminRole\",\n \"docs\": [\n \"Admin multisig. `None` means \\\"use the feature-gated default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"managerRole\",\n \"docs\": [\n \"Manager ops wallet. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cbControllerRole\",\n \"docs\": [\n \"Circuit-breaker activator. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n },\n {\n \"name\": \"baseMint\"\n },\n {\n \"name\": \"defaultRedemptionMint\",\n \"docs\": [\n \"The mint used as the default source when redeeming from the bank.\",\n \"Validated as a real SPL Token / Token-2022 mint by Anchor deserialization.\"\n ]\n },\n {\n \"name\": \"baseMintTokenAccount\",\n \"docs\": [\n \"Base mint ATA owned by the yielding bank PDA — created so refresh\",\n \"can always read the token balance for the base asset.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yieldingBank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"baseMintTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"baseMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"baseMintTokenProgram\"\n },\n {\n \"name\": \"associatedTokenProgram\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"systemProgram\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"createYieldingBankParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"createYieldingBankAllocation\",\n \"docs\": [\n \"Add a new asset holding or external position to a yielding bank.\"\n ],\n \"discriminator\": [\n 213,\n 191,\n 99,\n 159,\n 78,\n 2,\n 87,\n 126\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n },\n {\n \"name\": \"allocationMint\",\n \"docs\": [\n \"Mint for the new asset holding.\"\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"yieldingBankAllocationConfig\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"creditUnlentToRedemptionEpoch\",\n \"docs\": [\n \"Credit already-unlent collateral reserves to a redemption epoch.\"\n ],\n \"discriminator\": [\n 236,\n 123,\n 27,\n 93,\n 229,\n 169,\n 214,\n 129\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenProgram\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"decreaseCarryPosition\",\n \"docs\": [\n \"Reduce a carry position and return freed collateral.\"\n ],\n \"discriminator\": [\n 109,\n 115,\n 98,\n 62,\n 206,\n 179,\n 42,\n 145\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true,\n \"optional\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"decreaseCarryPositionParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"depositUnlentCollateral\",\n \"docs\": [\n \"Lend idle collateral from a token into a lending position.\"\n ],\n \"discriminator\": [\n 112,\n 210,\n 209,\n 249,\n 61,\n 231,\n 192,\n 207\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's collateral reserve — balance is checked before and\",\n \"after the deposit CPI to derive the actual deposited amount.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenProgram\"\n },\n {\n \"name\": \"lendingPositionUserAccount\",\n \"docs\": [\n \"The lending position's user/authority account on the lending protocol\",\n \"(e.g. Kamino obligation). Used to refresh the position after deposit.\"\n ]\n },\n {\n \"name\": \"lendingPositionCollateralReserve\",\n \"docs\": [\n \"The lending protocol's collateral reserve account. Used to convert\",\n \"cTokens to underlying liquidity during the post-deposit refresh.\"\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"ixRefs\",\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"lendingPositionIndex\",\n \"type\": \"u8\"\n }\n ]\n },\n {\n \"name\": \"increaseCarryPosition\",\n \"docs\": [\n \"Increase a carry position using borrowed funds.\"\n ],\n \"discriminator\": [\n 216,\n 191,\n 255,\n 166,\n 144,\n 169,\n 3,\n 187\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"docs\": [\n \"via `remaining_accounts`, so the role check is enforced at runtime in\",\n \"the handler rather than by an Anchor constraint here.\"\n ],\n \"signer\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"increaseCarryPositionParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"mintToken\",\n \"docs\": [\n \"Deposit collateral and mint long-yield-carry tokens.\"\n ],\n \"discriminator\": [\n 172,\n 137,\n 183,\n 14,\n 207,\n 110,\n 234,\n 56\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The yToken mint — authority is the token PDA\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"collateralMint\",\n \"docs\": [\n \"Collateral mint (for TransferChecked decimals validation)\"\n ]\n },\n {\n \"name\": \"userCollateralAccount\",\n \"docs\": [\n \"User's collateral ATA (source of deposit)\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"userTokenAccount\",\n \"docs\": [\n \"User's yToken ATA — must be created before calling this instruction\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"tokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's collateral reserve\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"tokenProgram\",\n \"docs\": [\n \"Token program for yToken operations (MintTo)\"\n ]\n },\n {\n \"name\": \"collateralTokenProgram\",\n \"docs\": [\n \"Token program for collateral operations (TransferChecked)\"\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"depositAmount\",\n \"type\": \"u64\"\n }\n ]\n },\n {\n \"name\": \"processAsyncBurn\",\n \"docs\": [\n \"Process the next FIFO async burn request in an epoch.\"\n ],\n \"discriminator\": [\n 95,\n 36,\n 6,\n 2,\n 122,\n 146,\n 3,\n 215\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Validated against the payer stored on the request at creation time.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true\n },\n {\n \"name\": \"request\",\n \"writable\": true\n },\n {\n \"name\": \"user\",\n \"docs\": [\n \"collateral is wrapped SOL; otherwise unused except for identity binding.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"writable\": true\n },\n {\n \"name\": \"requestTokenAccount\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"tokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"userCollateralAccount\",\n \"docs\": [\n \"User's collateral ATA — required when collateral is not wrapped SOL.\"\n ],\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"requestCollateralAccount\",\n \"docs\": [\n \"Request PDA's collateral ATA — required when collateral is wrapped SOL.\",\n \"The handler transfers WSOL here, then closes the account to unwrap into\",\n \"native SOL for `user`.\"\n ],\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"epochRentRecipient\",\n \"docs\": [\n \"marks fully processed epochs). Must match `header.payer`, or `manager`\",\n \"when `payer` is default (legacy epochs).\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"tokenProgram\"\n },\n {\n \"name\": \"collateralTokenProgram\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"rebalanceToken\",\n \"docs\": [\n \"Rebalance a token across its carry positions.\"\n ],\n \"discriminator\": [\n 152,\n 98,\n 123,\n 66,\n 134,\n 191,\n 199,\n 73\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"cpiPlan\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"rebalanceTokenParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"rebalanceYieldingBank\",\n \"docs\": [\n \"Rebalance a yielding bank across allocations and external liquidity.\"\n ],\n \"discriminator\": [\n 181,\n 53,\n 252,\n 136,\n 138,\n 104,\n 145,\n 137\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"ixRefs\",\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"recollateralizeLoss\",\n \"docs\": [\n \"Recollateralize a loss by withdrawing collateral, swapping to debt, and repaying.\"\n ],\n \"discriminator\": [\n 98,\n 11,\n 43,\n 3,\n 199,\n 227,\n 100,\n 112\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's collateral reserve — transit account for withdrawn collateral\",\n \"before it is swapped into the debt asset.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralOracle\",\n \"docs\": [\n \"Collateral oracle — refreshed to price the collateral decrease in USD\",\n \"for the slippage check against the debt decrease.\"\n ]\n },\n {\n \"name\": \"secondaryCollateralOracle\",\n \"docs\": [\n \"Optional secondary oracle account for composite oracle types (the SPL\",\n \"stake pool account for `PythSplStake` collateral); omit otherwise.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"lpPosition\",\n \"accounts\": [\n {\n \"name\": \"userAccount\",\n \"docs\": [\n \"The lending position's user/authority account.\"\n ]\n },\n {\n \"name\": \"collateralReserve\",\n \"docs\": [\n \"The lending position's collateral reserve/bank account.\"\n ]\n },\n {\n \"name\": \"debtOracle\",\n \"docs\": [\n \"Oracle for the lending position's debt asset.\"\n ]\n }\n ]\n },\n {\n \"name\": \"collateralTokenProgram\"\n },\n {\n \"name\": \"yieldingBank\",\n \"docs\": [\n \"Yielding bank to receive any excess debt tokens remaining after repay.\",\n \"Validated at runtime: base_mint must match the lending position's debt mint.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"debtMint\",\n \"docs\": [\n \"Debt mint for the lending position being recollateralized.\"\n ]\n },\n {\n \"name\": \"tokenLpDebtTa\",\n \"docs\": [\n \"Token PDA's ATA for the debt mint — receives swap output, source for repay and deposit.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debtTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debtMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"yieldingBankTa\",\n \"docs\": [\n \"Yielding bank's ATA for the debt mint — destination for excess debt token deposit.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yieldingBank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debtTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debtMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"debtTokenProgram\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"recollateralizeLossParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"refreshTokenState\",\n \"docs\": [\n \"Refresh token pricing and lending-position state.\"\n ],\n \"discriminator\": [\n 229,\n 167,\n 209,\n 155,\n 223,\n 252,\n 150,\n 188\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"collateralOracle\",\n \"docs\": [\n \"Collateral oracle account — validated against the registered oracle\",\n \"via the OraclePriceFeed trait's refresh_price method.\"\n ]\n },\n {\n \"name\": \"secondaryCollateralOracle\",\n \"docs\": [\n \"Optional secondary oracle account, required only for composite oracle\",\n \"types. For `PythSplStake` collateral this is the SPL stake pool account;\",\n \"omit for single-account oracle types.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"docs\": [\n \"Token PDA's collateral reserve account (read actual on-chain balance)\"\n ],\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenProgram\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"refreshTokenStateParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"refreshYieldingBank\",\n \"docs\": [\n \"Refresh yielding-bank asset balances, prices, and share accounting.\"\n ],\n \"discriminator\": [\n 234,\n 183,\n 180,\n 72,\n 113,\n 250,\n 213,\n 76\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"resetTokenBurnRateLimit\",\n \"docs\": [\n \"Reset the burn rate limit counter on a token.\"\n ],\n \"discriminator\": [\n 152,\n 222,\n 104,\n 180,\n 163,\n 231,\n 152,\n 77\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"setRedemptionEpochStatus\",\n \"docs\": [\n \"Advance a redemption epoch through funding and processing states.\"\n ],\n \"discriminator\": [\n 143,\n 149,\n 239,\n 71,\n 206,\n 151,\n 223,\n 200\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\"\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true\n },\n {\n \"name\": \"epochRentRecipient\",\n \"docs\": [\n \"Must match `header.payer`, or `manager` when `payer` is default (legacy epochs).\"\n ],\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"setRedemptionEpochStatusParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"setTokenCircuitBreaker\",\n \"docs\": [\n \"Enable or disable the token circuit breaker.\",\n \"\",\n \"Activation: token's `cb_controller` or `admin`.\",\n \"Deactivation: token's `admin` only, time-gated.\"\n ],\n \"discriminator\": [\n 123,\n 100,\n 170,\n 97,\n 214,\n 192,\n 245,\n 151\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Activation: `TokenRoles::cb_controller()` or `TokenRoles::admin()`.\",\n \"Deactivation: admin only.\"\n ],\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"active\",\n \"type\": \"bool\"\n }\n ]\n },\n {\n \"name\": \"setYieldingBankCircuitBreaker\",\n \"docs\": [\n \"Enable or disable the yielding-bank circuit breaker.\",\n \"\",\n \"Activation: bank's `cb_controller` or `admin`.\",\n \"Deactivation: bank's `admin` only, time-gated.\"\n ],\n \"discriminator\": [\n 25,\n 188,\n 1,\n 254,\n 63,\n 110,\n 168,\n 255\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Activation: `YieldingBankRoles::cb_controller()` or `YieldingBankRoles::admin()`.\",\n \"Deactivation: admin only.\"\n ],\n \"signer\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"active\",\n \"type\": \"bool\"\n }\n ]\n },\n {\n \"name\": \"topUpUnlentReserves\",\n \"docs\": [\n \"Withdraw freed lending collateral into unlent reserves.\"\n ],\n \"discriminator\": [\n 249,\n 228,\n 192,\n 151,\n 48,\n 54,\n 74,\n 179\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemptionEpoch\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"collateralMint\"\n },\n {\n \"name\": \"collateralTokenAccount\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralTokenProgram\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateralMint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateralTokenProgram\"\n },\n {\n \"name\": \"lendingPositionUserAccount\"\n },\n {\n \"name\": \"lendingPositionCollateralReserve\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"topUpUnlentReservesParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"updateLendingPositionConfig\",\n \"docs\": [\n \"Update configuration for an existing lending position.\"\n ],\n \"discriminator\": [\n 164,\n 56,\n 56,\n 248,\n 51,\n 167,\n 213,\n 96\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"updateLendingPositionConfigParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"updateTokenConfiguration\",\n \"docs\": [\n \"Update token-level fee parameters and optionally the burn rate limit.\"\n ],\n \"discriminator\": [\n 115,\n 111,\n 91,\n 203,\n 143,\n 224,\n 71,\n 136\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"docs\": [\n \"Token admin for full configuration updates, manager for\",\n \"`fee_drip_max_apy_bps` only, or curator for curator-fee-wallet updates.\"\n ],\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"managerRole\",\n \"docs\": [\n \"Optional new manager. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curatorFeeWallet\",\n \"docs\": [\n \"Optional new curator fee wallet. `None` means \\\"no change\\\".\",\n \"Rotatable by the token admin or the token curator.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cbControllerRole\",\n \"docs\": [\n \"Optional new circuit-breaker activator. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curatorRole\",\n \"docs\": [\n \"Optional new curator. Must be in `WHITELISTED_CURATORS`.\",\n \"`None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"adminRole\",\n \"docs\": [\n \"Optional new admin. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"updateTokenConfigurationParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"updateTokenMetadata\",\n \"docs\": [\n \"Update on-chain metadata for a token's mint via Metaplex Token Metadata CPI.\"\n ],\n \"discriminator\": [\n 243,\n 6,\n 8,\n 23,\n 126,\n 181,\n 251,\n 158\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"signer\": true\n },\n {\n \"name\": \"token\"\n },\n {\n \"name\": \"mint\"\n }\n ],\n \"args\": [\n {\n \"name\": \"ixRefs\",\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"updateYieldingBankConfig\",\n \"docs\": [\n \"Update yielding-bank configuration parameters.\"\n ],\n \"discriminator\": [\n 236,\n 3,\n 226,\n 53,\n 30,\n 160,\n 216,\n 24\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"signer\": true\n },\n {\n \"name\": \"yieldingBank\",\n \"writable\": true\n },\n {\n \"name\": \"defaultRedemptionMint\",\n \"docs\": [\n \"New default redemption mint.\"\n ]\n },\n {\n \"name\": \"managerRole\",\n \"docs\": [\n \"Optional new manager. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cbControllerRole\",\n \"docs\": [\n \"Optional new circuit-breaker activator. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curatorRole\",\n \"docs\": [\n \"Optional new curator. Must be in `WHITELISTED_CURATORS`.\",\n \"`None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"adminRole\",\n \"docs\": [\n \"Optional new admin. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"updateYieldingBankConfigParams\"\n }\n }\n }\n ]\n }\n ],\n \"accounts\": [\n {\n \"name\": \"asyncBurnRequest\",\n \"discriminator\": [\n 211,\n 147,\n 62,\n 108,\n 20,\n 247,\n 245,\n 141\n ]\n },\n {\n \"name\": \"cpiPlanAccount\",\n \"discriminator\": [\n 23,\n 23,\n 187,\n 18,\n 208,\n 103,\n 156,\n 246\n ]\n },\n {\n \"name\": \"redemptionEpoch\",\n \"discriminator\": [\n 84,\n 63,\n 161,\n 230,\n 59,\n 183,\n 69,\n 214\n ]\n },\n {\n \"name\": \"token\",\n \"discriminator\": [\n 131,\n 254,\n 39,\n 144,\n 4,\n 179,\n 134,\n 127\n ]\n },\n {\n \"name\": \"yieldingBank\",\n \"discriminator\": [\n 236,\n 126,\n 167,\n 207,\n 44,\n 134,\n 113,\n 92\n ]\n }\n ],\n \"errors\": [\n {\n \"code\": 8000,\n \"name\": \"unauthorized\",\n \"msg\": \"Signer is not authorized\"\n },\n {\n \"code\": 8001,\n \"name\": \"invalidFeeBps\",\n \"msg\": \"Fee basis points exceed maximum\"\n },\n {\n \"code\": 8002,\n \"name\": \"unsupportedInterestDistribution\",\n \"msg\": \"Interest distribution mode is not yet supported\"\n },\n {\n \"code\": 8003,\n \"name\": \"invalidMintAuthority\",\n \"msg\": \"Mint authority must be the token PDA\"\n },\n {\n \"code\": 8004,\n \"name\": \"decimalsMismatch\",\n \"msg\": \"yToken mint decimals must equal collateral mint decimals\"\n },\n {\n \"code\": 8005,\n \"name\": \"missingYieldingBank\",\n \"msg\": \"Missing yielding bank account in remaining_accounts for active carry position\"\n },\n {\n \"code\": 8006,\n \"name\": \"invalidYieldingBank\",\n \"msg\": \"Yielding bank account does not match expected PDA for carry position\"\n },\n {\n \"code\": 8007,\n \"name\": \"noAvailableSlot\",\n \"msg\": \"No available slot to register a new holding or position\"\n },\n {\n \"code\": 8008,\n \"name\": \"duplicateAllocationMint\",\n \"msg\": \"Active asset holding already exists for the provided mint\"\n },\n {\n \"code\": 8009,\n \"name\": \"stalePrice\",\n \"msg\": \"Token price is stale — call refresh_token_state before mint/burn\"\n },\n {\n \"code\": 8010,\n \"name\": \"invalidCollateralAccount\",\n \"msg\": \"Collateral token account mint does not match the token's registered collateral mint\"\n },\n {\n \"code\": 8011,\n \"name\": \"invalidTokenAccount\",\n \"msg\": \"Token account address does not match the expected ATA\"\n },\n {\n \"code\": 8012,\n \"name\": \"freezeAuthoritySet\",\n \"msg\": \"Mint freeze authority must be None\"\n },\n {\n \"code\": 8013,\n \"name\": \"zeroDeposit\",\n \"msg\": \"Deposit amount must be greater than zero\"\n },\n {\n \"code\": 8014,\n \"name\": \"depositLimitExceeded\",\n \"msg\": \"Deposit would exceed the token's configured collateral deposit limit\"\n },\n {\n \"code\": 8015,\n \"name\": \"depositLimitBelowCurrentCollateral\",\n \"msg\": \"Deposit limit cannot be set below current total collateral backing\"\n },\n {\n \"code\": 8016,\n \"name\": \"zeroBurnAmount\",\n \"msg\": \"Burn amount must be greater than zero\"\n },\n {\n \"code\": 8017,\n \"name\": \"zeroCollateral\",\n \"msg\": \"Burn amount is too small — collateral payout rounds to zero\"\n },\n {\n \"code\": 8018,\n \"name\": \"zeroPrice\",\n \"msg\": \"Token price is zero — minting is not possible\"\n },\n {\n \"code\": 8019,\n \"name\": \"utilizationRateExceedsTarget\",\n \"msg\": \"Lending position utilization rate exceeds its target\"\n },\n {\n \"code\": 8020,\n \"name\": \"invalidUtilizationRateCondition\",\n \"msg\": \"Unable to perform carry position update\"\n },\n {\n \"code\": 8021,\n \"name\": \"invalidLendingPosition\",\n \"msg\": \"Lending position index is out of range or inactive\"\n },\n {\n \"code\": 8022,\n \"name\": \"invalidLendingPositionConfig\",\n \"msg\": \"Lending position configuration is invalid\"\n },\n {\n \"code\": 8023,\n \"name\": \"invalidLendingPositionAccount\",\n \"msg\": \"Lending position user account does not match expected\"\n },\n {\n \"code\": 8024,\n \"name\": \"invalidBorrowCpiCount\",\n \"msg\": \"Borrow CPIs must contain exactly one borrow instruction\"\n },\n {\n \"code\": 8025,\n \"name\": \"invalidCpiTypes\",\n \"msg\": \"CPI types do not match the required category sequence\"\n },\n {\n \"code\": 8026,\n \"name\": \"missingDebtOracle\",\n \"msg\": \"Missing debt oracle account in remaining_accounts for active lending position\"\n },\n {\n \"code\": 8027,\n \"name\": \"insufficientUnlentCollateral\",\n \"msg\": \"Insufficient unlent collateral for the requested amount\"\n },\n {\n \"code\": 8028,\n \"name\": \"cpiProgramPlatformMismatch\",\n \"msg\": \"CPI program does not match the lending position's configured platform\"\n },\n {\n \"code\": 8029,\n \"name\": \"carryPositionSlippage\",\n \"msg\": \"Carry position TVL slippage exceeds allowed threshold\"\n },\n {\n \"code\": 8030,\n \"name\": \"noFeesToCollect\",\n \"msg\": \"No pending protocol fees to collect\"\n },\n {\n \"code\": 8031,\n \"name\": \"zeroRepay\",\n \"msg\": \"Repay amount must be greater than zero\"\n },\n {\n \"code\": 8032,\n \"name\": \"missingRepayAmount\",\n \"msg\": \"Either repay_amount or yb_ix_refs must be provided\"\n },\n {\n \"code\": 8033,\n \"name\": \"repayAmountMismatch\",\n \"msg\": \"Actual repay amount does not match the expected repay amount\"\n },\n {\n \"code\": 8034,\n \"name\": \"rebalanceAmountMismatch\",\n \"msg\": \"Actual rebalance amount does not match the expected rebalance amount\"\n },\n {\n \"code\": 8035,\n \"name\": \"rebalanceFlashMintsMatch\",\n \"msg\": \"Flash-loan-wrapped rebalance requires distinct source and destination debt mints\"\n },\n {\n \"code\": 8036,\n \"name\": \"rebalanceFlashRepayUnderfunded\",\n \"msg\": \"Post-swap source-debt balance is insufficient to fund the flash repay\"\n },\n {\n \"code\": 8037,\n \"name\": \"rebalanceFlashFeeTooHigh\",\n \"msg\": \"Flash-loan fee exceeds the maximum allowed (5 bps of flash-borrow principal)\"\n },\n {\n \"code\": 8038,\n \"name\": \"zeroBorrowAfterRebalance\",\n \"msg\": \"Destination lending position has zero debt after rebalance borrow\"\n },\n {\n \"code\": 8039,\n \"name\": \"balanceChangeMismatch\",\n \"msg\": \"Token account balance change does not match the lending position state change\"\n },\n {\n \"code\": 8040,\n \"name\": \"nonRedemptionMintDrained\",\n \"msg\": \"Swap drained a non-redemption-mint asset holding\"\n },\n {\n \"code\": 8041,\n \"name\": \"invalidSourceAssetHoldingMint\",\n \"msg\": \"Source asset holding mint cannot match the lending position debt mint\"\n },\n {\n \"code\": 8042,\n \"name\": \"missingRemainingAccount\",\n \"msg\": \"Required account missing from remaining_accounts\"\n },\n {\n \"code\": 8043,\n \"name\": \"duplicateAccount\",\n \"msg\": \"Duplicate account provided\"\n },\n {\n \"code\": 8044,\n \"name\": \"externalLiquidityTvlMismatch\",\n \"msg\": \"Asset-holding TVL losses were not matched by offsetting TVL increases\"\n },\n {\n \"code\": 8045,\n \"name\": \"invalidDefaultRedemptionMint\",\n \"msg\": \"Default redemption mint must match an existing yielding-bank asset holding\"\n },\n {\n \"code\": 8046,\n \"name\": \"insufficientCarryShares\",\n \"msg\": \"Cannot burn more shares than the carry position holds\"\n },\n {\n \"code\": 8047,\n \"name\": \"collectInterestInsolvency\",\n \"msg\": \"Collecting interest would leave carry position unable to cover debt\"\n },\n {\n \"code\": 8048,\n \"name\": \"carryPositionNotFound\",\n \"msg\": \"No carry position found for the given yielding bank\"\n },\n {\n \"code\": 8049,\n \"name\": \"invalidMintSupply\",\n \"msg\": \"yToken mint must have zero supply at creation\"\n },\n {\n \"code\": 8050,\n \"name\": \"unsupportedYieldingBankMint\",\n \"msg\": \"Mint is not in the supported yielding bank mints list\"\n },\n {\n \"code\": 8051,\n \"name\": \"recollateralizeLossNotNeeded\",\n \"msg\": \"Recollateralization not needed — debt does not exceed carry\"\n },\n {\n \"code\": 8052,\n \"name\": \"recollateralizeLossInsufficient\",\n \"msg\": \"Recollateralization incomplete — carry assets do not cover debt after instruction\"\n },\n {\n \"code\": 8053,\n \"name\": \"recollateralizeLossOvershot\",\n \"msg\": \"Recollateralization overshot — carry exceeds debt by more than the allowed threshold\"\n },\n {\n \"code\": 8054,\n \"name\": \"recollateralizeLossSlippage\",\n \"msg\": \"Recollateralization slippage — collateral and debt USD changes diverge beyond tolerance\"\n },\n {\n \"code\": 8055,\n \"name\": \"recollateralizeLossNoChange\",\n \"msg\": \"Recollateralization failed — no change in collateral or debt on the lending position\"\n },\n {\n \"code\": 8056,\n \"name\": \"invalidTvlBiasBps\",\n \"msg\": \"Deprecated stub: InvalidTvlBiasBps — retained only for Anchor error discriminant compatibility (TVL bias removed)\"\n },\n {\n \"code\": 8057,\n \"name\": \"claimIncentivesNoChange\",\n \"msg\": \"Claimed incentives did not increase the expected token account or produce collateral\"\n },\n {\n \"code\": 8058,\n \"name\": \"unsupportedIncentivePlatform\",\n \"msg\": \"Only Kamino lending positions currently support incentive claims\"\n },\n {\n \"code\": 8059,\n \"name\": \"invalidBurnAdjacentNextInstruction\",\n \"msg\": \"Burn-adjacent decrease_carry_position requires the immediate next instruction to be a matching burn_token\"\n },\n {\n \"code\": 8060,\n \"name\": \"missingBurnAdjacentWithdrawParams\",\n \"msg\": \"Burn-adjacent decrease_carry_position requires burn_token withdraw params when unlent collateral is insufficient\"\n },\n {\n \"code\": 8061,\n \"name\": \"curatorMismatch\",\n \"msg\": \"Yielding bank curator does not match token curator\"\n },\n {\n \"code\": 8062,\n \"name\": \"curatorNotWhitelisted\",\n \"msg\": \"Signer is not in the whitelisted curators list\"\n },\n {\n \"code\": 8063,\n \"name\": \"roleAccountNotEmpty\",\n \"msg\": \"Role account is not empty\"\n },\n {\n \"code\": 8064,\n \"name\": \"roleAccountInvalidOwner\",\n \"msg\": \"Role account owner must be the System Program\"\n },\n {\n \"code\": 8065,\n \"name\": \"duplicateFeeWallet\",\n \"msg\": \"Curator and protocol fee wallets must be distinct\"\n },\n {\n \"code\": 8066,\n \"name\": \"invalidLendingPositionState\",\n \"msg\": \"Newly created lending position must have zero collateral and debt\"\n },\n {\n \"code\": 8067,\n \"name\": \"invalidIncentiveOracle\",\n \"msg\": \"Incentive mint, oracle, or oracle type does not match the lending position's debt config\"\n },\n {\n \"code\": 8068,\n \"name\": \"invalidCollateralIncentiveOracle\",\n \"msg\": \"Incentive oracle / oracle type does not match the token's collateral config\"\n },\n {\n \"code\": 8069,\n \"name\": \"missingYieldingBankAccounts\",\n \"msg\": \"Yielding-bank accounts (yielding_bank, yielding_bank_incentive_ata, incentive_oracle) are required when the incentive mint matches the lending position's debt mint\"\n },\n {\n \"code\": 8070,\n \"name\": \"missingCollateralIncentiveOracle\",\n \"msg\": \"incentive_oracle is required when the incentive mint matches the token's collateral mint\"\n },\n {\n \"code\": 8071,\n \"name\": \"missingFeeWalletAccounts\",\n \"msg\": \"fee_wallet and fee_wallet_incentive_ata are required when the incentive mint is neither the debt mint nor the collateral mint\"\n },\n {\n \"code\": 8072,\n \"name\": \"invalidFeeWallet\",\n \"msg\": \"fee_wallet does not match the token's curator fee wallet\"\n },\n {\n \"code\": 8073,\n \"name\": \"mintAllNativeSol\",\n \"msg\": \"Cannot mint all when collateral is native SOL — user needs SOL for transaction fees and rent\"\n },\n {\n \"code\": 8074,\n \"name\": \"untrackedDebtResidue\",\n \"msg\": \"Untracked debt tokens remain on the yielding bank after repay — register a debt-mint holding or ensure the swap output equals repay amount\"\n },\n {\n \"code\": 8075,\n \"name\": \"dcpSwapOverOutput\",\n \"msg\": \"DCP swap output exceeds repay amount tolerance\"\n },\n {\n \"code\": 8076,\n \"name\": \"invalidRedemptionEpochStatus\",\n \"msg\": \"Redemption epoch is not in the required status\"\n },\n {\n \"code\": 8077,\n \"name\": \"asyncBurnRequestOutOfOrder\",\n \"msg\": \"Async burn request is not next in FIFO order\"\n },\n {\n \"code\": 8078,\n \"name\": \"asyncBurnRequestAlreadyProcessed\",\n \"msg\": \"Async burn request has already been processed\"\n },\n {\n \"code\": 8079,\n \"name\": \"insufficientRedemptionEpochFunding\",\n \"msg\": \"Async redemption epoch has insufficient funded collateral\"\n },\n {\n \"code\": 8080,\n \"name\": \"asyncBurnRequestAlreadyExists\",\n \"msg\": \"Async burn request already exists\"\n },\n {\n \"code\": 8081,\n \"name\": \"redemptionEpochAlreadyFunded\",\n \"msg\": \"Redemption epoch is already fully funded\"\n },\n {\n \"code\": 8082,\n \"name\": \"redemptionEpochNotFullyFunded\",\n \"msg\": \"Redemption epoch must be fully funded before transitioning to Processing\"\n },\n {\n \"code\": 8083,\n \"name\": \"invalidCpiPlanAccount\",\n \"msg\": \"CPI plan account does not match the expected PDA\"\n },\n {\n \"code\": 8084,\n \"name\": \"unsupportedDebtMint\",\n \"msg\": \"New debt mint is not in the list of supported YB mints\"\n },\n {\n \"code\": 8085,\n \"name\": \"missingUsdcHolding\",\n \"msg\": \"Yielding bank holds USD* but has no USDC holding to convert its price basis\"\n },\n {\n \"code\": 8086,\n \"name\": \"asyncBurnRequestNotCancellable\",\n \"msg\": \"Async burn request is not cancellable yet\"\n },\n {\n \"code\": 8087,\n \"name\": \"feeDripConfigRequired\",\n \"msg\": \"Reserved fee-drip configuration error\"\n },\n {\n \"code\": 8088,\n \"name\": \"rebalanceRateLimited\",\n \"msg\": \"Lending position was rebalanced within the rate-limit window — try again later\"\n }\n ],\n \"types\": [\n {\n \"name\": \"amountRateLimit\",\n \"docs\": [\n \"Rolling amount rate limit using a tumbling time window.\",\n \"\",\n \"Tracks cumulative usage within a fixed-length window. When the window\",\n \"expires, the counter resets automatically on the next operation.\",\n \"\",\n \"The rate limit is only enforced when both `max_amount > 0` and\",\n \"`window_duration_secs > 0`. The default (all zeros) means no rate limiting.\"\n ],\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"maxAmount\",\n \"docs\": [\n \"Maximum cumulative amount allowed within one window.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"windowDurationSecs\",\n \"docs\": [\n \"Length of the rate-limit window in seconds.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"amountUsed\",\n \"docs\": [\n \"Cumulative amount consumed in the current window.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"windowStartTs\",\n \"docs\": [\n \"Unix timestamp when the current window started.\"\n ],\n \"type\": \"u64\"\n }\n ]\n }\n },\n {\n \"name\": \"assetAllocationConfig\",\n \"docs\": [\n \"Configuration for the collateral or debt side of an external lending position.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"tokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"assetConfig\",\n \"docs\": [\n \"Configuration for adding a new yield-bearing asset holding.\",\n \"\",\n \"Fields derivable from the mint account (`mint`, `decimals`, `token_program`)\",\n \"are provided separately — the mint is a named account on the instruction,\",\n \"and the handler reads decimals/token_program from it.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"oracle\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"oracleType\",\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n },\n {\n \"name\": \"externalLiquidity\",\n \"type\": {\n \"defined\": {\n \"name\": \"externalLiquidityType\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"assetHolding\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint of the asset (e.g. base stablecoin, LST, or receipt token)\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"amount\",\n \"docs\": [\n \"Amount of the asset held (in native mint units)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"price\",\n \"docs\": [\n \"Current USD price of the asset\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"oracle\",\n \"docs\": [\n \"Oracle account for price resolution\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"docs\": [\n \"Decimal precision of the mint\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"tokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n },\n {\n \"name\": \"oracleType\",\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n },\n {\n \"name\": \"externalLiquidity\",\n \"docs\": [\n \"In some cases, an asset will not have all funds sitting in the PDA's token account.\",\n \"We track the source type and read the accounts accordingly to know the full amount\",\n \"owed to the yielding bank onchain.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"externalLiquidityType\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 4\n ]\n }\n },\n {\n \"name\": \"timeCreated\",\n \"docs\": [\n \"Unix timestamp when this holding was registered.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 5\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"assetHoldingData\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"amount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"price\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"tokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 6\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"asyncBurnRequest\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"header\",\n \"type\": {\n \"defined\": {\n \"name\": \"asyncBurnRequestHeader\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"asyncBurnRequestAccounting\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"asyncBurnRequestAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"yTokenAmount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"grossCollateralClaim\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"protocolFee\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"curatorFee\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"asyncBurnRequestHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"token\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"epoch\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"user\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Account that funded the request PDA rent. Receives the rent back when\",\n \"the request is closed during `process_async_burn`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"epochId\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"sequence\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"padding0\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n },\n {\n \"name\": \"requestTs\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 4\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"burnRateLimitUpdateParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"maxAmount\",\n \"docs\": [\n \"Maximum cumulative burn amount allowed within one window (0 to disable).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"windowDurationSecs\",\n \"docs\": [\n \"Length of the rate-limit window in seconds (0 to disable).\"\n ],\n \"type\": \"u64\"\n }\n ]\n }\n },\n {\n \"name\": \"burnTokenParams\",\n \"docs\": [\n \"Instruction params for burning yTokens.\",\n \"\",\n \"Use [`BurnTokenParams::Sync`] when unlent collateral is sufficient without\",\n \"allocating redemption epoch PDAs. Use [`BurnTokenParams::Async`] when async\",\n \"fallback PDAs are passed — required when reserves may be insufficient at\",\n \"execution time.\"\n ],\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"sync\",\n \"fields\": [\n {\n \"name\": \"burnAmount\",\n \"type\": \"u64\"\n }\n ]\n },\n {\n \"name\": \"async\",\n \"fields\": [\n {\n \"name\": \"burnAmount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"epochId\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"requestSequence\",\n \"type\": \"u64\"\n }\n ]\n }\n ]\n }\n },\n {\n \"name\": \"claimIncentivesParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisiteCpis\",\n \"docs\": [\n \"Optional prerequisite CPIs (e.g. Kamino reserve / obligation refresh)\",\n \"executed before the claim CPI.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"tokenIxRefs\",\n \"docs\": [\n \"CPI refs for the single claim-incentives action.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"lendingPositionIndex\",\n \"docs\": [\n \"Lending position index whose farm rewards are being claimed. Used for\",\n \"platform routing and timelock enforcement.\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"incentiveOracleType\",\n \"docs\": [\n \"Oracle type for pricing the claimed reward when the incentive mint\",\n \"matches the lending position's debt mint or the token's collateral\",\n \"mint. Ignored on the fee-wallet branch.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"collateralConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint of the underlying collateral asset backing this token\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"price\",\n \"docs\": [\n \"Current USD price of the collateral asset (from oracle)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"unlentAmount\",\n \"docs\": [\n \"Amount of collateral held in reserve, not deployed to any lending position\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"oracle\",\n \"docs\": [\n \"Oracle account used to price the collateral asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"lastRefreshedTs\",\n \"docs\": [\n \"Timestamp of the last oracle price refresh\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"tokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n },\n {\n \"name\": \"oracleType\",\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 5\n ]\n }\n },\n {\n \"name\": \"secondaryOracle\",\n \"docs\": [\n \"Optional secondary oracle account. Used by composite oracle types that\",\n \"need a second input — e.g. `PythSplStake` stores the SPL stake pool\",\n \"account here while `oracle` holds the Pyth SOL/USD feed. Left as\",\n \"`Pubkey::default()` for single-account oracle types.\"\n ],\n \"type\": \"pubkey\"\n }\n ]\n }\n },\n {\n \"name\": \"cpiMapping\",\n \"docs\": [\n \"Mapping for extracting accounts from `remaining_accounts` across multiple CPIs.\",\n \"\",\n \"This struct enables efficient multi-CPI transactions by:\",\n \"1. Deduplicating all accounts into a single `remaining_accounts` pool\",\n \"2. Storing all indices for all CPIs in a single flattened vector\",\n \"3. Using `lengths` to slice the indices for each individual CPI\",\n \"\",\n \"# Example\",\n \"\",\n \"For 2 CPIs where CPI 0 needs 10 accounts and CPI 1 needs 8 accounts:\",\n \"```text\",\n \"indices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 5, 7, 10, 11, 12, 13, 14]\",\n \"lengths: [10, 8]\",\n \"\",\n \"CPI 0 uses indices[0..10]\",\n \"CPI 1 uses indices[10..18]\",\n \"```\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"indices\",\n \"docs\": [\n \"All indices into `remaining_accounts`, flattened across all CPIs.\"\n ],\n \"type\": \"bytes\"\n },\n {\n \"name\": \"lengths\",\n \"docs\": [\n \"Number of accounts for each CPI call.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"cpiPlan\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"header\",\n \"type\": {\n \"defined\": {\n \"name\": \"cpiPlanHeader\"\n }\n }\n },\n {\n \"name\": \"refCount\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"padding\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n },\n {\n \"name\": \"refs\",\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"packedInstructionRefHeader\"\n }\n },\n 10\n ]\n }\n },\n {\n \"name\": \"cpiLengths\",\n \"type\": {\n \"array\": [\n \"u8\",\n 64\n ]\n }\n },\n {\n \"name\": \"cpiTypes\",\n \"type\": {\n \"array\": [\n \"u8\",\n 64\n ]\n }\n },\n {\n \"name\": \"accountIndices\",\n \"type\": {\n \"array\": [\n {\n \"array\": [\n \"u8\",\n 1024\n ]\n },\n 4\n ]\n }\n },\n {\n \"name\": \"args\",\n \"type\": {\n \"array\": [\n {\n \"array\": [\n \"u8\",\n 1024\n ]\n },\n 4\n ]\n }\n },\n {\n \"name\": \"tracked\",\n \"type\": {\n \"array\": [\n \"u8\",\n 128\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"cpiPlanAccount\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"packed\",\n \"type\": {\n \"defined\": {\n \"name\": \"cpiPlan\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"cpiPlanHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"uniqueId\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"payer\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"createdTs\",\n \"type\": \"i64\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"padding\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"cpiRefs\",\n \"docs\": [\n \"References for CPI invocations.\",\n \"\",\n \"This structure contains all the information needed to invoke CPIs\",\n \"from a pool of deduplicated accounts.\",\n \"\",\n \"# Fields\",\n \"\",\n \"- `accounts`: Mapping of account indices per CPI slot (first = program)\",\n \"- `types`: Index into `CPI_REGISTRY` for each CPI slot\",\n \"- `args`: Packed CPI args buffer (u16-length-prefixed per slot)\",\n \"\",\n \"# Convention\",\n \"\",\n \"The **first account** in each CPI slot's account list is the **program**.\",\n \"This is validated during invocation against the registry entry.\",\n \"\",\n \"# Example\",\n \"\",\n \"```text\",\n \"CpiRefs {\",\n \"accounts: CpiMapping {\",\n \"indices: [5, 0, 1, 2, 3, 4, 8, 6, 7, 0, 1],\",\n \"lengths: [6, 5],\",\n \"},\",\n \"types: [0, 2], // CPI 0 = PERENA_MINT, CPI 1 = JUPITER_SWAP\",\n \"args: [16, 0, ..16 bytes.., 0xFF, 0xFF],\",\n \"}\",\n \"```\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"accounts\",\n \"docs\": [\n \"Account indices per CPI (first account of each CPI = program).\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"cpiMapping\"\n }\n }\n },\n {\n \"name\": \"types\",\n \"docs\": [\n \"Index into `CPI_REGISTRY` for each CPI slot.\"\n ],\n \"type\": \"bytes\"\n },\n {\n \"name\": \"args\",\n \"docs\": [\n \"Packed CPI args — `[u16 LE length][data]` per slot.\",\n \"0xFFFF = skip (program-provided), 0 = no-args, N = N bytes of client data.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"createCpiPlanParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"uniqueId\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"createdTs\",\n \"type\": \"i64\"\n },\n {\n \"name\": \"refs\",\n \"type\": {\n \"vec\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"createTokenLendingPositionParams\",\n \"docs\": [\n \"Parameters for initializing a new lending position on a Token.\",\n \"\",\n \"Account-backed values (`protocol_user_acc`, `collateral_reserve`,\",\n \"`debt_oracle`) are read from the `lp_position` composite on the `Accounts`\",\n \"struct rather than duplicated in this params struct.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lendingPlatform\",\n \"docs\": [\n \"Which lending protocol (e.g. Kamino, Marginfi)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"lendingPlatform\"\n }\n }\n },\n {\n \"name\": \"pool\",\n \"docs\": [\n \"The lending protocol's pool/group account\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debtReserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the debt asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"targetUtilizationRateBps\",\n \"docs\": [\n \"Target LTV utilization rate in basis points (relative to max LTV)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"maxDeviationAboveTargetUtilBps\",\n \"docs\": [\n \"Max bps the utilization rate can exceed target before permissionless unwind is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"maxDeviationBelowTargetUtilBps\",\n \"docs\": [\n \"Max bps the utilization rate can fall below target before carry trade increase is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"debtMint\",\n \"docs\": [\n \"Debt asset configuration\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debtDecimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"debtTokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n },\n {\n \"name\": \"debtOracleType\",\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n },\n {\n \"name\": \"tokenCpis\",\n \"docs\": [\n \"Optional setup CPIs (e.g. Kamino init_user_metadata, init_obligation,\",\n \"refresh_reserve, refresh_obligation) signed by the Token PDA and\",\n \"executed before the final refresh. When provided, the on-chain refresh\",\n \"reads the freshly-initialized protocol user account; otherwise the\",\n \"refresh is a no-op over an empty account.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"createTokenParams\",\n \"docs\": [\n \"Parameters for creating a new yield token.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"interestDistribution\",\n \"type\": {\n \"defined\": {\n \"name\": \"interestDistribution\"\n }\n }\n },\n {\n \"name\": \"oracleConfig\",\n \"docs\": [\n \"Oracle configuration for pricing the collateral asset\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"oracleConfigDetails\"\n }\n }\n },\n {\n \"name\": \"feeConfig\",\n \"docs\": [\n \"Fee configuration\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"feeConfig\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"createYieldingBankParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"oracleConfig\",\n \"docs\": [\n \"Oracle configuration for pricing the base asset\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"oracleConfigDetails\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"debtAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint of the borrowed asset (e.g. USDC)\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"amount\",\n \"docs\": [\n \"Outstanding debt amount in the debt mint's native units\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvlUsd\",\n \"docs\": [\n \"USD value of the outstanding debt\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"price\",\n \"docs\": [\n \"Oracle price of the debt asset (scaled to 10^decimals)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"oracle\",\n \"docs\": [\n \"Oracle account for the debt asset's price feed\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"tokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n },\n {\n \"name\": \"oracleType\",\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 5\n ]\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 1\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"decreaseCarryPositionParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisiteCpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"targetUtilizationRateBps\",\n \"docs\": [\n \"Optional manager-only target utilization override used for post-repay\",\n \"validation.\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"ybIxRefs\",\n \"docs\": [\n \"Optional CPI refs for yielding-bank swap operations.\",\n \"When present, `source_asset_holding_index` must also be set.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"tokenIxRefs\",\n \"docs\": [\n \"Pre-built repay CPI refs (must contain exactly one Repay CPI).\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"lendingPositionIndex\",\n \"docs\": [\n \"Index into the token's lending_positions array for the position to repay.\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"repayAmount\",\n \"docs\": [\n \"Amount of debt tokens to repay. `AMOUNT_ALL_SENTINEL` repays the maximum\",\n \"available amount, capped by current debt. When set with `yb_ix_refs`, the\",\n \"swap only runs if the yielding bank TA is short of this amount and\",\n \"non-manager swap over-output is capped. When None, `yb_ix_refs` must be\",\n \"present and the maximum available repay amount is derived from the\",\n \"yielding bank TA balance change; swap over-output remains on the yielding\",\n \"bank.\"\n ],\n \"type\": {\n \"option\": \"u64\"\n }\n },\n {\n \"name\": \"sourceAssetHoldingIndex\",\n \"docs\": [\n \"Index of the source asset holding for the swap (0 = base_asset, 1-12 = assets[0-11]).\",\n \"Required when `yb_ix_refs` is present. Non-manager signers may only\",\n \"specify a holding whose mint matches the bank's `default_redemption_mint`.\"\n ],\n \"type\": {\n \"option\": \"u8\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"externalLiquidityType\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"none\"\n },\n {\n \"name\": \"perenaWithdrawalQueue\"\n }\n ]\n }\n },\n {\n \"name\": \"externalPositionConfig\",\n \"docs\": [\n \"Configuration for adding a new external yielding position.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lendingPlatform\",\n \"type\": {\n \"defined\": {\n \"name\": \"lendingPlatform\"\n }\n }\n },\n {\n \"name\": \"lendingType\",\n \"type\": {\n \"defined\": {\n \"name\": \"lendingType\"\n }\n }\n },\n {\n \"name\": \"pool\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateralReserve\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debtReserve\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"protocolUserAcc\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral\",\n \"type\": {\n \"defined\": {\n \"name\": \"assetAllocationConfig\"\n }\n }\n },\n {\n \"name\": \"debt\",\n \"type\": {\n \"defined\": {\n \"name\": \"assetAllocationConfig\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"externalYielding\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lendingPlatform\",\n \"docs\": [\n \"Which lending protocol this position is on (e.g. Marginfi, Kamino)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"lendingPlatform\"\n }\n }\n },\n {\n \"name\": \"lendingType\",\n \"docs\": [\n \"Whether this is a direct lending market deposit or a vault position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"lendingType\"\n }\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"pool\",\n \"docs\": [\n \"The lending protocol's pool/group account\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateralReserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the collateral asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debtReserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the debt asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"protocolUserAcc\",\n \"docs\": [\n \"The program's user/authority account on the lending protocol (e.g. marginfi account)\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral\",\n \"docs\": [\n \"Collateral deposited into this external position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"assetHoldingData\"\n }\n }\n },\n {\n \"name\": \"debt\",\n \"docs\": [\n \"Debt borrowed against the collateral (zero if lending-only, non-zero if leveraged)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"assetHoldingData\"\n }\n }\n },\n {\n \"name\": \"tvl\",\n \"docs\": [\n \"Total value locked in this position (collateral value net of debt)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"timeCreated\",\n \"docs\": [\n \"Unix timestamp when this external yielding position slot was initialized.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding3\",\n \"type\": {\n \"array\": [\n \"u64\",\n 13\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"feeConfig\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"performanceFeeBps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"mintingFeeBps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"burningFeeBps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"protocolMintBurnPctBps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the protocol (vs. into the token price)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curatorMintBurnPctBps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the curator (vs. into the token price).\",\n \"`protocol_mint_burn_pct_bps + curator_mint_burn_pct_bps` must be <= 10000.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curatorPerfPctBps\",\n \"docs\": [\n \"Curator's share of performance fees in basis points (rest goes to protocol).\",\n \"Must be <= 10000.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"feeDripMaxApyBps\",\n \"docs\": [\n \"Target and hard cap (bps) for annualized token-price growth during fee\",\n \"release. `0` parks absorbed fees.\"\n ],\n \"type\": \"u16\"\n }\n ]\n }\n },\n {\n \"name\": \"feeDripState\",\n \"docs\": [\n \"Runtime state for the mint/burn fee \\\"drip\\\".\",\n \"\",\n \"When a mint or burn absorbs a holder fee (the residual after protocol and\",\n \"curator take their split), the fee is not applied to the token price\",\n \"immediately. The fee is physically extra collateral held in the reserve;\",\n \"it is parked here as `undripped_fee_collateral` and **subtracted from the\",\n \"price basis** (`price = (collateral − undripped_fee_collateral) / total_supply`)\",\n \"so the price stays flat at absorption time. `refresh_token` then releases the\",\n \"buffer gradually, which grows the price numerator and lifts the price smoothly\",\n \"rather than in a spike.\",\n \"\",\n \"Denominating the buffer in collateral (rather than phantom supply) keeps each\",\n \"absorbed fee a fixed nominal amount: it does not ride the token's appreciation\",\n \"while parked, and ongoing yield flows fully to holders during the drip window.\",\n \"\",\n \"A configurable APY target and hard cap\",\n \"(`TokenFees::fee_drip_max_apy_bps`) releases enough of the buffer on each\",\n \"refresh to bring annualized price growth up to the target without exceeding\",\n \"it. A zero target parks the buffer.\",\n \"`recollateralize_loss` may consume this buffer after exhausting any pending\",\n \"unwind residual, before the deficit reaches ordinary collateral backing.\"\n ],\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"undrippedFeeCollateral\",\n \"docs\": [\n \"Collateral-denominated buffer of absorbed mint/burn holder fees not yet\",\n \"released into the price. Subtracted from the collateral in the price basis.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding0\",\n \"type\": {\n \"array\": [\n \"u64\",\n 2\n ]\n }\n },\n {\n \"name\": \"apyReferencePrice\",\n \"docs\": [\n \"Token price at the start of the current APY measurement window.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"apyReferenceTs\",\n \"docs\": [\n \"Timestamp at which `apy_reference_price` was recorded. The pair rolls\",\n \"only after the configured APY measurement window has elapsed.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 3\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"increaseCarryPositionParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisiteCpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"ixRefs\",\n \"docs\": [\n \"Pre-built borrow CPI refs (must contain exactly one Borrow CPI).\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"lendingPositionIndex\",\n \"docs\": [\n \"Index into the token's lending_positions array for the position to borrow against.\"\n ],\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"instructionRefs\",\n \"docs\": [\n \"Top-level references for an instruction.\",\n \"\",\n \"Bundles CPI refs (accounts, types, args) with tracked account indices.\",\n \"Passed as an instruction argument from TypeScript.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"cpi\",\n \"docs\": [\n \"CPI account mapping, type indices, and packed args.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"cpiRefs\"\n }\n }\n },\n {\n \"name\": \"tracked\",\n \"docs\": [\n \"Indices into `remaining_accounts` for direct access.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"interestDistribution\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"intoTokenPrice\"\n },\n {\n \"name\": \"intoWallets\"\n }\n ]\n }\n },\n {\n \"name\": \"lendingPlatform\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"none\"\n },\n {\n \"name\": \"marginfi\"\n },\n {\n \"name\": \"kamino\"\n }\n ]\n }\n },\n {\n \"name\": \"lendingPosition\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"platform\",\n \"docs\": [\n \"Which lending protocol this position is on (e.g. Marginfi, Kamino)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"lendingPlatform\"\n }\n }\n },\n {\n \"name\": \"withdrawPending\",\n \"docs\": [\n \"This is a flag if we should allow this position's utilization rate to fall below target\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"podBool\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"lendingPositionAccounting\"\n }\n }\n },\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"lendingPositionConfig\"\n }\n }\n },\n {\n \"name\": \"pool\",\n \"docs\": [\n \"The lending protocol's pool/group account\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateralReserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the collateral asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debtReserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the debt asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"protocolUserAcc\",\n \"docs\": [\n \"The program's user/authority account on the lending protocol\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"lastUpdatedTs\",\n \"docs\": [\n \"Unix timestamp of the last `rebalance_token` executed against this\",\n \"position. Enforces the `REBALANCE_TOKEN_RATE_LIMIT_SECS` cooldown so a\",\n \"single position cannot be rebalanced (and pay the swap spread) more than\",\n \"once per rate-limit window. Zero until the first rebalance.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding3\",\n \"type\": {\n \"array\": [\n \"u64\",\n 23\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"lendingPositionAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"collateral\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"debt\",\n \"type\": {\n \"defined\": {\n \"name\": \"debtAccounting\"\n }\n }\n },\n {\n \"name\": \"ltvUtilizationRateBps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"lendingPositionConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"targetUtilizationRateBps\",\n \"docs\": [\n \"Target LTV utilization rate in basis points (relative to max LTV)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"maxDeviationAboveTargetUtilBps\",\n \"docs\": [\n \"Max bps the utilization rate can exceed target before permissionless unwind is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"maxDeviationBelowTargetUtilBps\",\n \"docs\": [\n \"Max bps the utilization rate can fall below target before carry position increase is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 2\n ]\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 3\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"lendingType\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"lendingMarket\"\n },\n {\n \"name\": \"vault\"\n }\n ]\n }\n },\n {\n \"name\": \"lpRefIndices\",\n \"docs\": [\n \"Index-based account references for the token refresh.\",\n \"\",\n \"All indices point into the shared `remaining_accounts` pool, which is also\",\n \"used by `prerequisite_cpis`. Accounts are deduplicated across both: a single\",\n \"oracle or reserve referenced by multiple positions (or by a prereq CPI and a\",\n \"position) appears once in `remaining_accounts` and is referenced by index.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"userAccount\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"collateralReserve\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"debtOracle\",\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"oracleConfigDetails\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"oracle\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"oracleType\",\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n },\n {\n \"name\": \"secondaryOracle\",\n \"docs\": [\n \"Optional secondary oracle account for composite oracle types (e.g. the\",\n \"SPL stake pool account for `PythSplStake`). `None` for single-account\",\n \"oracle types.\"\n ],\n \"type\": {\n \"option\": \"pubkey\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"oracleType\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"pyth\"\n },\n {\n \"name\": \"switchboard\"\n },\n {\n \"name\": \"perenaBank\"\n },\n {\n \"name\": \"perenaTranche\"\n },\n {\n \"name\": \"pythSplStake\"\n },\n {\n \"name\": \"tpConsensusOracle\"\n }\n ]\n }\n },\n {\n \"name\": \"packedInstructionRefHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"cpiStart\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"cpiCount\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"accountIndicesStart\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"accountIndicesLen\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"argsStart\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"argsLen\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"trackedStart\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"trackedLen\",\n \"type\": \"u16\"\n }\n ]\n }\n },\n {\n \"name\": \"podBool\",\n \"repr\": {\n \"kind\": \"transparent\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n \"u8\"\n ]\n }\n },\n {\n \"name\": \"rebalanceTokenParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lpIndex\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"flashFeeAmount\",\n \"docs\": [\n \"Flash-loan fee in source-debt base units. The handler derives the\",\n \"total flash-repay amount from this plus the source-debt ATA balance\",\n \"observed at handler entry (= what Kamino actually flash-borrowed\",\n \"into the ATA), so the post-swap balance check, dust sweep, and\",\n \"SPL-Approve delegation always use the on-chain reality even if the\",\n \"off-chain builder's borrow size drifts.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"repayAmount\",\n \"docs\": [\n \"Source LP repay = flash-borrow principal. The handler injects this\",\n \"into the repay CPI loaded from the CPI plan.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"destinationDebtOracleType\",\n \"docs\": [\n \"Oracle type for the destination debt mint. Used to update the lending\",\n \"position's stored oracle_type when swapping debt in place, so that the\",\n \"post-borrow refresh reads the new oracle price correctly.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"oracleType\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"recollateralizeLossParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisiteCpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh\",\n \"(e.g. Kamino refresh_reserve, refresh_obligation).\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"ixRefs\",\n \"docs\": [\n \"CPI refs for the Withdraw -> Swap -> Repay sequence (exactly 1 of each,\",\n \"in that order). All three CPIs share one deduplicated account pool.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"lendingPositionIndex\",\n \"docs\": [\n \"Index into the token's lending_positions array.\"\n ],\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"redemptionEpoch\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"header\",\n \"type\": {\n \"defined\": {\n \"name\": \"redemptionEpochHeader\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"redemptionEpochAccounting\"\n }\n }\n },\n {\n \"name\": \"processing\",\n \"type\": {\n \"defined\": {\n \"name\": \"redemptionEpochProcessing\"\n }\n }\n },\n {\n \"name\": \"sequencing\",\n \"type\": {\n \"defined\": {\n \"name\": \"redemptionEpochSequencing\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"redemptionEpochAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"grossCollateralClaim\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"requestedYTokenAmount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"realizedUnwindLoss\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"fundedCollateral\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"redemptionEpochHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"token\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"id\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"status\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"padding0\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"createdTs\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"closedTs\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"SOL rent payer for this epoch PDA's allocation (first async burn).\",\n \"Lamports from closing this account must return here (Pubkey::default =\",\n \"legacy epochs → refund may fall back to manager on-chain).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 4\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"redemptionEpochProcessing\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"processedCollateral\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processedUnwindLoss\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processedYTokenAmount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processedGrossCollateralClaim\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"redemptionEpochSequencing\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"requestCount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processedRequestCount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"nextRequestSequence\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"nextRequestSequenceToProcess\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"refreshTokenStateParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisiteCpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"accountRefs\",\n \"docs\": [\n \"Index-based account references into the shared `remaining_accounts` pool.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"tokenRefreshRefs\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"setRedemptionEpochStatusParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"status\",\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"token\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenConfig\"\n }\n }\n },\n {\n \"name\": \"collateral\",\n \"type\": {\n \"defined\": {\n \"name\": \"collateralConfig\"\n }\n }\n },\n {\n \"name\": \"fees\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenFees\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenAccounting\"\n }\n }\n },\n {\n \"name\": \"debtCarry\",\n \"docs\": [\n \"The carry positions — borrows debt against collateral deposited in lending positions,\",\n \"then converts proceeds into yielding banks to earn the yield spread\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"yieldingCarryPosition\"\n }\n },\n 3\n ]\n }\n },\n {\n \"name\": \"padding0\",\n \"type\": {\n \"array\": [\n \"u64\",\n 19\n ]\n }\n },\n {\n \"name\": \"lendingPositions\",\n \"docs\": [\n \"Lending positions across supported platforms (e.g. Marginfi, Kamino) where collateral is deployed\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"lendingPosition\"\n }\n },\n 6\n ]\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 128\n ]\n }\n },\n {\n \"name\": \"roles\",\n \"docs\": [\n \"Per-token authorization roles. Unset fields fall back to program-level defaults.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"tokenRoles\"\n }\n }\n },\n {\n \"name\": \"feeDrip\",\n \"docs\": [\n \"Mint/burn fee-drip buffer and APY reference. Appended after `roles`\",\n \"(consuming reserved padding) so all preceding field offsets stay stable\",\n \"for already-deployed accounts.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"feeDripState\"\n }\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 164\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"tokenAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"price\",\n \"docs\": [\n \"Price here is denominated in the collateral mint price\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"totalSupply\",\n \"docs\": [\n \"Total number of tokens in circulating supply (includes pending protocol fees)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvlUsd\",\n \"docs\": [\n \"Total TVL of a token. All collateral + YBA carry positions - debt\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"lastRefreshedTs\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"firstMintTs\",\n \"docs\": [\n \"First successful mint timestamp. Remains 0 until first mint.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pendingProtocolFees\",\n \"docs\": [\n \"Protocol fees accrued but not yet minted (collected via `collect_fees`\",\n \"by `PROTOCOL_ADMIN`).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pendingCuratorFees\",\n \"docs\": [\n \"Curator fees accrued but not yet minted (collected via `collect_fees`\",\n \"by the token's curator).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pendingAsyncRedemptionLiability\",\n \"docs\": [\n \"Collateral claim from async redemption requests that has not yet been\",\n \"settled. This is tracked separately so redemption-specific unwind losses\",\n \"can reduce the liability instead of active-holder NAV.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pendingAsyncBurnAmount\",\n \"docs\": [\n \"yTokens currently escrowed in async burn requests and awaiting FIFO\",\n \"fulfillment.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pendingAsyncFeeRetained\",\n \"docs\": [\n \"Protocol + curator fee tokens within `pending_async_burn_amount` that\",\n \"will be retained in `total_supply` as pending fees when the burn is\",\n \"processed.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pendingUnwindResidual\",\n \"docs\": [\n \"Collateral retained from async burners as their share of epoch unwind\",\n \"losses (`loss_for_request` in `process_async_burn`). Physically part of\",\n \"the collateral balance (and of `unlent_amount`), but earmarked to cover\",\n \"the carry−debt deficit the epoch unwind left behind. The price formula\",\n \"excludes `min(residual, hidden deficit)` from the price basis so the\",\n \"residual doesn't inflate the price while the deficit it funds is still\",\n \"clamped out of it; `recollateralize_loss` consumes it before undripped\",\n \"fees and ordinary collateral backing as the deficit is closed.\"\n ],\n \"type\": \"u64\"\n }\n ]\n }\n },\n {\n \"name\": \"tokenConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"id\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The token's mint address\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"tokenProgram\",\n \"type\": {\n \"defined\": {\n \"name\": \"tokenProgram\"\n }\n }\n },\n {\n \"name\": \"interestDistribution\",\n \"docs\": [\n \"Determines how accrued interest is distributed — either folded into\",\n \"the token price (rebase) or sent directly to holder wallets\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"interestDistribution\"\n }\n }\n },\n {\n \"name\": \"circuitBreaker\",\n \"docs\": [\n \"When active, halts all activity except decrease_carry_position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"podBool\"\n }\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u8\",\n 4\n ]\n }\n },\n {\n \"name\": \"padding3\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"burnRateLimit\",\n \"docs\": [\n \"Rolling rate limit on burn (redemption) volume per time window.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"amountRateLimit\"\n }\n }\n },\n {\n \"name\": \"depositLimit\",\n \"docs\": [\n \"Maximum total collateral backing the token, in raw collateral base units.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding4\",\n \"type\": {\n \"array\": [\n \"u64\",\n 6\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"tokenFees\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"performanceFeeBps\",\n \"docs\": [\n \"The protocol fee to take against the yield that has been earned.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"mintingFeeBps\",\n \"docs\": [\n \"The fee to take when minting new tokens. Split between protocol, curator,\",\n \"and token price per the `*_mint_burn_pct_bps` fields below.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"burningFeeBps\",\n \"docs\": [\n \"The fee to take when burning tokens. Split between protocol, curator,\",\n \"and token price per the `*_mint_burn_pct_bps` fields below.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"protocolMintBurnPctBps\",\n \"docs\": [\n \"Protocol's share of mint/burn fees (in bps of `total_fee`).\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curatorMintBurnPctBps\",\n \"docs\": [\n \"Curator's share of mint/burn fees (in bps of `total_fee`).\",\n \"`protocol_mint_burn_pct_bps + curator_mint_burn_pct_bps <= 10_000`; the\",\n \"remainder (if any) stays in the token price.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curatorPerfPctBps\",\n \"docs\": [\n \"Curator's share of performance fees (in bps of `total_perf_fee`).\",\n \"The protocol implicitly receives `10_000 - curator_perf_pct_bps`.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"feeDripMaxApyBps\",\n \"docs\": [\n \"Target and hard cap (in bps) for annualized token-price growth during fee\",\n \"release. Refreshes release enough buffered collateral to approach this\",\n \"target without exceeding it. Natural yield can exceed the target and\",\n \"cannot be clawed back. `0` parks the buffer.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 2\n ]\n }\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 5\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"tokenProgram\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"spl\"\n },\n {\n \"name\": \"token2022\"\n }\n ]\n }\n },\n {\n \"name\": \"tokenRefreshRefs\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lendingPositions\",\n \"docs\": [\n \"Per active lending position (in active-slot order, skipping inactive slots).\"\n ],\n \"type\": {\n \"vec\": {\n \"defined\": {\n \"name\": \"lpRefIndices\"\n }\n }\n }\n },\n {\n \"name\": \"carryPositions\",\n \"docs\": [\n \"Per active carry position (in active-slot order, skipping zero-share slots):\",\n \"index of the `YieldingBank` account in `remaining_accounts`.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"tokenRoles\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"padding0\",\n \"docs\": [\n \"Reserved space that keeps the role fields at their existing offsets\",\n \"after reducing the token's lending-position capacity.\"\n ],\n \"type\": {\n \"array\": [\n \"u64\",\n 16\n ]\n }\n },\n {\n \"name\": \"curator\",\n \"docs\": [\n \"The whitelisted curator that created this token. Treated as the \\\"creator\\\"\",\n \"and used for cross-state curator-match checks (e.g. increase_carry_position\",\n \"requires token.curator == yielding_bank.curator). Rotatable by the token\",\n \"admin to another `WHITELISTED_CURATORS` entry via\",\n \"`update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"admin\",\n \"docs\": [\n \"Authority for token-level config updates, metadata changes, fee edits, and\",\n \"circuit-breaker deactivation. Intended to be a multisig in production.\",\n \"Rotatable by the current admin via `update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"manager\",\n \"docs\": [\n \"Ops wallet authorized to run manager-gated instructions (increase_carry_position,\",\n \"collect_interest, rebalance, deposit_unlent_collateral, claim_incentives, etc).\",\n \"Rotatable via `update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"fees\",\n \"docs\": [\n \"Curator's fee wallet — receives the curator's share of mint/burn fees and\",\n \"performance fees. Rotatable by the token admin or the token curator via\",\n \"`update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"cbController\",\n \"docs\": [\n \"Emergency-halt wallet authorized to *activate* the circuit breaker.\",\n \"Deactivation remains admin-only and time-gated. Rotatable via\",\n \"`update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n }\n ]\n }\n },\n {\n \"name\": \"topUpUnlentReservesParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisiteCpis\",\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"ixRefs\",\n \"type\": {\n \"defined\": {\n \"name\": \"instructionRefs\"\n }\n }\n },\n {\n \"name\": \"lendingPositionIndex\",\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"updateLendingPositionConfigParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lendingPositionIndex\",\n \"docs\": [\n \"Index into the token's lending_positions array\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"targetUtilizationRateBps\",\n \"docs\": [\n \"Target LTV utilization rate in basis points (relative to max LTV)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"maxDeviationAboveTargetUtilBps\",\n \"docs\": [\n \"Max bps the utilization rate can exceed target before permissionless unwind is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"maxDeviationBelowTargetUtilBps\",\n \"docs\": [\n \"Max bps the utilization rate can fall below target before carry trade increase is allowed\"\n ],\n \"type\": \"u16\"\n }\n ]\n }\n },\n {\n \"name\": \"updateTokenConfigurationParams\",\n \"docs\": [\n \"Parameters for updating a token's mutable configuration.\",\n \"\",\n \"Every field is optional: `None` means \\\"no change\\\". Oracle configuration is\",\n \"immutable after creation — use `create_token` to set the oracle, and deploy a\",\n \"new token if it needs to change.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"performanceFeeBps\",\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"mintingFeeBps\",\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"burningFeeBps\",\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"protocolMintBurnPctBps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the protocol (in bps)\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"curatorMintBurnPctBps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the curator (in bps)\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"curatorPerfPctBps\",\n \"docs\": [\n \"Curator's share of performance fees (in bps); protocol implicitly gets the rest.\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"feeDripMaxApyBps\",\n \"docs\": [\n \"Target and hard cap (bps) for annualized price growth during fee release.\",\n \"`Some(0)` parks absorbed fees.\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"burnRateLimit\",\n \"docs\": [\n \"Optional burn-rate-limit config update; omitted leaves the current config unchanged.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"burnRateLimitUpdateParams\"\n }\n }\n }\n },\n {\n \"name\": \"depositLimit\",\n \"docs\": [\n \"Optional cap on total collateral backing (unlent + lent), in raw collateral base units.\",\n \"`None` leaves unchanged. `Some(0)` disables the cap (same semantics as `mint_token`).\",\n \"For `Some(limit)` with `limit > 0`, `limit` must be ≥ that total or the instruction errors.\"\n ],\n \"type\": {\n \"option\": \"u64\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"updateYieldingBankConfigParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": []\n }\n },\n {\n \"name\": \"yieldingAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"totalShares\",\n \"docs\": [\n \"Total shares outstanding across all token carry positions allocated to this bank,\",\n \"stored in raw share units scaled by the yielding bank `config.decimals`\",\n \"(canonically 8 share decimals).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"sharePrice\",\n \"docs\": [\n \"Price per whole UI share, stored in the shared 8-decimal USD base unit\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding1\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"lastRefreshedTs\",\n \"docs\": [\n \"Timestamp of the last share price refresh\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvl\",\n \"docs\": [\n \"Total TVL across all YBA holdings and external lending positions,\",\n \"normalized to the shared 8-decimal USD base unit ($1 = 100_000_000).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"lastRebalancedTs\",\n \"docs\": [\n \"Timestamp of the last time the yielding bank has been rebalanced\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 19\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"yieldingBank\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"yieldingConfig\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"yieldingAccounting\"\n }\n }\n },\n {\n \"name\": \"baseAsset\",\n \"docs\": [\n \"The base mint asset holding — always present, never cleared by cleanup.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"assetHolding\"\n }\n }\n },\n {\n \"name\": \"assets\",\n \"docs\": [\n \"Additional asset holdings beyond the base mint.\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"assetHolding\"\n }\n },\n 12\n ]\n }\n },\n {\n \"name\": \"externalYieldingPositions\",\n \"docs\": [\n \"Positions in external lending/vault protocols that actively generate yield\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"externalYielding\"\n }\n },\n 6\n ]\n }\n },\n {\n \"name\": \"roles\",\n \"docs\": [\n \"Per-yielding-bank authorization roles. Unset fields fall back to program-level defaults.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"yieldingBankRoles\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 144\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"yieldingBankAllocationConfig\",\n \"docs\": [\n \"Argument on `rebalance_yielding_bank` to register one new holding or\",\n \"external position that the rebalance will fund. At most one of the two\",\n \"fields may be `Some` per call.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"assetHolding\",\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"assetConfig\"\n }\n }\n }\n },\n {\n \"name\": \"externalPosition\",\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"externalPositionConfig\"\n }\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"yieldingBankRoles\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"curator\",\n \"docs\": [\n \"The whitelisted curator that created this yielding bank. Must match the\",\n \"token's curator when attaching a carry position via `increase_carry_position`.\",\n \"Rotatable by the bank admin to another `WHITELISTED_CURATORS` entry via\",\n \"`update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"admin\",\n \"docs\": [\n \"Authority for yielding-bank config updates and circuit-breaker deactivation.\",\n \"Intended to be a multisig in production. Rotatable by the current admin via\",\n \"`update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"manager\",\n \"docs\": [\n \"Ops wallet authorized to run manager-gated instructions on this bank\",\n \"(rebalance_yielding_bank, create_yielding_bank_allocation). Rotatable\",\n \"via `update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"cbController\",\n \"docs\": [\n \"Emergency-halt wallet authorized to activate the circuit breaker. Deactivation\",\n \"remains admin-only and time-gated. Rotatable via `update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n }\n ]\n }\n },\n {\n \"name\": \"yieldingCarryPosition\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"yieldingBaseMint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"yieldingBankId\",\n \"docs\": [\n \"Identifier for the yield-bearing asset bank this carry position is allocated to\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n },\n {\n \"name\": \"shares\",\n \"docs\": [\n \"Number of shares held in the yielding bank (converts to underlying via bank share price)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvlUsd\",\n \"docs\": [\n \"Raw USD value of this token's share of the yielding bank, normalized to\",\n \"8-decimal USD ($1 = 100_000_000).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding3\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"yieldingConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"baseMint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"id\",\n \"docs\": [\n \"Unique identifier for this bank, used in PDA derivation and referenced by token carry positions\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"decimals\",\n \"docs\": [\n \"Share precision for `total_shares` accounting and share-price math.\",\n \"Canonically 8 so one whole UI share is priced in the shared TVL USD base unit.\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"circuitBreaker\",\n \"docs\": [\n \"When active, halts all activity except decrease_carry_position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"podBool\"\n }\n }\n },\n {\n \"name\": \"padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 4\n ]\n }\n },\n {\n \"name\": \"defaultRedemptionMint\",\n \"docs\": [\n \"The mint that should be used as the default source when redeeming\",\n \"(e.g. swapping from this mint into a debt mint during decrease_carry_position).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"timeCreatedTs\",\n \"docs\": [\n \"Unix timestamp when this yielding bank was created.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 18\n ]\n }\n }\n ]\n }\n }\n ]\n};\n\n\nexport const IDL = {\n \"address\": \"7YPAKESPJ7zJAvBuk45ZVziu6tXGKoNzg3p9YpvrH6pX\",\n \"metadata\": {\n \"name\": \"long_yield_carry\",\n \"version\": \"0.1.0\",\n \"spec\": \"0.1.0\",\n \"description\": \"Created with Anchor\"\n },\n \"instructions\": [\n {\n \"name\": \"burn_token\",\n \"docs\": [\n \"Burn long-yield-carry tokens and redeem collateral.\"\n ],\n \"discriminator\": [\n 185,\n 165,\n 216,\n 246,\n 144,\n 31,\n 70,\n 74\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Pays SOL rent when async-path PDAs are created; must authorize lamport debits.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The yToken mint. Mutable because the burn CPI decrements total supply.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"user_token_account\",\n \"docs\": [\n \"User's yToken ATA — source of the burn. The user is the authority.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"user_collateral_account\",\n \"docs\": [\n \"User's collateral ATA — destination of the redeemed collateral.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's collateral reserve — source of the collateral payout, and\",\n \"the destination for the collateral withdrawal in the liquidity path.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"request\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"request_token_account\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"token_program\",\n \"docs\": [\n \"Token program for yToken operations (Burn).\"\n ]\n },\n {\n \"name\": \"collateral_token_program\",\n \"docs\": [\n \"Token program for collateral operations (Transfer).\"\n ]\n },\n {\n \"name\": \"associated_token_program\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"BurnTokenParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"cancel_async_burn\",\n \"docs\": [\n \"Cancel a timed-out FIFO-head async burn request while its epoch is still open.\"\n ],\n \"discriminator\": [\n 66,\n 63,\n 112,\n 221,\n 71,\n 95,\n 126,\n 145\n ],\n \"accounts\": [\n {\n \"name\": \"user\",\n \"signer\": true\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Validated against the payer stored on the request at creation time.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true\n },\n {\n \"name\": \"request\",\n \"writable\": true\n },\n {\n \"name\": \"mint\"\n },\n {\n \"name\": \"user_token_account\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"user\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"request_token_account\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"epoch_rent_recipient\",\n \"docs\": [\n \"Must match `redemption_epoch.header.payer`.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"token_program\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"claim_incentives\",\n \"docs\": [\n \"Claim lending-platform farm incentives and deposit them into the\",\n \"token's carry position via the yielding bank.\"\n ],\n \"discriminator\": [\n 79,\n 126,\n 77,\n 51,\n 253,\n 163,\n 193,\n 248\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"expected_incentive_mint\"\n },\n {\n \"name\": \"token_incentive_ata\",\n \"docs\": [\n \"Token PDA's ATA for the reward mint — receives rewards from the claim CPI.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"incentive_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"expected_incentive_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"yielding_bank\",\n \"docs\": [\n \"Required only on the debt-mint branch. Self-pointer check happens\",\n \"inline at the start of `settle_debt_branch`.\"\n ],\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"yielding_bank_incentive_ata\",\n \"docs\": [\n \"Yielding bank's ATA for the reward mint — receives the transfer on the\",\n \"debt-mint branch.\"\n ],\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yielding_bank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"incentive_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"expected_incentive_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"incentive_oracle\",\n \"docs\": [\n \"`incentive_oracle_type`, which validates feed identity. Required on\",\n \"the debt-mint and collateral-mint branches.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"fee_wallet\",\n \"docs\": [\n \"Required on the fee-wallet branch.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"fee_wallet_incentive_ata\",\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"fee_wallet\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"incentive_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"expected_incentive_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"incentive_token_program\"\n },\n {\n \"name\": \"associated_token_program\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"ClaimIncentivesParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"close_cpi_plan\",\n \"docs\": [\n \"Close an orphaned CPI plan PDA and return its rent to the manager.\",\n \"\",\n \"CPI plan accounts normally auto-close via `close = manager` when\",\n \"`rebalance_token` succeeds. This instruction reclaims rent from any\",\n \"plans that were left open due to a failed or interrupted transaction.\"\n ],\n \"discriminator\": [\n 47,\n 118,\n 163,\n 160,\n 199,\n 31,\n 63,\n 26\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"docs\": [\n \"Receives the reclaimed rent. Must be the original payer of this CPI plan.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"cpi_plan\",\n \"writable\": true\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"collect_fees\",\n \"docs\": [\n \"Collect accrued protocol fees from a token.\"\n ],\n \"discriminator\": [\n 164,\n 152,\n 207,\n 99,\n 30,\n 186,\n 19,\n 182\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Must match either the token's `curator()` or the program-level `PROTOCOL_ADMIN`.\",\n \"If the signer is `PROTOCOL_ADMIN`, the protocol fee bucket and wallet are used\",\n \"(even when that key is also the curator). Otherwise, when the signer is the\",\n \"curator only, the curator bucket and curator fee wallet are used.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"writable\": true\n },\n {\n \"name\": \"fee_wallet\",\n \"docs\": [\n \"Fee wallet that receives the minted yTokens. Must match the\",\n \"`curator_fee_wallet()` wallet when signed by the curator, or\",\n \"`protocol_fee_wallet()` when signed by PROTOCOL_ADMIN.\"\n ]\n },\n {\n \"name\": \"fee_wallet_token_account\",\n \"docs\": [\n \"Fee wallet's yToken ATA — created on first collection, reused thereafter\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"fee_wallet\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"token_program\"\n },\n {\n \"name\": \"associated_token_program\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"collect_interest\",\n \"docs\": [\n \"Realize accrued yield from a carry position.\"\n ],\n \"discriminator\": [\n 238,\n 101,\n 253,\n 86,\n 160,\n 25,\n 16,\n 134\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"collateral_oracle\",\n \"docs\": [\n \"Collateral oracle account — refreshed before slippage validation so the\",\n \"collateral USD value is checked against a fresh price.\"\n ]\n },\n {\n \"name\": \"secondary_collateral_oracle\",\n \"docs\": [\n \"Optional secondary oracle account for composite oracle types (the SPL\",\n \"stake pool account for `PythSplStake` collateral); omit otherwise.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"redemption_oracle\",\n \"docs\": [\n \"Oracle account for the yielding bank's default redemption mint —\",\n \"refreshed at the top of the handler so share accounting and the phase 4\",\n \"slippage check all use a live price basis that matches what the SDK\",\n \"planner read when sizing the swap input.\"\n ]\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's collateral ATA — final destination for the swapped collateral\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"yb_collateral_token_account\",\n \"docs\": [\n \"Yielding bank's collateral ATA — receives the swap output before the\",\n \"handler transfers the delta into the token's collateral ATA.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yielding_bank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"curator_fee_wallet_collateral_account\",\n \"docs\": [\n \"Curator fee wallet's collateral ATA — receives the curator share of the performance fee.\",\n \"Address is the ATA of `token.roles.curator_fee_wallet()` for this collateral mint.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"protocol_fee_wallet_collateral_account\",\n \"docs\": [\n \"Protocol fee wallet's collateral ATA — receives the protocol share of the performance fee.\",\n \"Address is the ATA of `TokenRoles::protocol_fee_wallet()` for this collateral mint.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"yb_redemption_token_account\",\n \"docs\": [\n \"YB's ATA for the default redemption mint — snapshotted before and after\",\n \"swap CPIs to verify only this asset was sold.\",\n \"default_redemption_mint and the yielding bank PDA.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"collateral_token_program\"\n },\n {\n \"name\": \"associated_token_program\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"refs\",\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"create_cpi_plan\",\n \"docs\": [\n \"Create a temporary zero-copy CPI plan account for a later instruction.\"\n ],\n \"discriminator\": [\n 176,\n 0,\n 30,\n 192,\n 57,\n 208,\n 40,\n 114\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"cpi_plan\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 99,\n 112,\n 105,\n 32,\n 112,\n 108,\n 97,\n 110\n ]\n },\n {\n \"kind\": \"arg\",\n \"path\": \"params.unique_id\"\n },\n {\n \"kind\": \"arg\",\n \"path\": \"params.created_ts\"\n }\n ]\n }\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"CreateCpiPlanParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"create_token\",\n \"docs\": [\n \"Create a new token and initialize its configuration.\"\n ],\n \"discriminator\": [\n 84,\n 52,\n 204,\n 228,\n 24,\n 140,\n 234,\n 75\n ],\n \"accounts\": [\n {\n \"name\": \"curator\",\n \"docs\": [\n \"Curator that will own this token. Must be in `WHITELISTED_CURATORS`.\",\n \"Pays for account rent.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"admin_role\",\n \"docs\": [\n \"Admin multisig. `None` means \\\"use the feature-gated default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"manager_role\",\n \"docs\": [\n \"Manager ops wallet. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curator_fee_wallet\",\n \"docs\": [\n \"Curator fee wallet. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cb_controller_role\",\n \"docs\": [\n \"Circuit-breaker activator. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"yToken mint — must be pre-created with its authority set to the token PDA\",\n \"and freeze authority set to None. This allows the caller to set mint metadata\",\n \"(name, symbol, icon) before registering the token with the program.\"\n ]\n },\n {\n \"name\": \"collateral_mint\",\n \"docs\": [\n \"The underlying collateral mint (e.g. wSOL)\"\n ]\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's account for holding unlent collateral reserves\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n },\n {\n \"name\": \"token_program\",\n \"docs\": [\n \"Token program for the yToken mint\"\n ]\n },\n {\n \"name\": \"collateral_token_program\",\n \"docs\": [\n \"Token program for the collateral mint\"\n ]\n },\n {\n \"name\": \"associated_token_program\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"CreateTokenParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"create_token_lending_position\",\n \"docs\": [\n \"Register a new lending position for a token.\"\n ],\n \"discriminator\": [\n 32,\n 13,\n 223,\n 159,\n 125,\n 144,\n 219,\n 148\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"lp_position\",\n \"accounts\": [\n {\n \"name\": \"user_account\",\n \"docs\": [\n \"The lending position's user/authority account.\"\n ]\n },\n {\n \"name\": \"collateral_reserve\",\n \"docs\": [\n \"The lending position's collateral reserve/bank account.\"\n ]\n },\n {\n \"name\": \"debt_oracle\",\n \"docs\": [\n \"Oracle for the lending position's debt asset.\"\n ]\n }\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"CreateTokenLendingPositionParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"create_yielding_bank\",\n \"docs\": [\n \"Create a new yielding bank for a base mint.\"\n ],\n \"discriminator\": [\n 123,\n 125,\n 211,\n 195,\n 102,\n 102,\n 90,\n 7\n ],\n \"accounts\": [\n {\n \"name\": \"curator\",\n \"docs\": [\n \"Curator that will own this yielding bank. Must be in `WHITELISTED_CURATORS`.\",\n \"Pays for account rent.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"admin_role\",\n \"docs\": [\n \"Admin multisig. `None` means \\\"use the feature-gated default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"manager_role\",\n \"docs\": [\n \"Manager ops wallet. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cb_controller_role\",\n \"docs\": [\n \"Circuit-breaker activator. `None` means \\\"use default\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n },\n {\n \"name\": \"base_mint\"\n },\n {\n \"name\": \"default_redemption_mint\",\n \"docs\": [\n \"The mint used as the default source when redeeming from the bank.\",\n \"Validated as a real SPL Token / Token-2022 mint by Anchor deserialization.\"\n ]\n },\n {\n \"name\": \"base_mint_token_account\",\n \"docs\": [\n \"Base mint ATA owned by the yielding bank PDA — created so refresh\",\n \"can always read the token balance for the base asset.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yielding_bank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"base_mint_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"base_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"base_mint_token_program\"\n },\n {\n \"name\": \"associated_token_program\",\n \"address\": \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"CreateYieldingBankParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"create_yielding_bank_allocation\",\n \"docs\": [\n \"Add a new asset holding or external position to a yielding bank.\"\n ],\n \"discriminator\": [\n 213,\n 191,\n 99,\n 159,\n 78,\n 2,\n 87,\n 126\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n },\n {\n \"name\": \"allocation_mint\",\n \"docs\": [\n \"Mint for the new asset holding.\"\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"YieldingBankAllocationConfig\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"credit_unlent_to_redemption_epoch\",\n \"docs\": [\n \"Credit already-unlent collateral reserves to a redemption epoch.\"\n ],\n \"discriminator\": [\n 236,\n 123,\n 27,\n 93,\n 229,\n 169,\n 214,\n 129\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"collateral_token_account\",\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_program\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"decrease_carry_position\",\n \"docs\": [\n \"Reduce a carry position and return freed collateral.\"\n ],\n \"discriminator\": [\n 109,\n 115,\n 98,\n 62,\n 206,\n 179,\n 42,\n 145\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true,\n \"optional\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"DecreaseCarryPositionParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"deposit_unlent_collateral\",\n \"docs\": [\n \"Lend idle collateral from a token into a lending position.\"\n ],\n \"discriminator\": [\n 112,\n 210,\n 209,\n 249,\n 61,\n 231,\n 192,\n 207\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's collateral reserve — balance is checked before and\",\n \"after the deposit CPI to derive the actual deposited amount.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_program\"\n },\n {\n \"name\": \"lending_position_user_account\",\n \"docs\": [\n \"The lending position's user/authority account on the lending protocol\",\n \"(e.g. Kamino obligation). Used to refresh the position after deposit.\"\n ]\n },\n {\n \"name\": \"lending_position_collateral_reserve\",\n \"docs\": [\n \"The lending protocol's collateral reserve account. Used to convert\",\n \"cTokens to underlying liquidity during the post-deposit refresh.\"\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"ix_refs\",\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"lending_position_index\",\n \"type\": \"u8\"\n }\n ]\n },\n {\n \"name\": \"increase_carry_position\",\n \"docs\": [\n \"Increase a carry position using borrowed funds.\"\n ],\n \"discriminator\": [\n 216,\n 191,\n 255,\n 166,\n 144,\n 169,\n 3,\n 187\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"docs\": [\n \"via `remaining_accounts`, so the role check is enforced at runtime in\",\n \"the handler rather than by an Anchor constraint here.\"\n ],\n \"signer\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"IncreaseCarryPositionParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"mint_token\",\n \"docs\": [\n \"Deposit collateral and mint long-yield-carry tokens.\"\n ],\n \"discriminator\": [\n 172,\n 137,\n 183,\n 14,\n 207,\n 110,\n 234,\n 56\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The yToken mint — authority is the token PDA\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"collateral_mint\",\n \"docs\": [\n \"Collateral mint (for TransferChecked decimals validation)\"\n ]\n },\n {\n \"name\": \"user_collateral_account\",\n \"docs\": [\n \"User's collateral ATA (source of deposit)\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"user_token_account\",\n \"docs\": [\n \"User's yToken ATA — must be created before calling this instruction\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"signer\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's collateral reserve\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"token_program\",\n \"docs\": [\n \"Token program for yToken operations (MintTo)\"\n ]\n },\n {\n \"name\": \"collateral_token_program\",\n \"docs\": [\n \"Token program for collateral operations (TransferChecked)\"\n ]\n }\n ],\n \"args\": [\n {\n \"name\": \"deposit_amount\",\n \"type\": \"u64\"\n }\n ]\n },\n {\n \"name\": \"process_async_burn\",\n \"docs\": [\n \"Process the next FIFO async burn request in an epoch.\"\n ],\n \"discriminator\": [\n 95,\n 36,\n 6,\n 2,\n 122,\n 146,\n 3,\n 215\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Validated against the payer stored on the request at creation time.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true\n },\n {\n \"name\": \"request\",\n \"writable\": true\n },\n {\n \"name\": \"user\",\n \"docs\": [\n \"collateral is wrapped SOL; otherwise unused except for identity binding.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"writable\": true\n },\n {\n \"name\": \"request_token_account\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"user_collateral_account\",\n \"docs\": [\n \"User's collateral ATA — required when collateral is not wrapped SOL.\"\n ],\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"request_collateral_account\",\n \"docs\": [\n \"Request PDA's collateral ATA — required when collateral is wrapped SOL.\",\n \"The handler transfers WSOL here, then closes the account to unwrap into\",\n \"native SOL for `user`.\"\n ],\n \"writable\": true,\n \"optional\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"request\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_account\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"epoch_rent_recipient\",\n \"docs\": [\n \"marks fully processed epochs). Must match `header.payer`, or `manager`\",\n \"when `payer` is default (legacy epochs).\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"token_program\"\n },\n {\n \"name\": \"collateral_token_program\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"rebalance_token\",\n \"docs\": [\n \"Rebalance a token across its carry positions.\"\n ],\n \"discriminator\": [\n 152,\n 98,\n 123,\n 66,\n 134,\n 191,\n 199,\n 73\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"cpi_plan\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"RebalanceTokenParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"rebalance_yielding_bank\",\n \"docs\": [\n \"Rebalance a yielding bank across allocations and external liquidity.\"\n ],\n \"discriminator\": [\n 181,\n 53,\n 252,\n 136,\n 138,\n 104,\n 145,\n 137\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"ix_refs\",\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"recollateralize_loss\",\n \"docs\": [\n \"Recollateralize a loss by withdrawing collateral, swapping to debt, and repaying.\"\n ],\n \"discriminator\": [\n 98,\n 11,\n 43,\n 3,\n 199,\n 227,\n 100,\n 112\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's collateral reserve — transit account for withdrawn collateral\",\n \"before it is swapped into the debt asset.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_oracle\",\n \"docs\": [\n \"Collateral oracle — refreshed to price the collateral decrease in USD\",\n \"for the slippage check against the debt decrease.\"\n ]\n },\n {\n \"name\": \"secondary_collateral_oracle\",\n \"docs\": [\n \"Optional secondary oracle account for composite oracle types (the SPL\",\n \"stake pool account for `PythSplStake` collateral); omit otherwise.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"lp_position\",\n \"accounts\": [\n {\n \"name\": \"user_account\",\n \"docs\": [\n \"The lending position's user/authority account.\"\n ]\n },\n {\n \"name\": \"collateral_reserve\",\n \"docs\": [\n \"The lending position's collateral reserve/bank account.\"\n ]\n },\n {\n \"name\": \"debt_oracle\",\n \"docs\": [\n \"Oracle for the lending position's debt asset.\"\n ]\n }\n ]\n },\n {\n \"name\": \"collateral_token_program\"\n },\n {\n \"name\": \"yielding_bank\",\n \"docs\": [\n \"Yielding bank to receive any excess debt tokens remaining after repay.\",\n \"Validated at runtime: base_mint must match the lending position's debt mint.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"debt_mint\",\n \"docs\": [\n \"Debt mint for the lending position being recollateralized.\"\n ]\n },\n {\n \"name\": \"token_lp_debt_ta\",\n \"docs\": [\n \"Token PDA's ATA for the debt mint — receives swap output, source for repay and deposit.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debt_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debt_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"yielding_bank_ta\",\n \"docs\": [\n \"Yielding bank's ATA for the debt mint — destination for excess debt token deposit.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"yielding_bank\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debt_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"debt_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"debt_token_program\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"RecollateralizeLossParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"refresh_token_state\",\n \"docs\": [\n \"Refresh token pricing and lending-position state.\"\n ],\n \"discriminator\": [\n 229,\n 167,\n 209,\n 155,\n 223,\n 252,\n 150,\n 188\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"collateral_oracle\",\n \"docs\": [\n \"Collateral oracle account — validated against the registered oracle\",\n \"via the OraclePriceFeed trait's refresh_price method.\"\n ]\n },\n {\n \"name\": \"secondary_collateral_oracle\",\n \"docs\": [\n \"Optional secondary oracle account, required only for composite oracle\",\n \"types. For `PythSplStake` collateral this is the SPL stake pool account;\",\n \"omit for single-account oracle types.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"collateral_token_account\",\n \"docs\": [\n \"Token PDA's collateral reserve account (read actual on-chain balance)\"\n ],\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_program\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"RefreshTokenStateParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"refresh_yielding_bank\",\n \"docs\": [\n \"Refresh yielding-bank asset balances, prices, and share accounting.\"\n ],\n \"discriminator\": [\n 234,\n 183,\n 180,\n 72,\n 113,\n 250,\n 213,\n 76\n ],\n \"accounts\": [\n {\n \"name\": \"signer\",\n \"signer\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"reset_token_burn_rate_limit\",\n \"docs\": [\n \"Reset the burn rate limit counter on a token.\"\n ],\n \"discriminator\": [\n 152,\n 222,\n 104,\n 180,\n 163,\n 231,\n 152,\n 77\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"set_redemption_epoch_status\",\n \"docs\": [\n \"Advance a redemption epoch through funding and processing states.\"\n ],\n \"discriminator\": [\n 143,\n 149,\n 239,\n 71,\n 206,\n 151,\n 223,\n 200\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\"\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true\n },\n {\n \"name\": \"epoch_rent_recipient\",\n \"docs\": [\n \"Must match `header.payer`, or `manager` when `payer` is default (legacy epochs).\"\n ],\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"SetRedemptionEpochStatusParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"set_token_circuit_breaker\",\n \"docs\": [\n \"Enable or disable the token circuit breaker.\",\n \"\",\n \"Activation: token's `cb_controller` or `admin`.\",\n \"Deactivation: token's `admin` only, time-gated.\"\n ],\n \"discriminator\": [\n 123,\n 100,\n 170,\n 97,\n 214,\n 192,\n 245,\n 151\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Activation: `TokenRoles::cb_controller()` or `TokenRoles::admin()`.\",\n \"Deactivation: admin only.\"\n ],\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"active\",\n \"type\": \"bool\"\n }\n ]\n },\n {\n \"name\": \"set_yielding_bank_circuit_breaker\",\n \"docs\": [\n \"Enable or disable the yielding-bank circuit breaker.\",\n \"\",\n \"Activation: bank's `cb_controller` or `admin`.\",\n \"Deactivation: bank's `admin` only, time-gated.\"\n ],\n \"discriminator\": [\n 25,\n 188,\n 1,\n 254,\n 63,\n 110,\n 168,\n 255\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Activation: `YieldingBankRoles::cb_controller()` or `YieldingBankRoles::admin()`.\",\n \"Deactivation: admin only.\"\n ],\n \"signer\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"active\",\n \"type\": \"bool\"\n }\n ]\n },\n {\n \"name\": \"top_up_unlent_reserves\",\n \"docs\": [\n \"Withdraw freed lending collateral into unlent reserves.\"\n ],\n \"discriminator\": [\n 249,\n 228,\n 192,\n 151,\n 48,\n 54,\n 74,\n 179\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"redemption_epoch\",\n \"writable\": true,\n \"optional\": true\n },\n {\n \"name\": \"collateral_mint\"\n },\n {\n \"name\": \"collateral_token_account\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"account\",\n \"path\": \"token\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_token_program\"\n },\n {\n \"kind\": \"account\",\n \"path\": \"collateral_mint\"\n }\n ],\n \"program\": {\n \"kind\": \"const\",\n \"value\": [\n 140,\n 151,\n 37,\n 143,\n 78,\n 36,\n 137,\n 241,\n 187,\n 61,\n 16,\n 41,\n 20,\n 142,\n 13,\n 131,\n 11,\n 90,\n 19,\n 153,\n 218,\n 255,\n 16,\n 132,\n 4,\n 142,\n 123,\n 216,\n 219,\n 233,\n 248,\n 89\n ]\n }\n }\n },\n {\n \"name\": \"collateral_token_program\"\n },\n {\n \"name\": \"lending_position_user_account\"\n },\n {\n \"name\": \"lending_position_collateral_reserve\"\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"TopUpUnlentReservesParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"update_lending_position_config\",\n \"docs\": [\n \"Update configuration for an existing lending position.\"\n ],\n \"discriminator\": [\n 164,\n 56,\n 56,\n 248,\n 51,\n 167,\n 213,\n 96\n ],\n \"accounts\": [\n {\n \"name\": \"manager\",\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"UpdateLendingPositionConfigParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"update_token_configuration\",\n \"docs\": [\n \"Update token-level fee parameters and optionally the burn rate limit.\"\n ],\n \"discriminator\": [\n 115,\n 111,\n 91,\n 203,\n 143,\n 224,\n 71,\n 136\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"docs\": [\n \"Token admin for full configuration updates, manager for\",\n \"`fee_drip_max_apy_bps` only, or curator for curator-fee-wallet updates.\"\n ],\n \"signer\": true\n },\n {\n \"name\": \"token\",\n \"writable\": true\n },\n {\n \"name\": \"manager_role\",\n \"docs\": [\n \"Optional new manager. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curator_fee_wallet\",\n \"docs\": [\n \"Optional new curator fee wallet. `None` means \\\"no change\\\".\",\n \"Rotatable by the token admin or the token curator.\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cb_controller_role\",\n \"docs\": [\n \"Optional new circuit-breaker activator. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curator_role\",\n \"docs\": [\n \"Optional new curator. Must be in `WHITELISTED_CURATORS`.\",\n \"`None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"admin_role\",\n \"docs\": [\n \"Optional new admin. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"UpdateTokenConfigurationParams\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"update_token_metadata\",\n \"docs\": [\n \"Update on-chain metadata for a token's mint via Metaplex Token Metadata CPI.\"\n ],\n \"discriminator\": [\n 243,\n 6,\n 8,\n 23,\n 126,\n 181,\n 251,\n 158\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"signer\": true\n },\n {\n \"name\": \"token\"\n },\n {\n \"name\": \"mint\"\n }\n ],\n \"args\": [\n {\n \"name\": \"ix_refs\",\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n ]\n },\n {\n \"name\": \"update_yielding_bank_config\",\n \"docs\": [\n \"Update yielding-bank configuration parameters.\"\n ],\n \"discriminator\": [\n 236,\n 3,\n 226,\n 53,\n 30,\n 160,\n 216,\n 24\n ],\n \"accounts\": [\n {\n \"name\": \"admin\",\n \"signer\": true\n },\n {\n \"name\": \"yielding_bank\",\n \"writable\": true\n },\n {\n \"name\": \"default_redemption_mint\",\n \"docs\": [\n \"New default redemption mint.\"\n ]\n },\n {\n \"name\": \"manager_role\",\n \"docs\": [\n \"Optional new manager. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"cb_controller_role\",\n \"docs\": [\n \"Optional new circuit-breaker activator. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"curator_role\",\n \"docs\": [\n \"Optional new curator. Must be in `WHITELISTED_CURATORS`.\",\n \"`None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n },\n {\n \"name\": \"admin_role\",\n \"docs\": [\n \"Optional new admin. `None` means \\\"no change\\\".\"\n ],\n \"optional\": true\n }\n ],\n \"args\": [\n {\n \"name\": \"params\",\n \"type\": {\n \"defined\": {\n \"name\": \"UpdateYieldingBankConfigParams\"\n }\n }\n }\n ]\n }\n ],\n \"accounts\": [\n {\n \"name\": \"AsyncBurnRequest\",\n \"discriminator\": [\n 211,\n 147,\n 62,\n 108,\n 20,\n 247,\n 245,\n 141\n ]\n },\n {\n \"name\": \"CpiPlanAccount\",\n \"discriminator\": [\n 23,\n 23,\n 187,\n 18,\n 208,\n 103,\n 156,\n 246\n ]\n },\n {\n \"name\": \"RedemptionEpoch\",\n \"discriminator\": [\n 84,\n 63,\n 161,\n 230,\n 59,\n 183,\n 69,\n 214\n ]\n },\n {\n \"name\": \"Token\",\n \"discriminator\": [\n 131,\n 254,\n 39,\n 144,\n 4,\n 179,\n 134,\n 127\n ]\n },\n {\n \"name\": \"YieldingBank\",\n \"discriminator\": [\n 236,\n 126,\n 167,\n 207,\n 44,\n 134,\n 113,\n 92\n ]\n }\n ],\n \"errors\": [\n {\n \"code\": 8000,\n \"name\": \"Unauthorized\",\n \"msg\": \"Signer is not authorized\"\n },\n {\n \"code\": 8001,\n \"name\": \"InvalidFeeBps\",\n \"msg\": \"Fee basis points exceed maximum\"\n },\n {\n \"code\": 8002,\n \"name\": \"UnsupportedInterestDistribution\",\n \"msg\": \"Interest distribution mode is not yet supported\"\n },\n {\n \"code\": 8003,\n \"name\": \"InvalidMintAuthority\",\n \"msg\": \"Mint authority must be the token PDA\"\n },\n {\n \"code\": 8004,\n \"name\": \"DecimalsMismatch\",\n \"msg\": \"yToken mint decimals must equal collateral mint decimals\"\n },\n {\n \"code\": 8005,\n \"name\": \"MissingYieldingBank\",\n \"msg\": \"Missing yielding bank account in remaining_accounts for active carry position\"\n },\n {\n \"code\": 8006,\n \"name\": \"InvalidYieldingBank\",\n \"msg\": \"Yielding bank account does not match expected PDA for carry position\"\n },\n {\n \"code\": 8007,\n \"name\": \"NoAvailableSlot\",\n \"msg\": \"No available slot to register a new holding or position\"\n },\n {\n \"code\": 8008,\n \"name\": \"DuplicateAllocationMint\",\n \"msg\": \"Active asset holding already exists for the provided mint\"\n },\n {\n \"code\": 8009,\n \"name\": \"StalePrice\",\n \"msg\": \"Token price is stale — call refresh_token_state before mint/burn\"\n },\n {\n \"code\": 8010,\n \"name\": \"InvalidCollateralAccount\",\n \"msg\": \"Collateral token account mint does not match the token's registered collateral mint\"\n },\n {\n \"code\": 8011,\n \"name\": \"InvalidTokenAccount\",\n \"msg\": \"Token account address does not match the expected ATA\"\n },\n {\n \"code\": 8012,\n \"name\": \"FreezeAuthoritySet\",\n \"msg\": \"Mint freeze authority must be None\"\n },\n {\n \"code\": 8013,\n \"name\": \"ZeroDeposit\",\n \"msg\": \"Deposit amount must be greater than zero\"\n },\n {\n \"code\": 8014,\n \"name\": \"DepositLimitExceeded\",\n \"msg\": \"Deposit would exceed the token's configured collateral deposit limit\"\n },\n {\n \"code\": 8015,\n \"name\": \"DepositLimitBelowCurrentCollateral\",\n \"msg\": \"Deposit limit cannot be set below current total collateral backing\"\n },\n {\n \"code\": 8016,\n \"name\": \"ZeroBurnAmount\",\n \"msg\": \"Burn amount must be greater than zero\"\n },\n {\n \"code\": 8017,\n \"name\": \"ZeroCollateral\",\n \"msg\": \"Burn amount is too small — collateral payout rounds to zero\"\n },\n {\n \"code\": 8018,\n \"name\": \"ZeroPrice\",\n \"msg\": \"Token price is zero — minting is not possible\"\n },\n {\n \"code\": 8019,\n \"name\": \"UtilizationRateExceedsTarget\",\n \"msg\": \"Lending position utilization rate exceeds its target\"\n },\n {\n \"code\": 8020,\n \"name\": \"InvalidUtilizationRateCondition\",\n \"msg\": \"Unable to perform carry position update\"\n },\n {\n \"code\": 8021,\n \"name\": \"InvalidLendingPosition\",\n \"msg\": \"Lending position index is out of range or inactive\"\n },\n {\n \"code\": 8022,\n \"name\": \"InvalidLendingPositionConfig\",\n \"msg\": \"Lending position configuration is invalid\"\n },\n {\n \"code\": 8023,\n \"name\": \"InvalidLendingPositionAccount\",\n \"msg\": \"Lending position user account does not match expected\"\n },\n {\n \"code\": 8024,\n \"name\": \"InvalidBorrowCpiCount\",\n \"msg\": \"Borrow CPIs must contain exactly one borrow instruction\"\n },\n {\n \"code\": 8025,\n \"name\": \"InvalidCpiTypes\",\n \"msg\": \"CPI types do not match the required category sequence\"\n },\n {\n \"code\": 8026,\n \"name\": \"MissingDebtOracle\",\n \"msg\": \"Missing debt oracle account in remaining_accounts for active lending position\"\n },\n {\n \"code\": 8027,\n \"name\": \"InsufficientUnlentCollateral\",\n \"msg\": \"Insufficient unlent collateral for the requested amount\"\n },\n {\n \"code\": 8028,\n \"name\": \"CpiProgramPlatformMismatch\",\n \"msg\": \"CPI program does not match the lending position's configured platform\"\n },\n {\n \"code\": 8029,\n \"name\": \"CarryPositionSlippage\",\n \"msg\": \"Carry position TVL slippage exceeds allowed threshold\"\n },\n {\n \"code\": 8030,\n \"name\": \"NoFeesToCollect\",\n \"msg\": \"No pending protocol fees to collect\"\n },\n {\n \"code\": 8031,\n \"name\": \"ZeroRepay\",\n \"msg\": \"Repay amount must be greater than zero\"\n },\n {\n \"code\": 8032,\n \"name\": \"MissingRepayAmount\",\n \"msg\": \"Either repay_amount or yb_ix_refs must be provided\"\n },\n {\n \"code\": 8033,\n \"name\": \"RepayAmountMismatch\",\n \"msg\": \"Actual repay amount does not match the expected repay amount\"\n },\n {\n \"code\": 8034,\n \"name\": \"RebalanceAmountMismatch\",\n \"msg\": \"Actual rebalance amount does not match the expected rebalance amount\"\n },\n {\n \"code\": 8035,\n \"name\": \"RebalanceFlashMintsMatch\",\n \"msg\": \"Flash-loan-wrapped rebalance requires distinct source and destination debt mints\"\n },\n {\n \"code\": 8036,\n \"name\": \"RebalanceFlashRepayUnderfunded\",\n \"msg\": \"Post-swap source-debt balance is insufficient to fund the flash repay\"\n },\n {\n \"code\": 8037,\n \"name\": \"RebalanceFlashFeeTooHigh\",\n \"msg\": \"Flash-loan fee exceeds the maximum allowed (5 bps of flash-borrow principal)\"\n },\n {\n \"code\": 8038,\n \"name\": \"ZeroBorrowAfterRebalance\",\n \"msg\": \"Destination lending position has zero debt after rebalance borrow\"\n },\n {\n \"code\": 8039,\n \"name\": \"BalanceChangeMismatch\",\n \"msg\": \"Token account balance change does not match the lending position state change\"\n },\n {\n \"code\": 8040,\n \"name\": \"NonRedemptionMintDrained\",\n \"msg\": \"Swap drained a non-redemption-mint asset holding\"\n },\n {\n \"code\": 8041,\n \"name\": \"InvalidSourceAssetHoldingMint\",\n \"msg\": \"Source asset holding mint cannot match the lending position debt mint\"\n },\n {\n \"code\": 8042,\n \"name\": \"MissingRemainingAccount\",\n \"msg\": \"Required account missing from remaining_accounts\"\n },\n {\n \"code\": 8043,\n \"name\": \"DuplicateAccount\",\n \"msg\": \"Duplicate account provided\"\n },\n {\n \"code\": 8044,\n \"name\": \"ExternalLiquidityTvlMismatch\",\n \"msg\": \"Asset-holding TVL losses were not matched by offsetting TVL increases\"\n },\n {\n \"code\": 8045,\n \"name\": \"InvalidDefaultRedemptionMint\",\n \"msg\": \"Default redemption mint must match an existing yielding-bank asset holding\"\n },\n {\n \"code\": 8046,\n \"name\": \"InsufficientCarryShares\",\n \"msg\": \"Cannot burn more shares than the carry position holds\"\n },\n {\n \"code\": 8047,\n \"name\": \"CollectInterestInsolvency\",\n \"msg\": \"Collecting interest would leave carry position unable to cover debt\"\n },\n {\n \"code\": 8048,\n \"name\": \"CarryPositionNotFound\",\n \"msg\": \"No carry position found for the given yielding bank\"\n },\n {\n \"code\": 8049,\n \"name\": \"InvalidMintSupply\",\n \"msg\": \"yToken mint must have zero supply at creation\"\n },\n {\n \"code\": 8050,\n \"name\": \"UnsupportedYieldingBankMint\",\n \"msg\": \"Mint is not in the supported yielding bank mints list\"\n },\n {\n \"code\": 8051,\n \"name\": \"RecollateralizeLossNotNeeded\",\n \"msg\": \"Recollateralization not needed — debt does not exceed carry\"\n },\n {\n \"code\": 8052,\n \"name\": \"RecollateralizeLossInsufficient\",\n \"msg\": \"Recollateralization incomplete — carry assets do not cover debt after instruction\"\n },\n {\n \"code\": 8053,\n \"name\": \"RecollateralizeLossOvershot\",\n \"msg\": \"Recollateralization overshot — carry exceeds debt by more than the allowed threshold\"\n },\n {\n \"code\": 8054,\n \"name\": \"RecollateralizeLossSlippage\",\n \"msg\": \"Recollateralization slippage — collateral and debt USD changes diverge beyond tolerance\"\n },\n {\n \"code\": 8055,\n \"name\": \"RecollateralizeLossNoChange\",\n \"msg\": \"Recollateralization failed — no change in collateral or debt on the lending position\"\n },\n {\n \"code\": 8056,\n \"name\": \"InvalidTvlBiasBps\",\n \"msg\": \"Deprecated stub: InvalidTvlBiasBps — retained only for Anchor error discriminant compatibility (TVL bias removed)\"\n },\n {\n \"code\": 8057,\n \"name\": \"ClaimIncentivesNoChange\",\n \"msg\": \"Claimed incentives did not increase the expected token account or produce collateral\"\n },\n {\n \"code\": 8058,\n \"name\": \"UnsupportedIncentivePlatform\",\n \"msg\": \"Only Kamino lending positions currently support incentive claims\"\n },\n {\n \"code\": 8059,\n \"name\": \"InvalidBurnAdjacentNextInstruction\",\n \"msg\": \"Burn-adjacent decrease_carry_position requires the immediate next instruction to be a matching burn_token\"\n },\n {\n \"code\": 8060,\n \"name\": \"MissingBurnAdjacentWithdrawParams\",\n \"msg\": \"Burn-adjacent decrease_carry_position requires burn_token withdraw params when unlent collateral is insufficient\"\n },\n {\n \"code\": 8061,\n \"name\": \"CuratorMismatch\",\n \"msg\": \"Yielding bank curator does not match token curator\"\n },\n {\n \"code\": 8062,\n \"name\": \"CuratorNotWhitelisted\",\n \"msg\": \"Signer is not in the whitelisted curators list\"\n },\n {\n \"code\": 8063,\n \"name\": \"RoleAccountNotEmpty\",\n \"msg\": \"Role account is not empty\"\n },\n {\n \"code\": 8064,\n \"name\": \"RoleAccountInvalidOwner\",\n \"msg\": \"Role account owner must be the System Program\"\n },\n {\n \"code\": 8065,\n \"name\": \"DuplicateFeeWallet\",\n \"msg\": \"Curator and protocol fee wallets must be distinct\"\n },\n {\n \"code\": 8066,\n \"name\": \"InvalidLendingPositionState\",\n \"msg\": \"Newly created lending position must have zero collateral and debt\"\n },\n {\n \"code\": 8067,\n \"name\": \"InvalidIncentiveOracle\",\n \"msg\": \"Incentive mint, oracle, or oracle type does not match the lending position's debt config\"\n },\n {\n \"code\": 8068,\n \"name\": \"InvalidCollateralIncentiveOracle\",\n \"msg\": \"Incentive oracle / oracle type does not match the token's collateral config\"\n },\n {\n \"code\": 8069,\n \"name\": \"MissingYieldingBankAccounts\",\n \"msg\": \"Yielding-bank accounts (yielding_bank, yielding_bank_incentive_ata, incentive_oracle) are required when the incentive mint matches the lending position's debt mint\"\n },\n {\n \"code\": 8070,\n \"name\": \"MissingCollateralIncentiveOracle\",\n \"msg\": \"incentive_oracle is required when the incentive mint matches the token's collateral mint\"\n },\n {\n \"code\": 8071,\n \"name\": \"MissingFeeWalletAccounts\",\n \"msg\": \"fee_wallet and fee_wallet_incentive_ata are required when the incentive mint is neither the debt mint nor the collateral mint\"\n },\n {\n \"code\": 8072,\n \"name\": \"InvalidFeeWallet\",\n \"msg\": \"fee_wallet does not match the token's curator fee wallet\"\n },\n {\n \"code\": 8073,\n \"name\": \"MintAllNativeSol\",\n \"msg\": \"Cannot mint all when collateral is native SOL — user needs SOL for transaction fees and rent\"\n },\n {\n \"code\": 8074,\n \"name\": \"UntrackedDebtResidue\",\n \"msg\": \"Untracked debt tokens remain on the yielding bank after repay — register a debt-mint holding or ensure the swap output equals repay amount\"\n },\n {\n \"code\": 8075,\n \"name\": \"DcpSwapOverOutput\",\n \"msg\": \"DCP swap output exceeds repay amount tolerance\"\n },\n {\n \"code\": 8076,\n \"name\": \"InvalidRedemptionEpochStatus\",\n \"msg\": \"Redemption epoch is not in the required status\"\n },\n {\n \"code\": 8077,\n \"name\": \"AsyncBurnRequestOutOfOrder\",\n \"msg\": \"Async burn request is not next in FIFO order\"\n },\n {\n \"code\": 8078,\n \"name\": \"AsyncBurnRequestAlreadyProcessed\",\n \"msg\": \"Async burn request has already been processed\"\n },\n {\n \"code\": 8079,\n \"name\": \"InsufficientRedemptionEpochFunding\",\n \"msg\": \"Async redemption epoch has insufficient funded collateral\"\n },\n {\n \"code\": 8080,\n \"name\": \"AsyncBurnRequestAlreadyExists\",\n \"msg\": \"Async burn request already exists\"\n },\n {\n \"code\": 8081,\n \"name\": \"RedemptionEpochAlreadyFunded\",\n \"msg\": \"Redemption epoch is already fully funded\"\n },\n {\n \"code\": 8082,\n \"name\": \"RedemptionEpochNotFullyFunded\",\n \"msg\": \"Redemption epoch must be fully funded before transitioning to Processing\"\n },\n {\n \"code\": 8083,\n \"name\": \"InvalidCpiPlanAccount\",\n \"msg\": \"CPI plan account does not match the expected PDA\"\n },\n {\n \"code\": 8084,\n \"name\": \"UnsupportedDebtMint\",\n \"msg\": \"New debt mint is not in the list of supported YB mints\"\n },\n {\n \"code\": 8085,\n \"name\": \"MissingUsdcHolding\",\n \"msg\": \"Yielding bank holds USD* but has no USDC holding to convert its price basis\"\n },\n {\n \"code\": 8086,\n \"name\": \"AsyncBurnRequestNotCancellable\",\n \"msg\": \"Async burn request is not cancellable yet\"\n },\n {\n \"code\": 8087,\n \"name\": \"FeeDripConfigRequired\",\n \"msg\": \"Reserved fee-drip configuration error\"\n },\n {\n \"code\": 8088,\n \"name\": \"RebalanceRateLimited\",\n \"msg\": \"Lending position was rebalanced within the rate-limit window — try again later\"\n }\n ],\n \"types\": [\n {\n \"name\": \"AmountRateLimit\",\n \"docs\": [\n \"Rolling amount rate limit using a tumbling time window.\",\n \"\",\n \"Tracks cumulative usage within a fixed-length window. When the window\",\n \"expires, the counter resets automatically on the next operation.\",\n \"\",\n \"The rate limit is only enforced when both `max_amount > 0` and\",\n \"`window_duration_secs > 0`. The default (all zeros) means no rate limiting.\"\n ],\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"max_amount\",\n \"docs\": [\n \"Maximum cumulative amount allowed within one window.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"window_duration_secs\",\n \"docs\": [\n \"Length of the rate-limit window in seconds.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"amount_used\",\n \"docs\": [\n \"Cumulative amount consumed in the current window.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"window_start_ts\",\n \"docs\": [\n \"Unix timestamp when the current window started.\"\n ],\n \"type\": \"u64\"\n }\n ]\n }\n },\n {\n \"name\": \"AssetAllocationConfig\",\n \"docs\": [\n \"Configuration for the collateral or debt side of an external lending position.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"AssetConfig\",\n \"docs\": [\n \"Configuration for adding a new yield-bearing asset holding.\",\n \"\",\n \"Fields derivable from the mint account (`mint`, `decimals`, `token_program`)\",\n \"are provided separately — the mint is a named account on the instruction,\",\n \"and the handler reads decimals/token_program from it.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"oracle\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"oracle_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n },\n {\n \"name\": \"external_liquidity\",\n \"type\": {\n \"defined\": {\n \"name\": \"ExternalLiquidityType\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"AssetHolding\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint of the asset (e.g. base stablecoin, LST, or receipt token)\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"amount\",\n \"docs\": [\n \"Amount of the asset held (in native mint units)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"price\",\n \"docs\": [\n \"Current USD price of the asset\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"oracle\",\n \"docs\": [\n \"Oracle account for price resolution\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"docs\": [\n \"Decimal precision of the mint\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n },\n {\n \"name\": \"oracle_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n },\n {\n \"name\": \"external_liquidity\",\n \"docs\": [\n \"In some cases, an asset will not have all funds sitting in the PDA's token account.\",\n \"We track the source type and read the accounts accordingly to know the full amount\",\n \"owed to the yielding bank onchain.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"ExternalLiquidityType\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 4\n ]\n }\n },\n {\n \"name\": \"time_created\",\n \"docs\": [\n \"Unix timestamp when this holding was registered.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 5\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"AssetHoldingData\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"amount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"price\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 6\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"AsyncBurnRequest\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"header\",\n \"type\": {\n \"defined\": {\n \"name\": \"AsyncBurnRequestHeader\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"AsyncBurnRequestAccounting\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"AsyncBurnRequestAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"y_token_amount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"gross_collateral_claim\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"protocol_fee\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"curator_fee\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"AsyncBurnRequestHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"token\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"epoch\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"user\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Account that funded the request PDA rent. Receives the rent back when\",\n \"the request is closed during `process_async_burn`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"epoch_id\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"sequence\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"_padding0\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n },\n {\n \"name\": \"request_ts\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 4\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"BurnRateLimitUpdateParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"max_amount\",\n \"docs\": [\n \"Maximum cumulative burn amount allowed within one window (0 to disable).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"window_duration_secs\",\n \"docs\": [\n \"Length of the rate-limit window in seconds (0 to disable).\"\n ],\n \"type\": \"u64\"\n }\n ]\n }\n },\n {\n \"name\": \"BurnTokenParams\",\n \"docs\": [\n \"Instruction params for burning yTokens.\",\n \"\",\n \"Use [`BurnTokenParams::Sync`] when unlent collateral is sufficient without\",\n \"allocating redemption epoch PDAs. Use [`BurnTokenParams::Async`] when async\",\n \"fallback PDAs are passed — required when reserves may be insufficient at\",\n \"execution time.\"\n ],\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"Sync\",\n \"fields\": [\n {\n \"name\": \"burn_amount\",\n \"type\": \"u64\"\n }\n ]\n },\n {\n \"name\": \"Async\",\n \"fields\": [\n {\n \"name\": \"burn_amount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"epoch_id\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"request_sequence\",\n \"type\": \"u64\"\n }\n ]\n }\n ]\n }\n },\n {\n \"name\": \"ClaimIncentivesParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisite_cpis\",\n \"docs\": [\n \"Optional prerequisite CPIs (e.g. Kamino reserve / obligation refresh)\",\n \"executed before the claim CPI.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"token_ix_refs\",\n \"docs\": [\n \"CPI refs for the single claim-incentives action.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"lending_position_index\",\n \"docs\": [\n \"Lending position index whose farm rewards are being claimed. Used for\",\n \"platform routing and timelock enforcement.\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"incentive_oracle_type\",\n \"docs\": [\n \"Oracle type for pricing the claimed reward when the incentive mint\",\n \"matches the lending position's debt mint or the token's collateral\",\n \"mint. Ignored on the fee-wallet branch.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"CollateralConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint of the underlying collateral asset backing this token\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"price\",\n \"docs\": [\n \"Current USD price of the collateral asset (from oracle)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"unlent_amount\",\n \"docs\": [\n \"Amount of collateral held in reserve, not deployed to any lending position\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"oracle\",\n \"docs\": [\n \"Oracle account used to price the collateral asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"last_refreshed_ts\",\n \"docs\": [\n \"Timestamp of the last oracle price refresh\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n },\n {\n \"name\": \"oracle_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 5\n ]\n }\n },\n {\n \"name\": \"secondary_oracle\",\n \"docs\": [\n \"Optional secondary oracle account. Used by composite oracle types that\",\n \"need a second input — e.g. `PythSplStake` stores the SPL stake pool\",\n \"account here while `oracle` holds the Pyth SOL/USD feed. Left as\",\n \"`Pubkey::default()` for single-account oracle types.\"\n ],\n \"type\": \"pubkey\"\n }\n ]\n }\n },\n {\n \"name\": \"CpiMapping\",\n \"docs\": [\n \"Mapping for extracting accounts from `remaining_accounts` across multiple CPIs.\",\n \"\",\n \"This struct enables efficient multi-CPI transactions by:\",\n \"1. Deduplicating all accounts into a single `remaining_accounts` pool\",\n \"2. Storing all indices for all CPIs in a single flattened vector\",\n \"3. Using `lengths` to slice the indices for each individual CPI\",\n \"\",\n \"# Example\",\n \"\",\n \"For 2 CPIs where CPI 0 needs 10 accounts and CPI 1 needs 8 accounts:\",\n \"```text\",\n \"indices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 5, 7, 10, 11, 12, 13, 14]\",\n \"lengths: [10, 8]\",\n \"\",\n \"CPI 0 uses indices[0..10]\",\n \"CPI 1 uses indices[10..18]\",\n \"```\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"indices\",\n \"docs\": [\n \"All indices into `remaining_accounts`, flattened across all CPIs.\"\n ],\n \"type\": \"bytes\"\n },\n {\n \"name\": \"lengths\",\n \"docs\": [\n \"Number of accounts for each CPI call.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"CpiPlan\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"header\",\n \"type\": {\n \"defined\": {\n \"name\": \"CpiPlanHeader\"\n }\n }\n },\n {\n \"name\": \"ref_count\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"_padding\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n },\n {\n \"name\": \"refs\",\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"PackedInstructionRefHeader\"\n }\n },\n 10\n ]\n }\n },\n {\n \"name\": \"cpi_lengths\",\n \"type\": {\n \"array\": [\n \"u8\",\n 64\n ]\n }\n },\n {\n \"name\": \"cpi_types\",\n \"type\": {\n \"array\": [\n \"u8\",\n 64\n ]\n }\n },\n {\n \"name\": \"account_indices\",\n \"type\": {\n \"array\": [\n {\n \"array\": [\n \"u8\",\n 1024\n ]\n },\n 4\n ]\n }\n },\n {\n \"name\": \"args\",\n \"type\": {\n \"array\": [\n {\n \"array\": [\n \"u8\",\n 1024\n ]\n },\n 4\n ]\n }\n },\n {\n \"name\": \"tracked\",\n \"type\": {\n \"array\": [\n \"u8\",\n 128\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"CpiPlanAccount\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"packed\",\n \"type\": {\n \"defined\": {\n \"name\": \"CpiPlan\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"CpiPlanHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"unique_id\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"payer\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"created_ts\",\n \"type\": \"i64\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"_padding\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"CpiRefs\",\n \"docs\": [\n \"References for CPI invocations.\",\n \"\",\n \"This structure contains all the information needed to invoke CPIs\",\n \"from a pool of deduplicated accounts.\",\n \"\",\n \"# Fields\",\n \"\",\n \"- `accounts`: Mapping of account indices per CPI slot (first = program)\",\n \"- `types`: Index into `CPI_REGISTRY` for each CPI slot\",\n \"- `args`: Packed CPI args buffer (u16-length-prefixed per slot)\",\n \"\",\n \"# Convention\",\n \"\",\n \"The **first account** in each CPI slot's account list is the **program**.\",\n \"This is validated during invocation against the registry entry.\",\n \"\",\n \"# Example\",\n \"\",\n \"```text\",\n \"CpiRefs {\",\n \"accounts: CpiMapping {\",\n \"indices: [5, 0, 1, 2, 3, 4, 8, 6, 7, 0, 1],\",\n \"lengths: [6, 5],\",\n \"},\",\n \"types: [0, 2], // CPI 0 = PERENA_MINT, CPI 1 = JUPITER_SWAP\",\n \"args: [16, 0, ..16 bytes.., 0xFF, 0xFF],\",\n \"}\",\n \"```\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"accounts\",\n \"docs\": [\n \"Account indices per CPI (first account of each CPI = program).\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"CpiMapping\"\n }\n }\n },\n {\n \"name\": \"types\",\n \"docs\": [\n \"Index into `CPI_REGISTRY` for each CPI slot.\"\n ],\n \"type\": \"bytes\"\n },\n {\n \"name\": \"args\",\n \"docs\": [\n \"Packed CPI args — `[u16 LE length][data]` per slot.\",\n \"0xFFFF = skip (program-provided), 0 = no-args, N = N bytes of client data.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"CreateCpiPlanParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"unique_id\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"created_ts\",\n \"type\": \"i64\"\n },\n {\n \"name\": \"refs\",\n \"type\": {\n \"vec\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"CreateTokenLendingPositionParams\",\n \"docs\": [\n \"Parameters for initializing a new lending position on a Token.\",\n \"\",\n \"Account-backed values (`protocol_user_acc`, `collateral_reserve`,\",\n \"`debt_oracle`) are read from the `lp_position` composite on the `Accounts`\",\n \"struct rather than duplicated in this params struct.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lending_platform\",\n \"docs\": [\n \"Which lending protocol (e.g. Kamino, Marginfi)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"LendingPlatform\"\n }\n }\n },\n {\n \"name\": \"pool\",\n \"docs\": [\n \"The lending protocol's pool/group account\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debt_reserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the debt asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"target_utilization_rate_bps\",\n \"docs\": [\n \"Target LTV utilization rate in basis points (relative to max LTV)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"max_deviation_above_target_util_bps\",\n \"docs\": [\n \"Max bps the utilization rate can exceed target before permissionless unwind is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"max_deviation_below_target_util_bps\",\n \"docs\": [\n \"Max bps the utilization rate can fall below target before carry trade increase is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"debt_mint\",\n \"docs\": [\n \"Debt asset configuration\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debt_decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"debt_token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n },\n {\n \"name\": \"debt_oracle_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n },\n {\n \"name\": \"token_cpis\",\n \"docs\": [\n \"Optional setup CPIs (e.g. Kamino init_user_metadata, init_obligation,\",\n \"refresh_reserve, refresh_obligation) signed by the Token PDA and\",\n \"executed before the final refresh. When provided, the on-chain refresh\",\n \"reads the freshly-initialized protocol user account; otherwise the\",\n \"refresh is a no-op over an empty account.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"CreateTokenParams\",\n \"docs\": [\n \"Parameters for creating a new yield token.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"interest_distribution\",\n \"type\": {\n \"defined\": {\n \"name\": \"InterestDistribution\"\n }\n }\n },\n {\n \"name\": \"oracle_config\",\n \"docs\": [\n \"Oracle configuration for pricing the collateral asset\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"OracleConfigDetails\"\n }\n }\n },\n {\n \"name\": \"fee_config\",\n \"docs\": [\n \"Fee configuration\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"FeeConfig\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"CreateYieldingBankParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"oracle_config\",\n \"docs\": [\n \"Oracle configuration for pricing the base asset\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"OracleConfigDetails\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"DebtAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint of the borrowed asset (e.g. USDC)\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"amount\",\n \"docs\": [\n \"Outstanding debt amount in the debt mint's native units\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvl_usd\",\n \"docs\": [\n \"USD value of the outstanding debt\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"price\",\n \"docs\": [\n \"Oracle price of the debt asset (scaled to 10^decimals)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"oracle\",\n \"docs\": [\n \"Oracle account for the debt asset's price feed\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n },\n {\n \"name\": \"oracle_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 5\n ]\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 1\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"DecreaseCarryPositionParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisite_cpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"target_utilization_rate_bps\",\n \"docs\": [\n \"Optional manager-only target utilization override used for post-repay\",\n \"validation.\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"yb_ix_refs\",\n \"docs\": [\n \"Optional CPI refs for yielding-bank swap operations.\",\n \"When present, `source_asset_holding_index` must also be set.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"token_ix_refs\",\n \"docs\": [\n \"Pre-built repay CPI refs (must contain exactly one Repay CPI).\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"lending_position_index\",\n \"docs\": [\n \"Index into the token's lending_positions array for the position to repay.\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"repay_amount\",\n \"docs\": [\n \"Amount of debt tokens to repay. `AMOUNT_ALL_SENTINEL` repays the maximum\",\n \"available amount, capped by current debt. When set with `yb_ix_refs`, the\",\n \"swap only runs if the yielding bank TA is short of this amount and\",\n \"non-manager swap over-output is capped. When None, `yb_ix_refs` must be\",\n \"present and the maximum available repay amount is derived from the\",\n \"yielding bank TA balance change; swap over-output remains on the yielding\",\n \"bank.\"\n ],\n \"type\": {\n \"option\": \"u64\"\n }\n },\n {\n \"name\": \"source_asset_holding_index\",\n \"docs\": [\n \"Index of the source asset holding for the swap (0 = base_asset, 1-12 = assets[0-11]).\",\n \"Required when `yb_ix_refs` is present. Non-manager signers may only\",\n \"specify a holding whose mint matches the bank's `default_redemption_mint`.\"\n ],\n \"type\": {\n \"option\": \"u8\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"ExternalLiquidityType\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"None\"\n },\n {\n \"name\": \"PerenaWithdrawalQueue\"\n }\n ]\n }\n },\n {\n \"name\": \"ExternalPositionConfig\",\n \"docs\": [\n \"Configuration for adding a new external yielding position.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lending_platform\",\n \"type\": {\n \"defined\": {\n \"name\": \"LendingPlatform\"\n }\n }\n },\n {\n \"name\": \"lending_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"LendingType\"\n }\n }\n },\n {\n \"name\": \"pool\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral_reserve\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debt_reserve\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"protocol_user_acc\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral\",\n \"type\": {\n \"defined\": {\n \"name\": \"AssetAllocationConfig\"\n }\n }\n },\n {\n \"name\": \"debt\",\n \"type\": {\n \"defined\": {\n \"name\": \"AssetAllocationConfig\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"ExternalYielding\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lending_platform\",\n \"docs\": [\n \"Which lending protocol this position is on (e.g. Marginfi, Kamino)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"LendingPlatform\"\n }\n }\n },\n {\n \"name\": \"lending_type\",\n \"docs\": [\n \"Whether this is a direct lending market deposit or a vault position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"LendingType\"\n }\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"pool\",\n \"docs\": [\n \"The lending protocol's pool/group account\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral_reserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the collateral asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debt_reserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the debt asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"protocol_user_acc\",\n \"docs\": [\n \"The program's user/authority account on the lending protocol (e.g. marginfi account)\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral\",\n \"docs\": [\n \"Collateral deposited into this external position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"AssetHoldingData\"\n }\n }\n },\n {\n \"name\": \"debt\",\n \"docs\": [\n \"Debt borrowed against the collateral (zero if lending-only, non-zero if leveraged)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"AssetHoldingData\"\n }\n }\n },\n {\n \"name\": \"tvl\",\n \"docs\": [\n \"Total value locked in this position (collateral value net of debt)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"time_created\",\n \"docs\": [\n \"Unix timestamp when this external yielding position slot was initialized.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding3\",\n \"type\": {\n \"array\": [\n \"u64\",\n 13\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"FeeConfig\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"performance_fee_bps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"minting_fee_bps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"burning_fee_bps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"protocol_mint_burn_pct_bps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the protocol (vs. into the token price)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curator_mint_burn_pct_bps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the curator (vs. into the token price).\",\n \"`protocol_mint_burn_pct_bps + curator_mint_burn_pct_bps` must be <= 10000.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curator_perf_pct_bps\",\n \"docs\": [\n \"Curator's share of performance fees in basis points (rest goes to protocol).\",\n \"Must be <= 10000.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"fee_drip_max_apy_bps\",\n \"docs\": [\n \"Target and hard cap (bps) for annualized token-price growth during fee\",\n \"release. `0` parks absorbed fees.\"\n ],\n \"type\": \"u16\"\n }\n ]\n }\n },\n {\n \"name\": \"FeeDripState\",\n \"docs\": [\n \"Runtime state for the mint/burn fee \\\"drip\\\".\",\n \"\",\n \"When a mint or burn absorbs a holder fee (the residual after protocol and\",\n \"curator take their split), the fee is not applied to the token price\",\n \"immediately. The fee is physically extra collateral held in the reserve;\",\n \"it is parked here as `undripped_fee_collateral` and **subtracted from the\",\n \"price basis** (`price = (collateral − undripped_fee_collateral) / total_supply`)\",\n \"so the price stays flat at absorption time. `refresh_token` then releases the\",\n \"buffer gradually, which grows the price numerator and lifts the price smoothly\",\n \"rather than in a spike.\",\n \"\",\n \"Denominating the buffer in collateral (rather than phantom supply) keeps each\",\n \"absorbed fee a fixed nominal amount: it does not ride the token's appreciation\",\n \"while parked, and ongoing yield flows fully to holders during the drip window.\",\n \"\",\n \"A configurable APY target and hard cap\",\n \"(`TokenFees::fee_drip_max_apy_bps`) releases enough of the buffer on each\",\n \"refresh to bring annualized price growth up to the target without exceeding\",\n \"it. A zero target parks the buffer.\",\n \"`recollateralize_loss` may consume this buffer after exhausting any pending\",\n \"unwind residual, before the deficit reaches ordinary collateral backing.\"\n ],\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"undripped_fee_collateral\",\n \"docs\": [\n \"Collateral-denominated buffer of absorbed mint/burn holder fees not yet\",\n \"released into the price. Subtracted from the collateral in the price basis.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding0\",\n \"type\": {\n \"array\": [\n \"u64\",\n 2\n ]\n }\n },\n {\n \"name\": \"apy_reference_price\",\n \"docs\": [\n \"Token price at the start of the current APY measurement window.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"apy_reference_ts\",\n \"docs\": [\n \"Timestamp at which `apy_reference_price` was recorded. The pair rolls\",\n \"only after the configured APY measurement window has elapsed.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 3\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"IncreaseCarryPositionParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisite_cpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"ix_refs\",\n \"docs\": [\n \"Pre-built borrow CPI refs (must contain exactly one Borrow CPI).\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"lending_position_index\",\n \"docs\": [\n \"Index into the token's lending_positions array for the position to borrow against.\"\n ],\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"InstructionRefs\",\n \"docs\": [\n \"Top-level references for an instruction.\",\n \"\",\n \"Bundles CPI refs (accounts, types, args) with tracked account indices.\",\n \"Passed as an instruction argument from TypeScript.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"cpi\",\n \"docs\": [\n \"CPI account mapping, type indices, and packed args.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"CpiRefs\"\n }\n }\n },\n {\n \"name\": \"tracked\",\n \"docs\": [\n \"Indices into `remaining_accounts` for direct access.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"InterestDistribution\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"IntoTokenPrice\"\n },\n {\n \"name\": \"IntoWallets\"\n }\n ]\n }\n },\n {\n \"name\": \"LendingPlatform\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"None\"\n },\n {\n \"name\": \"Marginfi\"\n },\n {\n \"name\": \"Kamino\"\n }\n ]\n }\n },\n {\n \"name\": \"LendingPosition\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"platform\",\n \"docs\": [\n \"Which lending protocol this position is on (e.g. Marginfi, Kamino)\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"LendingPlatform\"\n }\n }\n },\n {\n \"name\": \"withdraw_pending\",\n \"docs\": [\n \"This is a flag if we should allow this position's utilization rate to fall below target\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"PodBool\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"LendingPositionAccounting\"\n }\n }\n },\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"LendingPositionConfig\"\n }\n }\n },\n {\n \"name\": \"pool\",\n \"docs\": [\n \"The lending protocol's pool/group account\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"collateral_reserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the collateral asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"debt_reserve\",\n \"docs\": [\n \"The lending protocol's reserve/bank for the debt asset\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"protocol_user_acc\",\n \"docs\": [\n \"The program's user/authority account on the lending protocol\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"last_updated_ts\",\n \"docs\": [\n \"Unix timestamp of the last `rebalance_token` executed against this\",\n \"position. Enforces the `REBALANCE_TOKEN_RATE_LIMIT_SECS` cooldown so a\",\n \"single position cannot be rebalanced (and pay the swap spread) more than\",\n \"once per rate-limit window. Zero until the first rebalance.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding3\",\n \"type\": {\n \"array\": [\n \"u64\",\n 23\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"LendingPositionAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"collateral\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"debt\",\n \"type\": {\n \"defined\": {\n \"name\": \"DebtAccounting\"\n }\n }\n },\n {\n \"name\": \"ltv_utilization_rate_bps\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"LendingPositionConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"target_utilization_rate_bps\",\n \"docs\": [\n \"Target LTV utilization rate in basis points (relative to max LTV)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"max_deviation_above_target_util_bps\",\n \"docs\": [\n \"Max bps the utilization rate can exceed target before permissionless unwind is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"max_deviation_below_target_util_bps\",\n \"docs\": [\n \"Max bps the utilization rate can fall below target before carry position increase is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 2\n ]\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 3\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"LendingType\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"LendingMarket\"\n },\n {\n \"name\": \"Vault\"\n }\n ]\n }\n },\n {\n \"name\": \"LpRefIndices\",\n \"docs\": [\n \"Index-based account references for the token refresh.\",\n \"\",\n \"All indices point into the shared `remaining_accounts` pool, which is also\",\n \"used by `prerequisite_cpis`. Accounts are deduplicated across both: a single\",\n \"oracle or reserve referenced by multiple positions (or by a prereq CPI and a\",\n \"position) appears once in `remaining_accounts` and is referenced by index.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"user_account\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"collateral_reserve\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"debt_oracle\",\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"OracleConfigDetails\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"oracle\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"oracle_type\",\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n },\n {\n \"name\": \"secondary_oracle\",\n \"docs\": [\n \"Optional secondary oracle account for composite oracle types (e.g. the\",\n \"SPL stake pool account for `PythSplStake`). `None` for single-account\",\n \"oracle types.\"\n ],\n \"type\": {\n \"option\": \"pubkey\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"OracleType\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"Pyth\"\n },\n {\n \"name\": \"Switchboard\"\n },\n {\n \"name\": \"PerenaBank\"\n },\n {\n \"name\": \"PerenaTranche\"\n },\n {\n \"name\": \"PythSplStake\"\n },\n {\n \"name\": \"TPConsensusOracle\"\n }\n ]\n }\n },\n {\n \"name\": \"PackedInstructionRefHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"cpi_start\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"cpi_count\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"account_indices_start\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"account_indices_len\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"args_start\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"args_len\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"tracked_start\",\n \"type\": \"u16\"\n },\n {\n \"name\": \"tracked_len\",\n \"type\": \"u16\"\n }\n ]\n }\n },\n {\n \"name\": \"PodBool\",\n \"repr\": {\n \"kind\": \"transparent\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n \"u8\"\n ]\n }\n },\n {\n \"name\": \"RebalanceTokenParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lp_index\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"flash_fee_amount\",\n \"docs\": [\n \"Flash-loan fee in source-debt base units. The handler derives the\",\n \"total flash-repay amount from this plus the source-debt ATA balance\",\n \"observed at handler entry (= what Kamino actually flash-borrowed\",\n \"into the ATA), so the post-swap balance check, dust sweep, and\",\n \"SPL-Approve delegation always use the on-chain reality even if the\",\n \"off-chain builder's borrow size drifts.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"repay_amount\",\n \"docs\": [\n \"Source LP repay = flash-borrow principal. The handler injects this\",\n \"into the repay CPI loaded from the CPI plan.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"destination_debt_oracle_type\",\n \"docs\": [\n \"Oracle type for the destination debt mint. Used to update the lending\",\n \"position's stored oracle_type when swapping debt in place, so that the\",\n \"post-borrow refresh reads the new oracle price correctly.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"OracleType\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"RecollateralizeLossParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisite_cpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh\",\n \"(e.g. Kamino refresh_reserve, refresh_obligation).\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"ix_refs\",\n \"docs\": [\n \"CPI refs for the Withdraw -> Swap -> Repay sequence (exactly 1 of each,\",\n \"in that order). All three CPIs share one deduplicated account pool.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"lending_position_index\",\n \"docs\": [\n \"Index into the token's lending_positions array.\"\n ],\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"RedemptionEpoch\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"header\",\n \"type\": {\n \"defined\": {\n \"name\": \"RedemptionEpochHeader\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"RedemptionEpochAccounting\"\n }\n }\n },\n {\n \"name\": \"processing\",\n \"type\": {\n \"defined\": {\n \"name\": \"RedemptionEpochProcessing\"\n }\n }\n },\n {\n \"name\": \"sequencing\",\n \"type\": {\n \"defined\": {\n \"name\": \"RedemptionEpochSequencing\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"RedemptionEpochAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"gross_collateral_claim\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"requested_y_token_amount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"realized_unwind_loss\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"funded_collateral\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"RedemptionEpochHeader\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"token\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"id\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"status\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"_padding0\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"created_ts\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"closed_ts\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"payer\",\n \"docs\": [\n \"SOL rent payer for this epoch PDA's allocation (first async burn).\",\n \"Lamports from closing this account must return here (Pubkey::default =\",\n \"legacy epochs → refund may fall back to manager on-chain).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 4\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"RedemptionEpochProcessing\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"processed_collateral\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processed_unwind_loss\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processed_y_token_amount\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processed_gross_collateral_claim\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"RedemptionEpochSequencing\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"request_count\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"processed_request_count\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"next_request_sequence\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"next_request_sequence_to_process\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"RefreshTokenStateParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisite_cpis\",\n \"docs\": [\n \"Optional prerequisite CPIs executed before any lending-position refresh.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n }\n },\n {\n \"name\": \"account_refs\",\n \"docs\": [\n \"Index-based account references into the shared `remaining_accounts` pool.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"TokenRefreshRefs\"\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"SetRedemptionEpochStatusParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"status\",\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"Token\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenConfig\"\n }\n }\n },\n {\n \"name\": \"collateral\",\n \"type\": {\n \"defined\": {\n \"name\": \"CollateralConfig\"\n }\n }\n },\n {\n \"name\": \"fees\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenFees\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenAccounting\"\n }\n }\n },\n {\n \"name\": \"debt_carry\",\n \"docs\": [\n \"The carry positions — borrows debt against collateral deposited in lending positions,\",\n \"then converts proceeds into yielding banks to earn the yield spread\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"YieldingCarryPosition\"\n }\n },\n 3\n ]\n }\n },\n {\n \"name\": \"_padding0\",\n \"type\": {\n \"array\": [\n \"u64\",\n 19\n ]\n }\n },\n {\n \"name\": \"lending_positions\",\n \"docs\": [\n \"Lending positions across supported platforms (e.g. Marginfi, Kamino) where collateral is deployed\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"LendingPosition\"\n }\n },\n 6\n ]\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 128\n ]\n }\n },\n {\n \"name\": \"roles\",\n \"docs\": [\n \"Per-token authorization roles. Unset fields fall back to program-level defaults.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"TokenRoles\"\n }\n }\n },\n {\n \"name\": \"fee_drip\",\n \"docs\": [\n \"Mint/burn fee-drip buffer and APY reference. Appended after `roles`\",\n \"(consuming reserved padding) so all preceding field offsets stay stable\",\n \"for already-deployed accounts.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"FeeDripState\"\n }\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 164\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"TokenAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"price\",\n \"docs\": [\n \"Price here is denominated in the collateral mint price\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"total_supply\",\n \"docs\": [\n \"Total number of tokens in circulating supply (includes pending protocol fees)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvl_usd\",\n \"docs\": [\n \"Total TVL of a token. All collateral + YBA carry positions - debt\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"last_refreshed_ts\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"first_mint_ts\",\n \"docs\": [\n \"First successful mint timestamp. Remains 0 until first mint.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pending_protocol_fees\",\n \"docs\": [\n \"Protocol fees accrued but not yet minted (collected via `collect_fees`\",\n \"by `PROTOCOL_ADMIN`).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pending_curator_fees\",\n \"docs\": [\n \"Curator fees accrued but not yet minted (collected via `collect_fees`\",\n \"by the token's curator).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pending_async_redemption_liability\",\n \"docs\": [\n \"Collateral claim from async redemption requests that has not yet been\",\n \"settled. This is tracked separately so redemption-specific unwind losses\",\n \"can reduce the liability instead of active-holder NAV.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pending_async_burn_amount\",\n \"docs\": [\n \"yTokens currently escrowed in async burn requests and awaiting FIFO\",\n \"fulfillment.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pending_async_fee_retained\",\n \"docs\": [\n \"Protocol + curator fee tokens within `pending_async_burn_amount` that\",\n \"will be retained in `total_supply` as pending fees when the burn is\",\n \"processed.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"pending_unwind_residual\",\n \"docs\": [\n \"Collateral retained from async burners as their share of epoch unwind\",\n \"losses (`loss_for_request` in `process_async_burn`). Physically part of\",\n \"the collateral balance (and of `unlent_amount`), but earmarked to cover\",\n \"the carry−debt deficit the epoch unwind left behind. The price formula\",\n \"excludes `min(residual, hidden deficit)` from the price basis so the\",\n \"residual doesn't inflate the price while the deficit it funds is still\",\n \"clamped out of it; `recollateralize_loss` consumes it before undripped\",\n \"fees and ordinary collateral backing as the deficit is closed.\"\n ],\n \"type\": \"u64\"\n }\n ]\n }\n },\n {\n \"name\": \"TokenConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"id\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 6\n ]\n }\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The token's mint address\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"decimals\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"token_program\",\n \"type\": {\n \"defined\": {\n \"name\": \"TokenProgram\"\n }\n }\n },\n {\n \"name\": \"interest_distribution\",\n \"docs\": [\n \"Determines how accrued interest is distributed — either folded into\",\n \"the token price (rebase) or sent directly to holder wallets\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"InterestDistribution\"\n }\n }\n },\n {\n \"name\": \"circuit_breaker\",\n \"docs\": [\n \"When active, halts all activity except decrease_carry_position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"PodBool\"\n }\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u8\",\n 4\n ]\n }\n },\n {\n \"name\": \"_padding3\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"burn_rate_limit\",\n \"docs\": [\n \"Rolling rate limit on burn (redemption) volume per time window.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"AmountRateLimit\"\n }\n }\n },\n {\n \"name\": \"deposit_limit\",\n \"docs\": [\n \"Maximum total collateral backing the token, in raw collateral base units.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding4\",\n \"type\": {\n \"array\": [\n \"u64\",\n 6\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"TokenFees\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"performance_fee_bps\",\n \"docs\": [\n \"The protocol fee to take against the yield that has been earned.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"minting_fee_bps\",\n \"docs\": [\n \"The fee to take when minting new tokens. Split between protocol, curator,\",\n \"and token price per the `*_mint_burn_pct_bps` fields below.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"burning_fee_bps\",\n \"docs\": [\n \"The fee to take when burning tokens. Split between protocol, curator,\",\n \"and token price per the `*_mint_burn_pct_bps` fields below.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"protocol_mint_burn_pct_bps\",\n \"docs\": [\n \"Protocol's share of mint/burn fees (in bps of `total_fee`).\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curator_mint_burn_pct_bps\",\n \"docs\": [\n \"Curator's share of mint/burn fees (in bps of `total_fee`).\",\n \"`protocol_mint_burn_pct_bps + curator_mint_burn_pct_bps <= 10_000`; the\",\n \"remainder (if any) stays in the token price.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"curator_perf_pct_bps\",\n \"docs\": [\n \"Curator's share of performance fees (in bps of `total_perf_fee`).\",\n \"The protocol implicitly receives `10_000 - curator_perf_pct_bps`.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"fee_drip_max_apy_bps\",\n \"docs\": [\n \"Target and hard cap (in bps) for annualized token-price growth during fee\",\n \"release. Refreshes release enough buffered collateral to approach this\",\n \"target without exceeding it. Natural yield can exceed the target and\",\n \"cannot be clawed back. `0` parks the buffer.\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 2\n ]\n }\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 5\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"TokenProgram\",\n \"repr\": {\n \"kind\": \"rust\"\n },\n \"type\": {\n \"kind\": \"enum\",\n \"variants\": [\n {\n \"name\": \"Spl\"\n },\n {\n \"name\": \"Token2022\"\n }\n ]\n }\n },\n {\n \"name\": \"TokenRefreshRefs\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lending_positions\",\n \"docs\": [\n \"Per active lending position (in active-slot order, skipping inactive slots).\"\n ],\n \"type\": {\n \"vec\": {\n \"defined\": {\n \"name\": \"LpRefIndices\"\n }\n }\n }\n },\n {\n \"name\": \"carry_positions\",\n \"docs\": [\n \"Per active carry position (in active-slot order, skipping zero-share slots):\",\n \"index of the `YieldingBank` account in `remaining_accounts`.\"\n ],\n \"type\": \"bytes\"\n }\n ]\n }\n },\n {\n \"name\": \"TokenRoles\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"_padding0\",\n \"docs\": [\n \"Reserved space that keeps the role fields at their existing offsets\",\n \"after reducing the token's lending-position capacity.\"\n ],\n \"type\": {\n \"array\": [\n \"u64\",\n 16\n ]\n }\n },\n {\n \"name\": \"curator\",\n \"docs\": [\n \"The whitelisted curator that created this token. Treated as the \\\"creator\\\"\",\n \"and used for cross-state curator-match checks (e.g. increase_carry_position\",\n \"requires token.curator == yielding_bank.curator). Rotatable by the token\",\n \"admin to another `WHITELISTED_CURATORS` entry via\",\n \"`update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"admin\",\n \"docs\": [\n \"Authority for token-level config updates, metadata changes, fee edits, and\",\n \"circuit-breaker deactivation. Intended to be a multisig in production.\",\n \"Rotatable by the current admin via `update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"manager\",\n \"docs\": [\n \"Ops wallet authorized to run manager-gated instructions (increase_carry_position,\",\n \"collect_interest, rebalance, deposit_unlent_collateral, claim_incentives, etc).\",\n \"Rotatable via `update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"fees\",\n \"docs\": [\n \"Curator's fee wallet — receives the curator's share of mint/burn fees and\",\n \"performance fees. Rotatable by the token admin or the token curator via\",\n \"`update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"cb_controller\",\n \"docs\": [\n \"Emergency-halt wallet authorized to *activate* the circuit breaker.\",\n \"Deactivation remains admin-only and time-gated. Rotatable via\",\n \"`update_token_configuration`.\"\n ],\n \"type\": \"pubkey\"\n }\n ]\n }\n },\n {\n \"name\": \"TopUpUnlentReservesParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"prerequisite_cpis\",\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"ix_refs\",\n \"type\": {\n \"defined\": {\n \"name\": \"InstructionRefs\"\n }\n }\n },\n {\n \"name\": \"lending_position_index\",\n \"type\": \"u8\"\n }\n ]\n }\n },\n {\n \"name\": \"UpdateLendingPositionConfigParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"lending_position_index\",\n \"docs\": [\n \"Index into the token's lending_positions array\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"target_utilization_rate_bps\",\n \"docs\": [\n \"Target LTV utilization rate in basis points (relative to max LTV)\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"max_deviation_above_target_util_bps\",\n \"docs\": [\n \"Max bps the utilization rate can exceed target before permissionless unwind is allowed\"\n ],\n \"type\": \"u16\"\n },\n {\n \"name\": \"max_deviation_below_target_util_bps\",\n \"docs\": [\n \"Max bps the utilization rate can fall below target before carry trade increase is allowed\"\n ],\n \"type\": \"u16\"\n }\n ]\n }\n },\n {\n \"name\": \"UpdateTokenConfigurationParams\",\n \"docs\": [\n \"Parameters for updating a token's mutable configuration.\",\n \"\",\n \"Every field is optional: `None` means \\\"no change\\\". Oracle configuration is\",\n \"immutable after creation — use `create_token` to set the oracle, and deploy a\",\n \"new token if it needs to change.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"performance_fee_bps\",\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"minting_fee_bps\",\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"burning_fee_bps\",\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"protocol_mint_burn_pct_bps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the protocol (in bps)\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"curator_mint_burn_pct_bps\",\n \"docs\": [\n \"Percentage of mint/burn fees that go to the curator (in bps)\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"curator_perf_pct_bps\",\n \"docs\": [\n \"Curator's share of performance fees (in bps); protocol implicitly gets the rest.\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"fee_drip_max_apy_bps\",\n \"docs\": [\n \"Target and hard cap (bps) for annualized price growth during fee release.\",\n \"`Some(0)` parks absorbed fees.\"\n ],\n \"type\": {\n \"option\": \"u16\"\n }\n },\n {\n \"name\": \"burn_rate_limit\",\n \"docs\": [\n \"Optional burn-rate-limit config update; omitted leaves the current config unchanged.\"\n ],\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"BurnRateLimitUpdateParams\"\n }\n }\n }\n },\n {\n \"name\": \"deposit_limit\",\n \"docs\": [\n \"Optional cap on total collateral backing (unlent + lent), in raw collateral base units.\",\n \"`None` leaves unchanged. `Some(0)` disables the cap (same semantics as `mint_token`).\",\n \"For `Some(limit)` with `limit > 0`, `limit` must be ≥ that total or the instruction errors.\"\n ],\n \"type\": {\n \"option\": \"u64\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"UpdateYieldingBankConfigParams\",\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": []\n }\n },\n {\n \"name\": \"YieldingAccounting\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"total_shares\",\n \"docs\": [\n \"Total shares outstanding across all token carry positions allocated to this bank,\",\n \"stored in raw share units scaled by the yielding bank `config.decimals`\",\n \"(canonically 8 share decimals).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"share_price\",\n \"docs\": [\n \"Price per whole UI share, stored in the shared 8-decimal USD base unit\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"last_refreshed_ts\",\n \"docs\": [\n \"Timestamp of the last share price refresh\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvl\",\n \"docs\": [\n \"Total TVL across all YBA holdings and external lending positions,\",\n \"normalized to the shared 8-decimal USD base unit ($1 = 100_000_000).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"last_rebalanced_ts\",\n \"docs\": [\n \"Timestamp of the last time the yielding bank has been rebalanced\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 19\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"YieldingBank\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"config\",\n \"type\": {\n \"defined\": {\n \"name\": \"YieldingConfig\"\n }\n }\n },\n {\n \"name\": \"accounting\",\n \"type\": {\n \"defined\": {\n \"name\": \"YieldingAccounting\"\n }\n }\n },\n {\n \"name\": \"base_asset\",\n \"docs\": [\n \"The base mint asset holding — always present, never cleared by cleanup.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"AssetHolding\"\n }\n }\n },\n {\n \"name\": \"assets\",\n \"docs\": [\n \"Additional asset holdings beyond the base mint.\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"AssetHolding\"\n }\n },\n 12\n ]\n }\n },\n {\n \"name\": \"external_yielding_positions\",\n \"docs\": [\n \"Positions in external lending/vault protocols that actively generate yield\"\n ],\n \"type\": {\n \"array\": [\n {\n \"defined\": {\n \"name\": \"ExternalYielding\"\n }\n },\n 6\n ]\n }\n },\n {\n \"name\": \"roles\",\n \"docs\": [\n \"Per-yielding-bank authorization roles. Unset fields fall back to program-level defaults.\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"YieldingBankRoles\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u64\",\n 144\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"YieldingBankAllocationConfig\",\n \"docs\": [\n \"Argument on `rebalance_yielding_bank` to register one new holding or\",\n \"external position that the rebalance will fund. At most one of the two\",\n \"fields may be `Some` per call.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"asset_holding\",\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"AssetConfig\"\n }\n }\n }\n },\n {\n \"name\": \"external_position\",\n \"type\": {\n \"option\": {\n \"defined\": {\n \"name\": \"ExternalPositionConfig\"\n }\n }\n }\n }\n ]\n }\n },\n {\n \"name\": \"YieldingBankRoles\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"curator\",\n \"docs\": [\n \"The whitelisted curator that created this yielding bank. Must match the\",\n \"token's curator when attaching a carry position via `increase_carry_position`.\",\n \"Rotatable by the bank admin to another `WHITELISTED_CURATORS` entry via\",\n \"`update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"admin\",\n \"docs\": [\n \"Authority for yielding-bank config updates and circuit-breaker deactivation.\",\n \"Intended to be a multisig in production. Rotatable by the current admin via\",\n \"`update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"manager\",\n \"docs\": [\n \"Ops wallet authorized to run manager-gated instructions on this bank\",\n \"(rebalance_yielding_bank, create_yielding_bank_allocation). Rotatable\",\n \"via `update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"cb_controller\",\n \"docs\": [\n \"Emergency-halt wallet authorized to activate the circuit breaker. Deactivation\",\n \"remains admin-only and time-gated. Rotatable via `update_yielding_bank_config`.\"\n ],\n \"type\": \"pubkey\"\n }\n ]\n }\n },\n {\n \"name\": \"YieldingCarryPosition\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"yielding_base_mint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"yielding_bank_id\",\n \"docs\": [\n \"Identifier for the yield-bearing asset bank this carry position is allocated to\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 7\n ]\n }\n },\n {\n \"name\": \"shares\",\n \"docs\": [\n \"Number of shares held in the yielding bank (converts to underlying via bank share price)\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"tvl_usd\",\n \"docs\": [\n \"Raw USD value of this token's share of the yielding bank, normalized to\",\n \"8-decimal USD ($1 = 100_000_000).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding3\",\n \"type\": {\n \"array\": [\n \"u64\",\n 12\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"YieldingConfig\",\n \"serialization\": \"bytemuck\",\n \"repr\": {\n \"kind\": \"c\"\n },\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"base_mint\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"bump\",\n \"type\": \"u8\"\n },\n {\n \"name\": \"id\",\n \"docs\": [\n \"Unique identifier for this bank, used in PDA derivation and referenced by token carry positions\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"decimals\",\n \"docs\": [\n \"Share precision for `total_shares` accounting and share-price math.\",\n \"Canonically 8 so one whole UI share is priced in the shared TVL USD base unit.\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"circuit_breaker\",\n \"docs\": [\n \"When active, halts all activity except decrease_carry_position\"\n ],\n \"type\": {\n \"defined\": {\n \"name\": \"PodBool\"\n }\n }\n },\n {\n \"name\": \"_padding1\",\n \"type\": {\n \"array\": [\n \"u8\",\n 4\n ]\n }\n },\n {\n \"name\": \"default_redemption_mint\",\n \"docs\": [\n \"The mint that should be used as the default source when redeeming\",\n \"(e.g. swapping from this mint into a debt mint during decrease_carry_position).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"time_created_ts\",\n \"docs\": [\n \"Unix timestamp when this yielding bank was created.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"_padding2\",\n \"type\": {\n \"array\": [\n \"u64\",\n 18\n ]\n }\n }\n ]\n }\n }\n ]\n} as unknown as LongYieldCarry;\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 { Address } from \"@solana/kit\";\nimport { fromUiAmount } from \"common\";\nimport type { YieldingBankExternalLiquiditySource } from \"../client/types\";\n\n/**\n * PodBool is a Rust `#[repr(transparent)]` newtype over `u8`.\n * Anchor deserializes tuple-struct fields using positional integer keys, so\n * `PodBool(1)` arrives from the RPC as `{ '0': 1 }` instead of a plain number.\n *\n * This helper extracts the underlying u8 value so callers work with a plain\n * number rather than the intermediate struct object.\n */\nexport function podBoolToNumber(val: { 0: number } | number): number {\n if (typeof val === \"number\") return val;\n return (val as Record<string | number, number>)[0] ?? 0;\n}\n\n/**\n * Build external-liquidity source descriptors for one mint across multiple accounts.\n */\nexport function toYieldingBankExternalLiquiditySources(\n mint: Address,\n accounts: Address[]\n): YieldingBankExternalLiquiditySource[] {\n return accounts.map((account) => ({ mint, account }));\n}\n\n/**\n * Convert a raw token amount and raw oracle price into 8-decimal USD TVL units.\n */\nexport function amountToTvl(\n amount: number | bigint | BN,\n price: number | bigint | BN,\n decimals: number\n): BN {\n const amountBn = new BN(amount.toString());\n const priceBn = new BN(price.toString());\n const assetScale = fromUiAmount(1, decimals);\n const tvlScale = fromUiAmount(1, 8);\n const scaleFactor = assetScale.mul(assetScale).div(tvlScale);\n return amountBn.mul(priceBn).div(scaleFactor);\n}\n\nconst EPOCH_BUCKET_MS = 60_000;\n\n/**\n * Generate a redemption epoch ID by flooring `Date.now()` to the nearest minute.\n * Burns within the same 60-second window will share an epoch PDA, allowing the\n * manager to batch-process them together.\n */\nexport function currentEpochId(): BN {\n return new BN(Math.floor(Date.now() / EPOCH_BUCKET_MS) * EPOCH_BUCKET_MS);\n}\n","/**\n * Collectable net yield in 8-decimal normalized USD: any carry surplus above\n * debt. Returns `0n` when carry TVL does not exceed debt TVL.\n *\n * Used by SDK planning and metrics to size collect-interest attempts.\n *\n * @param totalCarryTvlUsd Aggregate carry-position TVL (8-dec USD).\n * @param totalDebtUsd Aggregate lending-position debt TVL (8-dec USD).\n */\nexport function collectableNetYieldUsd(totalCarryTvlUsd: bigint, totalDebtUsd: bigint): bigint {\n return totalCarryTvlUsd > totalDebtUsd ? totalCarryTvlUsd - totalDebtUsd : 0n;\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 { type Address, Rpc, SolanaRpcApi, TransactionSigner } from \"@solana/kit\";\nimport { ADDRESS_LOOKUP_TABLE_PROGRAM_ADDRESS } from \"@solana-program/address-lookup-table\";\nimport { COMPUTE_BUDGET_PROGRAM_ADDRESS } from \"@solana-program/compute-budget\";\nimport { SYSTEM_PROGRAM_ADDRESS } from \"@solana-program/system\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { TOKEN_2022_PROGRAM_ADDRESS } from \"@solana-program/token-2022\";\nimport {\n DEFAULT_PUBLIC_KEY,\n dedupeOrderedAddresses,\n type DeployedEnv,\n type Environment,\n JITO_TIP_ACCOUNTS,\n LendingPlatform,\n type MintIdentifier,\n fromWeb3Pk,\n getAtaAddress,\n getRpcUrl,\n lendingPlatformToEnum,\n lutManager,\n mints,\n resolveTokenProgram,\n} from \"common\";\nimport { oracle } from \"oracle\";\nimport {\n getGeneralLookupTableAccountsForPerena,\n PERENA_PROGRAM_ID,\n PerenaClient,\n} from \"perena-helpers\";\nimport { LongYieldCarryClient } from \"../client/client\";\nimport { LYCToken } from \"../models/lycToken\";\nimport { GENERAL_LOOKUP_TABLES, MANAGER, PROGRAM_ID } from \"../constants/general\";\nimport { TOKEN_LOOKUP_TABLES } from \"../constants\";\n\n/**\n * Oracle account when {@link oracle} can resolve Pyth, Switchboard, or a custom feed.\n * Not exported — module-local helper (TypeScript has no `private` on file-level functions).\n */\nfunction tryOracleAddress(mint: MintIdentifier): Address | undefined {\n try {\n return oracle.getOracleData(mint).oracle;\n } catch {\n return undefined;\n }\n}\n\n/** Registry stablecoins + YBAs — used for yielding-bank ATA derivation. */\nconst DEBT_AND_YBA_MINT_INFOS = [...mints.stablecoins(), ...mints.yieldBearingAssets()];\n\n/** Registry Standard + LST mints — risk / collateral-style assets (oracle-only on general LUT). */\nconst RISK_ASSET_MINT_INFOS = [\n ...mints.filterAssetsByType(\"Standard\"),\n ...mints.filterAssetsByType(\"LST\"),\n];\n\n/**\n * Stablecoin + YBA mints with registry oracles for the general LUT.\n * Risk assets (Standard + LST registry entries): oracle only — mints stay on each token's LUT via on-chain collateral.\n * Not exported — module-local helper.\n */\nfunction getMintRegistryAccountsForGeneralLut(): Address[] {\n const out: Address[] = [];\n for (const m of DEBT_AND_YBA_MINT_INFOS) {\n out.push(m.address);\n const o = tryOracleAddress(m.address);\n if (o) {\n out.push(o);\n }\n }\n for (const m of RISK_ASSET_MINT_INFOS) {\n const o = tryOracleAddress(m.address);\n if (o) {\n out.push(o);\n }\n }\n return out;\n}\n\n/**\n * Every YieldingBank PDA plus, for each bank, the ATA for each registry stablecoin and YBA mint.\n * Not exported — module-local helper.\n */\nasync function getYieldingBankAccountsForGeneralLut(\n client: LongYieldCarryClient\n): Promise<Address[]> {\n const banks = await client.account.fetchAllYieldingBanks();\n const out: Address[] = [];\n\n for (const b of banks) {\n out.push(b.address);\n for (const m of DEBT_AND_YBA_MINT_INFOS) {\n out.push(await getAtaAddress(m.address, b.address, m.tokenProgram));\n }\n }\n return out;\n}\n\n/**\n * Get the specific lookup table for the given Token PDA (if it exists).\n *\n * `TOKEN_LOOKUP_TABLES` is keyed by Token PDA address.\n */\nexport function getLookupTableForToken(tokenPda: Address) {\n if (tokenPda in TOKEN_LOOKUP_TABLES) {\n return TOKEN_LOOKUP_TABLES[tokenPda];\n }\n}\n\n/**\n * Assembles lookup table addresses for LYC transaction plans: the deployment\n * general LUT (when not `local`), any registered per-token LUT for the given\n * token PDAs, then any CPI/swap tables. Entries are omitted when missing or\n * equal to the default (unused) public key; duplicates are removed in first-seen\n * order.\n */\nexport function mergeLycLookupTables(\n environment: Environment,\n tokenPda?: Address | readonly Address[],\n existingLookupTables?: readonly Address[]\n): Address[] {\n const all: (Address | undefined)[] = [];\n\n if (environment !== \"local\") {\n all.push(GENERAL_LOOKUP_TABLES[environment as DeployedEnv]);\n }\n\n if (tokenPda !== undefined) {\n for (const t of Array.isArray(tokenPda) ? tokenPda : [tokenPda]) {\n all.push(getLookupTableForToken(t));\n }\n }\n\n if (existingLookupTables) {\n all.push(...existingLookupTables);\n }\n\n const valid = all.filter((a): a is Address => a !== undefined && a !== DEFAULT_PUBLIC_KEY);\n return [...new Set(valid)];\n}\n\n/**\n * Refresh per-token lookup tables for every Token account owned by the program.\n *\n * @param client - Initialized client (provides RPC-backed account fetch and Kamino helpers).\n */\nexport async function updateTokenLutsIfNeeded(\n signer: TransactionSigner,\n rpc: Rpc<SolanaRpcApi>,\n client: LongYieldCarryClient\n) {\n const tokens = await client.account.fetchAllTokens();\n for (const t of tokens) {\n await updateTokenLutIfNeeded(signer, rpc, client, t);\n }\n}\n\n/**\n * Extend the per-token lookup table with addresses needed for that token's\n * instructions: mints, token/YB ATAs, registry debt-mint ATAs for the token PDA, lending protocol accounts, Kamino\n * obligation ATAs when applicable. Lending reserve accounts live on the\n * lending-platform LUT; price oracles for registry-listed debt/YBAs and risk\n * assets live on the general LUT.\n *\n * Collateral mint is read from on-chain token state (it is not a PDA).\n *\n * @param client - Used for Kamino reserve metadata and reserve interaction ATAs.\n * @param token - Fetched token model (`LYCToken`); avoids an extra fetch.\n */\nexport async function updateTokenLutIfNeeded(\n signer: TransactionSigner,\n rpc: Rpc<SolanaRpcApi>,\n client: LongYieldCarryClient,\n token: LYCToken\n) {\n const kaminoClient = client.getLendingPlatformClientByPlatform(LendingPlatform.Kamino);\n const allAccounts: Address[] = [];\n\n const tokenPda = token.address;\n const yMint = token.mint;\n const collateralMint = token.collateralMint;\n const collateralTp = resolveTokenProgram(token.data.collateral.tokenProgram);\n const yTokenTp = resolveTokenProgram(token.data.config.tokenProgram);\n\n allAccounts.push(tokenPda, yMint, collateralMint);\n allAccounts.push(\n await getAtaAddress(collateralMint, tokenPda, collateralTp),\n await getAtaAddress(yMint, tokenPda, yTokenTp)\n );\n\n for (const m of mints.stablecoins()) {\n allAccounts.push(await getAtaAddress(m.address, tokenPda, m.tokenProgram));\n }\n\n for (const position of token.data.lendingPositions) {\n const platform = lendingPlatformToEnum(position.platform);\n if (platform === LendingPlatform.None) {\n continue;\n }\n\n allAccounts.push(fromWeb3Pk(position.protocolUserAcc));\n\n const debtMint = fromWeb3Pk(position.accounting.debt.mint);\n const debtTp = resolveTokenProgram(position.accounting.debt.tokenProgram);\n allAccounts.push(await getAtaAddress(debtMint, tokenPda, debtTp));\n\n if (platform === LendingPlatform.Kamino) {\n const pool = fromWeb3Pk(position.pool);\n const userAcc = fromWeb3Pk(position.protocolUserAcc);\n for (const reserve of [\n fromWeb3Pk(position.collateralReserve),\n fromWeb3Pk(position.debtReserve),\n ]) {\n const details = await kaminoClient.accounts.reserveInteractionDetails(\n tokenPda,\n pool,\n reserve,\n userAcc\n );\n allAccounts.push(\n details.userLiquidityTa.address,\n details.userCollateralTa.address,\n userAcc\n );\n\n const userFarmAddresses = await kaminoClient.accounts.getUserFarmAddresses(\n pool,\n reserve,\n userAcc\n );\n allAccounts.push(...userFarmAddresses);\n }\n }\n }\n\n console.log(\"Updating token LUT for token:\", tokenPda);\n lutManager.clearCache();\n await lutManager.updateLookupTable(signer, rpc, allAccounts, getLookupTableForToken(tokenPda));\n}\n\n/**\n * Extend the shared general lookup table: program IDs, well-known SPL programs,\n * stablecoin and YBA mints (plus registry oracles), Standard + LST oracle accounts,\n * Perena program id, every on-chain YieldingBank PDA, each bank’s ATAs for\n * all registry debt mints (stablecoins) and yield-bearing assets, the canonical\n * Jito tip accounts (referenced by every Jito-bundle tip ix), the ComputeBudget\n * program (referenced by every CU-limit ix), and the deployment's manager.\n *\n * Risk asset (Standard + LST) mints are omitted here; they appear on each token LUT\n * as collateral.\n *\n * Uses {@link GENERAL_LOOKUP_TABLES} for {@link LongYieldCarryClient.environment}\n * (`test` | `prod` only) and only that tier’s program ID.\n *\n * @throws If `client.environment` is `local` — there is no pinned general LUT for local.\n */\nexport async function updateGeneralLutIfNeeded(\n signer: TransactionSigner,\n rpc: Rpc<SolanaRpcApi>,\n client: LongYieldCarryClient\n): Promise<Address> {\n const deployedEnv = client.environment;\n\n if (deployedEnv === \"local\") {\n throw new Error(\n \"updateGeneralLutIfNeeded requires LongYieldCarryClient built with test or prod; local has no GENERAL_LOOKUP_TABLES entry.\"\n );\n }\n\n const registryAccounts = getMintRegistryAccountsForGeneralLut();\n const yieldingBankAccounts = await getYieldingBankAccountsForGeneralLut(client);\n const perenaAccounts = await getGeneralLookupTableAccountsForPerena(\n new PerenaClient(getRpcUrl(deployedEnv))\n );\n\n const allAccounts: Address[] = [\n PROGRAM_ID[deployedEnv],\n SYSTEM_PROGRAM_ADDRESS,\n TOKEN_PROGRAM_ADDRESS,\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n TOKEN_2022_PROGRAM_ADDRESS,\n COMPUTE_BUDGET_PROGRAM_ADDRESS,\n DEFAULT_PUBLIC_KEY,\n ADDRESS_LOOKUP_TABLE_PROGRAM_ADDRESS,\n PERENA_PROGRAM_ID,\n MANAGER[deployedEnv],\n ...JITO_TIP_ACCOUNTS,\n ...registryAccounts,\n ...perenaAccounts,\n ...yieldingBankAccounts,\n ];\n\n lutManager.clearCache();\n return lutManager.updateLookupTable(\n signer,\n rpc,\n dedupeOrderedAddresses(allAccounts),\n GENERAL_LOOKUP_TABLES[deployedEnv]\n );\n}\n","import { BN } from \"@anchor-lang/core\";\nimport { Address, address } from \"@solana/kit\";\nimport {\n DEPLOYED_ADMIN_KEYPAIR_FP,\n PROTOCOL_ADMIN,\n type DeployedEnv,\n type Environment,\n} from \"common\";\n\n/** Program ID per environment */\nexport const PROGRAM_ID: Record<Environment, Address> = {\n local: address(\"7YPAKESPJ7zJAvBuk45ZVziu6tXGKoNzg3p9YpvrH6pX\"),\n test: address(\"7C39GeKrqLygmgV9D4bicUaiyFhKrX6Eevk6PDACwuj7\"),\n prod: address(\"LYC8YiiSzQfPpxUW2tpxfuPKGZwywAJhXKUfDP2B66f\"),\n};\n\n/** Deployed `long_yield_carry` program IDs. */\nexport const LYC_PROGRAM_IDS = new Set<string>(Object.values(PROGRAM_ID).map(String));\n\n/** Manager authority for manager-gated instruction accounts */\nexport const MANAGER: Record<Environment, Address> = {\n local: address(\"4g1CzxGL2hopch95Aeww9RrQjx3NPq7NgN9QFK7jx8X1\"),\n test: address(\"AqB478KVcoBwV39QjftJQ6qvV9xTh8CYB9jEnc2XSNLu\"),\n prod: address(\"2kv6b4wmbF2ausJ3spLDzpNCei64NzCkHKQhyL2sQgWu\"),\n};\n\n/** Circuit breaker controller for circuit-breaker-gated instruction accounts */\nexport const CIRCUIT_BREAKER_CONTROLLER: Record<Environment, Address> = {\n local: address(\"CAcAFXBQBbr5xpESdbd9L1tEijPq1o2bdxju56qMZssj\"),\n test: address(\"Wrj4caR4RJcmPgrRBE3HyFVMRKEmd2Y1ZuChbcjdeQu\"),\n prod: address(\"Fpm61bZCvoucprM5YQJRS2V9nSduvjQDn3h7pfCRL4Ld\"),\n};\n\n/** Re-exported from `common` — see {@link PROTOCOL_ADMIN} there. */\nexport { PROTOCOL_ADMIN };\n\n/**\n * Protocol fee wallet — receives the protocol share of mint/burn + perf fees\n * and serves as the on-chain fallback for a token's `roles.fees` when unset\n * (`TokenRoles::curator_fee_wallet()` delegates to `protocol_fee_wallet()`).\n */\nexport const PROTOCOL_FEE_WALLET: Record<Environment, Address> = {\n local: address(\"Fo6ihiHavRRnFG7k24JgwxNqVt6j7FWAWxDwoGoKd2MY\"),\n test: address(\"8L2dWQqs6oQW6GCwp3fuosFTi5uCRJcbhhCKkjtyFG2e\"),\n prod: address(\"Fo6ihiHavRRnFG7k24JgwxNqVt6j7FWAWxDwoGoKd2MY\"), // TODO\n};\n\n/** Redemption epoch status: accepting new async burn requests. */\nexport const REDEMPTION_EPOCH_STATUS_OPEN = 0;\n/** Redemption epoch status: closed to new requests, collateral being funded. */\nexport const REDEMPTION_EPOCH_STATUS_FUNDING = 1;\n/** Redemption epoch status: funded, individual burn requests being processed. */\nexport const REDEMPTION_EPOCH_STATUS_PROCESSING = 2;\n\n/**\n * On-chain `TokenAccounting::MAX_FRESHNESS_SECS` = ONE_HOUR (3600s).\n * We use a 120s buffer so the refresh lands before on-chain staleness kicks in.\n */\nexport const TOKEN_STALENESS_THRESHOLD_SECS = 3600 - 120;\n\n/** Maximum heap-frame size requested by composed multi-CPI transactions. */\nexport const MAX_HEAP_FRAME_BYTES = 256 * 1024;\n\n/**\n * Mirror of the on-chain `REBALANCE_TOKEN_RATE_LIMIT_SECS` (24 hours). The\n * program rejects a `rebalance_token` on a lending position that was already\n * rebalanced within this window (`RebalanceRateLimited`); the SDK skips such\n * candidates client-side so we never build a transaction that would revert.\n */\nexport const REBALANCE_TOKEN_RATE_LIMIT_SECS = 24 * 60 * 60;\n\n/** Default recollateralize-loss swap slippage, capped by the on-chain 150 bps check. */\nexport const DEFAULT_RECOLLATERALIZE_LOSS_SLIPPAGE_BPS = 150;\n\n/**\n * Minimum claimable reward (in the reward token's UI units) for an incentive to\n * be worth harvesting. Below this, the on-chain `HarvestReward` moves only dust\n * while still costing a transaction fee, so `getOutstandingIncentives` omits it.\n */\nexport const DEFAULT_MIN_INCENTIVE_UI_AMOUNT = 0.01;\n\n/**\n * Sentinel value (u64::MAX) that callers can pass as an amount to `mint_token`\n * or `burn_token` to indicate \"use the entire balance\".\n * - mint_token: deposits the full collateral ATA balance.\n * - burn_token: burns the full yToken ATA balance.\n */\nexport const AMOUNT_ALL_SENTINEL = new BN(\"18446744073709551615\");\n\n/** Re-exported from `common` — see {@link DEPLOYED_ADMIN_KEYPAIR_FP} there. */\nexport const LYC_ADMIN_KEYPAIR_FP = DEPLOYED_ADMIN_KEYPAIR_FP;\n\n/**\n * Filesystem paths to the manager keypair for future manager CLI scripts,\n * fixed per deployment tier (no env overrides).\n */\nexport const LYC_MANAGER_KEYPAIR_FP: Record<DeployedEnv, string> = {\n test: \"~/.config/solana/tp/lyc-manager-test.json\",\n prod: \"~/.config/solana/tp/lyc-manager-prod.json\",\n};\n\n/**\n * Filesystem paths to the circuit breaker controller keypair.\n * Used by emergency scripts (trigger circuit breaker, reset burn rate limit).\n */\nexport const LYC_CB_KEYPAIR_FP: Record<DeployedEnv, string> = {\n test: \"~/.config/solana/tp/lyc-cb-test.json\",\n prod: \"~/.config/solana/tp/lyc-cb-prod.json\",\n};\n\n/**\n * Shared general LUT per remote deployment tier (`test` | `prod`), same split as\n * {@link LYC_ADMIN_KEYPAIR_FP}. Populate via `pnpm run update-general-lut -- test|prod`.\n */\nexport const GENERAL_LOOKUP_TABLES: Record<DeployedEnv, Address> = {\n test: address(\"GbiTxgWknTyRD2qwCvtytPXa1KnCwJWqakH4mJRpU3mF\"),\n prod: address(\"4ZP1hmYuePwAwmr2uHvjRL12okdG2krf4A9sacSxvHcs\"),\n};\n\nexport const TOKEN_LOOKUP_TABLES: Record<Address, Address> = {\n // TEST\n [address(\"7fEA5HTsveMn5HfnXN82nmTniXeWDs6YJuvLyk7qFcNG\")]: address(\n \"HTBxsGsKgfMmPVuxdia1PQkdATUrFofmbJAtC7he6qEK\"\n ),\n [address(\"2BGSs7s5mSJgSCMcppAaQj5Ppp1kHmQNQ9ESoGWK2Hmx\")]: address(\n \"5UmqM2LE4RwpF91aXiXNVB5tSJKsLoVfxLA3gc6Qrj35\"\n ),\n [address(\"6qtzJnVn6nTZXJhcAUgmofKsTYuaSp8ag1BcxcE9EEz7\")]: address(\n \"DJstSjLyA4KwhgRh3s1Bd28eSoke8st6nAXTDNVtckqj\"\n ),\n [address(\"3m9Nx5ZCghjsMPmBpJm1ZWb27SUHLzdUJdwb2mquo3Kb\")]: address(\n \"3bZYrhiqee6zPCvnXqMjNjtN5M7aPa4rebvmEtVUvGwG\"\n ),\n [address(\"HbhfU6ihxuzzpwmdgpWP5QC6HpemnMGZANCQEDQ7V92L\")]: address(\n \"EJSQZD9qzqaBacntUgouM9dmo9dgeBechNvASZ3V4NRr\"\n ),\n [address(\"GphwC2jwG3mcM8FYFFm5j8A4jNw3i7Hhic4poLbnoKpu\")]: address(\n \"6x8fiZxU6f82a3grAECC8nLuwkFoBPjFwAYhfpbeqw18\"\n ),\n [address(\"975Zp2WbD7WQfG6mTDPVUjc4mbEALMBXeyn4Pwr45f7p\")]: address(\n \"9ERF9KcYvehmMku9mqAvzhduDHpJu36pcvZ3xr2NJJ9o\"\n ),\n // PROD\n [address(\"6MSD4oSiJq8y5hmryCuMykyTjNXbhha6HSAtrT1EFKQe\")]: address(\n \"D5DndWnaEP7JN2vVftG2UE3v1AYjrG1zUPi9MTF67jmf\"\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 { Environment } from \"common\";\n\n/**\n * Display fields used as the fallback when on-chain Metaplex Token-Metadata\n * is missing or empty. Mirrors {@link OnchainTokenMetadata} on the read path\n * so the consumer can treat both sources uniformly.\n */\nexport interface LycTokenMetadataEntry {\n /** Brand-cased symbol shown as the primary label (e.g. \"ksBTC\", \"primeBTC\"). */\n symbol: string;\n /** Human-readable name (e.g. \"Kestrel BTC\", \"Prime BTC\"). */\n name: string;\n}\n\n/**\n * Curated fallback registry of LYC token display metadata, keyed by the\n * token's mint address. Only used when on-chain Metaplex Token-Metadata\n * isn't set yet — the on-chain value always wins.\n *\n * This exists because:\n * 1. Multiple LYC tokens can share the same underlying collateral\n * (e.g. ksBTC and primeBTC both built on cbBTC), so the LYC token's\n * symbol cannot be synthesized from the collateral's symbol alone.\n * 2. Metaplex `update_token_metadata` requires an admin transaction we\n * don't always run before a token starts surfacing in the UI.\n *\n * Keyed by environment because LYC mints are unique per program deployment.\n *\n * To populate, add the LYC token mint address as the key. Once metadata is\n * set on-chain via:\n *\n * pnpm --filter @kestrelfi/lyc-sdk run \\\n * update-token-metadata -- test|prod <TOKEN_PDA|COLLATERAL_SYMBOL> \\\n * --name \"<Display Name>\" --symbol \"<ksXXX>\" --uri \"<json uri>\"\n *\n * the entry here can be removed.\n */\nexport const LYC_TOKEN_METADATA: Record<Environment, Record<string, LycTokenMetadataEntry>> = {\n local: {},\n test: {\n EsMqszfbgHtVgh5N2q1wKSEQQAP4HqojRVjDgDo6MB4U: { symbol: \"ksBTC\", name: \"Kestrel BTC\" },\n JD9axkbp23WabWcVJJQfBvJ9z7Qn4A2zayHhRED8ynZq: { symbol: \"ksETH\", name: \"Kestrel ETH\" },\n GFMBAKop6cdzBTqW9PP2eKddowDgXZSK1P6Bp8rCuFFm: { symbol: \"ksSOL\", name: \"Kestrel SOL\" },\n \"2z8P6DvqPzii6vuNu8JGPFBrGHQ94Fjgi9hHQQ7JcS34\": {\n symbol: \"ksDFDVSOL\",\n name: \"Kestrel dfdvSOL\",\n },\n \"8k3eDWZ6wZkJcBWYS4tzmtHfk2HjqxmwkLzr8wixXAcj\": { symbol: \"ksQQQX\", name: \"Kestrel QQQx\" },\n \"9tPaWdEkjBYW3FbEBMt38wYAGdSWFj6wGXvzPrYwC4Bp\": { symbol: \"ksSPYX\", name: \"Kestrel SPYx\" },\n },\n prod: {},\n};\n","import { type Address } from \"@solana/kit\";\nimport { IdlTypes } from \"@anchor-lang/core\";\nimport {\n IX_SYSVAR_META,\n createMultiCpiRefs,\n type CustomAccountMeta,\n type InstructionRefs,\n toWeb3Pk,\n toCustomAccountMeta,\n} from \"common\";\nimport type { LongYieldCarry } from \"../idl/long_yield_carry\";\nimport type {\n AssetConfig,\n AssetAllocationConfig,\n DecreaseCarryPositionPlan,\n ExternalPositionConfig,\n YieldingBankAllocationConfig,\n} from \"../client/types\";\n\nfunction toAnchorAssetConfig(cfg: AssetConfig) {\n return {\n oracle: toWeb3Pk(cfg.oracle),\n oracleType: cfg.oracleType,\n externalLiquidity: cfg.externalLiquidityType,\n };\n}\n\nfunction toAnchorAssetAllocationConfig(cfg: AssetAllocationConfig) {\n return {\n mint: toWeb3Pk(cfg.mint),\n decimals: cfg.decimals,\n tokenProgram: cfg.tokenProgram,\n };\n}\n\nfunction toAnchorExternalPositionConfig(cfg: ExternalPositionConfig) {\n return {\n lendingPlatform: cfg.lendingPlatform,\n lendingType: cfg.lendingType,\n pool: toWeb3Pk(cfg.pool),\n collateralReserve: toWeb3Pk(cfg.collateralReserve),\n debtReserve: toWeb3Pk(cfg.debtReserve),\n protocolUserAcc: toWeb3Pk(cfg.protocolUserAcc),\n collateral: toAnchorAssetAllocationConfig(cfg.collateral),\n debt: toAnchorAssetAllocationConfig(cfg.debt),\n };\n}\n\nexport function toAnchorAllocationConfig(\n cfg: YieldingBankAllocationConfig\n): IdlTypes<LongYieldCarry>[\"yieldingBankAllocationConfig\"] {\n return {\n assetHolding: cfg.assetHolding ? toAnchorAssetConfig(cfg.assetHolding) : null,\n externalPosition: cfg.externalPosition\n ? toAnchorExternalPositionConfig(cfg.externalPosition)\n : null,\n };\n}\n\n/**\n * Build the carry-trade account metas that are prepended to remaining_accounts\n * for increase/decrease carry position instructions.\n *\n * The two ATA accounts are tagged with `isRequiredAta` so that\n * `getCreateAtaInstructions` will create them if they don't yet exist.\n *\n * Order must match `parse_carry_trade_accounts` on the Rust side:\n * 0. token (writable)\n * 1. yieldingBank (writable)\n * 2. tokenLpDebtTa (writable, ATA)\n * 3. yieldingBankTa (writable, ATA)\n * 4. lendingPositionUserAccount (readonly)\n * 5. lendingPositionCollateralReserve (readonly)\n * 6. debtOracle (readonly)\n * 7. debtTokenProgram (readonly)\n * 8. instructions_sysvar (readonly)\n */\nexport function buildCarryTradeAccountMetas(\n token: Address,\n yieldingBank: Address,\n tokenLpDebtTa: Address,\n yieldingBankTa: Address,\n lendingPositionUserAccount: Address,\n lendingPositionCollateralReserve: Address,\n debtOracle: Address,\n debtMint: Address,\n debtTokenProgram: Address\n): CustomAccountMeta[] {\n return [\n toCustomAccountMeta(token, true),\n toCustomAccountMeta(yieldingBank, true),\n toCustomAccountMeta(tokenLpDebtTa, true, {\n owner: token,\n mint: debtMint,\n tokenProgram: debtTokenProgram,\n }),\n toCustomAccountMeta(yieldingBankTa, true, {\n owner: yieldingBank,\n mint: debtMint,\n tokenProgram: debtTokenProgram,\n }),\n toCustomAccountMeta(lendingPositionUserAccount),\n toCustomAccountMeta(lendingPositionCollateralReserve),\n toCustomAccountMeta(debtOracle),\n toCustomAccountMeta(debtTokenProgram),\n IX_SYSVAR_META,\n ];\n}\n\n/**\n * Build the initial remaining-accounts prefix for `rebalance_token`.\n *\n * Order must match `RebalanceTokenAccounts::parse` on the Rust side:\n * 0. token (writable)\n * 1. yieldingBank (writable)\n * 2. sourceDebtTokenProgram (readonly)\n * 3. yieldingBankSourceDebtAta (writable, ATA)\n * 4. sourceLpUserAccount (readonly)\n * 5. sourceLpCollateralReserve (readonly)\n * 6. sourceLpDebtOracle (readonly — also serves as the\n * dust-sweep source_debt_oracle)\n * 7. destinationLpUserAccount (readonly)\n * 8. destinationLpCollateralReserve (readonly)\n * 9. destinationLpDebtOracle (readonly)\n *\n * The destination debt mint is referenced by inner CPIs (borrow / swap) and\n * reaches the pool through CPI dedup; it does not need a fixed slot here.\n * The token PDA's source-debt ATA is part of the flash-borrow / repay path\n * and is also resolved at runtime from the CPI account pool — only the\n * yielding-bank's source-debt ATA needs an explicit slot for the dust sweep.\n */\nexport function buildRebalanceTokenInitialAccounts(args: {\n token: Address;\n yieldingBank: Address;\n sourceDebtMint: Address;\n sourceDebtTokenProgram: Address;\n yieldingBankSourceDebtAta: Address;\n lpUserAccount: Address;\n sourceDebtOracle: Address;\n destinationDebtOracle: Address;\n}): CustomAccountMeta[] {\n return [\n toCustomAccountMeta(args.token, true),\n toCustomAccountMeta(args.yieldingBank, true),\n toCustomAccountMeta(args.sourceDebtTokenProgram),\n toCustomAccountMeta(args.yieldingBankSourceDebtAta, true, {\n owner: args.yieldingBank,\n mint: args.sourceDebtMint,\n tokenProgram: args.sourceDebtTokenProgram,\n }),\n toCustomAccountMeta(args.lpUserAccount),\n toCustomAccountMeta(args.sourceDebtOracle),\n toCustomAccountMeta(args.destinationDebtOracle),\n ];\n}\n\n/**\n * Normalize grouped CPI refs for `decrease_carry_position`.\n *\n * The plan can contain either:\n * - one group: repay only, or\n * - two groups: yielding-bank swap/redeem first, then repay.\n */\nexport function resolveDecreaseCarryIxRefs(\n refsGroups: InstructionRefs[],\n options?: { hasTokenPrerequisiteCpis?: boolean }\n): {\n ybIxRefs?: InstructionRefs;\n prerequisiteCpis?: InstructionRefs;\n tokenIxRefs: InstructionRefs;\n} {\n const hasTokenPrerequisiteCpis = options?.hasTokenPrerequisiteCpis ?? false;\n const lastRefs = refsGroups[refsGroups.length - 1];\n\n if (!lastRefs) {\n throw new Error(\"Expected at least one CPI ref group for decrease carry flow\");\n }\n\n const prerequisiteCpis = hasTokenPrerequisiteCpis ? refsGroups[refsGroups.length - 2] : undefined;\n if (hasTokenPrerequisiteCpis && !prerequisiteCpis) {\n throw new Error(\"Expected prerequisite CPI ref group for decrease carry flow\");\n }\n\n const ybIxRefs =\n refsGroups[0] && refsGroups[0] !== prerequisiteCpis && refsGroups[0] !== lastRefs\n ? refsGroups[0]\n : undefined;\n\n return {\n tokenIxRefs: lastRefs,\n ...(prerequisiteCpis ? { prerequisiteCpis } : {}),\n ...(ybIxRefs ? { ybIxRefs } : {}),\n };\n}\n\nexport interface ResolvedDecreaseCarryCpiPlan {\n accounts: CustomAccountMeta[];\n lookupTables: Address[];\n ybIxRefs?: InstructionRefs;\n prerequisiteCpis?: InstructionRefs;\n tokenIxRefs: InstructionRefs;\n}\n\n/**\n * Build the grouped CPI pool for `decrease_carry_position` and normalize the\n * resulting ref groups into the instruction params the SDK passes on-chain.\n */\nexport function resolveDecreaseCarryCpiPlan(\n plan: DecreaseCarryPositionPlan\n): ResolvedDecreaseCarryCpiPlan {\n const cpiDataGroups = [\n ...(plan.cpiDataGroups.length === 2 ? [plan.cpiDataGroups[0]] : []),\n ...(plan.tokenPrerequisiteCpis?.length ? [plan.tokenPrerequisiteCpis] : []),\n plan.cpiDataGroups[plan.cpiDataGroups.length - 1],\n ];\n const { accounts, refsGroups, lookupTables } = createMultiCpiRefs(cpiDataGroups, {\n initialAccounts: plan.initialAccounts,\n });\n\n return {\n accounts,\n lookupTables,\n ...resolveDecreaseCarryIxRefs(refsGroups, {\n hasTokenPrerequisiteCpis: Boolean(plan.tokenPrerequisiteCpis?.length),\n }),\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 { type Address } from \"@solana/kit\";\nimport { type TransactionCacheInvalidation } from \"common\";\n\nexport function getTokenCacheInvalidation(token: Address): TransactionCacheInvalidation {\n return { client: \"lycToken\", tokenPda: token };\n}\n\nexport function getYieldingBankCacheInvalidation(\n yieldingBank: Address\n): TransactionCacheInvalidation {\n return { client: \"lycYieldingBank\", yieldingBankPda: yieldingBank };\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 {\n type Address,\n type ProgramDerivedAddressBump,\n getAddressEncoder,\n getProgramDerivedAddress,\n} from \"@solana/kit\";\n\nconst addressEncoder = getAddressEncoder();\n\nfunction u64LeBytes(value: bigint | number): Uint8Array {\n const bytes = new Uint8Array(8);\n const view = new DataView(bytes.buffer);\n view.setBigUint64(0, BigInt(value), true);\n return bytes;\n}\n\n/**\n * PDA derivation for the long_yield_carry program.\n *\n * The program ID is injected via constructor — no global state.\n */\nexport class PdaClient {\n constructor(private readonly programAddress: Address) {}\n\n /**\n * Derives the Token PDA for a given mint and ID.\n *\n * Seeds: [\"TOKEN\", mint_pubkey, id]\n *\n * @param mintAddress - The yToken mint address\n * @param id - The token ID (u8)\n * @returns Tuple of [PDA address, bump seed]\n */\n async deriveTokenPda(\n mintAddress: Address,\n id: number\n ): Promise<readonly [Address, ProgramDerivedAddressBump]> {\n return await getProgramDerivedAddress({\n programAddress: this.programAddress,\n seeds: [Buffer.from(\"TOKEN\"), addressEncoder.encode(mintAddress), new Uint8Array([id])],\n });\n }\n\n /**\n * Derives the YieldingBank PDA for a given base mint and yielding ID.\n *\n * Seeds: [\"YIELDING_BANK\", base_mint_pubkey, id_le_bytes]\n *\n * @param baseMint - The base mint address\n * @param yieldingId - The yielding bank ID (u8)\n * @returns Tuple of [PDA address, bump seed]\n */\n async deriveYieldingBankPda(\n baseMint: Address,\n yieldingId: number\n ): Promise<readonly [Address, ProgramDerivedAddressBump]> {\n return await getProgramDerivedAddress({\n programAddress: this.programAddress,\n seeds: [\n Buffer.from(\"YIELDING_BANK\"),\n addressEncoder.encode(baseMint),\n new Uint8Array([yieldingId]),\n ],\n });\n }\n\n async deriveRedemptionEpochPda(\n token: Address,\n epochId: bigint | number\n ): Promise<readonly [Address, ProgramDerivedAddressBump]> {\n return await getProgramDerivedAddress({\n programAddress: this.programAddress,\n seeds: [Buffer.from(\"REDEMPTION_EPOCH\"), addressEncoder.encode(token), u64LeBytes(epochId)],\n });\n }\n\n async deriveAsyncBurnRequestPda(\n token: Address,\n epochId: bigint | number,\n sequence: bigint | number\n ): Promise<readonly [Address, ProgramDerivedAddressBump]> {\n return await getProgramDerivedAddress({\n programAddress: this.programAddress,\n seeds: [\n Buffer.from(\"ASYNC_BURN_REQUEST\"),\n addressEncoder.encode(token),\n u64LeBytes(epochId),\n u64LeBytes(sequence),\n ],\n });\n }\n\n async deriveCpiPlanPda(\n uniqueId: Address,\n createdTs: bigint | number\n ): Promise<readonly [Address, ProgramDerivedAddressBump]> {\n return await getProgramDerivedAddress({\n programAddress: this.programAddress,\n seeds: [Buffer.from(\"cpi plan\"), addressEncoder.encode(uniqueId), u64LeBytes(createdTs)],\n });\n }\n}\n","import { type Address, address, type Rpc, type SolanaRpcApi } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport { Program } from \"@anchor-lang/core\";\nimport { LongYieldCarry } from \"../idl/long_yield_carry\";\nimport { LYCToken, type TokenAccountData } from \"../models/lycToken\";\nimport { LYCYieldingBank, type YieldingBankAccountData } from \"../models/yieldingBank\";\nimport {\n BaseAccountClient,\n CustomAccountMeta,\n ExternalLiquidityType,\n ExternalLiquidityTypeToEnum,\n fetchSplTokenAccountAmounts,\n fromWeb3Pk,\n getAtaAddress,\n LendingPlatform,\n lendingPlatformToEnum,\n resolveTokenProgram,\n toBigInt,\n toCustomAccountMeta,\n toUiAmount,\n toWeb3Pk,\n} from \"common\";\nimport type { PdaClient } from \"./pda\";\nimport type {\n RedemptionEpochSnapshot,\n TokenLpPositionAccountOverrides,\n UserHolding,\n YieldingBankAllocationConfig,\n YieldingBankExternalLiquiditySource,\n} from \"./types\";\nimport { buildCarryTradeAccountMetas, buildRebalanceTokenInitialAccounts } from \"../utils/ix\";\n\n/** DataCache category for LYC `Token` accounts (used when clearing cache after writes). */\nexport const LYC_TOKEN_CACHE_CATEGORY = \"token\";\nexport const YIELDING_BANK_CACHE_CATEGORY = \"yieldingBank\";\nexport const REDEMPTION_EPOCH_CACHE_CATEGORY = \"redemptionEpoch\";\nexport const IGNORED_LYC_TOKEN_ADDRESSES = new Set<string>([\n \"GphwC2jwG3mcM8FYFFm5j8A4jNw3i7Hhic4poLbnoKpu\", // jupSOL - need proper oracle implementation to fix this (TODO)\n]);\n\n/**\n * Account fetchers for the long_yield_carry program.\n *\n * Extends {@link BaseAccountClient} for shared DataCache + `splAtaExists`, then adds LYC-specific\n * deserialization and helpers (Token, YieldingBank, carry-trade metas).\n */\nexport class AccountClient extends BaseAccountClient {\n constructor(\n private readonly program: Program<LongYieldCarry>,\n readonly pda: PdaClient,\n rpc: Rpc<SolanaRpcApi>\n ) {\n super(rpc, {\n categoryTtlMs: {\n [LYC_TOKEN_CACHE_CATEGORY]: 60_000 * 5,\n [YIELDING_BANK_CACHE_CATEGORY]: 60_000 * 10,\n [REDEMPTION_EPOCH_CACHE_CATEGORY]: 30_000,\n },\n });\n }\n\n /** Fetch and deserialize a Token account by its PDA address. */\n async fetchToken(token: Address, opts?: { fresh?: boolean }): Promise<LYCToken> {\n if (opts?.fresh) {\n this.dataCache.clearCacheEntry(LYC_TOKEN_CACHE_CATEGORY, token);\n }\n const { data } = await this.dataCache.getDataOrThrow(\n () => this.program.account.token.fetch(toWeb3Pk(token)),\n LYC_TOKEN_CACHE_CATEGORY,\n token\n );\n return new LYCToken(token, data);\n }\n\n /** Fetch and deserialize multiple Token accounts by their PDA addresses. */\n async fetchTokens(tokens: Address[]): Promise<LYCToken[]> {\n const { data } = await this.dataCache.getDataBatch(\n () => this.program.account.token.fetchMultiple(tokens.map(toWeb3Pk)),\n LYC_TOKEN_CACHE_CATEGORY,\n tokens\n );\n return data.map((x, i) => new LYCToken(tokens[i], x));\n }\n\n /**\n * Fetch all Token accounts owned by the program.\n *\n * Pass `{ fresh: true }` to clear the cached `\"all\"` entry before reading,\n * forcing a fresh `getProgramAccounts` call. The returned data is\n * re-cached so subsequent callers benefit from the same refresh.\n */\n async fetchAllTokens(opts?: { fresh?: boolean }): Promise<LYCToken[]> {\n if (opts?.fresh) {\n this.dataCache.clearCacheEntry(LYC_TOKEN_CACHE_CATEGORY, \"all\");\n }\n const { data } = await this.dataCache.getDataOrThrow(\n () => this.program.account.token.all(),\n LYC_TOKEN_CACHE_CATEGORY,\n \"all\"\n );\n return data\n .map((acc) => new LYCToken(address(acc.publicKey.toBase58()), acc.account))\n .filter(\n (token) =>\n !IGNORED_LYC_TOKEN_ADDRESSES.has(token.address) &&\n !IGNORED_LYC_TOKEN_ADDRESSES.has(token.mint)\n );\n }\n\n /** Fetch and deserialize a YieldingBank account by its PDA address. */\n async fetchYieldingBank(bank: Address): Promise<LYCYieldingBank> {\n const { data } = await this.dataCache.getDataOrThrow(\n () => this.program.account.yieldingBank.fetch(toWeb3Pk(bank)),\n YIELDING_BANK_CACHE_CATEGORY,\n bank\n );\n return new LYCYieldingBank(bank, data);\n }\n\n /** Fetch and deserialize multiple YieldingBank accounts by their PDA addresses. */\n async fetchYieldingBanks(banks: Address[]): Promise<LYCYieldingBank[]> {\n const { data } = await this.dataCache.getDataBatch(\n () => this.program.account.yieldingBank.fetchMultiple(banks.map(toWeb3Pk)),\n YIELDING_BANK_CACHE_CATEGORY,\n banks\n );\n return data.map((x, i) => new LYCYieldingBank(banks[i], x));\n }\n\n /** Fetch all YieldingBank accounts owned by the program. */\n async fetchAllYieldingBanks(): Promise<LYCYieldingBank[]> {\n const { data } = await this.dataCache.getDataOrThrow(\n () => this.program.account.yieldingBank.all(),\n YIELDING_BANK_CACHE_CATEGORY,\n \"all\"\n );\n return data.map((acc) => new LYCYieldingBank(address(acc.publicKey.toBase58()), acc.account));\n }\n\n /** Fetch and deserialize a RedemptionEpoch account by its PDA address. */\n async fetchRedemptionEpoch(\n epochPda: Address,\n opts?: { fresh?: boolean }\n ): Promise<RedemptionEpochSnapshot> {\n if (opts?.fresh) {\n this.dataCache.clearCacheEntry(REDEMPTION_EPOCH_CACHE_CATEGORY, epochPda);\n }\n const { data } = await this.dataCache.getDataOrThrow(\n () => this.program.account.redemptionEpoch.fetch(toWeb3Pk(epochPda)),\n REDEMPTION_EPOCH_CACHE_CATEGORY,\n epochPda\n );\n return this.toRedemptionEpochSnapshot(epochPda, data);\n }\n\n /** Fetch all RedemptionEpoch accounts owned by the program. */\n async fetchAllRedemptionEpochs(opts?: { fresh?: boolean }): Promise<RedemptionEpochSnapshot[]> {\n if (opts?.fresh) {\n this.dataCache.clearCacheEntry(REDEMPTION_EPOCH_CACHE_CATEGORY, \"all\");\n }\n const { data } = await this.dataCache.getDataOrThrow(\n () => this.program.account.redemptionEpoch.all(),\n REDEMPTION_EPOCH_CACHE_CATEGORY,\n \"all\"\n );\n return data\n .filter((acc) => acc?.publicKey && acc?.account)\n .map((acc) => this.toRedemptionEpochSnapshot(address(acc.publicKey.toBase58()), acc.account));\n }\n\n /**\n * Fetch all LYC yToken holdings for a wallet.\n *\n * Reads the user's ATA per LYC token directly via `getMultipleAccounts` —\n * cost scales with the LYC token count (typically <10), not the wallet's\n * total token-account count, which can be in the hundreds for active users.\n *\n * USD valuation: only when `opts.priceMap` supplies a positive USD price for\n * the collateral mint and `token.price` (NAV) is positive:\n * `valueUsd = uiBalance × token.price × priceMap[collateralMint]`.\n * If the caller does not supply a usable collateral price, `valueUsd` is\n * omitted — we do not infer USD from on-chain `tvlUsd` / `totalSupply`, since\n * those can lag risk-asset markets by tens of minutes.\n *\n * Tokens with no user ATA or a zero balance are filtered out unless\n * `opts.includeEmpty` is set.\n *\n * Pass `opts.tokens` when the caller already has a list of tokens (e.g. a\n * backend service with its own shorter-lived tokens cache) to skip the\n * internal `fetchAllTokens` call and its 5-minute SDK cache.\n */\n async fetchUserHoldings(\n owner: Address,\n opts?: {\n includeEmpty?: boolean;\n tokens?: LYCToken[];\n priceMap?: Partial<Record<Address, number>>;\n }\n ): Promise<UserHolding[]> {\n const tokens = opts?.tokens ?? (await this.fetchAllTokens());\n if (tokens.length === 0) return [];\n\n // Derive the user's ATA per LYC token mint up front so we can fetch them\n // all in a single round trip rather than enumerating the wallet's full\n // token-account set.\n const ataByMint = new Map<Address, Address>();\n const ataAddresses: Address[] = [];\n for (const token of tokens) {\n const tokenProgram = resolveTokenProgram(token.data.config.tokenProgram);\n const ata = await getAtaAddress(token.mint, owner, tokenProgram);\n ataByMint.set(token.mint, ata);\n ataAddresses.push(ata);\n }\n\n const balanceByAta = await fetchSplTokenAccountAmounts(this.rpc, ataAddresses);\n\n const holdings: UserHolding[] = [];\n for (const token of tokens) {\n const tokenAccount = ataByMint.get(token.mint)!;\n const balance = balanceByAta.get(tokenAccount) ?? BigInt(0);\n\n if (balance === BigInt(0) && !opts?.includeEmpty) continue;\n\n const uiBalance = toUiAmount(balance, token.decimals);\n\n const collateralPrice = opts?.priceMap?.[token.collateralMint];\n let valueUsd: number | undefined;\n if (collateralPrice !== undefined && collateralPrice > 0 && token.price > 0) {\n valueUsd = uiBalance * token.price * collateralPrice;\n }\n\n holdings.push({\n token,\n tokenAccount,\n balance,\n uiBalance,\n valueUsd,\n });\n }\n return holdings;\n }\n\n /** Fetch all Token and YieldingBank accounts in parallel. */\n async fetchAllTokensAndYieldingBanks(): Promise<{\n tokens: LYCToken[];\n yieldingBanks: LYCYieldingBank[];\n }> {\n const [tokens, yieldingBanks] = await Promise.all([\n this.fetchAllTokens(),\n this.fetchAllYieldingBanks(),\n ]);\n return { tokens, yieldingBanks };\n }\n\n /**\n * Build the ordered remaining-accounts list required by refresh_yielding_bank\n * (and embedded within rebalance_yielding_bank):\n *\n * 1. base_asset: [token_account, oracle, external_liquidity...] (if active)\n * 2. Per active asset holding (in slot order): [token_account, oracle, external_liquidity...]\n * The token_account is the mint's ATA owned by the bank PDA; the program\n * reads its raw balance to sync asset.amount on every refresh.\n * 3. One user account per active external yielding position (in slot order)\n *\n * If `newAllocation` is provided, its [token_account, oracle, external_liquidity...]\n * tuple is injected at the first inactive slot, matching where `apply_allocation`\n * will register it.\n */\n async getYieldingBankRefreshAccounts(\n bank: Address,\n newAllocation?: YieldingBankAllocationConfig,\n externalLiquiditySources: YieldingBankExternalLiquiditySource[] = []\n ): Promise<CustomAccountMeta[]> {\n const bankData = await this.fetchYieldingBank(bank);\n\n const pushAssetAccounts = async (\n mint: Address,\n tokenProgramAddr: Address,\n externalLiquidityType: YieldingBankAccountData[\"baseAsset\"][\"externalLiquidity\"],\n oracle: Address,\n accounts: CustomAccountMeta[]\n ) => {\n const ata = await getAtaAddress(mint, bank, tokenProgramAddr);\n accounts.push(\n toCustomAccountMeta(ata, false, { owner: bank, tokenProgram: tokenProgramAddr, mint })\n );\n accounts.push(toCustomAccountMeta(oracle));\n if (ExternalLiquidityTypeToEnum(externalLiquidityType) !== ExternalLiquidityType.None) {\n const sources = externalLiquiditySources\n .filter((source) => source.mint === mint)\n .map((source) => source.account);\n accounts.push(...sources.map((source) => toCustomAccountMeta(source)));\n }\n };\n\n const assetAccounts: CustomAccountMeta[] = [];\n\n // base_asset first\n const baseAsset = bankData.baseAsset;\n if (!baseAsset.mint.equals(PublicKey.default)) {\n await pushAssetAccounts(\n fromWeb3Pk(baseAsset.mint),\n resolveTokenProgram(baseAsset.tokenProgram),\n baseAsset.externalLiquidity,\n fromWeb3Pk(baseAsset.oracle),\n assetAccounts\n );\n }\n\n // Per active asset holding: [token_account, oracle].\n // The first inactive slot gets the newAllocation pair (if provided).\n let newAssetInserted = false;\n for (const asset of bankData.assets) {\n if (!asset.mint.equals(PublicKey.default)) {\n await pushAssetAccounts(\n fromWeb3Pk(asset.mint),\n resolveTokenProgram(asset.tokenProgram),\n asset.externalLiquidity,\n fromWeb3Pk(asset.oracle),\n assetAccounts\n );\n } else if (newAllocation?.assetHolding && !newAssetInserted) {\n const { mint, oracle, externalLiquidityType } = newAllocation.assetHolding;\n const mintInfo = await this.rpc.getAccountInfo(mint, { encoding: \"base64\" }).send();\n const mintOwner = mintInfo.value!.owner;\n await pushAssetAccounts(mint, mintOwner, externalLiquidityType, oracle, assetAccounts);\n newAssetInserted = true;\n }\n }\n\n // External position accounts — active slots only (lendingPlatform != None).\n // Per position: [protocol_user_acc, collateral_reserve].\n // The new allocation's accounts are inserted at the first inactive slot.\n const extAccounts: CustomAccountMeta[] = [];\n let newExtInserted = false;\n for (const pos of bankData.externalYieldingPositions) {\n if (!(\"none\" in pos.lendingPlatform)) {\n extAccounts.push(toCustomAccountMeta(fromWeb3Pk(pos.protocolUserAcc)));\n extAccounts.push(toCustomAccountMeta(fromWeb3Pk(pos.collateralReserve)));\n } else if (newAllocation?.externalPosition && !newExtInserted) {\n extAccounts.push(toCustomAccountMeta(newAllocation.externalPosition.protocolUserAcc));\n extAccounts.push(toCustomAccountMeta(newAllocation.externalPosition.collateralReserve));\n newExtInserted = true;\n }\n }\n\n return [...assetAccounts, ...extAccounts];\n }\n\n /**\n * Build the carry-trade remaining accounts for increase/decrease carry\n * position instructions.\n *\n * Fetches the token's lending position at `lendingPositionIndex`, derives\n * the debt ATAs, and returns the ordered account metas that\n * `parse_carry_trade_accounts` expects on the Rust side.\n *\n * Returns the fixed carry-trade account prefix, including the instructions\n * sysvar in slot 8 so CPI refs are derived against the on-chain layout.\n *\n * @param lendingPositionUserAccount - Override for the protocol user account.\n * Defaults to the value stored in the on-chain lending position.\n */\n async getCarryTradeAccounts(\n token: Address,\n yieldingBank: Address,\n lendingPositionIndex: number,\n lendingPositionUserAccount?: Address\n ): Promise<CustomAccountMeta[]> {\n const tokenData = await this.fetchToken(token);\n const position = tokenData.data.lendingPositions[lendingPositionIndex];\n const debt = position.accounting.debt;\n const debtMint = fromWeb3Pk(debt.mint);\n const debtTokenProgram = resolveTokenProgram(debt.tokenProgram);\n const tokenLpDebtTa = await getAtaAddress(debtMint, token, debtTokenProgram);\n const yieldingBankTa = await getAtaAddress(debtMint, yieldingBank, debtTokenProgram);\n return buildCarryTradeAccountMetas(\n token,\n yieldingBank,\n tokenLpDebtTa,\n yieldingBankTa,\n lendingPositionUserAccount ?? fromWeb3Pk(position.protocolUserAcc),\n fromWeb3Pk(position.collateralReserve),\n fromWeb3Pk(position.accounting.debt.oracle),\n debtMint,\n debtTokenProgram\n );\n }\n\n /**\n * Derive the account set needed to refresh a single token lending position.\n *\n * This pulls the protocol user account, collateral reserve, and debt oracle\n * from the selected lending position so callers can pass the exact accounts\n * required by refresh-oriented instructions. Optional overrides let tests or\n * advanced callers substitute explicit addresses when needed.\n */\n getTokenLendingPositionRefreshAccounts(\n tokenData: TokenAccountData,\n lendingPositionIndex: number,\n overrides?: TokenLpPositionAccountOverrides\n ) {\n const position = tokenData.lendingPositions[lendingPositionIndex];\n if (!position) {\n throw new Error(`Invalid lending position index: ${lendingPositionIndex}`);\n }\n\n return {\n userAccount: overrides?.userAccount ?? fromWeb3Pk(position.protocolUserAcc),\n collateralReserve: overrides?.collateralReserve ?? fromWeb3Pk(position.collateralReserve),\n debtOracle: overrides?.debtOracle ?? fromWeb3Pk(position.accounting.debt.oracle),\n };\n }\n\n /**\n * Build the fixed initial-accounts prefix for `rebalance_token`.\n *\n * The Rust handler reads these positionally from the front of\n * `remaining_accounts` (see `RebalanceTokenAccounts::parse`). Returning the\n * prefix as `initialAccounts` to `createMultiCpiRefs` lets every CPI in the\n * flash-rebalance bundle deduplicate against these slots, shrinking the\n * transaction's account list compared to declaring them as named ix\n * accounts that would force separate copies in the message header.\n */\n async getRebalanceTokenInitialAccounts(\n token: Address,\n yieldingBank: Address,\n lpIndex: number,\n destinationDebtOracle: Address,\n overrides?: TokenLpPositionAccountOverrides\n ): Promise<CustomAccountMeta[]> {\n const tokenData = await this.fetchToken(token);\n const position = tokenData.data.lendingPositions[lpIndex];\n if (!position) {\n throw new Error(`Invalid lending position index: ${lpIndex}`);\n }\n const sourceDebtMint = fromWeb3Pk(position.accounting.debt.mint);\n const sourceDebtTokenProgram = resolveTokenProgram(position.accounting.debt.tokenProgram);\n const yieldingBankSourceDebtAta = await getAtaAddress(\n sourceDebtMint,\n yieldingBank,\n sourceDebtTokenProgram\n );\n const lp = this.getTokenLendingPositionRefreshAccounts(tokenData.data, lpIndex, overrides);\n return buildRebalanceTokenInitialAccounts({\n token,\n yieldingBank,\n sourceDebtMint,\n sourceDebtTokenProgram,\n yieldingBankSourceDebtAta,\n lpUserAccount: lp.userAccount,\n sourceDebtOracle: lp.debtOracle,\n destinationDebtOracle,\n });\n }\n\n /**\n * Build the initial account pool seed for refresh_token_state.\n *\n * These accounts are placed at the front of the deduplicated remaining_accounts\n * pool (positions 0..N-1), so the index-based TokenRefreshRefs computed by\n * the builder remain stable whether or not prereq CPIs introduce additional accounts.\n *\n * Order:\n * 1. Per active lending position (in slot order): protocol_user_acc, collateral_reserve, debt_oracle\n * 2. One YieldingBank PDA per active carry position (in slot order)\n */\n async getTokenRefreshAccounts(token: Address): Promise<CustomAccountMeta[]> {\n const tokenData = await this.fetchToken(token);\n const accounts: CustomAccountMeta[] = [];\n\n for (const position of tokenData.data.lendingPositions) {\n if (lendingPlatformToEnum(position.platform) === LendingPlatform.None) continue;\n accounts.push(toCustomAccountMeta(fromWeb3Pk(position.protocolUserAcc)));\n accounts.push(toCustomAccountMeta(fromWeb3Pk(position.collateralReserve)));\n accounts.push(toCustomAccountMeta(fromWeb3Pk(position.accounting.debt.oracle)));\n }\n\n for (const { data: carry } of tokenData.activeCarryPositions) {\n const baseMint = fromWeb3Pk(carry.yieldingBaseMint);\n const [bankPda] = await this.pda.deriveYieldingBankPda(baseMint, carry.yieldingBankId);\n accounts.push(toCustomAccountMeta(bankPda));\n }\n\n return accounts;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private toRedemptionEpochSnapshot(pda: Address, data: any): RedemptionEpochSnapshot {\n return {\n pda,\n tokenPda: data.header.token.toBase58() as Address,\n epochId: BigInt(data.header.id.toString()),\n payer: data.header.payer.toBase58() as Address,\n status: data.header.status,\n requestCount: Number(data.sequencing.requestCount.toString()),\n processedRequestCount: Number(data.sequencing.processedRequestCount.toString()),\n grossCollateralClaim: toBigInt(data.accounting.grossCollateralClaim),\n realizedUnwindLoss: toBigInt(data.accounting.realizedUnwindLoss),\n fundedCollateral: toBigInt(data.accounting.fundedCollateral),\n };\n }\n}\n","import { address, type Address } from \"@solana/kit\";\nimport { BN, IdlAccounts } from \"@anchor-lang/core\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport { LongYieldCarry } from \"../idl/long_yield_carry\";\nimport {\n applyBps,\n fromWeb3Pk,\n LendingPlatform,\n lendingPlatformToEnum,\n mints,\n toBigInt,\n toUiAmount,\n TVL_USD_DECIMAL_PLACES,\n} from \"common\";\nimport type { PdaClient } from \"../client/pda\";\nimport { podBoolToNumber } from \"../utils/general\";\nimport { collectableNetYieldUsd } from \"../utils/tokenFeeMath\";\nimport type { BurnAmounts, MintAmounts } from \"../client/types/general\";\n\nconst MAX_COLLECTABLE_SURPLUS_BPS = BigInt(1);\nconst BASIS_POINTS = BigInt(10_000);\n\n/** Decoded on-chain data for a Token account, derived from the IDL. */\nexport type TokenAccountData = IdlAccounts<LongYieldCarry>[\"token\"];\n\nexport type TokenLendingPositionData = TokenAccountData[\"lendingPositions\"][number];\n\nexport type TokenCarryPositionData = TokenAccountData[\"debtCarry\"][number];\n\n/** A carry position paired with its index in the `debtCarry` array. */\nexport interface IndexedCarryPosition {\n index: number;\n data: TokenCarryPositionData;\n}\n\n/** A lending position paired with its index in the `lendingPositions` array. */\nexport interface IndexedLendingPosition {\n index: number;\n data: TokenLendingPositionData;\n}\n\n/**\n * Wrapper around the raw Token account data from the program.\n *\n * Provides typed access to on-chain state and a home for\n * derived/computed helpers as the SDK grows.\n */\nexport class LYCToken {\n constructor(\n /** The Token PDA address this data was fetched from */\n readonly address: Address,\n /** Deserialized account data */\n readonly data: TokenAccountData\n ) {}\n\n get circuitBreaker(): number {\n return podBoolToNumber(this.data.config.circuitBreaker);\n }\n\n /** Whether the token is operational (circuit breaker is off). */\n get isActive(): boolean {\n return this.circuitBreaker === 0;\n }\n\n /**\n * Returns carry positions that have a non-default yielding base mint and\n * positive shares — i.e. positions with actual yield exposure. Includes the\n * original array index so callers can reference `debtCarry[index]` on-chain.\n */\n get activeCarryPositions(): IndexedCarryPosition[] {\n return this.data.debtCarry\n .map((carry, index) => ({ index, data: carry }))\n .filter(\n ({ data }) =>\n !data.yieldingBaseMint.equals(PublicKey.default) && toBigInt(data.shares) > BigInt(0)\n );\n }\n\n /**\n * Returns lending positions that have a non-None platform — i.e. positions\n * with an active lending protocol. Includes the original array index so\n * callers can reference `lendingPositions[index]` on-chain.\n */\n get activeLendingPositions(): IndexedLendingPosition[] {\n return this.data.lendingPositions\n .map((lp, index) => ({ index, data: lp }))\n .filter(({ data }) => lendingPlatformToEnum(data.platform) !== LendingPlatform.None);\n }\n\n /**\n * Subset of {@link activeLendingPositions} that currently has supplied\n * collateral on-chain. Filters out slots whose platform is set but whose\n * collateral has been fully withdrawn — those slots can still report\n * non-zero protocol-level state via a shared obligation, which makes them\n * unsafe targets for borrow/withdraw flows.\n */\n get usedLendingPositions(): IndexedLendingPosition[] {\n return this.activeLendingPositions.filter(\n ({ data }) => toBigInt(data.accounting.collateral) > BigInt(0)\n );\n }\n\n get config(): TokenAccountData[\"config\"] {\n return this.data.config;\n }\n\n get collateral(): TokenAccountData[\"collateral\"] {\n return this.data.collateral;\n }\n\n get fees(): TokenAccountData[\"fees\"] {\n return this.data.fees;\n }\n\n get accounting(): TokenAccountData[\"accounting\"] {\n return this.data.accounting;\n }\n\n get id(): number {\n return this.data.config.id;\n }\n\n get mint(): Address {\n return address(this.data.config.mint.toString());\n }\n\n get collateralMint(): Address {\n return address(this.data.collateral.mint.toString());\n }\n\n get label(): string {\n const symbol = mints.get(this.collateralMint)?.symbol;\n return (symbol ? symbol : this.address).toLowerCase();\n }\n\n get decimals(): number {\n return this.data.config.decimals;\n }\n\n /**\n * On-chain token price: **collateral per yToken** in UI units (same decimals as\n * the yToken), not USD. At genesis this is 1:1 with the collateral asset; it\n * moves with NAV. For USD notional use `tvlUsd` / `totalSupply`, or\n * `client.account.fetchUserHoldings` (pro-rata TVL).\n */\n get price(): number {\n return toUiAmount(this.data.accounting.price, this.decimals);\n }\n\n get totalSupply(): number {\n return toUiAmount(this.data.accounting.totalSupply, this.decimals);\n }\n\n /**\n * Total protocol TVL in USD (on-chain `accounting.tvlUsd` is 8-decimal\n * fixed-point USD, $1 = 10^8).\n */\n get tvlUsd(): number {\n return toUiAmount(this.data.accounting.tvlUsd, TVL_USD_DECIMAL_PLACES);\n }\n\n get depositLimitUi(): number {\n return toUiAmount(this.data.config.depositLimit, this.data.collateral.decimals);\n }\n\n /**\n * Sum of active `debtCarry[*].tvlUsd` (8-decimal normalized USD stored on-chain).\n * Mirrors the on-chain `Token::total_carry_tvl_usd` helper.\n */\n get totalCarryTvlUsd(): bigint {\n return this.activeCarryPositions.reduce(\n (sum, { data }) => sum + toBigInt(data.tvlUsd),\n BigInt(0)\n );\n }\n\n /**\n * Sum of active `lendingPositions[*].accounting.debt.tvlUsd` (8-decimal normalized USD).\n * Mirrors the on-chain `Token::total_lp_debt_usd` helper.\n */\n get totalLendingDebtTvlUsd(): bigint {\n return this.activeLendingPositions.reduce(\n (sum, { data }) => sum + toBigInt(data.accounting.debt.tvlUsd),\n BigInt(0)\n );\n }\n\n /**\n * Collectable net yield (8-dec USD): any carry surplus above debt. Zero when\n * carry TVL does not exceed debt TVL.\n */\n get collectableNetYieldUsd(): bigint {\n return collectableNetYieldUsd(this.totalCarryTvlUsd, this.totalLendingDebtTvlUsd);\n }\n\n /**\n * True when the token is active and carry TVL exceeds debt by at most 1 bp.\n */\n hasInterestToCollect(): boolean {\n const totalDebtUsd = this.totalLendingDebtTvlUsd;\n const surplusUsd = collectableNetYieldUsd(this.totalCarryTvlUsd, totalDebtUsd);\n\n if (!this.isActive || totalDebtUsd === BigInt(0) || surplusUsd === BigInt(0)) {\n return false;\n }\n\n // A carry surplus above 1 bp of debt cannot plausibly accrue between hourly\n // collection cycles at supported yields, so treat it as stablecoin pricing\n // drift instead of realizable interest. Cross-multiplication preserves\n // sub-bp precision without truncating an integer bps calculation.\n return surplusUsd * BASIS_POINTS <= totalDebtUsd * MAX_COLLECTABLE_SURPLUS_BPS;\n }\n\n /**\n * Returns every active lending position whose debt mint matches `debtMint`,\n * in on-chain slot order. A token may hold more than one position on the same\n * debt mint, so callers should loop over all of them. Empty when none match.\n */\n findLendingPositionsByDebtMint(debtMint: Address): IndexedLendingPosition[] {\n return this.activeLendingPositions.filter(\n ({ data }) => fromWeb3Pk(data.accounting.debt.mint) === debtMint\n );\n }\n\n /**\n * Mirror the on-chain `Token::compute_mint_amounts` formula.\n *\n * The holder price-fee (the residual after protocol/curator take their split)\n * is a gift to the pre-mint supply `S`. To stop the minter clawing back their\n * own gift, all minted tokens are sized at the post-gift price — i.e. scaled by\n * `S / (S + priceFee)`. The fee is not applied to the price on-chain at mint\n * time; it is buffered and released gradually by `refreshTokenState`, so this\n * quote returns the same base-unit amounts the program mints.\n *\n * When `totalSupply === 0`, the user is priced at the current price, protocol\n * and curator receive their configured base shares, and the residual is\n * buffered without post-gift scaling.\n */\n computeMintAmounts(depositAmount: BN | number): MintAmounts {\n const deposit = BigInt(depositAmount.toString());\n const feeBps = BigInt(this.data.fees.mintingFeeBps);\n const protocolPctBps = BigInt(this.data.fees.protocolMintBurnPctBps);\n const curatorPctBps = BigInt(this.data.fees.curatorMintBurnPctBps);\n const price = BigInt(this.data.accounting.price.toString());\n const scale = BigInt(Math.pow(10, this.data.config.decimals));\n const totalSupply = BigInt(this.data.accounting.totalSupply.toString());\n\n const tokensBeforeFees = (deposit * scale) / price;\n const totalFee = applyBps(tokensBeforeFees, feeBps);\n\n const baseProtocolFee = applyBps(totalFee, protocolPctBps);\n const baseCuratorFee = applyBps(totalFee, curatorPctBps);\n\n // Genesis: post-gift sizing has no pre-mint supply denominator. Keep the\n // configured split and let the on-chain accounting buffer the residual.\n if (totalSupply === 0n) {\n return {\n tokensToUser: tokensBeforeFees - totalFee,\n protocolFee: baseProtocolFee,\n curatorFee: baseCuratorFee,\n };\n }\n\n const priceFee = totalFee - baseProtocolFee - baseCuratorFee;\n\n // Post-gift sizing: scale every minted amount by S / (S + priceFee).\n const denom = totalSupply + priceFee;\n const tokensToUser = ((tokensBeforeFees - totalFee) * totalSupply) / denom;\n const protocolFee = (baseProtocolFee * totalSupply) / denom;\n const curatorFee = (baseCuratorFee * totalSupply) / denom;\n\n return { tokensToUser, protocolFee, curatorFee };\n }\n\n /**\n * Mirror the on-chain `Token::compute_burn_amounts` formula.\n *\n * Returns exact base-unit values for the three accounting effects of a burn:\n * - `collateralToUser`: collateral returned to the burner\n * - `protocolFee`: yTokens accrued as pending protocol fees\n * - `supplyReduction`: net decrease in total supply\n *\n * The holder price-fee (residual after protocol/curator take their split) is\n * not paid out as collateral; on-chain it is buffered and dripped into the\n * price for the remaining holders. The burner is leaving, so there is no\n * self-dealing to guard against and no post-gift scaling is applied. The same\n * configured split applies when all circulating supply is burned; the residual\n * remains buffered until it can be released gradually.\n */\n computeBurnAmounts(burnAmount: BN | number): BurnAmounts {\n const burn = BigInt(burnAmount.toString());\n const feeBps = BigInt(this.data.fees.burningFeeBps);\n const protocolPctBps = BigInt(this.data.fees.protocolMintBurnPctBps);\n const curatorPctBps = BigInt(this.data.fees.curatorMintBurnPctBps);\n const price = BigInt(this.data.accounting.price.toString());\n const scale = BigInt(Math.pow(10, this.data.config.decimals));\n\n const totalFee = applyBps(burn, feeBps);\n const protocolFee = applyBps(totalFee, protocolPctBps);\n const curatorFee = applyBps(totalFee, curatorPctBps);\n const tokensAfterFee = burn - totalFee;\n const collateralToUser = (tokensAfterFee * price) / scale;\n const supplyReduction = burn - protocolFee - curatorFee;\n\n return { collateralToUser, protocolFee, curatorFee, supplyReduction };\n }\n\n /**\n * Convenience wrapper around {@link computeBurnAmounts} that returns only\n * the collateral owed to the user, converted to a UI amount\n * (divided by 10^collateral.decimals).\n */\n computeBurnWithdrawUiAmount(burnAmount: BN | number): number {\n const { collateralToUser } = this.computeBurnAmounts(burnAmount);\n return toUiAmount(collateralToUser, this.data.collateral.decimals);\n }\n\n /**\n * Derives the YieldingBank PDA for the `debtCarry` entry at `debtCarryIndex`.\n *\n * @param debtCarryIndex - Index into `data.debtCarry`\n * @param pda - Program PDA client (`YIELDING_BANK` seeds match on-chain).\n */\n async deriveYieldingBankAddressForDebtCarryIndex(\n debtCarryIndex: number,\n pda: PdaClient\n ): Promise<Address> {\n const carry = this.data.debtCarry[debtCarryIndex];\n if (!carry) {\n throw new Error(\n `Invalid debtCarryIndex ${debtCarryIndex} (token has ${this.data.debtCarry.length} debt carry entries)`\n );\n }\n if (carry.yieldingBaseMint.equals(PublicKey.default)) {\n throw new Error(\n `debtCarry[${debtCarryIndex}] has no active yielding bank (zero yielding base mint)`\n );\n }\n const [bankPda] = await pda.deriveYieldingBankPda(\n fromWeb3Pk(carry.yieldingBaseMint),\n carry.yieldingBankId\n );\n return bankPda;\n }\n\n /**\n * Resolves the YieldingBank PDA for the token's first active `debtCarry`\n * entry. Used as a default when callers haven't picked a specific bank.\n */\n async resolveFirstYieldingBankAddress(pda: PdaClient): Promise<Address> {\n const firstActiveIdx = this.data.debtCarry.findIndex(\n (entry) => !entry.yieldingBaseMint.equals(PublicKey.default)\n );\n if (firstActiveIdx < 0) {\n throw new Error(\n \"Token has no active yielding banks — call `increase_carry_position` first or pick a bank explicitly\"\n );\n }\n return this.deriveYieldingBankAddressForDebtCarryIndex(firstActiveIdx, pda);\n }\n}\n","import { type Address } from \"@solana/kit\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport { IdlAccounts } from \"@anchor-lang/core\";\nimport { LongYieldCarry } from \"../idl/long_yield_carry\";\nimport { fromWeb3Pk, toUiAmount } from \"common\";\nimport { podBoolToNumber } from \"../utils/general\";\nimport { TOKEN_STALENESS_THRESHOLD_SECS } from \"../constants/general\";\n\n/** Decoded on-chain data for a YieldingBank account, derived from the IDL. */\nexport type YieldingBankAccountData = IdlAccounts<LongYieldCarry>[\"yieldingBank\"];\n\n/**\n * Wrapper around the raw YieldingBank account data from the program.\n *\n * Provides typed access to on-chain state and a home for\n * derived/computed helpers as the SDK grows.\n */\nexport class LYCYieldingBank {\n constructor(\n /** The YieldingBank PDA address this data was fetched from */\n readonly address: Address,\n /** Deserialized account data */\n readonly data: YieldingBankAccountData\n ) {}\n\n get circuitBreaker(): number {\n return podBoolToNumber(this.data.config.circuitBreaker);\n }\n\n get isActive(): boolean {\n return this.circuitBreaker === 0;\n }\n\n get config(): YieldingBankAccountData[\"config\"] {\n return this.data.config;\n }\n\n get accounting(): YieldingBankAccountData[\"accounting\"] {\n return this.data.accounting;\n }\n\n get baseMint(): Address {\n return fromWeb3Pk(this.data.config.baseMint);\n }\n\n get defaultRedemptionMint(): Address {\n return fromWeb3Pk(this.data.config.defaultRedemptionMint);\n }\n\n get id(): number {\n return this.data.config.id;\n }\n\n get decimals(): number {\n return this.data.config.decimals;\n }\n\n get timeCreatedTs(): bigint {\n return BigInt(this.data.config.timeCreatedTs.toString());\n }\n\n get sharePrice(): number {\n return toUiAmount(this.data.accounting.sharePrice, this.decimals);\n }\n\n get totalShares(): number {\n return toUiAmount(this.data.accounting.totalShares, this.decimals);\n }\n\n /**\n * `true` when the bank's cached `lastRefreshedTs` is older than the\n * client-side staleness threshold and a `refresh_yielding_bank` ix should\n * be prepended before any handler that calls `verify_price_is_fresh`.\n */\n get isStale(): boolean {\n const lastRefreshed = this.data.accounting.lastRefreshedTs.toNumber();\n const nowSecs = Math.floor(Date.now() / 1000);\n return nowSecs - lastRefreshed > TOKEN_STALENESS_THRESHOLD_SECS;\n }\n\n get baseAsset(): YieldingBankAccountData[\"baseAsset\"] {\n return this.data.baseAsset;\n }\n\n get assets(): YieldingBankAccountData[\"assets\"] {\n return this.data.assets;\n }\n\n get externalYieldingPositions(): YieldingBankAccountData[\"externalYieldingPositions\"] {\n return this.data.externalYieldingPositions;\n }\n\n /**\n * Find the asset holding entry for a given mint across the bank's\n * base asset and additional assets. Returns null if not held.\n */\n findAssetHolding(mint: Address): YieldingBankAccountData[\"baseAsset\"] | null {\n if (this.baseMint === mint) {\n return this.data.baseAsset;\n }\n\n for (const asset of this.data.assets) {\n if (asset.mint.equals(PublicKey.default)) continue;\n if (fromWeb3Pk(asset.mint) === mint) {\n return asset;\n }\n }\n\n return null;\n }\n\n /**\n * Returns the flat index for the asset holding matching the given mint\n * (0 = base_asset, 1–12 = assets[0–11]), or null if not found.\n */\n findAssetHoldingIndex(mint: Address): number | null {\n if (this.baseMint === mint) return 0;\n\n for (let i = 0; i < this.data.assets.length; i++) {\n const asset = this.data.assets[i];\n if (asset.mint.equals(PublicKey.default)) continue;\n if (fromWeb3Pk(asset.mint) === mint) return i + 1;\n }\n\n return null;\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 { BN } from \"@anchor-lang/core\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport {\n BaseIXBuilderService,\n accountExists,\n createSignerFromAddress,\n fromWeb3Pk,\n getCreateAtaIxIfNeeded,\n getWrapSolInstructions,\n mints,\n} from \"common\";\nimport type {\n LendingOperationCpiBundle,\n LendingOperationParams,\n RepayOperationParams,\n} from \"lending-platforms\";\n// Specific module, not the utils barrel — keeps the Kamino-heavy enrichment\n// graph out of the browser-safe `core` entry (see src/core.ts).\nimport { mergeLycLookupTables } from \"../../utils/lookupTables\";\nimport type { TokenAccountData, TokenLendingPositionData } from \"../../models/lycToken\";\nimport type { YieldingBankAccountData } from \"../../models/yieldingBank\";\nimport {\n CIRCUIT_BREAKER_CONTROLLER,\n MANAGER,\n PROGRAM_ID,\n PROTOCOL_ADMIN,\n PROTOCOL_FEE_WALLET,\n} from \"../../constants/general\";\nimport type { LongYieldCarryBuilderContext } from \"../types/builders\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\n\nexport abstract class LongYieldCarryBuilderBase<\n TIxArgs,\n TTxArgs = TIxArgs,\n TTxResult = LongYieldCarryTransactionPlan,\n> extends BaseIXBuilderService<LongYieldCarryBuilderContext, TIxArgs, TTxArgs, TTxResult> {\n protected get rpc() {\n return this.context.rpc;\n }\n\n protected get program() {\n return this.context.program;\n }\n\n protected get account() {\n return this.context.account;\n }\n\n protected get pda() {\n return this.context.pda;\n }\n\n protected get swap() {\n return this.context.swap;\n }\n\n protected get externalLiquidityResolver() {\n return this.context.externalLiquidityResolver;\n }\n\n protected get environment() {\n return this.context.environment;\n }\n\n protected get lendingPlatformClients() {\n return this.context.lendingPlatformClients;\n }\n\n /**\n * Environment-level manager fallback. Use {@link resolveTokenManager} /\n * {@link resolveYieldingBankManager} whenever a specific token/bank's role\n * might override the default.\n */\n private get manager() {\n return MANAGER[this.environment];\n }\n\n /**\n * Environment-level circuit-breaker-controller fallback. Use\n * {@link resolveTokenCbController} / {@link resolveYieldingBankCbController}\n * whenever a specific token/bank's role might override the default.\n */\n private get circuitBreakerController() {\n return CIRCUIT_BREAKER_CONTROLLER[this.environment];\n }\n\n /**\n * Program-level admin. Also doubles as the environment-level fallback for\n * `TokenRoles::admin()` / `YieldingBankRoles::admin()` when their stored role\n * is unset — both Rust fallbacks resolve to this same pubkey by design.\n */\n private get protocolAdmin() {\n return PROTOCOL_ADMIN[this.environment];\n }\n\n /**\n * Program-level fee wallet. Also doubles as the fallback for\n * `TokenRoles::curator_fee_wallet()` when a token's `roles.fees` is unset —\n * the Rust `curator_fee_wallet()` getter delegates to `protocol_fee_wallet()`.\n */\n protected get protocolFeeWallet() {\n return PROTOCOL_FEE_WALLET[this.environment];\n }\n\n /** Program ID for this environment — used as the \"no-change\"/\"use-default\" sentinel on role accounts. */\n protected get programId() {\n return PROGRAM_ID[this.environment];\n }\n\n /**\n * Return the on-chain role key if it's set, otherwise the environment\n * fallback. Mirrors the Rust role getter pattern (`if self.role != default()\n * { self.role } else { <env default> }`).\n */\n private resolveStoredOrFallback(stored: PublicKey, fallback: Address): Address {\n return stored.equals(PublicKey.default) ? fallback : fromWeb3Pk(stored);\n }\n\n protected resolveTokenAdmin(tokenData: TokenAccountData): Address {\n return this.resolveStoredOrFallback(tokenData.roles.admin, this.protocolAdmin);\n }\n\n protected resolveTokenManager(tokenData: TokenAccountData): Address {\n return this.resolveStoredOrFallback(tokenData.roles.manager, this.manager);\n }\n\n protected resolveTokenCuratorFeeWallet(tokenData: TokenAccountData): Address {\n return this.resolveStoredOrFallback(tokenData.roles.fees, this.protocolFeeWallet);\n }\n\n protected resolveTokenCbController(tokenData: TokenAccountData): Address {\n return this.resolveStoredOrFallback(\n tokenData.roles.cbController,\n this.circuitBreakerController\n );\n }\n\n /**\n * Optional composite collateral oracle (e.g. SPL stake pool for PythSplStake).\n * Anchor optional accounts must be passed as `null` when unset.\n */\n protected resolveOptionalSecondaryCollateralOracle(\n collateral: TokenAccountData[\"collateral\"]\n ): Address | null {\n return collateral.secondaryOracle.equals(PublicKey.default)\n ? null\n : fromWeb3Pk(collateral.secondaryOracle);\n }\n\n protected resolveYieldingBankAdmin(bankData: YieldingBankAccountData): Address {\n return this.resolveStoredOrFallback(bankData.roles.admin, this.protocolAdmin);\n }\n\n protected resolveYieldingBankManager(bankData: YieldingBankAccountData): Address {\n return this.resolveStoredOrFallback(bankData.roles.manager, this.manager);\n }\n\n protected resolveYieldingBankCbController(bankData: YieldingBankAccountData): Address {\n return this.resolveStoredOrFallback(bankData.roles.cbController, this.circuitBreakerController);\n }\n\n protected getTxLookupTables(\n tokenPda?: Address | readonly Address[],\n existingLookupTables?: readonly Address[]\n ): Address[] {\n return mergeLycLookupTables(this.context.environment, tokenPda, existingLookupTables);\n }\n\n protected getLendingPlatformClient(position: TokenLendingPositionData) {\n return this.lendingPlatformClients.getForPosition(position);\n }\n\n protected async getCreateUserCollateralAtaIxIfNeeded(\n owner: Address,\n collateralMint: Address,\n collateralTokenProgram: Address\n ) {\n return getCreateAtaIxIfNeeded(this.rpc, owner, collateralMint, owner, collateralTokenProgram, {\n accountClient: this.account,\n });\n }\n\n protected async getWrapSolInstructionsIfMintIsSol(\n owner: Address,\n mint: Address,\n lamports: BN\n ): Promise<{\n instructions?: Instruction[];\n postSuccessCacheInvalidations?: LongYieldCarryTransactionPlan[\"postSuccessCacheInvalidations\"];\n }> {\n const solMint = mints.get(\"SOL\");\n if (!solMint || mint !== solMint.address) {\n return {};\n }\n\n const wrap = await getWrapSolInstructions(\n this.rpc,\n owner,\n createSignerFromAddress(owner),\n lamports,\n { accountClient: this.account }\n );\n return {\n instructions: wrap.instructions,\n postSuccessCacheInvalidations: wrap.postSuccessCacheInvalidations,\n };\n }\n\n protected async getLendingOperationCpiData(\n token: Address,\n manager: Address,\n position: TokenLendingPositionData,\n txId: string,\n operation: \"deposit\" | \"withdraw\" | \"borrow\" | \"repay\",\n uiAmount?: number | \"all\"\n ): Promise<LendingOperationCpiBundle> {\n const lpClient = this.getLendingPlatformClient(position);\n const pool = fromWeb3Pk(position.pool);\n const userAccount = fromWeb3Pk(position.protocolUserAcc);\n const reserve =\n operation === \"deposit\" || operation === \"withdraw\"\n ? fromWeb3Pk(position.collateralReserve)\n : fromWeb3Pk(position.debtReserve);\n\n const operationParams = {\n user: token,\n payer: manager,\n pool,\n reserve,\n userAccount,\n uiAmount,\n txId,\n } satisfies LendingOperationParams;\n\n if (operation === \"deposit\") {\n return lpClient.ix.getDepositCpiBundle(operationParams);\n }\n\n if (operation === \"borrow\") {\n const needsInit = !(await accountExists(this.rpc, userAccount));\n return needsInit\n ? lpClient.ix.getInitBorrowPositionCpiBundle(\n operationParams,\n fromWeb3Pk(position.collateralReserve)\n )\n : lpClient.ix.getBorrowCpiBundle(operationParams);\n }\n\n if (operation === \"withdraw\") {\n return lpClient.ix.getWithdrawCpiBundle(operationParams);\n }\n\n if (uiAmount === \"all\") {\n throw new Error('The \"all\" amount sentinel is only valid for withdrawals');\n }\n const repayParams: RepayOperationParams = { ...operationParams, uiAmount };\n return lpClient.ix.getRepayCpiBundle(repayParams);\n }\n}\n\nexport abstract class LongYieldCarrySingleInstructionBuilderService<\n TIxArgs,\n TTxArgs = TIxArgs,\n TTxPlan extends LongYieldCarryTransactionPlan = LongYieldCarryTransactionPlan,\n> extends LongYieldCarryBuilderBase<TIxArgs, TTxArgs, TTxPlan> {\n protected async deriveIxArgs(txArgs: TTxArgs): Promise<TIxArgs> {\n return txArgs as unknown as TIxArgs;\n }\n\n protected async buildPreambleInstructions(\n _args: TIxArgs,\n _txArgs: TTxArgs\n ): Promise<Instruction[]> {\n return [];\n }\n\n protected async buildLookupTables(\n _args: TIxArgs,\n _txArgs: TTxArgs\n ): Promise<readonly Address[] | undefined> {\n return undefined;\n }\n\n protected async buildPlanExtras(\n _args: TIxArgs,\n _txArgs: TTxArgs\n ): Promise<Omit<TTxPlan, \"instructions\" | \"lookupTables\"> | undefined> {\n return undefined;\n }\n\n async getTx(txArgs: TTxArgs): Promise<TTxPlan> {\n const args = await this.deriveIxArgs(txArgs);\n const preambleInstructions = await this.buildPreambleInstructions(args, txArgs);\n const instruction = await this.getIx(args);\n const lookupTables = await this.buildLookupTables(args, txArgs);\n const extras = await this.buildPlanExtras(args, txArgs);\n\n return {\n instructions: [...preambleInstructions, instruction],\n ...(lookupTables?.length ? { lookupTables: [...lookupTables] } : {}),\n ...(extras ?? {}),\n } as TTxPlan;\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport { fromWeb3Pk, getAtaAddress, resolveTokenProgram } from \"common\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport type { LongYieldCarryBuilderContext } from \"../types/builders\";\nimport type { LYCToken } from \"../../models\";\n// Specific module, not the utils barrel — keeps the Kamino-heavy enrichment\n// graph out of the browser-safe `core` entry (see src/core.ts).\nimport { mergeLycLookupTables } from \"../../utils/lookupTables\";\nimport type { RefreshTokensBuilderTxArgs } from \"./args\";\nimport { RefreshTokenStateBuilder } from \"./refreshTokenStateBuilder\";\nimport { RefreshYieldingBankBuilder } from \"./refreshYieldingBankBuilder\";\n\nexport class RefreshTokensBuilder {\n constructor(private readonly context: LongYieldCarryBuilderContext) {}\n\n async getTx(args: RefreshTokensBuilderTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const tokens = await this.context.account.fetchTokens(args.params.tokens);\n const instructions: Instruction[] = [];\n const ybAddresses = await this.getYieldingBanksToRefresh(\n tokens,\n args.params.alwaysRefreshYieldingBanks ?? false\n );\n const refreshYieldingBankBuilder = new RefreshYieldingBankBuilder(this.context);\n const refreshTokenStateBuilder = new RefreshTokenStateBuilder(this.context);\n\n for (const yieldingBank of ybAddresses) {\n const ybPlan = await refreshYieldingBankBuilder.getTx({\n signer: args.signer,\n yieldingBank,\n });\n instructions.push(...ybPlan.instructions);\n }\n\n for (const token of tokens) {\n instructions.push(\n await refreshTokenStateBuilder.getIx({\n signer: args.signer,\n token: token.address,\n collateralOracle: fromWeb3Pk(token.data.collateral.oracle),\n secondaryCollateralOracle: fromWeb3Pk(token.data.collateral.secondaryOracle),\n collateralTokenAccount: await getAtaAddress(\n token.collateralMint,\n token.address,\n resolveTokenProgram(token.data.collateral.tokenProgram)\n ),\n collateralTokenProgram: resolveTokenProgram(token.data.collateral.tokenProgram),\n })\n );\n }\n\n return {\n instructions,\n lookupTables: mergeLycLookupTables(this.context.environment, args.params.tokens),\n };\n }\n\n private async getYieldingBanksToRefresh(\n tokens: LYCToken[],\n alwaysRefreshYieldingBanks: boolean\n ): Promise<Address[]> {\n const uniqueYbAddresses: Address[] = [];\n const seen = new Set<Address>();\n\n for (const token of tokens) {\n for (const { data: carry } of token.activeCarryPositions) {\n const [yieldingBank] = await this.context.pda.deriveYieldingBankPda(\n fromWeb3Pk(carry.yieldingBaseMint),\n carry.yieldingBankId\n );\n if (!seen.has(yieldingBank)) {\n seen.add(yieldingBank);\n uniqueYbAddresses.push(yieldingBank);\n }\n }\n }\n\n if (alwaysRefreshYieldingBanks || uniqueYbAddresses.length === 0) {\n return uniqueYbAddresses;\n }\n\n const banks = await this.context.account.fetchYieldingBanks(uniqueYbAddresses);\n return banks.filter((bank) => bank.isStale).map((bank) => bank.address);\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarrySingleInstructionBuilderService } from \"./base\";\nimport type { RefreshTokenStateIxArgs } from \"./args\";\nimport {\n type CpiData,\n LendingPlatform,\n createCpiRefs,\n fromWeb3Pk,\n toKitInstruction,\n toWeb3AccountMeta,\n} from \"common\";\nimport { TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { RefreshYieldingBankBuilder } from \"./refreshYieldingBankBuilder\";\n\ninterface RefreshPrerequisiteTarget {\n pool: Address;\n userAccount: Address;\n collateralReserves: Address[];\n debtReserves: Address[];\n}\n\nexport class RefreshTokenStateBuilder extends LongYieldCarrySingleInstructionBuilderService<RefreshTokenStateIxArgs> {\n async getIx(args: RefreshTokenStateIxArgs): Promise<Instruction> {\n const { prerequisiteCpis, accountRefs, remainingAccounts } =\n await this.getRefreshTokenStateParams(args.token);\n\n return this.program.methods\n .refreshTokenState({\n prerequisiteCpis,\n accountRefs,\n })\n .accountsPartial({\n signer: args.signer,\n token: args.token,\n collateralOracle: args.collateralOracle,\n secondaryCollateralOracle: args.secondaryCollateralOracle ?? null,\n collateralTokenAccount: args.collateralTokenAccount,\n collateralTokenProgram: args.collateralTokenProgram ?? TOKEN_PROGRAM_ADDRESS,\n })\n .remainingAccounts(remainingAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: RefreshTokenStateIxArgs): Promise<LongYieldCarryTransactionPlan> {\n const ixs: Instruction[] = [];\n const tokenAccount = await this.account.fetchToken(args.token);\n const uniqueBanks = new Set<Address>();\n\n for (const { data: carry } of tokenAccount.activeCarryPositions) {\n const [yieldingBank] = await this.pda.deriveYieldingBankPda(\n fromWeb3Pk(carry.yieldingBaseMint),\n carry.yieldingBankId\n );\n uniqueBanks.add(yieldingBank);\n }\n\n for (const yieldingBank of uniqueBanks) {\n const refreshYieldingBankPlan = await new RefreshYieldingBankBuilder(this.context).getTx({\n signer: args.signer,\n yieldingBank,\n });\n ixs.push(...refreshYieldingBankPlan.instructions);\n }\n\n ixs.push(await this.getIx(args));\n\n return {\n instructions: ixs,\n lookupTables: this.getTxLookupTables(args.token),\n };\n }\n\n private async getRefreshTokenStateParams(token: Address) {\n const tokenData = await this.account.fetchToken(token);\n const refreshAccounts = await this.account.getTokenRefreshAccounts(token);\n const prerequisiteCpis: CpiData[] = [];\n const refreshTargetsByPlatform = new Map<\n LendingPlatform,\n Map<string, RefreshPrerequisiteTarget>\n >();\n\n for (const { data: position } of tokenData.activeLendingPositions) {\n const platform = this.lendingPlatformClients.getPlatformForPosition(position);\n if (platform === LendingPlatform.None) {\n continue;\n }\n\n const pool = fromWeb3Pk(position.pool);\n const userAccount = fromWeb3Pk(position.protocolUserAcc);\n const collateralReserve = fromWeb3Pk(position.collateralReserve);\n const debtReserve = fromWeb3Pk(position.debtReserve);\n const platformTargets =\n refreshTargetsByPlatform.get(platform) ?? new Map<string, RefreshPrerequisiteTarget>();\n const targetKey = `${pool}:${userAccount}`;\n if (platformTargets.has(targetKey)) {\n continue;\n }\n platformTargets.set(targetKey, {\n pool,\n userAccount,\n collateralReserves: [collateralReserve],\n debtReserves: [debtReserve],\n });\n refreshTargetsByPlatform.set(platform, platformTargets);\n }\n\n for (const [platform, platformTargets] of refreshTargetsByPlatform) {\n const lpClient = this.lendingPlatformClients.getByPlatform(platform);\n const positionPrerequisiteCpis = await lpClient.ix.getPrerequisiteCpisForRefresh([\n ...platformTargets.values(),\n ]);\n prerequisiteCpis.push(...positionPrerequisiteCpis);\n }\n\n // Compute account indices. refreshAccounts is ordered as:\n // [userAcc, collateralReserve, debtOracle] × numActiveLPs, then [yieldingBank] × numActiveCarry\n // initialAccounts are prepended to the pool at stable positions 0..N-1 by createCpiRefs,\n // so indices are the same whether or not prereq CPIs are present.\n const numActiveLPs = tokenData.activeLendingPositions.length;\n const lendingPositions = tokenData.activeLendingPositions.map((_, i) => ({\n userAccount: i * 3,\n collateralReserve: i * 3 + 1,\n debtOracle: i * 3 + 2,\n }));\n const carryPositions = Buffer.from(\n tokenData.activeCarryPositions.map((_, i) => numActiveLPs * 3 + i)\n );\n const accountRefs = { lendingPositions, carryPositions };\n\n if (!prerequisiteCpis.length) {\n return {\n prerequisiteCpis: null,\n accountRefs,\n remainingAccounts: refreshAccounts,\n };\n }\n\n const { accounts: remainingAccounts, refs: prerequisiteCpiRefs } = createCpiRefs(\n prerequisiteCpis,\n {\n initialAccounts: refreshAccounts,\n }\n );\n\n return {\n prerequisiteCpis: prerequisiteCpiRefs,\n accountRefs,\n remainingAccounts,\n };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { RefreshYieldingBankIxArgs, RefreshYieldingBankTxArgs } from \"./args\";\nimport { toKitInstruction, toWeb3AccountMeta } from \"common\";\n\nexport class RefreshYieldingBankBuilder extends LongYieldCarryBuilderBase<\n RefreshYieldingBankIxArgs,\n RefreshYieldingBankTxArgs\n> {\n async getIx(args: RefreshYieldingBankIxArgs): Promise<Instruction> {\n const oracleAccounts = await this.account.getYieldingBankRefreshAccounts(\n args.yieldingBank,\n undefined,\n args.externalLiquiditySources\n );\n\n return this.program.methods\n .refreshYieldingBank()\n .accountsPartial({\n signer: args.signer,\n yieldingBank: args.yieldingBank,\n })\n .remainingAccounts(oracleAccounts.map(toWeb3AccountMeta))\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: RefreshYieldingBankTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const { externalLiquiditySources } =\n await this.externalLiquidityResolver.resolveYieldingBankRefreshExternalLiquidity(\n this.account,\n args.yieldingBank\n );\n const ix = await this.getIx({\n signer: args.signer,\n yieldingBank: args.yieldingBank,\n externalLiquiditySources,\n });\n return { instructions: [ix], lookupTables: this.getTxLookupTables() };\n }\n}\n","import type { Address, Instruction } from \"@solana/kit\";\nimport type { LongYieldCarryBuilderContext } from \"../types/builders\";\nimport type { LYCToken } from \"../../models/lycToken\";\nimport { TOKEN_STALENESS_THRESHOLD_SECS } from \"../../constants/general\";\nimport { RefreshTokensBuilder } from \"./refreshTokensBuilder\";\n\nexport async function getRefreshTokenInstructionsIfStale(\n context: LongYieldCarryBuilderContext,\n signer: Address,\n tokenData: LYCToken\n): Promise<Instruction[]> {\n const lastRefreshed = tokenData.data.accounting.lastRefreshedTs.toNumber();\n const nowSecs = Math.floor(Date.now() / 1000);\n if (nowSecs - lastRefreshed <= TOKEN_STALENESS_THRESHOLD_SECS) {\n return [];\n }\n\n return new RefreshTokensBuilder(context)\n .getTx({\n signer,\n params: {\n tokens: [tokenData.address],\n },\n })\n .then((plan) => [...plan.instructions]);\n}\n","import { BN } from \"@anchor-lang/core\";\nimport type { Instruction } from \"@solana/kit\";\nimport { SYSTEM_PROGRAM_ADDRESS } from \"@solana-program/system\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport {\n createSignerFromAddress,\n fetchSplTokenAccountAmounts,\n getAtaAddress,\n getUnwrapSolInstruction,\n mints,\n resolveTokenProgram,\n toKitInstruction,\n type TransactionCacheInvalidation,\n} from \"common\";\nimport { AMOUNT_ALL_SENTINEL } from \"../../constants/general\";\nimport type { LYCToken } from \"../../models/lycToken\";\n// Import from the specific util modules, not the barrel: the barrel pulls the\n// enrichment/carry graph (lending-platforms → Kamino SDKs), which must stay\n// out of the browser-safe `core` entry that includes this builder.\nimport { getTokenCacheInvalidation } from \"../../utils/cache\";\nimport { currentEpochId } from \"../../utils/general\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport type { BurnTokenIxArgs, BurnTokenTxArgs } from \"./args\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport { getRefreshTokenInstructionsIfStale } from \"./utils\";\n\nexport interface BundledBurnPlan {\n instructions?: Instruction[];\n [key: string]: unknown;\n}\n\ntype ResolvedBurnTokenTxArgs = Omit<BurnTokenTxArgs, \"params\"> & {\n params: Omit<BurnTokenTxArgs[\"params\"], \"burnAmount\"> & { burnAmount: BN | number };\n ixBurnAmount: BN;\n};\n\ntype BurnTokenAsyncAccounts = {\n epochId: BN | number;\n requestSequence: BN | number;\n redemptionEpoch: BurnTokenIxArgs[\"token\"];\n request: BurnTokenIxArgs[\"token\"];\n requestTokenAccount: BurnTokenIxArgs[\"token\"];\n};\n\nexport class BurnTokenBuilder extends LongYieldCarryBuilderBase<BurnTokenIxArgs, BurnTokenTxArgs> {\n async getIx(args: BurnTokenIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const mint = tokenData.mint;\n const collateralMint = tokenData.collateralMint;\n const tokenProgram = resolveTokenProgram(tokenData.data.config.tokenProgram);\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const userTokenAccount = await getAtaAddress(mint, args.signer, tokenProgram);\n const userCollateralAccount = await getAtaAddress(\n collateralMint,\n args.signer,\n collateralTokenProgram\n );\n const collateralTokenAccount = await getAtaAddress(\n collateralMint,\n args.token,\n collateralTokenProgram\n );\n const asyncAccounts = await this.resolveAsyncAccounts(args, mint, tokenProgram);\n\n const burnIxArgs = asyncAccounts\n ? {\n async: {\n burnAmount: new BN(args.params.burnAmount.toString()),\n epochId: new BN(asyncAccounts.epochId.toString()),\n requestSequence: new BN(asyncAccounts.requestSequence.toString()),\n },\n }\n : {\n sync: {\n burnAmount: new BN(args.params.burnAmount.toString()),\n },\n };\n\n return this.program.methods\n .burnToken(burnIxArgs)\n .accountsPartial({\n signer: args.signer,\n payer: args.payer ?? args.signer,\n token: args.token,\n mint,\n userTokenAccount,\n collateralMint,\n userCollateralAccount,\n collateralTokenAccount,\n redemptionEpoch: asyncAccounts?.redemptionEpoch ?? null,\n request: asyncAccounts?.request ?? null,\n requestTokenAccount: asyncAccounts?.requestTokenAccount ?? null,\n tokenProgram,\n collateralTokenProgram,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n systemProgram: SYSTEM_PROGRAM_ADDRESS,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: BurnTokenTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const resolved = await this.resolveAllSentinel(args);\n const tokenData = await this.account.fetchToken(args.token, { fresh: true });\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const userCollateralAtaSetup = await this.getCreateUserCollateralAtaIxIfNeeded(\n args.signer,\n tokenData.collateralMint,\n collateralTokenProgram\n );\n const refreshInstructions = await getRefreshTokenInstructionsIfStale(\n this.context,\n args.signer,\n tokenData\n );\n\n const asyncAccounts = await this.resolveAsyncFallbackParams(args.token, {\n epochId: args.params.epochId,\n requestSequence: args.params.requestSequence,\n });\n\n const instructions: Instruction[] = [...refreshInstructions];\n if (userCollateralAtaSetup.instruction) {\n instructions.push(userCollateralAtaSetup.instruction);\n }\n instructions.push(\n await this.getIx({\n signer: args.signer,\n payer: args.payer,\n token: args.token,\n params: {\n burnAmount: resolved.ixBurnAmount,\n asyncFallback: asyncAccounts,\n },\n })\n );\n\n const unwrapSolIx = await this.getUnwrapSolAfterBurnIfCollateralSol(args.signer, tokenData);\n if (unwrapSolIx) {\n instructions.push(unwrapSolIx);\n }\n\n const postSuccessCacheInvalidations: TransactionCacheInvalidation[] = [\n ...(userCollateralAtaSetup.postSuccessCacheInvalidations ?? []),\n getTokenCacheInvalidation(args.token),\n ];\n if (unwrapSolIx) {\n const userCollateralAta = await getAtaAddress(\n tokenData.collateralMint,\n args.signer,\n collateralTokenProgram\n );\n postSuccessCacheInvalidations.push({ client: \"splAta\", ata: userCollateralAta });\n }\n\n return {\n instructions,\n lookupTables: this.getTxLookupTables(args.token),\n postSuccessCacheInvalidations,\n };\n }\n\n async buildBundledBurnPlan(..._args: unknown[]): Promise<BundledBurnPlan> {\n throw new Error(\"Managed burn unwind plans were removed; use async burn funding instead.\");\n }\n\n private async resolveAllSentinel(args: BurnTokenTxArgs): Promise<ResolvedBurnTokenTxArgs> {\n if (args.params.burnAmount !== \"all\") {\n const amount = args.params.burnAmount;\n return {\n ...args,\n params: { ...args.params, burnAmount: amount },\n ixBurnAmount: new BN(amount.toString()),\n };\n }\n const tokenData = await this.account.fetchToken(args.token);\n const userTokenAta = await getAtaAddress(\n tokenData.mint,\n args.signer,\n resolveTokenProgram(tokenData.data.config.tokenProgram)\n );\n const balances = await fetchSplTokenAccountAmounts(this.rpc, [userTokenAta]);\n return {\n ...args,\n params: {\n ...args.params,\n burnAmount: new BN((balances.get(userTokenAta) ?? BigInt(0)).toString()),\n },\n ixBurnAmount: AMOUNT_ALL_SENTINEL,\n };\n }\n\n private async resolveAsyncFallbackParams(\n token: BurnTokenTxArgs[\"token\"],\n overrides: { epochId?: BN | number; requestSequence?: BN | number }\n ): Promise<NonNullable<BurnTokenIxArgs[\"params\"][\"asyncFallback\"]>> {\n const epochId = overrides.epochId ?? currentEpochId();\n const [redemptionEpoch] = await this.pda.deriveRedemptionEpochPda(\n token,\n BigInt(epochId.toString())\n );\n const requestSequence =\n overrides.requestSequence ?? (await this.resolveNextRequestSequence(redemptionEpoch));\n const [request] = await this.pda.deriveAsyncBurnRequestPda(\n token,\n BigInt(epochId.toString()),\n BigInt(requestSequence.toString())\n );\n return { epochId, requestSequence, redemptionEpoch, request };\n }\n\n private async resolveNextRequestSequence(redemptionEpoch: BurnTokenIxArgs[\"token\"]): Promise<BN> {\n try {\n const epoch = await this.program.account.redemptionEpoch.fetch(redemptionEpoch);\n return new BN(epoch.sequencing.nextRequestSequence.toString());\n } catch {\n return new BN(0);\n }\n }\n\n private async resolveAsyncAccounts(\n args: BurnTokenIxArgs,\n mint: BurnTokenIxArgs[\"token\"],\n tokenProgram: BurnTokenIxArgs[\"token\"]\n ): Promise<BurnTokenAsyncAccounts | undefined> {\n if (!args.params.asyncFallback) {\n return undefined;\n }\n const epochId = args.params.asyncFallback.epochId;\n const requestSequence = args.params.asyncFallback.requestSequence;\n const redemptionEpoch =\n args.params.asyncFallback.redemptionEpoch ??\n (await this.pda.deriveRedemptionEpochPda(args.token, BigInt(epochId.toString())))[0];\n const request =\n args.params.asyncFallback.request ??\n (\n await this.pda.deriveAsyncBurnRequestPda(\n args.token,\n BigInt(epochId.toString()),\n BigInt(requestSequence.toString())\n )\n )[0];\n return {\n epochId,\n requestSequence,\n redemptionEpoch,\n request,\n requestTokenAccount: await getAtaAddress(mint, request, tokenProgram),\n };\n }\n\n private async getUnwrapSolAfterBurnIfCollateralSol(\n signer: BurnTokenTxArgs[\"signer\"],\n tokenData: LYCToken\n ): Promise<Instruction | null> {\n const solMint = mints.get(\"SOL\");\n if (!solMint || tokenData.collateralMint !== solMint.address) {\n return null;\n }\n return getUnwrapSolInstruction(createSignerFromAddress(signer));\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, 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 } 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 { 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 type { Instruction } from \"@solana/kit\";\nimport { BN } from \"@anchor-lang/core\";\nimport type { LongYieldCarryTransactionPlan } from \"../types\";\nimport { LongYieldCarryBuilderBase } from \"./base\";\nimport type { MintTokenIxArgs, MintTokenTxArgs } from \"./args\";\nimport {\n getAtaAddress,\n getCreateAtaIxIfNeeded,\n mints,\n resolveTokenProgram,\n toKitInstruction,\n} from \"common\";\nimport { AMOUNT_ALL_SENTINEL } from \"../../constants/general\";\nimport { getRefreshTokenInstructionsIfStale } from \"./utils\";\n\n/** Reserve kept in the wallet when depositing \"all\" SOL (covers tx fees + rent). */\nconst SOL_RESERVE_LAMPORTS = 10_000_000; // 0.01 SOL\n\nexport class MintTokenBuilder extends LongYieldCarryBuilderBase<MintTokenIxArgs, MintTokenTxArgs> {\n async getIx(args: MintTokenIxArgs): Promise<Instruction> {\n const tokenData = await this.account.fetchToken(args.token);\n const mint = tokenData.mint;\n const collateralMint = tokenData.collateralMint;\n const tokenProgram = resolveTokenProgram(tokenData.data.config.tokenProgram);\n const collateralTokenProgram = resolveTokenProgram(tokenData.data.collateral.tokenProgram);\n const userCollateralAccount = await getAtaAddress(\n collateralMint,\n args.signer,\n collateralTokenProgram\n );\n const userTokenAccount = await getAtaAddress(mint, args.signer, tokenProgram);\n const collateralTokenAccount = await getAtaAddress(\n collateralMint,\n args.token,\n collateralTokenProgram\n );\n\n return this.program.methods\n .mintToken(args.depositAmount)\n .accountsPartial({\n signer: args.signer,\n token: args.token,\n mint,\n collateralMint,\n userCollateralAccount,\n userTokenAccount,\n collateralTokenAccount,\n tokenProgram,\n collateralTokenProgram,\n })\n .instruction()\n .then(toKitInstruction);\n }\n\n async getTx(args: MintTokenTxArgs): Promise<LongYieldCarryTransactionPlan> {\n const isAll = args.params.depositAmount === \"all\";\n\n const tokenData = await this.account.fetchToken(args.token);\n const mint = tokenData.mint;\n const collateralMint = tokenData.collateralMint;\n const tokenProgram = resolveTokenProgram(tokenData.data.config.tokenProgram);\n const instructions: Instruction[] = [];\n const postSuccessCacheInvalidations: NonNullable<\n LongYieldCarryTransactionPlan[\"postSuccessCacheInvalidations\"]\n > = [];\n instructions.push(\n ...(await getRefreshTokenInstructionsIfStale(this.context, args.signer, tokenData))\n );\n\n // Resolve the deposit amount. For native SOL + \"all\", we query the wallet\n // balance and reserve 0.01 SOL for tx fees, then wrap that concrete amount.\n // For non-SOL + \"all\", use the on-chain sentinel so the program reads the\n // ATA balance at execution time.\n const solMint = mints.get(\"SOL\");\n const isSolCollateral = solMint != null && collateralMint === solMint.address;\n let depositAmount: BN;\n\n if (isAll && isSolCollateral) {\n const { value: balanceLamports } = await this.rpc.getBalance(args.signer).send();\n const available = BigInt(balanceLamports.toString()) - BigInt(SOL_RESERVE_LAMPORTS);\n if (available <= 0n) {\n throw new Error(\n `Insufficient SOL balance: need more than ${\n SOL_RESERVE_LAMPORTS / 1e9\n } SOL reserved for fees`\n );\n }\n depositAmount = new BN(available.toString());\n } else if (isAll) {\n depositAmount = AMOUNT_ALL_SENTINEL;\n } else {\n depositAmount = args.params.depositAmount as BN;\n }\n\n if (!isAll || isSolCollateral) {\n const wrap = await this.getWrapSolInstructionsIfMintIsSol(\n args.signer,\n collateralMint,\n depositAmount\n );\n if (wrap.instructions) {\n instructions.push(...wrap.instructions);\n }\n if (wrap.postSuccessCacheInvalidations) {\n postSuccessCacheInvalidations.push(...wrap.postSuccessCacheInvalidations);\n }\n }\n\n const createAtaOptions = { accountClient: this.account };\n const yTokenAta = await getCreateAtaIxIfNeeded(\n this.rpc,\n args.signer,\n mint,\n args.signer,\n tokenProgram,\n createAtaOptions\n );\n if (yTokenAta.instruction) {\n instructions.push(yTokenAta.instruction);\n }\n postSuccessCacheInvalidations.push(...yTokenAta.postSuccessCacheInvalidations);\n instructions.push(\n await this.getIx({\n signer: args.signer,\n token: args.token,\n depositAmount,\n })\n );\n postSuccessCacheInvalidations.push({ client: \"lycToken\", tokenPda: args.token });\n\n return {\n instructions,\n lookupTables: this.getTxLookupTables(args.token),\n postSuccessCacheInvalidations,\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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QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;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","names":["address","address","import_kit","import_web3","import_token","buf","import_kit","address","address","import_kit","import_web3","import_kit","import_kit","init_general","init_general","import_token","import_token","import_kit","init_rpc","init_rpc","import_core","import_web3","init_rpc","import_system","init_cpi","init_cpi","init_general","import_kit","address","addressEncoder","import_system","bs58","sum","import_kit","import_kit","init_rpc","import_kit","import_kit","import_core","import_token","import_token_2022","import_system","import_kit","import_system","import_sysvars","init_cpi","init_general","init_rpc","init_solana","init_general","init_cpi","init_types","init_solana","init_general","init_cpi","init_types","init_types","init_types","init_token","init_types","init_token","init_types","import_kit","mints","mints","import_kit","init_constants","import_kit","init_constants","init_cpi","import_core","import_web3","import_token","import_system","init_constants","init_cpi","init_accounts","address","init_utils","init_src","init_constants","init_accounts","init_cpi","init_utils","init_splStake","init_utils","oracle","init_general","init_src","init_splStake","init_utils","init_general","import_ts_retry","init_pyth","init_constants","init_utils","mints","prices","init_switchboard","mints","address","oracle","mints","import_kit","init_pyth","init_switchboard","init_utils","oracle","mints","init_src","init_constants","init_utils","init_splStake","import_kit","init_constants","init_kamino","init_general","init_types","init_kamino","init_general","mintSymbol","init_accounts","init_constants","init_cache","Decimal","import_core","init_kamino","init_types","init_services","dep","init_utils","init_accounts","init_cache","init_kamino","import_klend_sdk","import_scope_sdk","import_farms_sdk","import_decimal","init_kamino","init_data","init_constants","init_types","init_utils","Decimal","init_kamino","address","import_decimal","import_core","import_farms_sdk","init_kamino","init_utils","Decimal","init_kamino","address","import_klend_sdk","import_decimal","init_kamino","Decimal","init_kamino","import_core","address","sum","import_core","init_kamino","init_kamino","import_core","import_kit","import_scope_sdk","import_klend_sdk","import_token","import_farms_sdk","init_kamino","init_constants","init_utils","tokens","chainTokens","configAddr","init_types","init_kamino","init_types","import_klend_sdk","import_token","init_kamino","init_constants","init_accounts","init_kamino","init_data","init_accounts","import_core","import_decimal","import_kit","import_klend_sdk","init_kamino","Decimal","import_klend_sdk","init_kamino","init_data","init_accounts","init_client","init_kamino","init_kamino","import_kit","init_constants","init_types","import_kit","init_constants","import_kit","init_constants","init_client","init_constants","init_src","init_constants","init_types","init_client","init_src","import_core","import_core","init_src","init_types","init_types","init_types","init_lendingPosition","init_types","init_services","init_client","init_lendingPosition","init_src","init_services","init_data","init_constants","init_utils","init_types","MAX_LENDING_POSITION_UPPER_UTIL_BPS","init_src","init_src","MAX_LENDING_POSITION_UPPER_UTIL_BPS","MAX_LENDING_POSITION_UPPER_UTIL_BPS","PROGRAM_ID","import_web3","init_src","import_core","sum","import_web3","import_address_lookup_table","import_compute_budget","import_system","import_token","import_token_2022","init_src","import_core","import_kit","PROGRAM_ID","init_src","PROGRAM_ID","import_kit","import_token","init_src","import_core","import_kit","init_src","init_src","import_kit","addressEncoder","import_kit","import_web3","import_kit","import_web3","BASIS_POINTS","address","sum","import_web3","address","oracle","init_src","import_web3","import_web3","PROGRAM_ID","import_token","import_core","import_system","import_token","init_src","import_token","import_core","import_web3","carry","import_core","import_token","import_token","init_src","init_src","init_src","import_core","import_core","init_src","import_web3","init_src","sum","PROGRAM_ID","InterestDistribution","LendingType","init_src","mintSymbol","lutManager","init_src","USD_STAR","import_web3","sum","import_web3","import_token","import_token_2022","fetchMaybeToken2022","sum","LycLendingPositionManager","import_bs58","import_token","import_token_2022","bs58","import_bs58","bs58"]}