upshift-config 0.5.14

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