@upshiftfinance/sdk 0.0.0-stage → 0.2.0

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 (344) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -2
  3. package/lib/abis/AddressResolver.d.ts +28 -0
  4. package/lib/abis/AddressResolver.js +23 -0
  5. package/lib/abis/ChainlinkV3.d.ts +87 -0
  6. package/lib/abis/ChainlinkV3.js +117 -0
  7. package/lib/abis/ERC20.d.ts +168 -0
  8. package/lib/abis/ERC20.js +226 -0
  9. package/lib/abis/ERC20_Bytes32.d.ts +139 -0
  10. package/lib/abis/ERC20_Bytes32.js +196 -0
  11. package/lib/abis/ERC4626.d.ts +364 -0
  12. package/lib/abis/ERC4626.js +507 -0
  13. package/lib/abis/ERC721.d.ts +231 -0
  14. package/lib/abis/ERC721.js +321 -0
  15. package/lib/abis/FeeOracle.d.ts +120 -0
  16. package/lib/abis/FeeOracle.js +162 -0
  17. package/lib/abis/LendingPool.d.ts +1393 -0
  18. package/lib/abis/LendingPool.js +1807 -0
  19. package/lib/abis/LendingPoolV2.d.ts +1413 -0
  20. package/lib/abis/LendingPoolV2.js +1833 -0
  21. package/lib/abis/LendingPoolV3.d.ts +1677 -0
  22. package/lib/abis/LendingPoolV3.js +1160 -0
  23. package/lib/abis/Loan.d.ts +837 -0
  24. package/lib/abis/Loan.js +1080 -0
  25. package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
  26. package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
  27. package/lib/abis/Multicall3.d.ts +30 -0
  28. package/lib/abis/Multicall3.js +97 -0
  29. package/lib/abis/OFT.d.ts +116 -0
  30. package/lib/abis/OFT.js +85 -0
  31. package/lib/abis/PoolAdapter.d.ts +36 -0
  32. package/lib/abis/PoolAdapter.js +51 -0
  33. package/lib/abis/RewardDistributor.d.ts +267 -0
  34. package/lib/abis/RewardDistributor.js +352 -0
  35. package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
  36. package/lib/abis/RwaRedeemSubaccount.js +548 -0
  37. package/lib/abis/SmartAccount.d.ts +17 -0
  38. package/lib/abis/SmartAccount.js +19 -0
  39. package/lib/abis/SwapRouter.d.ts +953 -0
  40. package/lib/abis/SwapRouter.js +1228 -0
  41. package/lib/abis/TextResolver.d.ts +16 -0
  42. package/lib/abis/TextResolver.js +16 -0
  43. package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
  44. package/lib/abis/TokenizedVaultV2.js +1041 -0
  45. package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
  46. package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
  47. package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
  48. package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
  49. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
  50. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
  51. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
  52. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
  53. package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
  54. package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
  55. package/lib/abis/UniversalResolverResolve.d.ts +69 -0
  56. package/lib/abis/UniversalResolverResolve.js +35 -0
  57. package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
  58. package/lib/abis/UniversalSignatureValidator.js +30 -0
  59. package/lib/abis/WrapperAdapter.d.ts +71 -0
  60. package/lib/abis/WrapperAdapter.js +77 -0
  61. package/lib/abis/index.d.ts +34 -0
  62. package/lib/abis/index.js +51 -0
  63. package/lib/adapters/evm/getters.d.ts +19 -0
  64. package/lib/adapters/evm/getters.js +249 -0
  65. package/lib/adapters/evm/index.d.ts +539 -0
  66. package/lib/adapters/evm/index.js +656 -0
  67. package/lib/adapters/evm/utils.d.ts +8 -0
  68. package/lib/adapters/evm/utils.js +51 -0
  69. package/lib/adapters/solana/confirm.d.ts +88 -0
  70. package/lib/adapters/solana/confirm.js +291 -0
  71. package/lib/adapters/solana/constants.d.ts +42 -0
  72. package/lib/adapters/solana/constants.js +59 -0
  73. package/lib/adapters/solana/getters.d.ts +42 -0
  74. package/lib/adapters/solana/getters.js +275 -0
  75. package/lib/adapters/solana/idl/vault-idl.d.ts +700 -0
  76. package/lib/adapters/solana/idl/vault-idl.js +2101 -0
  77. package/lib/adapters/solana/idl/withdrawal-queue-idl.d.ts +795 -0
  78. package/lib/adapters/solana/idl/withdrawal-queue-idl.js +1864 -0
  79. package/lib/adapters/solana/index.d.ts +372 -0
  80. package/lib/adapters/solana/index.js +459 -0
  81. package/lib/adapters/solana/pricing.d.ts +184 -0
  82. package/lib/adapters/solana/pricing.js +239 -0
  83. package/lib/adapters/solana/queue-hints.d.ts +29 -0
  84. package/lib/adapters/solana/queue-hints.js +59 -0
  85. package/lib/adapters/solana/queue.actions.d.ts +97 -0
  86. package/lib/adapters/solana/queue.actions.js +468 -0
  87. package/lib/adapters/solana/token-reads.d.ts +108 -0
  88. package/lib/adapters/solana/token-reads.js +145 -0
  89. package/lib/adapters/solana/types.d.ts +325 -0
  90. package/lib/adapters/solana/types.js +3 -0
  91. package/lib/adapters/solana/utils.d.ts +229 -0
  92. package/lib/adapters/solana/utils.js +773 -0
  93. package/lib/adapters/solana/vault.actions.d.ts +140 -0
  94. package/lib/adapters/solana/vault.actions.js +657 -0
  95. package/lib/adapters/solana/withdrawal-queue.d.ts +125 -0
  96. package/lib/adapters/solana/withdrawal-queue.js +301 -0
  97. package/lib/adapters/stellar/actions.d.ts +41 -0
  98. package/lib/adapters/stellar/actions.js +126 -0
  99. package/lib/adapters/stellar/constants.d.ts +43 -0
  100. package/lib/adapters/stellar/constants.js +53 -0
  101. package/lib/adapters/stellar/getters.d.ts +68 -0
  102. package/lib/adapters/stellar/getters.js +290 -0
  103. package/lib/adapters/stellar/index.d.ts +126 -0
  104. package/lib/adapters/stellar/index.js +187 -0
  105. package/lib/adapters/stellar/invocation.d.ts +55 -0
  106. package/lib/adapters/stellar/invocation.js +92 -0
  107. package/lib/adapters/stellar/soroban.d.ts +131 -0
  108. package/lib/adapters/stellar/soroban.js +617 -0
  109. package/lib/adapters/stellar/submit.d.ts +42 -0
  110. package/lib/adapters/stellar/submit.js +195 -0
  111. package/lib/adapters/stellar/types.d.ts +57 -0
  112. package/lib/adapters/stellar/types.js +6 -0
  113. package/lib/adapters/stellar/utils.d.ts +24 -0
  114. package/lib/adapters/stellar/utils.js +34 -0
  115. package/lib/adapters/sui/client.d.ts +83 -0
  116. package/lib/adapters/sui/client.js +216 -0
  117. package/lib/adapters/sui/constants.d.ts +33 -0
  118. package/lib/adapters/sui/constants.js +31 -0
  119. package/lib/adapters/sui/index.d.ts +57 -0
  120. package/lib/adapters/sui/index.js +100 -0
  121. package/lib/adapters/sui/targets.d.ts +171 -0
  122. package/lib/adapters/sui/targets.js +225 -0
  123. package/lib/adapters/sui/utils.d.ts +8 -0
  124. package/lib/adapters/sui/utils.js +17 -0
  125. package/lib/core/analytics/app-name.d.ts +27 -0
  126. package/lib/core/analytics/app-name.js +48 -0
  127. package/lib/core/analytics/chain-name.d.ts +9 -0
  128. package/lib/core/analytics/chain-name.js +34 -0
  129. package/lib/core/analytics/constants.d.ts +15 -0
  130. package/lib/core/analytics/constants.js +28 -0
  131. package/lib/core/analytics/env.d.ts +46 -0
  132. package/lib/core/analytics/env.js +147 -0
  133. package/lib/core/analytics/index.d.ts +39 -0
  134. package/lib/core/analytics/index.js +83 -0
  135. package/lib/core/analytics/instrumentation.d.ts +29 -0
  136. package/lib/core/analytics/instrumentation.js +292 -0
  137. package/lib/core/analytics/method-taxonomy.d.ts +19 -0
  138. package/lib/core/analytics/method-taxonomy.js +156 -0
  139. package/lib/core/analytics/metrics.d.ts +48 -0
  140. package/lib/core/analytics/metrics.js +142 -0
  141. package/lib/core/analytics/sanitize.d.ts +57 -0
  142. package/lib/core/analytics/sanitize.js +272 -0
  143. package/lib/core/analytics/sentry-runtime.d.ts +15 -0
  144. package/lib/core/analytics/sentry-runtime.js +131 -0
  145. package/lib/core/analytics/sentry.d.ts +100 -0
  146. package/lib/core/analytics/sentry.js +696 -0
  147. package/lib/core/analytics/types.d.ts +55 -0
  148. package/lib/core/analytics/types.js +3 -0
  149. package/lib/core/analytics/user-identity.d.ts +55 -0
  150. package/lib/core/analytics/user-identity.js +218 -0
  151. package/lib/core/analytics/version.d.ts +6 -0
  152. package/lib/core/analytics/version.js +10 -0
  153. package/lib/core/attribution.d.ts +159 -0
  154. package/lib/core/attribution.js +194 -0
  155. package/lib/core/auth/index.d.ts +1 -0
  156. package/lib/core/auth/index.js +18 -0
  157. package/lib/core/auth/verify.d.ts +2 -0
  158. package/lib/core/auth/verify.js +35 -0
  159. package/lib/core/base.class.d.ts +193 -0
  160. package/lib/core/base.class.js +163 -0
  161. package/lib/core/cache.d.ts +9 -0
  162. package/lib/core/cache.js +31 -0
  163. package/lib/core/constants/adapters.d.ts +103 -0
  164. package/lib/core/constants/adapters.js +180 -0
  165. package/lib/core/constants/core.d.ts +162 -0
  166. package/lib/core/constants/core.js +281 -0
  167. package/lib/core/constants/swap-router.d.ts +180 -0
  168. package/lib/core/constants/swap-router.js +203 -0
  169. package/lib/core/constants/vaults.d.ts +93 -0
  170. package/lib/core/constants/vaults.js +277 -0
  171. package/lib/core/constants/web3.d.ts +106 -0
  172. package/lib/core/constants/web3.js +251 -0
  173. package/lib/core/errors/index.d.ts +177 -0
  174. package/lib/core/errors/index.js +257 -0
  175. package/lib/core/fetcher.d.ts +237 -0
  176. package/lib/core/fetcher.js +1103 -0
  177. package/lib/core/helpers/adapters.d.ts +13 -0
  178. package/lib/core/helpers/adapters.js +39 -0
  179. package/lib/core/helpers/chain-address.d.ts +13 -0
  180. package/lib/core/helpers/chain-address.js +47 -0
  181. package/lib/core/helpers/chain-error.d.ts +207 -0
  182. package/lib/core/helpers/chain-error.js +697 -0
  183. package/lib/core/helpers/chain-support.d.ts +98 -0
  184. package/lib/core/helpers/chain-support.js +139 -0
  185. package/lib/core/helpers/concurrency.d.ts +51 -0
  186. package/lib/core/helpers/concurrency.js +79 -0
  187. package/lib/core/helpers/core.d.ts +92 -0
  188. package/lib/core/helpers/core.js +368 -0
  189. package/lib/core/helpers/explorer-link.d.ts +16 -0
  190. package/lib/core/helpers/explorer-link.js +26 -0
  191. package/lib/core/helpers/multicall.d.ts +68 -0
  192. package/lib/core/helpers/multicall.js +103 -0
  193. package/lib/core/helpers/revert-decode.d.ts +248 -0
  194. package/lib/core/helpers/revert-decode.js +515 -0
  195. package/lib/core/helpers/signer.d.ts +61 -0
  196. package/lib/core/helpers/signer.js +184 -0
  197. package/lib/core/helpers/swap-router.d.ts +269 -0
  198. package/lib/core/helpers/swap-router.js +542 -0
  199. package/lib/core/helpers/vault-version.d.ts +24 -0
  200. package/lib/core/helpers/vault-version.js +83 -0
  201. package/lib/core/helpers/vaults.d.ts +89 -0
  202. package/lib/core/helpers/vaults.js +241 -0
  203. package/lib/core/helpers/web3.d.ts +366 -0
  204. package/lib/core/helpers/web3.js +1034 -0
  205. package/lib/core/index.d.ts +23 -0
  206. package/lib/core/index.js +40 -0
  207. package/lib/core/logger/curator-alert.d.ts +217 -0
  208. package/lib/core/logger/curator-alert.js +276 -0
  209. package/lib/core/logger/index.d.ts +99 -0
  210. package/lib/core/logger/index.js +163 -0
  211. package/lib/core/logger/slack.d.ts +49 -0
  212. package/lib/core/logger/slack.js +111 -0
  213. package/lib/core/vault-metadata.d.ts +12 -0
  214. package/lib/core/vault-metadata.js +42 -0
  215. package/lib/core/version-check.d.ts +58 -0
  216. package/lib/core/version-check.js +182 -0
  217. package/lib/evm/index.d.ts +2 -0
  218. package/lib/evm/index.js +19 -0
  219. package/lib/evm/methods/crossChainVault.d.ts +132 -0
  220. package/lib/evm/methods/crossChainVault.js +857 -0
  221. package/lib/evm/methods/crossChainVaultRegistry.d.ts +92 -0
  222. package/lib/evm/methods/crossChainVaultRegistry.js +239 -0
  223. package/lib/evm/methods/index.d.ts +2 -0
  224. package/lib/evm/methods/index.js +19 -0
  225. package/lib/evm/types/crossChain.d.ts +363 -0
  226. package/lib/evm/types/crossChain.js +20 -0
  227. package/lib/evm/types/index.d.ts +1 -0
  228. package/lib/evm/types/index.js +18 -0
  229. package/lib/index.d.ts +30 -0
  230. package/lib/index.js +52 -0
  231. package/lib/main.d.ts +596 -0
  232. package/lib/main.js +681 -0
  233. package/lib/modules/api/fetcher.d.ts +108 -0
  234. package/lib/modules/api/fetcher.js +187 -0
  235. package/lib/modules/api/index.d.ts +1 -0
  236. package/lib/modules/api/index.js +6 -0
  237. package/lib/modules/api/main.d.ts +587 -0
  238. package/lib/modules/api/main.js +911 -0
  239. package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
  240. package/lib/modules/sub-accounts/fetcher.js +96 -0
  241. package/lib/modules/sub-accounts/index.d.ts +2 -0
  242. package/lib/modules/sub-accounts/index.js +19 -0
  243. package/lib/modules/sub-accounts/main.d.ts +249 -0
  244. package/lib/modules/sub-accounts/main.js +211 -0
  245. package/lib/modules/sub-accounts/utils.d.ts +106 -0
  246. package/lib/modules/sub-accounts/utils.js +112 -0
  247. package/lib/modules/vaults/adapter.helpers.d.ts +84 -0
  248. package/lib/modules/vaults/adapter.helpers.js +202 -0
  249. package/lib/modules/vaults/fetcher.d.ts +147 -0
  250. package/lib/modules/vaults/fetcher.js +357 -0
  251. package/lib/modules/vaults/getters.d.ts +1060 -0
  252. package/lib/modules/vaults/getters.js +4079 -0
  253. package/lib/modules/vaults/index.d.ts +20 -0
  254. package/lib/modules/vaults/index.js +44 -0
  255. package/lib/modules/vaults/main.d.ts +607 -0
  256. package/lib/modules/vaults/main.js +1687 -0
  257. package/lib/modules/vaults/prefetch.d.ts +65 -0
  258. package/lib/modules/vaults/prefetch.js +120 -0
  259. package/lib/modules/vaults/read.actions.d.ts +406 -0
  260. package/lib/modules/vaults/read.actions.js +891 -0
  261. package/lib/modules/vaults/types.d.ts +149 -0
  262. package/lib/modules/vaults/types.js +3 -0
  263. package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
  264. package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
  265. package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
  266. package/lib/modules/vaults/utils/date-utils.js +84 -0
  267. package/lib/modules/vaults/utils.d.ts +153 -0
  268. package/lib/modules/vaults/utils.js +818 -0
  269. package/lib/modules/vaults/write.actions.d.ts +812 -0
  270. package/lib/modules/vaults/write.actions.js +2377 -0
  271. package/lib/polyfills.d.ts +1 -0
  272. package/lib/polyfills.js +12 -0
  273. package/lib/sdk.d.ts +30173 -0
  274. package/lib/services/coingecko/fetcher.d.ts +15 -0
  275. package/lib/services/coingecko/fetcher.js +67 -0
  276. package/lib/services/coingecko/index.d.ts +2 -0
  277. package/lib/services/coingecko/index.js +19 -0
  278. package/lib/services/coingecko/utils.d.ts +1 -0
  279. package/lib/services/coingecko/utils.js +24 -0
  280. package/lib/services/debank/fetcher.d.ts +126 -0
  281. package/lib/services/debank/fetcher.js +47 -0
  282. package/lib/services/debank/index.d.ts +2 -0
  283. package/lib/services/debank/index.js +19 -0
  284. package/lib/services/debank/utils.d.ts +50 -0
  285. package/lib/services/debank/utils.js +325 -0
  286. package/lib/services/layerzero/deposits.d.ts +55 -0
  287. package/lib/services/layerzero/deposits.js +174 -0
  288. package/lib/services/layerzero/redeems.d.ts +20 -0
  289. package/lib/services/layerzero/redeems.js +92 -0
  290. package/lib/services/layerzero/utils.d.ts +9 -0
  291. package/lib/services/layerzero/utils.js +22 -0
  292. package/lib/services/octavfi/fetcher.d.ts +33 -0
  293. package/lib/services/octavfi/fetcher.js +39 -0
  294. package/lib/services/octavfi/index.d.ts +3 -0
  295. package/lib/services/octavfi/index.js +20 -0
  296. package/lib/services/octavfi/types.d.ts +34 -0
  297. package/lib/services/octavfi/types.js +3 -0
  298. package/lib/services/octavfi/utils.d.ts +16 -0
  299. package/lib/services/octavfi/utils.js +244 -0
  300. package/lib/services/subgraph/fetcher.d.ts +2 -0
  301. package/lib/services/subgraph/fetcher.js +66 -0
  302. package/lib/services/subgraph/index.d.ts +2 -0
  303. package/lib/services/subgraph/index.js +19 -0
  304. package/lib/services/subgraph/schema.d.ts +48 -0
  305. package/lib/services/subgraph/schema.js +87 -0
  306. package/lib/services/subgraph/vaults.d.ts +83 -0
  307. package/lib/services/subgraph/vaults.js +1282 -0
  308. package/lib/services/swap-quotes/index.d.ts +105 -0
  309. package/lib/services/swap-quotes/index.js +77 -0
  310. package/lib/services/swap-quotes/paraswap.d.ts +51 -0
  311. package/lib/services/swap-quotes/paraswap.js +138 -0
  312. package/lib/services/untangled/fetcher.d.ts +40 -0
  313. package/lib/services/untangled/fetcher.js +110 -0
  314. package/lib/services/untangled/index.d.ts +3 -0
  315. package/lib/services/untangled/index.js +20 -0
  316. package/lib/services/untangled/types.d.ts +83 -0
  317. package/lib/services/untangled/types.js +10 -0
  318. package/lib/services/untangled/utils.d.ts +91 -0
  319. package/lib/services/untangled/utils.js +339 -0
  320. package/lib/types/api.d.ts +498 -0
  321. package/lib/types/api.js +3 -0
  322. package/lib/types/index.d.ts +12 -0
  323. package/lib/types/index.js +28 -0
  324. package/lib/types/points.d.ts +28 -0
  325. package/lib/types/points.js +3 -0
  326. package/lib/types/pools.d.ts +144 -0
  327. package/lib/types/pools.js +3 -0
  328. package/lib/types/staking.d.ts +28 -0
  329. package/lib/types/staking.js +3 -0
  330. package/lib/types/sub-accounts.d.ts +150 -0
  331. package/lib/types/sub-accounts.js +3 -0
  332. package/lib/types/subgraph.d.ts +84 -0
  333. package/lib/types/subgraph.js +3 -0
  334. package/lib/types/typed-contract.d.ts +102 -0
  335. package/lib/types/typed-contract.js +3 -0
  336. package/lib/types/user.d.ts +1 -0
  337. package/lib/types/user.js +3 -0
  338. package/lib/types/vaults.d.ts +886 -0
  339. package/lib/types/vaults.js +30 -0
  340. package/lib/types/web3.d.ts +100 -0
  341. package/lib/types/web3.js +14 -0
  342. package/lib/types/webserver.d.ts +730 -0
  343. package/lib/types/webserver.js +3 -0
  344. package/package.json +79 -3
@@ -0,0 +1,818 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ERC_20_PERMIT_HASH = exports.getRewardMultiplierByTimestamp = void 0;
4
+ exports.walletClientToSigner = walletClientToSigner;
5
+ exports.getVaultRewards = getVaultRewards;
6
+ exports.getIdleAssets = getIdleAssets;
7
+ exports.getYieldLastRealizedOn = getYieldLastRealizedOn;
8
+ exports.formatVaultApy = formatVaultApy;
9
+ exports.mapVaultFreshness = mapVaultFreshness;
10
+ exports.mapUnderlyingVault = mapUnderlyingVault;
11
+ exports.mapStrategists = mapStrategists;
12
+ exports.mapComposabilityIntegrations = mapComposabilityIntegrations;
13
+ exports.backendTvlToNormalizedBn = backendTvlToNormalizedBn;
14
+ exports.buildBackendVault = buildBackendVault;
15
+ exports.buildFormattedVault = buildFormattedVault;
16
+ exports.generatePermitSignature = generatePermitSignature;
17
+ exports.createDeadline = createDeadline;
18
+ const abis_1 = require("../../abis");
19
+ const core_1 = require("../../core");
20
+ const vaults_1 = require("../../core/helpers/vaults");
21
+ const ethers_1 = require("ethers");
22
+ /**
23
+ * @param walletClient a wagmi-derived client (from useWalletClient)
24
+ * @returns An ethers JsonRpcSigner object used in sdk.evm.setSigner
25
+ */
26
+ async function walletClientToSigner(walletClient) {
27
+ const { account, chain, transport } = walletClient;
28
+ const network = {
29
+ chainId: chain.id,
30
+ name: chain.name,
31
+ ensAddress: chain.contracts?.ensRegistry?.address,
32
+ };
33
+ //@ts-expect-error
34
+ const provider = new ethers_1.BrowserProvider(transport, network);
35
+ const signer = await provider.getSigner(account.address);
36
+ return signer;
37
+ }
38
+ /**
39
+ * Calculates the reward multiplier based on the vault and optional timestamp.
40
+ * Returns the applicable multiplier for a given vault at a specific timestamp,
41
+ * or the latest multiplier if no timestamp is provided.
42
+ * @param foundPool The vault to get the multiplier for
43
+ * @param timestamp Optional timestamp to get historical multiplier
44
+ * @returns The reward multiplier value
45
+ */
46
+ const getRewardMultiplierByTimestamp = (foundPool, timestamp) => {
47
+ const multipliers = foundPool.rewards?.multipliers;
48
+ if (!multipliers?.length) {
49
+ return 1; // default multiplier if multipliers are not found
50
+ }
51
+ const multipliersByTimestamp = multipliers.reduce((acc, curr) => {
52
+ return {
53
+ ...acc,
54
+ [curr.timestamp]: curr.value,
55
+ };
56
+ }, {});
57
+ if (!multipliersByTimestamp) {
58
+ return 1; // default multiplier if pool is not found
59
+ }
60
+ // return the latest if timestamp not provided
61
+ if (!timestamp) {
62
+ const latest = Object.keys(multipliersByTimestamp)
63
+ .map(Number)
64
+ .sort((a, b) => b - a)[0];
65
+ return latest !== undefined ? (multipliersByTimestamp[latest] ?? 1) : 1;
66
+ }
67
+ const applicableTimestamp = Object.keys(multipliersByTimestamp)
68
+ .map(Number)
69
+ .filter((ts) => ts <= timestamp) // filter only timestamps before or equal to the given timestamp
70
+ .sort((a, b) => b - a)[0]; // get the latest applicable timestamp
71
+ return applicableTimestamp !== undefined
72
+ ? (multipliersByTimestamp[applicableTimestamp] ?? 1)
73
+ : 1;
74
+ };
75
+ exports.getRewardMultiplierByTimestamp = getRewardMultiplierByTimestamp;
76
+ /**
77
+ * Build the human-readable display label for a single reward.
78
+ *
79
+ * The format is `"{multiplier}x {text}"`, with the multiplier prefix omitted
80
+ * when it equals 1 (e.g. `"2x Cores"`, `" Cores"` when multiplier is 1 — the
81
+ * leading space is preserved to keep `additionalPoints` and the
82
+ * `additionalPointsDetailed` label in lockstep). This is a display string only;
83
+ * consumers that need a stable key should join on the reward's `id`
84
+ * (see {@link IVaultRewardDetail}), not on this label.
85
+ *
86
+ * @param reward - The raw tokenized-vault reward.
87
+ * @returns The display label string.
88
+ */
89
+ function getRewardLabel(reward) {
90
+ return `${reward.multiplier !== 1 ? `${reward.multiplier}x` : ''} ${reward.text}`;
91
+ }
92
+ /**
93
+ * Get the rewards for the vault.
94
+ *
95
+ * Builds the display-facing rewards summary from the raw tokenized-vault
96
+ * rewards array. In addition to the legacy `additionalPoints` string list, it
97
+ * emits `additionalPointsDetailed`, which pairs each label with its
98
+ * backend-provided `img_url`. Consumers (e.g. the Upshift app) resolve a
99
+ * reward's logo from this `imgUrl` first, falling back to a bundled asset only
100
+ * when it is absent — so a newly-added reward with a backend logo (e.g.
101
+ * "Cores") renders its icon without any client-side keyword mapping.
102
+ *
103
+ * @param tokenizedVault - The tokenized vault.
104
+ * @returns The rewards summary, including `additionalPointsDetailed`.
105
+ */
106
+ function getVaultRewards(tokenizedVault) {
107
+ const upshiftPointRewards = tokenizedVault.rewards?.filter((r) => r.text === 'Upshift Points');
108
+ const sortedPointsMultipliers = upshiftPointRewards?.sort((a, b) => new Date(b.start_datetime).getTime() -
109
+ new Date(a.start_datetime).getTime());
110
+ const upshiftPointsMultipliers = sortedPointsMultipliers?.map((r) => ({
111
+ timestamp: new Date(r.start_datetime).getTime() / 1000,
112
+ value: r.multiplier,
113
+ }));
114
+ const latestUpshiftPointMultiplier = upshiftPointsMultipliers?.[0]?.value;
115
+ const rewards = {
116
+ points: upshiftPointRewards.length
117
+ ? `${latestUpshiftPointMultiplier}x Upshift Points`
118
+ : '',
119
+ multiplier: latestUpshiftPointMultiplier,
120
+ multipliers: upshiftPointsMultipliers,
121
+ additionalPoints: tokenizedVault.rewards.map(getRewardLabel),
122
+ additionalPointsDetailed: tokenizedVault.rewards.map((r) => ({
123
+ id: r.id,
124
+ label: getRewardLabel(r),
125
+ text: r.text,
126
+ imgUrl: r.img_url || null,
127
+ multiplier: r.multiplier,
128
+ })),
129
+ };
130
+ return rewards;
131
+ }
132
+ /**
133
+ * Get the idle assets for the vault
134
+ * @param provider - The provider
135
+ * @param vaultAddress - The vault address
136
+ * @param totalAssets - The total assets of the vault
137
+ * @param knownVersion - Optional pre-resolved vault version. Callers that
138
+ * already hold the backend row (e.g. `buildFormattedVault`) pass it so this
139
+ * function doesn't re-fetch `GET /tokenized_vault/{address}` — and with the
140
+ * API's default load flags at that, a heavier payload on a different cache
141
+ * key than the caller's own fetch — just to dispatch on the version.
142
+ * @returns The idle assets
143
+ */
144
+ async function getIdleAssets(provider, vaultAddress, underlying, totalAssets, knownVersion) {
145
+ const version = knownVersion ??
146
+ (0, vaults_1.getVaultVersionV2)((await (0, core_1.fetchTokenizedVault)(vaultAddress, undefined, false, false))?.[0]);
147
+ let idleAssets;
148
+ switch (version) {
149
+ case 'evm-0': {
150
+ // old lending pool
151
+ const globalLoansAmount = await (0, core_1.createContract)({
152
+ provider,
153
+ address: vaultAddress,
154
+ abi: abis_1.ABI_LENDING_POOLS,
155
+ }).globalLoansAmount();
156
+ idleAssets = BigInt(totalAssets.raw) - BigInt(globalLoansAmount);
157
+ break;
158
+ }
159
+ case 'evm-2': {
160
+ const vaultContract = (0, core_1.createContract)({
161
+ provider,
162
+ address: vaultAddress,
163
+ abi: abis_1.ABI_TOKENIZED_VAULT_V2,
164
+ });
165
+ const primaryAsset = await vaultContract.asset();
166
+ idleAssets = await (0, core_1.createContract)({
167
+ provider,
168
+ address: primaryAsset,
169
+ abi: abis_1.ABI_ERC20,
170
+ }).balanceOf(vaultAddress);
171
+ break;
172
+ }
173
+ default: {
174
+ // tokenized vault
175
+ idleAssets = await (0, core_1.createContract)({
176
+ provider,
177
+ address: underlying,
178
+ abi: abis_1.ABI_ERC20,
179
+ }).balanceOf(vaultAddress);
180
+ break;
181
+ }
182
+ }
183
+ return idleAssets;
184
+ }
185
+ async function getYieldLastRealizedOn(provider, vaultAddress) {
186
+ const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vaultAddress))?.[0];
187
+ if (!tokenizedVault) {
188
+ throw new Error(`Vault ${vaultAddress} not found`);
189
+ }
190
+ const version = (0, vaults_1.getVaultVersionV2)(tokenizedVault);
191
+ let assetsUpdatedOn;
192
+ switch (version) {
193
+ case 'evm-2': {
194
+ const contract = (0, core_1.createContract)({
195
+ provider,
196
+ address: vaultAddress,
197
+ abi: abis_1.ABI_TOKENIZED_VAULT_V2,
198
+ });
199
+ assetsUpdatedOn = await contract.assetsUpdatedOn();
200
+ break;
201
+ }
202
+ case 'evm-0': {
203
+ const contract = (0, core_1.createContract)({
204
+ provider,
205
+ address: vaultAddress,
206
+ abi: abis_1.ABI_LENDING_POOL_V3,
207
+ });
208
+ assetsUpdatedOn = await contract.assetsUpdatedOn();
209
+ break;
210
+ }
211
+ case 'sol-0':
212
+ case 'stellar-0': {
213
+ return 0;
214
+ }
215
+ default: {
216
+ // Default to V3 ABI which has assetsUpdatedOn
217
+ const contract = (0, core_1.createContract)({
218
+ provider,
219
+ address: vaultAddress,
220
+ abi: abis_1.ABI_LENDING_POOL_V3,
221
+ });
222
+ assetsUpdatedOn = await contract.assetsUpdatedOn();
223
+ break;
224
+ }
225
+ }
226
+ return Number(assetsUpdatedOn);
227
+ }
228
+ /**
229
+ * Format APY data from backend tokenized vault into the unified IVaultApy shape.
230
+ * Shared across all chain adapters (EVM, Solana, Stellar).
231
+ */
232
+ function formatVaultApy(tokenizedVault) {
233
+ const { reported_apy, campaign_apy } = tokenizedVault;
234
+ return {
235
+ apy: (reported_apy?.apy ?? 0) * 100,
236
+ explainer: reported_apy?.explainer ?? null,
237
+ pointsApy: reported_apy?.points_apy != null ? reported_apy.points_apy * 100 : null,
238
+ campaignApy: campaign_apy != null ? campaign_apy * 100 : null,
239
+ liquidApy: (reported_apy?.liquid_apy ?? 0) * 100,
240
+ rewardsClaimable: reported_apy?.rewards_claimable ?? null,
241
+ rewardsCompounded: reported_apy?.rewards_compounded ?? null,
242
+ underlyingApy: (reported_apy?.underlying_apy ?? 0) * 100,
243
+ };
244
+ }
245
+ /**
246
+ * Map the backend `freshness` object onto the camelCased {@link IVaultFreshness}
247
+ * shape carried on `IVault`. Shared across all chain adapters (EVM, Solana,
248
+ * Stellar) so every surface reports provenance identically.
249
+ *
250
+ * Each of the three stamps is passed through independently: a missing member
251
+ * becomes `null` and is never defaulted from one of the others. That is the point
252
+ * of the object — `apy_computed_at` and `share_ratio_snapshot_at` describe two
253
+ * different pipelines, and collapsing them would erase the very staleness signal
254
+ * (snapshot newer than APY) the field exists to expose.
255
+ *
256
+ * @param tokenizedVault - Backend tokenized-vault payload. `freshness` is absent on
257
+ * responses predating the backend change, and may be explicitly null.
258
+ * @returns The mapped freshness object, or `null` when the backend reported none.
259
+ * Values are the backend's RFC 3339 UTC strings verbatim — no reformatting, so
260
+ * the trailing `Z` is preserved.
261
+ */
262
+ function mapVaultFreshness(tokenizedVault) {
263
+ const freshness = tokenizedVault?.freshness;
264
+ if (!freshness)
265
+ return null;
266
+ return {
267
+ apyComputedAt: freshness.apy_computed_at ?? null,
268
+ shareRatioSnapshotAt: freshness.share_ratio_snapshot_at ?? null,
269
+ cachedAt: freshness.cached_at ?? null,
270
+ };
271
+ }
272
+ /**
273
+ * Map a wrapper vault's link to the vault it wraps.
274
+ *
275
+ * @param tokenizedVault - Backend tokenized-vault payload.
276
+ * @returns The underlying vault address (casing preserved) and chain id, both
277
+ * null for a non-wrapper vault. A chain id without an address is dropped.
278
+ */
279
+ function mapUnderlyingVault(tokenizedVault) {
280
+ const address = tokenizedVault?.underlying_vault_address;
281
+ if (!address)
282
+ return { underlyingVaultAddress: null, underlyingChainId: null };
283
+ return {
284
+ underlyingVaultAddress: address,
285
+ underlyingChainId: tokenizedVault?.underlying_chain ?? null,
286
+ };
287
+ }
288
+ /**
289
+ * Map strategists from backend subaccounts or hardcoded list.
290
+ * Shared across all chain adapters.
291
+ */
292
+ function mapStrategists(tokenizedVault) {
293
+ const hasValidStrategists = tokenizedVault.subaccounts?.length > 0 &&
294
+ tokenizedVault.subaccounts.some((s) => s.strategist !== null);
295
+ return hasValidStrategists
296
+ ? tokenizedVault.subaccounts
297
+ .filter((s) => s.strategist !== null)
298
+ .map((s) => ({
299
+ address: s.address,
300
+ logo: s.strategist?.strategist_logo,
301
+ name: s.strategist?.strategist_name,
302
+ type: 'subaccount',
303
+ website_url: s.strategist?.website_url ?? null,
304
+ }))
305
+ : (tokenizedVault.hardcoded_strategists || []).map((s) => ({
306
+ address: '0x',
307
+ logo: s.strategist_logo,
308
+ name: s.strategist_name,
309
+ type: 'subaccount',
310
+ website_url: s.website_url ?? null,
311
+ }));
312
+ }
313
+ /**
314
+ * Map composability integrations from backend format to vault format.
315
+ * Shared across all chain adapters.
316
+ */
317
+ function mapComposabilityIntegrations(tokenizedVault) {
318
+ return (tokenizedVault.composability_integrations?.map((integration) => ({
319
+ name: integration.name,
320
+ description: integration.description,
321
+ earningMultiplier: integration.earning_multiplier,
322
+ protocolUrl: integration.protocol_url,
323
+ logoUrl: integration.logo_url,
324
+ tokenizedVaultId: integration.tokenized_vault_id,
325
+ id: integration.id,
326
+ })) || []);
327
+ }
328
+ /**
329
+ * Convert a backend-reported TVL (whole token units) to a NormalizedBn.
330
+ * Handles null, undefined, and non-finite values (NaN, Infinity) safely, defaulting to 0.
331
+ * Shared between non-EVM adapters (Solana, Stellar) and the module-level getVaultTvl handler.
332
+ */
333
+ function backendTvlToNormalizedBn(tvl, decimals) {
334
+ if (tvl == null) {
335
+ core_1.Logger.log.warn('backendTvlToNormalizedBn', 'TVL is null/undefined, defaulting to 0 — check backend data pipeline', { decimals });
336
+ return (0, core_1.toNormalizedBn)(BigInt(0), decimals);
337
+ }
338
+ if (!Number.isFinite(tvl) || tvl < 0) {
339
+ core_1.Logger.log.warn('backendTvlToNormalizedBn', tvl < 0
340
+ ? 'Negative TVL value, defaulting to 0'
341
+ : 'Non-finite TVL value, defaulting to 0', { tvl, decimals });
342
+ return (0, core_1.toNormalizedBn)(BigInt(0), decimals);
343
+ }
344
+ const scaleFactor = BigInt(10) ** BigInt(decimals);
345
+ const tvlWhole = BigInt(Math.round(tvl));
346
+ return (0, core_1.toNormalizedBn)(tvlWhole * scaleFactor, decimals);
347
+ }
348
+ /**
349
+ * Map daily PnL per share from backend Record format to array format.
350
+ * Shared across non-EVM adapters.
351
+ */
352
+ function mapDailyPnlPerShare(dailyPnl) {
353
+ if (!dailyPnl)
354
+ return [];
355
+ return Object.entries(dailyPnl).map(([timestamp, value]) => ({
356
+ timestamp,
357
+ value,
358
+ }));
359
+ }
360
+ /**
361
+ * Build a base IVault from backend data, shared across non-EVM adapters (Solana, Stellar).
362
+ * Chain-specific fields (chainId, version, name, totalAssets, totalSupply, depositAssets, receipt)
363
+ * must be provided via the overrides parameter.
364
+ */
365
+ function buildBackendVault(tokenizedVault, overrides) {
366
+ const apy = formatVaultApy(tokenizedVault);
367
+ const rewards = tokenizedVault.rewards?.length
368
+ ? getVaultRewards(tokenizedVault)
369
+ : {
370
+ points: '0',
371
+ multiplier: 0,
372
+ multipliers: [],
373
+ additionalPoints: [],
374
+ additionalPointsDetailed: [],
375
+ };
376
+ return {
377
+ operator: '0x',
378
+ eoa_operators: [],
379
+ operators: [],
380
+ historical_snapshots: tokenizedVault.historical_snapshots || [],
381
+ address: tokenizedVault.address,
382
+ historical_apy: tokenizedVault.historical_apy,
383
+ historical_compound_apy: tokenizedVault.historical_compound_apy,
384
+ max_drawdown: tokenizedVault.max_drawdown,
385
+ logoUrl: tokenizedVault.vault_logo_url || '/img/strategist/august.svg',
386
+ description: tokenizedVault.description || '',
387
+ startDatetime: tokenizedVault.start_datetime
388
+ ? new Date(tokenizedVault.start_datetime).toISOString()
389
+ : new Date(0).toISOString(),
390
+ status: tokenizedVault.status,
391
+ tags: [tokenizedVault.public_type || 'Defi Yield'],
392
+ isFeatured: tokenizedVault.is_featured || false,
393
+ isSpotlighted: tokenizedVault.is_spotlighted ?? false,
394
+ withdrawalOnly: tokenizedVault.withdrawal_only ?? false,
395
+ isVisible: tokenizedVault.is_visible || false,
396
+ reserveTarget: tokenizedVault.reserve_target || 0,
397
+ reserveTolerance: tokenizedVault.reserve_tolerance || 0,
398
+ // Vault decimals are derived from the receipt token decimals for non-EVM vaults
399
+ decimals: overrides.receipt.decimals,
400
+ maxSupply: (0, core_1.toNormalizedBn)(1_000_000_000),
401
+ depositCap: null,
402
+ apy,
403
+ rewards,
404
+ fees: {
405
+ performance: tokenizedVault.weekly_performance_fee_bps || 0,
406
+ management: tokenizedVault.platform_fee_override?.management_fee || 0,
407
+ isManagementWaived: (0, vaults_1.resolveFeeWaived)(tokenizedVault.platform_fee_override?.is_fee_waived ?? false, tokenizedVault.management_fee_waived_until_date ?? null, tokenizedVault.management_fee_waived_until_tvl ?? null),
408
+ managementFeeWaivedUntilDate: tokenizedVault.management_fee_waived_until_date ?? null,
409
+ managementFeeWaivedUntilTvl: tokenizedVault.management_fee_waived_until_tvl ?? null,
410
+ isPerformanceWaived: (0, vaults_1.resolveFeeWaived)(tokenizedVault.platform_fee_override?.is_fee_waived ?? false, tokenizedVault.performance_fee_waived_until_date ?? null, tokenizedVault.performance_fee_waived_until_tvl ?? null),
411
+ performanceFeeWaivedUntilDate: tokenizedVault.performance_fee_waived_until_date ?? null,
412
+ performanceFeeWaivedUntilTvl: tokenizedVault.performance_fee_waived_until_tvl ?? null,
413
+ },
414
+ lagDuration: 0,
415
+ withdrawalMarginSeconds: tokenizedVault.withdrawal_margin_seconds ?? null,
416
+ iatTraders: tokenizedVault.iat_traders ?? null,
417
+ maxDailyDrawdown: tokenizedVault.max_daily_drawdown || 0,
418
+ risk: tokenizedVault.risk || 'low',
419
+ isWithdrawalPaused: false,
420
+ isDepositPaused: false,
421
+ idleAssets: (0, core_1.toNormalizedBn)(0),
422
+ loans: [],
423
+ allocations: {
424
+ unfilteredTokens: [],
425
+ defi: [],
426
+ tokens: [],
427
+ cefi: [],
428
+ otc: {},
429
+ exposurePerCategory: {
430
+ borrowing: [],
431
+ supplying: [],
432
+ lending: [],
433
+ wallet: [],
434
+ cefiBalance: 0,
435
+ defiBalance: 0,
436
+ walletBalance: 0,
437
+ loanBalance: 0,
438
+ },
439
+ netValue: 0,
440
+ defiPerBorrower: {},
441
+ },
442
+ position: {
443
+ vault: tokenizedVault.address,
444
+ status: 'active',
445
+ availableRedemptions: [],
446
+ pendingRedemptions: [],
447
+ redeemable: (0, core_1.toNormalizedBn)(0),
448
+ walletBalance: (0, core_1.toNormalizedBn)(0),
449
+ },
450
+ composabilityIntegrations: mapComposabilityIntegrations(tokenizedVault),
451
+ strategists: mapStrategists(tokenizedVault),
452
+ cachedAt: tokenizedVault.cached_at ?? null,
453
+ freshness: mapVaultFreshness(tokenizedVault),
454
+ dailyPnlPerShare: mapDailyPnlPerShare(tokenizedVault.daily_pnl_per_share),
455
+ enabled_historical_price_horizons: tokenizedVault.enabled_historical_price_horizons || [],
456
+ latest_reported_tvl: tokenizedVault.latest_reported_tvl,
457
+ ...mapUnderlyingVault(tokenizedVault),
458
+ defaultApyHorizon: tokenizedVault.default_apy_horizon,
459
+ ...(tokenizedVault.instant_redeem_config
460
+ ? {
461
+ instant_redeem_config: {
462
+ subaccountAddress: tokenizedVault.instant_redeem_config
463
+ .subaccount_address,
464
+ outputAssetSymbol: tokenizedVault.instant_redeem_config.output_asset_symbol,
465
+ redeemableAssets: tokenizedVault.instant_redeem_config.redeemable_assets.map((a) => ({
466
+ address: a.address,
467
+ symbol: a.symbol,
468
+ decimals: a.decimals,
469
+ spreadBps: a.spread_bps,
470
+ })),
471
+ isPaused: tokenizedVault.instant_redeem_config.is_paused,
472
+ availableLiquidity: tokenizedVault.instant_redeem_config.available_liquidity,
473
+ },
474
+ }
475
+ : {}),
476
+ showCapFilled: tokenizedVault?.show_cap_filled ?? null,
477
+ apyOverride: tokenizedVault.apy_override ?? null,
478
+ // Spread chain-specific overrides last so they take precedence
479
+ ...overrides,
480
+ };
481
+ }
482
+ /**
483
+ * Build the formatted vault
484
+ * @param provider - The provider
485
+ * @param tokenizedVault - The tokenized vault
486
+ * @param contractCalls - The contract calls
487
+ * @returns The formatted vault
488
+ */
489
+ async function buildFormattedVault(provider, tokenizedVault, contractCalls) {
490
+ const strategists = mapStrategists(tokenizedVault);
491
+ const operators = tokenizedVault?.operators || [];
492
+ const eoa_operators = tokenizedVault?.eoa_operators || [];
493
+ // Load offchain props
494
+ const baseProps = {
495
+ chainId: tokenizedVault.chain,
496
+ maxDailyDrawdown: tokenizedVault.max_daily_drawdown || 0,
497
+ risk: tokenizedVault.risk,
498
+ lagDuration: Number(contractCalls.lagDuration),
499
+ withdrawalMarginSeconds: tokenizedVault.withdrawal_margin_seconds ?? null,
500
+ iatTraders: tokenizedVault.iat_traders ?? null,
501
+ address: tokenizedVault.address,
502
+ name: tokenizedVault.vault_name,
503
+ logoUrl: tokenizedVault.vault_logo_url,
504
+ // Single source of truth shared with the Solana/Stellar adapters. The
505
+ // inline version this replaced produced `NaN` for liquid/underlying APY
506
+ // when `reported_apy` was absent and `null` for a genuine 0% `apy`.
507
+ apy: formatVaultApy(tokenizedVault),
508
+ strategists: strategists,
509
+ eoa_operators,
510
+ operators,
511
+ fees: {
512
+ performance: tokenizedVault.weekly_performance_fee_bps,
513
+ management: tokenizedVault.platform_fee_override.management_fee,
514
+ isManagementWaived: (0, vaults_1.resolveFeeWaived)(tokenizedVault.platform_fee_override.is_fee_waived, tokenizedVault.management_fee_waived_until_date, tokenizedVault.management_fee_waived_until_tvl),
515
+ managementFeeWaivedUntilDate: tokenizedVault.management_fee_waived_until_date,
516
+ managementFeeWaivedUntilTvl: tokenizedVault.management_fee_waived_until_tvl,
517
+ isPerformanceWaived: (0, vaults_1.resolveFeeWaived)(tokenizedVault.platform_fee_override.is_fee_waived, tokenizedVault.performance_fee_waived_until_date, tokenizedVault.performance_fee_waived_until_tvl),
518
+ performanceFeeWaivedUntilDate: tokenizedVault.performance_fee_waived_until_date,
519
+ performanceFeeWaivedUntilTvl: tokenizedVault.performance_fee_waived_until_tvl,
520
+ },
521
+ rewards: getVaultRewards(tokenizedVault),
522
+ version: (0, vaults_1.getVaultVersionV2)(tokenizedVault),
523
+ description: tokenizedVault.description,
524
+ startDatetime: String(tokenizedVault.start_datetime),
525
+ status: tokenizedVault.status,
526
+ tags: [tokenizedVault.public_type],
527
+ isFeatured: tokenizedVault.is_featured,
528
+ withdrawalOnly: tokenizedVault.withdrawal_only ?? false,
529
+ isSpotlighted: tokenizedVault.is_spotlighted ?? false,
530
+ isVisible: tokenizedVault.is_visible,
531
+ reserveTarget: tokenizedVault.reserve_target,
532
+ reserveTolerance: tokenizedVault.reserve_tolerance,
533
+ // On-chain pause first, then the hardcoded deny list — a vault can be
534
+ // withheld from deposits for either reason and the list is not a substitute
535
+ // for reading the contract.
536
+ isDepositPaused: contractCalls.depositsPaused === true ||
537
+ (0, vaults_1.isBadVault)(tokenizedVault.address),
538
+ decimals: contractCalls.decimals,
539
+ isWithdrawalPaused: contractCalls.withdrawalsPaused,
540
+ idleAssets: (0, core_1.toNormalizedBn)(await getIdleAssets(provider, tokenizedVault.address, contractCalls.asset, contractCalls.totalAssets,
541
+ // The row is already in hand — don't let getIdleAssets re-fetch it
542
+ // just to resolve the version.
543
+ (0, vaults_1.getVaultVersionV2)(tokenizedVault)), Number(contractCalls.decimals)),
544
+ };
545
+ // Version specific logic
546
+ const version = (0, vaults_1.getVaultVersionV2)(tokenizedVault);
547
+ let operator = '0x';
548
+ let depositAssets = [];
549
+ let totalAssets = (0, core_1.toNormalizedBn)(0);
550
+ let totalSupply = (0, core_1.toNormalizedBn)(0);
551
+ let maxSupply = (0, core_1.toNormalizedBn)(0);
552
+ let depositCap = null;
553
+ let maxDepositAmount = null;
554
+ let receipt = {
555
+ symbol: '',
556
+ address: '0x',
557
+ decimals: 0,
558
+ };
559
+ switch (version) {
560
+ case 'sol-0': {
561
+ // @todo
562
+ break;
563
+ }
564
+ case 'evm-2': {
565
+ totalAssets = contractCalls.getTotalAssets;
566
+ depositAssets.push({
567
+ address: contractCalls.asset,
568
+ symbol: await (0, core_1.getSymbol)(provider, contractCalls.asset, false),
569
+ decimals: contractCalls.decimals,
570
+ });
571
+ const extraAssets = await Promise.all(contractCalls.getWhitelistedAssets.map(async (a) => {
572
+ const decimals = await (0, core_1.getDecimals)(provider, a, false);
573
+ const symbol = await (0, core_1.getSymbol)(provider, a, false);
574
+ return {
575
+ address: a,
576
+ symbol,
577
+ decimals,
578
+ };
579
+ }));
580
+ if (contractCalls.depositCap) {
581
+ depositCap = contractCalls.depositCap;
582
+ }
583
+ depositAssets = [...depositAssets, ...extraAssets];
584
+ totalSupply = contractCalls.totalSupply;
585
+ (maxSupply =
586
+ (0, core_1.toNormalizedBn)(1_000_000_000_000)), // @hardcoded: no maxSupply on here
587
+ (receipt = {
588
+ symbol: tokenizedVault.receipt_token_symbol,
589
+ address: contractCalls.lpTokenAddress,
590
+ decimals: contractCalls.decimals,
591
+ });
592
+ // @todo: get operator
593
+ // operator = contractCalls.loansOperator as IAddress;
594
+ break;
595
+ }
596
+ default: {
597
+ // get idle assets
598
+ depositAssets = [
599
+ {
600
+ address: contractCalls.asset,
601
+ symbol: await (0, core_1.getSymbol)(provider, contractCalls.asset, false),
602
+ decimals: contractCalls.decimals,
603
+ },
604
+ ];
605
+ totalAssets = contractCalls.totalAssets;
606
+ totalSupply = contractCalls.totalSupply;
607
+ maxSupply = contractCalls.maxSupply;
608
+ if (contractCalls.maxDepositAmount) {
609
+ maxDepositAmount = contractCalls.maxDepositAmount;
610
+ }
611
+ operator = contractCalls.loansOperator;
612
+ receipt = {
613
+ symbol: tokenizedVault.receipt_token_symbol,
614
+ address: tokenizedVault.address,
615
+ decimals: contractCalls.decimals,
616
+ };
617
+ break;
618
+ }
619
+ }
620
+ // Check for adapter configuration and add adapter deposit tokens
621
+ const adapterConfig = (0, core_1.getVaultAdapterConfig)(tokenizedVault.address);
622
+ if (adapterConfig) {
623
+ const allDepositTokens = (0, core_1.getVaultDepositTokens)(tokenizedVault.address, contractCalls.asset);
624
+ // Build deposit assets array including adapter tokens
625
+ const depositAssetsWithAdapters = await Promise.all(allDepositTokens.map(async (tokenAddress) => {
626
+ // Skip if already in depositAssets
627
+ if (depositAssets.find((a) => a.address.toLowerCase() === tokenAddress.toLowerCase())) {
628
+ return null;
629
+ }
630
+ const decimals = await (0, core_1.getDecimals)(provider, tokenAddress, false);
631
+ const symbol = await (0, core_1.getSymbol)(provider, tokenAddress, false);
632
+ return {
633
+ address: tokenAddress,
634
+ symbol,
635
+ decimals,
636
+ };
637
+ }));
638
+ // Add adapter tokens to depositAssets
639
+ depositAssets = [
640
+ ...depositAssets,
641
+ ...depositAssetsWithAdapters.filter((a) => a !== null),
642
+ ];
643
+ }
644
+ const result = {
645
+ ...baseProps,
646
+ operator: operator,
647
+ depositAssets: depositAssets,
648
+ totalAssets: totalAssets,
649
+ totalSupply: totalSupply,
650
+ maxSupply: maxSupply,
651
+ depositCap: depositCap,
652
+ maxDepositAmount: maxDepositAmount,
653
+ receipt: receipt,
654
+ historical_apy: tokenizedVault?.historical_apy,
655
+ historical_compound_apy: tokenizedVault?.historical_compound_apy,
656
+ historical_snapshots: tokenizedVault?.historical_snapshots || [],
657
+ max_drawdown: tokenizedVault?.max_drawdown,
658
+ composabilityIntegrations: mapComposabilityIntegrations(tokenizedVault),
659
+ dailyPnlPerShare: tokenizedVault?.daily_pnl_per_share
660
+ ? Object.entries(tokenizedVault.daily_pnl_per_share).map(([timestamp, value]) => ({
661
+ timestamp,
662
+ value,
663
+ }))
664
+ : [],
665
+ enabled_historical_price_horizons: tokenizedVault?.enabled_historical_price_horizons,
666
+ defaultApyHorizon: tokenizedVault?.default_apy_horizon ?? null,
667
+ latest_reported_tvl: tokenizedVault?.latest_reported_tvl,
668
+ ...mapUnderlyingVault(tokenizedVault),
669
+ cachedAt: tokenizedVault?.cached_at ?? null,
670
+ freshness: mapVaultFreshness(tokenizedVault),
671
+ showCapFilled: tokenizedVault?.show_cap_filled ?? null,
672
+ apyOverride: tokenizedVault?.apy_override ?? null,
673
+ };
674
+ if (tokenizedVault.instant_redeem_config) {
675
+ const config = tokenizedVault.instant_redeem_config;
676
+ result.instant_redeem_config = {
677
+ subaccountAddress: config.subaccount_address,
678
+ outputAssetSymbol: config.output_asset_symbol,
679
+ redeemableAssets: config.redeemable_assets.map((a) => ({
680
+ address: a.address,
681
+ symbol: a.symbol,
682
+ decimals: a.decimals,
683
+ spreadBps: a.spread_bps,
684
+ })),
685
+ isPaused: config.is_paused,
686
+ availableLiquidity: config.available_liquidity,
687
+ };
688
+ }
689
+ return result;
690
+ }
691
+ exports.ERC_20_PERMIT_HASH = '0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9';
692
+ /**
693
+ * Generate an ERC2612 permit signature
694
+ * @param token - The ERC20 token contract address
695
+ * @param owner - The token owner's address (signer)
696
+ * @param spender - The address that will be approved to spend (your pool contract)
697
+ * @param value - The amount to approve
698
+ * @param deadline - Unix timestamp for when the permit expires
699
+ * @param signer - The ethers.js Signer (wallet)
700
+ * @param provider - The ethers.js Provider
701
+ * @returns The signature components (v, r, s) and deadline
702
+ */
703
+ async function generatePermitSignature(token, owner, spender, value, deadline, signer, chainId) {
704
+ const tokenContract = (0, core_1.createContract)({
705
+ address: token,
706
+ provider: signer,
707
+ abi: abis_1.ABI_TOKENIZED_VAULT_V2_RECEIPT,
708
+ });
709
+ const noncePromise = tokenContract.nonces(owner);
710
+ const domainSeparatorPromise = (async () => {
711
+ try {
712
+ return await tokenContract.DOMAIN_SEPARATOR();
713
+ }
714
+ catch (error) {
715
+ core_1.Logger.log.error('generatePermitSignature', error, {
716
+ message: 'Could not fetch DOMAIN_SEPARATOR from contract',
717
+ });
718
+ throw error;
719
+ }
720
+ })();
721
+ const [nonce, contractDomainSeparator] = await Promise.all([
722
+ noncePromise,
723
+ domainSeparatorPromise,
724
+ ]);
725
+ const valueBigInt = typeof value === 'string' ? BigInt(value) : value;
726
+ const permitDomainCacheKey = `permit-domain-${chainId}-${token.toLowerCase()}`;
727
+ const cachedDomain = core_1.CACHE.get(permitDomainCacheKey);
728
+ let matchingDomain = null;
729
+ if (cachedDomain) {
730
+ const cachedHash = ethers_1.ethers.TypedDataEncoder.hashDomain(cachedDomain);
731
+ if (cachedHash.toLowerCase() === contractDomainSeparator.toLowerCase()) {
732
+ matchingDomain = cachedDomain;
733
+ }
734
+ else {
735
+ core_1.CACHE.delete(permitDomainCacheKey);
736
+ }
737
+ }
738
+ if (!matchingDomain) {
739
+ const name = (await tokenContract.name());
740
+ // Try different domain configurations to find which matches
741
+ const domainConfigs = [
742
+ // Standard EIP-2612
743
+ { name, version: '1', chainId, verifyingContract: token },
744
+ { name, version: '2', chainId, verifyingContract: token },
745
+ // Without version
746
+ { name, chainId, verifyingContract: token },
747
+ // With different salt values (some contracts use this)
748
+ {
749
+ name,
750
+ version: '1',
751
+ chainId,
752
+ verifyingContract: token,
753
+ salt: ethers_1.ethers.zeroPadValue('0x', 32),
754
+ },
755
+ ];
756
+ for (const domain of domainConfigs) {
757
+ const computed = ethers_1.ethers.TypedDataEncoder.hashDomain(domain);
758
+ if (computed.toLowerCase() === contractDomainSeparator.toLowerCase()) {
759
+ matchingDomain = domain;
760
+ break;
761
+ }
762
+ }
763
+ if (!matchingDomain) {
764
+ // If no match, try to get the version from the contract
765
+ // Some token contracts have a version() method for EIP-2612 domain
766
+ try {
767
+ const version = await tokenContract.version();
768
+ matchingDomain = { name, version, chainId, verifyingContract: token };
769
+ const computed = ethers_1.ethers.TypedDataEncoder.hashDomain(matchingDomain);
770
+ if (computed.toLowerCase() !== contractDomainSeparator.toLowerCase()) {
771
+ throw new Error('Could not match DOMAIN_SEPARATOR even with contract version');
772
+ }
773
+ }
774
+ catch {
775
+ throw new Error(`Could not determine correct domain configuration. Contract DOMAIN_SEPARATOR: ${contractDomainSeparator}`);
776
+ }
777
+ }
778
+ core_1.CACHE.set(permitDomainCacheKey, matchingDomain, {
779
+ ttl: 60 * 60 * 1000,
780
+ });
781
+ }
782
+ // EIP-2612 Permit type
783
+ const types = {
784
+ Permit: [
785
+ { name: 'owner', type: 'address' },
786
+ { name: 'spender', type: 'address' },
787
+ { name: 'value', type: 'uint256' },
788
+ { name: 'nonce', type: 'uint256' },
789
+ { name: 'deadline', type: 'uint256' },
790
+ ],
791
+ };
792
+ const message = {
793
+ owner: owner,
794
+ spender: spender,
795
+ value: valueBigInt,
796
+ nonce: Number(nonce),
797
+ deadline: deadline,
798
+ };
799
+ // Sign the typed data
800
+ const signature = await signer.signTypedData(matchingDomain, types, message);
801
+ // Split signature into r, s, v
802
+ const sig = ethers_1.ethers.Signature.from(signature);
803
+ return {
804
+ r: sig.r,
805
+ s: sig.s,
806
+ v: sig.v,
807
+ deadline: deadline,
808
+ };
809
+ }
810
+ /**
811
+ * Helper to create a deadline (current time + offset in seconds)
812
+ * @param offsetSeconds - Number of seconds from now (default: 20 minutes)
813
+ * @returns Unix timestamp
814
+ */
815
+ function createDeadline(offsetSeconds = 1200) {
816
+ return Math.floor(Date.now() / 1000) + offsetSeconds;
817
+ }
818
+ //# sourceMappingURL=utils.js.map