@moonwell-fi/moonwell-sdk 0.11.0 → 0.12.1

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 (242) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/_cjs/actions/axiosWithRetry.js +25 -0
  3. package/_cjs/actions/axiosWithRetry.js.map +1 -0
  4. package/_cjs/actions/beam/getBeamTokenLimits.js +2 -5
  5. package/_cjs/actions/beam/getBeamTokenLimits.js.map +1 -1
  6. package/_cjs/actions/beam/getBeamTokenRoutes.js +3 -6
  7. package/_cjs/actions/beam/getBeamTokenRoutes.js.map +1 -1
  8. package/_cjs/actions/core/markets/common.js +26 -12
  9. package/_cjs/actions/core/markets/common.js.map +1 -1
  10. package/_cjs/actions/core/markets/getMarketSnapshots.js +175 -326
  11. package/_cjs/actions/core/markets/getMarketSnapshots.js.map +1 -1
  12. package/_cjs/actions/core/user-positions/getUserPositionSnapshots.js +33 -31
  13. package/_cjs/actions/core/user-positions/getUserPositionSnapshots.js.map +1 -1
  14. package/_cjs/actions/governance/getCirculatingSupplySnapshots.js +38 -35
  15. package/_cjs/actions/governance/getCirculatingSupplySnapshots.js.map +1 -1
  16. package/_cjs/actions/governance/getDelegates.js +2 -5
  17. package/_cjs/actions/governance/getDelegates.js.map +1 -1
  18. package/_cjs/actions/governance/getDiscussions.js +3 -3
  19. package/_cjs/actions/governance/getDiscussions.js.map +1 -1
  20. package/_cjs/actions/governance/getStakingSnapshots.js +18 -17
  21. package/_cjs/actions/governance/getStakingSnapshots.js.map +1 -1
  22. package/_cjs/actions/governance/getUserVotingPowers.js +12 -4
  23. package/_cjs/actions/governance/getUserVotingPowers.js.map +1 -1
  24. package/_cjs/actions/governance/governor-api-client.js +10 -13
  25. package/_cjs/actions/governance/governor-api-client.js.map +1 -1
  26. package/_cjs/actions/governance/proposals/common.js +248 -211
  27. package/_cjs/actions/governance/proposals/common.js.map +1 -1
  28. package/_cjs/actions/governance/snapshot/common.js +2 -5
  29. package/_cjs/actions/governance/snapshot/common.js.map +1 -1
  30. package/_cjs/actions/lunar-indexer-client.js +4 -0
  31. package/_cjs/actions/lunar-indexer-client.js.map +1 -1
  32. package/_cjs/actions/morpho/markets/common.js +28 -34
  33. package/_cjs/actions/morpho/markets/common.js.map +1 -1
  34. package/_cjs/actions/morpho/markets/lunarIndexerTransform.js +5 -8
  35. package/_cjs/actions/morpho/markets/lunarIndexerTransform.js.map +1 -1
  36. package/_cjs/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js +12 -69
  37. package/_cjs/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js.map +1 -1
  38. package/_cjs/actions/morpho/vaults/common.js +7 -4
  39. package/_cjs/actions/morpho/vaults/common.js.map +1 -1
  40. package/_cjs/actions/morpho/vaults/getMorphoVaultSnapshots.js +21 -78
  41. package/_cjs/actions/morpho/vaults/getMorphoVaultSnapshots.js.map +1 -1
  42. package/_cjs/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js +13 -66
  43. package/_cjs/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js.map +1 -1
  44. package/_cjs/actions/retry.js +63 -0
  45. package/_cjs/actions/retry.js.map +1 -0
  46. package/_cjs/client/createMoonwellClient.js +9 -3
  47. package/_cjs/client/createMoonwellClient.js.map +1 -1
  48. package/_cjs/common/getBlockNumberAtTimestamp.js +42 -0
  49. package/_cjs/common/getBlockNumberAtTimestamp.js.map +1 -0
  50. package/_cjs/common/index.js +3 -1
  51. package/_cjs/common/index.js.map +1 -1
  52. package/_cjs/environments/definitions/arbitrum/environment.js +1 -2
  53. package/_cjs/environments/definitions/arbitrum/environment.js.map +1 -1
  54. package/_cjs/environments/definitions/avalanche/environment.js +1 -2
  55. package/_cjs/environments/definitions/avalanche/environment.js.map +1 -1
  56. package/_cjs/environments/definitions/base/custom.js +0 -1
  57. package/_cjs/environments/definitions/base/custom.js.map +1 -1
  58. package/_cjs/environments/definitions/base/environment.js +1 -2
  59. package/_cjs/environments/definitions/base/environment.js.map +1 -1
  60. package/_cjs/environments/definitions/ethereum/environment.js +1 -2
  61. package/_cjs/environments/definitions/ethereum/environment.js.map +1 -1
  62. package/_cjs/environments/definitions/moonbeam/environment.js +1 -2
  63. package/_cjs/environments/definitions/moonbeam/environment.js.map +1 -1
  64. package/_cjs/environments/definitions/optimism/custom.js +0 -1
  65. package/_cjs/environments/definitions/optimism/custom.js.map +1 -1
  66. package/_cjs/environments/definitions/optimism/environment.js +1 -2
  67. package/_cjs/environments/definitions/optimism/environment.js.map +1 -1
  68. package/_cjs/environments/definitions/polygon/environment.js +1 -2
  69. package/_cjs/environments/definitions/polygon/environment.js.map +1 -1
  70. package/_cjs/environments/index.js +8 -8
  71. package/_cjs/environments/index.js.map +1 -1
  72. package/_cjs/environments/types/config.js +1 -0
  73. package/_cjs/environments/types/config.js.map +1 -1
  74. package/_cjs/errors/version.js +1 -1
  75. package/_esm/actions/axiosWithRetry.js +32 -0
  76. package/_esm/actions/axiosWithRetry.js.map +1 -0
  77. package/_esm/actions/beam/getBeamTokenLimits.js +2 -2
  78. package/_esm/actions/beam/getBeamTokenLimits.js.map +1 -1
  79. package/_esm/actions/beam/getBeamTokenRoutes.js +3 -3
  80. package/_esm/actions/beam/getBeamTokenRoutes.js.map +1 -1
  81. package/_esm/actions/core/markets/common.js +26 -13
  82. package/_esm/actions/core/markets/common.js.map +1 -1
  83. package/_esm/actions/core/markets/getMarketSnapshots.js +196 -348
  84. package/_esm/actions/core/markets/getMarketSnapshots.js.map +1 -1
  85. package/_esm/actions/core/user-positions/getUserPositionSnapshots.js +34 -31
  86. package/_esm/actions/core/user-positions/getUserPositionSnapshots.js.map +1 -1
  87. package/_esm/actions/governance/getCirculatingSupplySnapshots.js +38 -33
  88. package/_esm/actions/governance/getCirculatingSupplySnapshots.js.map +1 -1
  89. package/_esm/actions/governance/getDelegates.js +2 -2
  90. package/_esm/actions/governance/getDelegates.js.map +1 -1
  91. package/_esm/actions/governance/getDiscussions.js +3 -3
  92. package/_esm/actions/governance/getDiscussions.js.map +1 -1
  93. package/_esm/actions/governance/getStakingSnapshots.js +19 -15
  94. package/_esm/actions/governance/getStakingSnapshots.js.map +1 -1
  95. package/_esm/actions/governance/getUserVotingPowers.js +13 -5
  96. package/_esm/actions/governance/getUserVotingPowers.js.map +1 -1
  97. package/_esm/actions/governance/governor-api-client.js +10 -10
  98. package/_esm/actions/governance/governor-api-client.js.map +1 -1
  99. package/_esm/actions/governance/proposals/common.js +247 -216
  100. package/_esm/actions/governance/proposals/common.js.map +1 -1
  101. package/_esm/actions/governance/snapshot/common.js +2 -2
  102. package/_esm/actions/governance/snapshot/common.js.map +1 -1
  103. package/_esm/actions/lunar-indexer-client.js +6 -0
  104. package/_esm/actions/lunar-indexer-client.js.map +1 -1
  105. package/_esm/actions/morpho/markets/common.js +29 -36
  106. package/_esm/actions/morpho/markets/common.js.map +1 -1
  107. package/_esm/actions/morpho/markets/lunarIndexerTransform.js +5 -5
  108. package/_esm/actions/morpho/markets/lunarIndexerTransform.js.map +1 -1
  109. package/_esm/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js +14 -68
  110. package/_esm/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js.map +1 -1
  111. package/_esm/actions/morpho/vaults/common.js +7 -4
  112. package/_esm/actions/morpho/vaults/common.js.map +1 -1
  113. package/_esm/actions/morpho/vaults/getMorphoVaultSnapshots.js +24 -78
  114. package/_esm/actions/morpho/vaults/getMorphoVaultSnapshots.js.map +1 -1
  115. package/_esm/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js +15 -65
  116. package/_esm/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js.map +1 -1
  117. package/_esm/actions/retry.js +90 -0
  118. package/_esm/actions/retry.js.map +1 -0
  119. package/_esm/client/createMoonwellClient.js +9 -3
  120. package/_esm/client/createMoonwellClient.js.map +1 -1
  121. package/_esm/common/getBlockNumberAtTimestamp.js +56 -0
  122. package/_esm/common/getBlockNumberAtTimestamp.js.map +1 -0
  123. package/_esm/common/index.js +1 -0
  124. package/_esm/common/index.js.map +1 -1
  125. package/_esm/environments/definitions/arbitrum/environment.js +1 -2
  126. package/_esm/environments/definitions/arbitrum/environment.js.map +1 -1
  127. package/_esm/environments/definitions/avalanche/environment.js +1 -2
  128. package/_esm/environments/definitions/avalanche/environment.js.map +1 -1
  129. package/_esm/environments/definitions/base/custom.js +0 -1
  130. package/_esm/environments/definitions/base/custom.js.map +1 -1
  131. package/_esm/environments/definitions/base/environment.js +1 -2
  132. package/_esm/environments/definitions/base/environment.js.map +1 -1
  133. package/_esm/environments/definitions/ethereum/environment.js +1 -2
  134. package/_esm/environments/definitions/ethereum/environment.js.map +1 -1
  135. package/_esm/environments/definitions/moonbeam/environment.js +1 -2
  136. package/_esm/environments/definitions/moonbeam/environment.js.map +1 -1
  137. package/_esm/environments/definitions/optimism/custom.js +0 -1
  138. package/_esm/environments/definitions/optimism/custom.js.map +1 -1
  139. package/_esm/environments/definitions/optimism/environment.js +1 -2
  140. package/_esm/environments/definitions/optimism/environment.js.map +1 -1
  141. package/_esm/environments/definitions/polygon/environment.js +1 -2
  142. package/_esm/environments/definitions/polygon/environment.js.map +1 -1
  143. package/_esm/environments/index.js +8 -8
  144. package/_esm/environments/index.js.map +1 -1
  145. package/_esm/environments/types/config.js +1 -0
  146. package/_esm/environments/types/config.js.map +1 -1
  147. package/_esm/errors/version.js +1 -1
  148. package/_types/actions/axiosWithRetry.d.ts +16 -0
  149. package/_types/actions/axiosWithRetry.d.ts.map +1 -0
  150. package/_types/actions/beam/getBeamTokenLimits.d.ts.map +1 -1
  151. package/_types/actions/beam/getBeamTokenRoutes.d.ts.map +1 -1
  152. package/_types/actions/core/markets/common.d.ts.map +1 -1
  153. package/_types/actions/core/markets/getMarketSnapshots.d.ts.map +1 -1
  154. package/_types/actions/core/user-positions/getUserPositionSnapshots.d.ts +0 -1
  155. package/_types/actions/core/user-positions/getUserPositionSnapshots.d.ts.map +1 -1
  156. package/_types/actions/governance/getCirculatingSupplySnapshots.d.ts.map +1 -1
  157. package/_types/actions/governance/getDelegates.d.ts.map +1 -1
  158. package/_types/actions/governance/getDiscussions.d.ts.map +1 -1
  159. package/_types/actions/governance/getStakingSnapshots.d.ts.map +1 -1
  160. package/_types/actions/governance/getUserVotingPowers.d.ts +13 -1
  161. package/_types/actions/governance/getUserVotingPowers.d.ts.map +1 -1
  162. package/_types/actions/governance/governor-api-client.d.ts.map +1 -1
  163. package/_types/actions/governance/proposals/common.d.ts +2 -8
  164. package/_types/actions/governance/proposals/common.d.ts.map +1 -1
  165. package/_types/actions/governance/snapshot/common.d.ts.map +1 -1
  166. package/_types/actions/lunar-indexer-client.d.ts.map +1 -1
  167. package/_types/actions/morpho/markets/common.d.ts.map +1 -1
  168. package/_types/actions/morpho/markets/lunarIndexerTransform.d.ts.map +1 -1
  169. package/_types/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.d.ts.map +1 -1
  170. package/_types/actions/morpho/vaults/common.d.ts.map +1 -1
  171. package/_types/actions/morpho/vaults/getMorphoVaultSnapshots.d.ts.map +1 -1
  172. package/_types/actions/morpho/vaults/getMorphoVaultStakingSnapshots.d.ts.map +1 -1
  173. package/_types/actions/retry.d.ts +45 -0
  174. package/_types/actions/retry.d.ts.map +1 -0
  175. package/_types/client/createMoonwellClient.d.ts +6 -6
  176. package/_types/client/createMoonwellClient.d.ts.map +1 -1
  177. package/_types/common/getBlockNumberAtTimestamp.d.ts +15 -0
  178. package/_types/common/getBlockNumberAtTimestamp.d.ts.map +1 -0
  179. package/_types/common/index.d.ts +1 -0
  180. package/_types/common/index.d.ts.map +1 -1
  181. package/_types/environments/definitions/arbitrum/environment.d.ts +1 -1
  182. package/_types/environments/definitions/arbitrum/environment.d.ts.map +1 -1
  183. package/_types/environments/definitions/avalanche/environment.d.ts +1 -1
  184. package/_types/environments/definitions/avalanche/environment.d.ts.map +1 -1
  185. package/_types/environments/definitions/base/custom.d.ts +0 -1
  186. package/_types/environments/definitions/base/custom.d.ts.map +1 -1
  187. package/_types/environments/definitions/base/environment.d.ts +22 -4
  188. package/_types/environments/definitions/base/environment.d.ts.map +1 -1
  189. package/_types/environments/definitions/ethereum/environment.d.ts +1 -1
  190. package/_types/environments/definitions/ethereum/environment.d.ts.map +1 -1
  191. package/_types/environments/definitions/moonbeam/custom.d.ts +1 -1
  192. package/_types/environments/definitions/moonbeam/environment.d.ts +2 -2
  193. package/_types/environments/definitions/moonbeam/environment.d.ts.map +1 -1
  194. package/_types/environments/definitions/optimism/custom.d.ts +0 -1
  195. package/_types/environments/definitions/optimism/custom.d.ts.map +1 -1
  196. package/_types/environments/definitions/optimism/environment.d.ts +1 -2
  197. package/_types/environments/definitions/optimism/environment.d.ts.map +1 -1
  198. package/_types/environments/definitions/polygon/environment.d.ts +1 -1
  199. package/_types/environments/definitions/polygon/environment.d.ts.map +1 -1
  200. package/_types/environments/index.d.ts +119 -23
  201. package/_types/environments/index.d.ts.map +1 -1
  202. package/_types/environments/types/config.d.ts +37 -44
  203. package/_types/environments/types/config.d.ts.map +1 -1
  204. package/_types/errors/version.d.ts +1 -1
  205. package/actions/axiosWithRetry.ts +42 -0
  206. package/actions/beam/getBeamTokenLimits.ts +2 -2
  207. package/actions/beam/getBeamTokenRoutes.ts +3 -3
  208. package/actions/core/markets/common.ts +33 -18
  209. package/actions/core/markets/getMarketSnapshots.ts +263 -513
  210. package/actions/core/user-positions/getUserPositionSnapshots.ts +46 -48
  211. package/actions/governance/getCirculatingSupplySnapshots.ts +46 -38
  212. package/actions/governance/getDelegates.ts +2 -2
  213. package/actions/governance/getDiscussions.ts +6 -5
  214. package/actions/governance/getStakingSnapshots.ts +34 -31
  215. package/actions/governance/getUserVotingPowers.ts +43 -8
  216. package/actions/governance/governor-api-client.ts +12 -10
  217. package/actions/governance/proposals/common.ts +370 -330
  218. package/actions/governance/snapshot/common.ts +2 -2
  219. package/actions/lunar-indexer-client.ts +8 -0
  220. package/actions/morpho/markets/common.ts +34 -45
  221. package/actions/morpho/markets/lunarIndexerTransform.ts +6 -5
  222. package/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.ts +20 -109
  223. package/actions/morpho/vaults/common.ts +7 -6
  224. package/actions/morpho/vaults/getMorphoVaultSnapshots.ts +36 -120
  225. package/actions/morpho/vaults/getMorphoVaultStakingSnapshots.ts +24 -111
  226. package/actions/retry.ts +121 -0
  227. package/client/createMoonwellClient.ts +17 -5
  228. package/common/getBlockNumberAtTimestamp.ts +59 -0
  229. package/common/index.ts +1 -0
  230. package/environments/definitions/arbitrum/environment.ts +0 -2
  231. package/environments/definitions/avalanche/environment.ts +0 -2
  232. package/environments/definitions/base/custom.ts +0 -1
  233. package/environments/definitions/base/environment.ts +0 -2
  234. package/environments/definitions/ethereum/environment.ts +0 -2
  235. package/environments/definitions/moonbeam/environment.ts +0 -2
  236. package/environments/definitions/optimism/custom.ts +0 -1
  237. package/environments/definitions/optimism/environment.ts +0 -2
  238. package/environments/definitions/polygon/environment.ts +0 -2
  239. package/environments/index.ts +6 -27
  240. package/environments/types/config.ts +45 -210
  241. package/errors/version.ts +1 -1
  242. package/package.json +2 -2
@@ -1,4 +1,3 @@
1
- import axios from "axios";
2
1
  import type { Address } from "viem";
3
2
  import type { MoonwellClient } from "../../../client/createMoonwellClient.js";
4
3
  import {
@@ -12,10 +11,10 @@ import {
12
11
  import type { NetworkParameterType } from "../../../common/types.js";
13
12
  import type { Chain, Environment } from "../../../environments/index.js";
14
13
  import type { UserPositionSnapshot } from "../../../types/userPosition.js";
14
+ import { postWithRetry } from "../../axiosWithRetry.js";
15
15
  import {
16
16
  DEFAULT_LUNAR_TIMEOUT_MS,
17
17
  createLunarIndexerClient,
18
- shouldFallback,
19
18
  } from "../../lunar-indexer-client.js";
20
19
  import { transformPortfolioToSnapshots } from "../../lunar-indexer-transformers.js";
21
20
 
@@ -56,7 +55,6 @@ export type GetUserPositionSnapshotsReturnType = Promise<
56
55
  * - Default behavior (no time parameters): Returns 365 days of history
57
56
  * - Parameter priority: Custom timestamps > period > default (365 days)
58
57
  * - When using Lunar Indexer, custom time ranges are supported
59
- * - When falling back to Ponder, all available data is returned (client-side filtering may be needed)
60
58
  * - Snapshots are filtered to start-of-day for "1d" granularity
61
59
  */
62
60
  export async function getUserPositionSnapshots<
@@ -90,34 +88,45 @@ async function fetchUserPositionSnapshots(
90
88
  endTime?: number,
91
89
  granularity?: "6h" | "1d",
92
90
  ): Promise<UserPositionSnapshot[]> {
93
- if (environment.lunarIndexerUrl) {
91
+ if (!environment.lunarIndexerUrl) {
92
+ if (!environment.indexerUrl) return [];
94
93
  try {
95
- const result = await fetchUserPositionSnapshotsFromLunar(
94
+ return await fetchUserPositionSnapshotsFromPonder(
96
95
  userAddress,
97
96
  environment,
98
- period,
99
- startTime,
100
- endTime,
101
- granularity,
102
97
  );
103
- return result;
104
98
  } catch (error) {
105
- if (!shouldFallback(error)) {
106
- throw error;
107
- }
108
- console.debug(
109
- "[Lunar fallback] Falling back to Ponder for user snapshots:",
99
+ console.warn(
100
+ `[getUserPositionSnapshots] Ponder failed for chain ${environment.chainId}:`,
110
101
  error,
111
102
  );
103
+ environment.onError?.(error, {
104
+ source: "user-position-snapshots-ponder",
105
+ chainId: environment.chainId,
106
+ });
107
+ return [];
112
108
  }
113
109
  }
114
-
115
- // Ponder fallback returns all available data (doesn't support time filtering)
116
- const result = await fetchUserPositionSnapshotsFromPonder(
117
- userAddress,
118
- environment,
119
- );
120
- return result;
110
+ try {
111
+ return await fetchUserPositionSnapshotsFromLunar(
112
+ userAddress,
113
+ environment,
114
+ period,
115
+ startTime,
116
+ endTime,
117
+ granularity,
118
+ );
119
+ } catch (error) {
120
+ console.warn(
121
+ `[getUserPositionSnapshots] Lunar Indexer failed for chain ${environment.chainId}:`,
122
+ error,
123
+ );
124
+ environment.onError?.(error, {
125
+ source: "user-position-snapshots",
126
+ chainId: environment.chainId,
127
+ });
128
+ return [];
129
+ }
121
130
  }
122
131
 
123
132
  async function fetchUserPositionSnapshotsFromLunar(
@@ -182,9 +191,7 @@ async function fetchUserPositionSnapshotsFromPonder(
182
191
  userAddress: Address,
183
192
  environment: Environment,
184
193
  ): Promise<UserPositionSnapshot[]> {
185
- const dailyData: UserDailyData[] = [];
186
- let hasNextPage = true;
187
- let endCursor: string | undefined;
194
+ if (!environment.indexerUrl) return [];
188
195
 
189
196
  interface UserDailyData {
190
197
  totalBorrowsUSD: string;
@@ -193,15 +200,16 @@ async function fetchUserPositionSnapshotsFromPonder(
193
200
  timestamp: number;
194
201
  }
195
202
 
203
+ const dailyData: UserDailyData[] = [];
204
+ let hasNextPage = true;
205
+ let endCursor: string | undefined;
206
+
196
207
  while (hasNextPage) {
197
- const result = await axios.post<{
208
+ const result = await postWithRetry<{
198
209
  data: {
199
210
  accountDailySnapshots: {
200
211
  items: UserDailyData[];
201
- pageInfo: {
202
- hasNextPage: boolean;
203
- endCursor: string;
204
- };
212
+ pageInfo: { hasNextPage: boolean; endCursor: string };
205
213
  };
206
214
  };
207
215
  }>(environment.indexerUrl, {
@@ -238,23 +246,13 @@ async function fetchUserPositionSnapshotsFromPonder(
238
246
  endCursor = result.data.data.accountDailySnapshots.pageInfo.endCursor;
239
247
  }
240
248
 
241
- if (dailyData.length > 0) {
242
- return dailyData.map((point: UserDailyData) => {
243
- const borrowUsd = Number(point.totalBorrowsUSD);
244
- const suppliedUsd = Number(point.totalSuppliesUSD);
245
- const collateralUsd = Number(point.totalCollateralUSD);
249
+ if (dailyData.length === 0) return [];
246
250
 
247
- const result: UserPositionSnapshot = {
248
- chainId: environment.chainId,
249
- timestamp: point.timestamp * 1000,
250
- totalSupplyUsd: suppliedUsd,
251
- totalBorrowsUsd: borrowUsd,
252
- totalCollateralUsd: collateralUsd,
253
- };
254
-
255
- return result;
256
- });
257
- } else {
258
- return [];
259
- }
251
+ return dailyData.map((point) => ({
252
+ chainId: environment.chainId,
253
+ timestamp: point.timestamp * 1000,
254
+ totalSupplyUsd: Number(point.totalSuppliesUSD),
255
+ totalBorrowsUsd: Number(point.totalBorrowsUSD),
256
+ totalCollateralUsd: Number(point.totalCollateralUSD),
257
+ }));
260
258
  }
@@ -1,10 +1,9 @@
1
- import axios from "axios";
2
1
  import type { MoonwellClient } from "../../client/createMoonwellClient.js";
3
2
  import { getEnvironmentFromArgs } from "../../common/index.js";
4
3
  import type { OptionalNetworkParameterType } from "../../common/types.js";
5
- import type { Chain } from "../../environments/index.js";
4
+ import type { Chain, Environment } from "../../environments/index.js";
6
5
  import type { CirculatingSupplySnapshot } from "../../types/circulatingSupply.js";
7
- import { shouldFallback } from "../lunar-indexer-client.js";
6
+ import { getWithRetry, postWithRetry } from "../axiosWithRetry.js";
8
7
 
9
8
  export type GetCirculatingSupplySnapshotsParameters<
10
9
  environments,
@@ -47,7 +46,7 @@ async function fetchCirculatingSupplyFromLunar(
47
46
  params.cursor = cursor;
48
47
  }
49
48
 
50
- const response = await axios.get<
49
+ const response = await getWithRetry<
51
50
  LunarPaginatedResponse<LunarCirculatingSupplySnapshot>
52
51
  >(`${lunarIndexerUrl}/api/v1/staking/circulating-supply/${chainId}`, {
53
52
  params,
@@ -74,42 +73,52 @@ export async function getCirculatingSupplySnapshots<
74
73
  return [];
75
74
  }
76
75
 
77
- if (environment.lunarIndexerUrl) {
78
- try {
79
- const items = await fetchCirculatingSupplyFromLunar(
80
- environment.lunarIndexerUrl,
81
- environment.chainId,
82
- );
83
- return items.flatMap((item) => {
84
- const token = Object.values(environment.config.tokens).find(
85
- (t) => t.address.toLowerCase() === item.tokenAddress.toLowerCase(),
86
- );
87
- if (!token) return [];
88
- return [
89
- {
90
- chainId: item.chainId,
91
- token,
92
- circulatingSupply: Number.parseFloat(item.circulatingSupply),
93
- totalSupply: item.totalSupply,
94
- excludedBalance: item.excludedBalance,
95
- timestamp: item.timestamp,
96
- },
97
- ];
98
- });
99
- } catch (error) {
100
- if (!shouldFallback(error)) {
101
- throw error;
102
- }
103
- console.debug(
104
- "[Lunar fallback] Falling back for circulating supply snapshots:",
105
- error,
76
+ if (!environment.lunarIndexerUrl) {
77
+ return environment.indexerUrl
78
+ ? fetchCirculatingSupplyFromPonder(environment)
79
+ : [];
80
+ }
81
+
82
+ try {
83
+ const items = await fetchCirculatingSupplyFromLunar(
84
+ environment.lunarIndexerUrl,
85
+ environment.chainId,
86
+ );
87
+ return items.flatMap((item) => {
88
+ const token = Object.values(environment.config.tokens).find(
89
+ (t) => t.address.toLowerCase() === item.tokenAddress.toLowerCase(),
106
90
  );
107
- }
91
+ if (!token) return [];
92
+ return [
93
+ {
94
+ chainId: item.chainId,
95
+ token,
96
+ circulatingSupply: Number.parseFloat(item.circulatingSupply),
97
+ totalSupply: item.totalSupply,
98
+ excludedBalance: item.excludedBalance,
99
+ timestamp: item.timestamp,
100
+ },
101
+ ];
102
+ });
103
+ } catch (error) {
104
+ console.warn(
105
+ `[getCirculatingSupplySnapshots] Lunar Indexer failed for chain ${environment.chainId}:`,
106
+ error,
107
+ );
108
+ environment.onError?.(error, {
109
+ source: "circulating-supply",
110
+ chainId: environment.chainId,
111
+ });
112
+ return [];
108
113
  }
114
+ }
109
115
 
110
- // Legacy fallback: GraphQL POST to Ponder indexer
116
+ async function fetchCirculatingSupplyFromPonder(
117
+ environment: Environment,
118
+ ): Promise<CirculatingSupplySnapshot[]> {
119
+ if (!environment.indexerUrl) return [];
111
120
  try {
112
- const response = await axios.post<{
121
+ const response = await postWithRetry<{
113
122
  data: {
114
123
  circulatingSupplyDailySnapshots: {
115
124
  items: {
@@ -160,9 +169,8 @@ export async function getCirculatingSupplySnapshots<
160
169
  ];
161
170
  },
162
171
  );
163
- } else {
164
- return [];
165
172
  }
173
+ return [];
166
174
  } catch (ex) {
167
175
  console.error(
168
176
  "An error occurred while fetching getCirculatingSupplySnapshots...",
@@ -1,4 +1,3 @@
1
- import axios from "axios";
2
1
  import { isAddress } from "viem";
3
2
  import { base, moonbeam, optimism } from "viem/chains";
4
3
  import type { MoonwellClient } from "../../client/createMoonwellClient.js";
@@ -8,6 +7,7 @@ import {
8
7
  } from "../../environments/index.js";
9
8
  import * as logger from "../../logger/console.js";
10
9
  import type { Delegate } from "../../types/delegate.js";
10
+ import { getWithRetry } from "../axiosWithRetry.js";
11
11
  import { fetchAllVoters } from "./governor-api-client.js";
12
12
 
13
13
  export type GetDelegatesReturnType = Promise<Delegate[]>;
@@ -119,7 +119,7 @@ const getForumProfiles = async () => {
119
119
 
120
120
  const getUsersPaginated = async (page = 0) => {
121
121
  try {
122
- const response = await axios.get<{
122
+ const response = await getWithRetry<{
123
123
  directory_items: {
124
124
  user: {
125
125
  id: number;
@@ -1,9 +1,9 @@
1
- import axios from "axios";
2
1
  import lodash from "lodash";
3
2
  import type { MoonwellClient } from "../../client/createMoonwellClient.js";
4
3
  import { HttpRequestError } from "../../common/index.js";
5
4
  import * as logger from "../../logger/console.js";
6
5
  import type { Discussion } from "../../types/discussion.js";
6
+ import { getWithRetry } from "../axiosWithRetry.js";
7
7
 
8
8
  const { isEqual, uniqWith } = lodash;
9
9
 
@@ -43,7 +43,7 @@ export async function getDiscussions(
43
43
  "Starting to get discussions...",
44
44
  );
45
45
 
46
- const moonwellProposalsResult = await axios.get<ForumTopicRequestResponse>(
46
+ const moonwellProposalsResult = await getWithRetry<ForumTopicRequestResponse>(
47
47
  "https://forum.moonwell.fi/c/proposals/moonwell-improvement-proposals/9/l/latest.json",
48
48
  );
49
49
 
@@ -51,9 +51,10 @@ export async function getDiscussions(
51
51
  throw new HttpRequestError(moonwellProposalsResult.statusText);
52
52
  }
53
53
 
54
- const communityProposalsResult = await axios.get<ForumTopicRequestResponse>(
55
- "https://forum.moonwell.fi/c/proposals/community-proposal/19/l/latest.json",
56
- );
54
+ const communityProposalsResult =
55
+ await getWithRetry<ForumTopicRequestResponse>(
56
+ "https://forum.moonwell.fi/c/proposals/community-proposal/19/l/latest.json",
57
+ );
57
58
 
58
59
  if (
59
60
  communityProposalsResult.status !== 200 ||
@@ -1,4 +1,3 @@
1
- import axios from "axios";
2
1
  import type { MoonwellClient } from "../../client/createMoonwellClient.js";
3
2
  import {
4
3
  type SnapshotPeriod,
@@ -10,10 +9,10 @@ import {
10
9
  import type { NetworkParameterType } from "../../common/types.js";
11
10
  import type { Chain } from "../../environments/index.js";
12
11
  import type { StakingSnapshot } from "../../types/staking.js";
12
+ import { postWithRetry } from "../axiosWithRetry.js";
13
13
  import {
14
14
  DEFAULT_LUNAR_TIMEOUT_MS,
15
15
  createLunarIndexerClient,
16
- shouldFallback,
17
16
  } from "../lunar-indexer-client.js";
18
17
  import { transformStakingSnapshots } from "../lunar-indexer-transformers.js";
19
18
 
@@ -47,36 +46,40 @@ export async function getStakingSnapshots<
47
46
  endTime: customEndTime,
48
47
  } = (args ?? {}) as GetStakingSnapshotsParameters<environments, undefined>;
49
48
 
50
- if (environment.lunarIndexerUrl) {
51
- try {
52
- return await fetchStakingSnapshotsFromLunar(
53
- environment.chainId,
54
- environment.lunarIndexerUrl,
55
- period,
56
- customStartTime,
57
- customEndTime,
58
- );
59
- } catch (error) {
60
- if (!shouldFallback(error)) {
61
- throw error;
62
- }
63
- console.debug(
64
- "[Lunar fallback] Falling back to Ponder for staking snapshots:",
65
- error,
66
- );
67
- }
49
+ if (!environment.lunarIndexerUrl) {
50
+ const { startTime } = calculateTimeRange(
51
+ period,
52
+ customStartTime,
53
+ customEndTime,
54
+ );
55
+ return environment.indexerUrl
56
+ ? fetchStakingSnapshotsFromPonder(
57
+ environment.chainId,
58
+ environment.indexerUrl,
59
+ startTime,
60
+ )
61
+ : [];
68
62
  }
69
63
 
70
- const { startTime } = calculateTimeRange(
71
- period,
72
- customStartTime,
73
- customEndTime,
74
- );
75
- return fetchStakingSnapshotsFromPonder(
76
- environment.chainId,
77
- environment.indexerUrl,
78
- startTime,
79
- );
64
+ try {
65
+ return await fetchStakingSnapshotsFromLunar(
66
+ environment.chainId,
67
+ environment.lunarIndexerUrl,
68
+ period,
69
+ customStartTime,
70
+ customEndTime,
71
+ );
72
+ } catch (error) {
73
+ console.warn(
74
+ `[getStakingSnapshots] Lunar Indexer failed for chain ${environment.chainId}:`,
75
+ error,
76
+ );
77
+ environment.onError?.(error, {
78
+ source: "staking-snapshots",
79
+ chainId: environment.chainId,
80
+ });
81
+ return [];
82
+ }
80
83
  }
81
84
 
82
85
  async function fetchStakingSnapshotsFromLunar(
@@ -126,7 +129,7 @@ async function fetchStakingSnapshotsFromPonder(
126
129
  startTime?: number,
127
130
  ): Promise<StakingSnapshot[]> {
128
131
  try {
129
- const response = await axios.post<{
132
+ const response = await postWithRetry<{
130
133
  data: {
131
134
  stakingDailySnapshots: {
132
135
  items: StakingSnapshot[];
@@ -1,6 +1,10 @@
1
1
  import { type Address, zeroAddress } from "viem";
2
2
  import type { MoonwellClient } from "../../client/createMoonwellClient.js";
3
- import { Amount, getEnvironmentsFromArgs } from "../../common/index.js";
3
+ import {
4
+ Amount,
5
+ getBlockNumberAtTimestamp,
6
+ getEnvironmentsFromArgs,
7
+ } from "../../common/index.js";
4
8
  import type { OptionalNetworkParameterType } from "../../common/types.js";
5
9
  import type { Chain, GovernanceToken } from "../../environments/index.js";
6
10
  import type { UserVotingPowers } from "../../types/userVotingPowers.js";
@@ -15,8 +19,21 @@ export type GetUserVotingPowersParameters<
15
19
  /** User address*/
16
20
  userAddress: Address;
17
21
 
18
- /** Block number **/
22
+ /**
23
+ * Block number to read voting power at. Applied to every queried chain — only safe
24
+ * for single-chain governance tokens. For cross-chain tokens (e.g. WELL) prefer
25
+ * `snapshotTimestamp`, which resolves a correct per-chain block.
26
+ */
19
27
  blockNumber?: bigint;
28
+
29
+ /**
30
+ * Unix timestamp (seconds) at which to read voting power. When set, the SDK looks up
31
+ * the block on each queried chain whose timestamp is the latest one ≤ this value, and
32
+ * uses that per-chain block. Use this for cross-chain governance tokens; supplying a
33
+ * single block number across heterogeneous chains is unsafe because chain heights
34
+ * diverge. Takes priority over `blockNumber` when both are provided.
35
+ */
36
+ snapshotTimestamp?: number;
20
37
  };
21
38
 
22
39
  export type GetUserVotingPowersReturnType = Promise<UserVotingPowers[]>;
@@ -28,7 +45,7 @@ export async function getUserVotingPowers<
28
45
  client: MoonwellClient,
29
46
  args: GetUserVotingPowersParameters<environments, Network>,
30
47
  ): GetUserVotingPowersReturnType {
31
- const { governanceToken, userAddress, blockNumber } = args;
48
+ const { governanceToken, userAddress, blockNumber, snapshotTimestamp } = args;
32
49
 
33
50
  const environments = getEnvironmentsFromArgs(client, args);
34
51
 
@@ -36,12 +53,30 @@ export async function getUserVotingPowers<
36
53
  (env) => env.custom?.governance?.token === governanceToken,
37
54
  );
38
55
 
56
+ const perChainBlockNumbers =
57
+ snapshotTimestamp !== undefined
58
+ ? await Promise.all(
59
+ tokenEnvironments.map((env) =>
60
+ getBlockNumberAtTimestamp(
61
+ env.publicClient,
62
+ BigInt(snapshotTimestamp),
63
+ ),
64
+ ),
65
+ )
66
+ : undefined;
67
+
39
68
  const environmentsUserVotingPowers = await Promise.all(
40
- tokenEnvironments.map((environment) =>
41
- environment.contracts.views?.read.getUserVotingPower([userAddress], {
42
- blockNumber,
43
- }),
44
- ),
69
+ tokenEnvironments.map((environment, index) => {
70
+ const blockForChain = perChainBlockNumbers
71
+ ? perChainBlockNumbers[index]
72
+ : blockNumber;
73
+ return environment.contracts.views?.read.getUserVotingPower(
74
+ [userAddress],
75
+ {
76
+ blockNumber: blockForChain,
77
+ },
78
+ );
79
+ }),
45
80
  );
46
81
 
47
82
  return tokenEnvironments.map((environment, index) => {
@@ -1,5 +1,5 @@
1
- import axios from "axios";
2
1
  import type { Environment } from "../../environments/index.js";
2
+ import { getWithRetry } from "../axiosWithRetry.js";
3
3
 
4
4
  /**
5
5
  * Base configuration for Governor API requests
@@ -108,7 +108,7 @@ export async function fetchProposals(
108
108
  if (options?.cursor) params.append("cursor", options.cursor);
109
109
  if (options?.chainId) params.append("chainId", options.chainId.toString());
110
110
 
111
- const response = await axios.get<PaginatedResponse<ApiProposal>>(
111
+ const response = await getWithRetry<PaginatedResponse<ApiProposal>>(
112
112
  `${baseUrl}/api/v1/governor/proposals?${params.toString()}`,
113
113
  );
114
114
 
@@ -152,7 +152,7 @@ export async function fetchProposal(
152
152
  ): Promise<ApiProposal> {
153
153
  const baseUrl = getGovernorApiUrl(environment);
154
154
 
155
- const response = await axios.get<ApiProposal>(
155
+ const response = await getWithRetry<ApiProposal>(
156
156
  `${baseUrl}/api/v1/governor/proposals/${proposalId}`,
157
157
  );
158
158
 
@@ -177,7 +177,7 @@ export async function fetchProposalVotes(
177
177
  if (options?.limit) params.append("limit", options.limit.toString());
178
178
  if (options?.cursor) params.append("cursor", options.cursor);
179
179
 
180
- const response = await axios.get<PaginatedResponse<ApiVote>>(
180
+ const response = await getWithRetry<PaginatedResponse<ApiVote>>(
181
181
  `${baseUrl}/api/v1/governor/proposals/${proposalId}/votes?${params.toString()}`,
182
182
  );
183
183
 
@@ -225,7 +225,9 @@ export async function fetchProposalStateChanges(
225
225
  if (options?.limit) params.append("limit", options.limit.toString());
226
226
  if (options?.cursor) params.append("cursor", options.cursor);
227
227
 
228
- const response = await axios.get<PaginatedResponse<ApiProposalStateChange>>(
228
+ const response = await getWithRetry<
229
+ PaginatedResponse<ApiProposalStateChange>
230
+ >(
229
231
  `${baseUrl}/api/v1/governor/proposals/${proposalId}/state-changes?${params.toString()}`,
230
232
  );
231
233
 
@@ -277,7 +279,7 @@ export async function fetchVoters(
277
279
  const endpoint = `${baseUrl}/api/v1/governor/voters?${params.toString()}`;
278
280
 
279
281
  try {
280
- const response = await axios.get<PaginatedResponse<ApiVoter>>(endpoint);
282
+ const response = await getWithRetry<PaginatedResponse<ApiVoter>>(endpoint);
281
283
 
282
284
  if (response.status !== 200 || !response.data) {
283
285
  throw new Error(`Failed to fetch voters: ${response.statusText}`);
@@ -328,7 +330,7 @@ export async function fetchVoter(
328
330
  ): Promise<ApiVoter> {
329
331
  const baseUrl = getGovernorApiUrl(environment);
330
332
 
331
- const response = await axios.get<ApiVoter>(
333
+ const response = await getWithRetry<ApiVoter>(
332
334
  `${baseUrl}/api/v1/governor/voters/${address}`,
333
335
  );
334
336
 
@@ -359,7 +361,7 @@ export async function fetchVoterProposals(
359
361
 
360
362
  const endpoint = `${baseUrl}/api/v1/governor/voters/${address}/proposals?${params.toString()}`;
361
363
 
362
- const response = await axios.get<PaginatedResponse<ApiProposal>>(endpoint);
364
+ const response = await getWithRetry<PaginatedResponse<ApiProposal>>(endpoint);
363
365
 
364
366
  if (response.status !== 200 || !response.data) {
365
367
  throw new Error(`Failed to fetch voter proposals: ${response.statusText}`);
@@ -407,7 +409,7 @@ export async function fetchVoterVotes(
407
409
 
408
410
  const endpoint = `${baseUrl}/api/v1/governor/voters/${address}/votes?${params.toString()}`;
409
411
 
410
- const response = await axios.get<PaginatedResponse<ApiVote>>(endpoint);
412
+ const response = await getWithRetry<PaginatedResponse<ApiVote>>(endpoint);
411
413
 
412
414
  if (response.status !== 200 || !response.data) {
413
415
  throw new Error(`Failed to fetch voter votes: ${response.statusText}`);
@@ -450,7 +452,7 @@ export async function fetchUserVoteReceipt(
450
452
  ): Promise<ApiVoteReceipt[]> {
451
453
  const baseUrl = getGovernorApiUrl(environment);
452
454
 
453
- const response = await axios.get<ApiVoteReceipt[]>(
455
+ const response = await getWithRetry<ApiVoteReceipt[]>(
454
456
  `${baseUrl}/api/v1/governor/proposals/${proposalId}/vote/${voterAddress}`,
455
457
  );
456
458