@defisaver/positions-sdk 2.1.169-custom-fetching-2-dev → 2.1.169-custom-fetching-4-dev

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 (145) hide show
  1. package/cjs/aaveV2/index.d.ts +4 -4
  2. package/cjs/aaveV2/index.js +7 -7
  3. package/cjs/aaveV3/index.d.ts +4 -3
  4. package/cjs/aaveV3/index.js +14 -10
  5. package/cjs/aaveV3/merkl.d.ts +5 -1
  6. package/cjs/aaveV3/merkl.js +8 -3
  7. package/cjs/aaveV4/index.d.ts +4 -3
  8. package/cjs/aaveV4/index.js +19 -16
  9. package/cjs/aaveV4/merkl.d.ts +10 -2
  10. package/cjs/aaveV4/merkl.js +15 -6
  11. package/cjs/claiming/aaveV3.d.ts +2 -2
  12. package/cjs/claiming/aaveV3.js +5 -4
  13. package/cjs/claiming/king.d.ts +2 -2
  14. package/cjs/claiming/king.js +3 -2
  15. package/cjs/claiming/spark.d.ts +3 -3
  16. package/cjs/claiming/spark.js +8 -7
  17. package/cjs/claiming/uniswap.d.ts +2 -2
  18. package/cjs/claiming/uniswap.js +3 -2
  19. package/cjs/compoundV2/index.d.ts +4 -4
  20. package/cjs/compoundV2/index.js +9 -9
  21. package/cjs/compoundV3/index.d.ts +5 -4
  22. package/cjs/compoundV3/index.js +17 -13
  23. package/cjs/compoundV3/merkl.d.ts +1 -1
  24. package/cjs/compoundV3/merkl.js +2 -5
  25. package/cjs/curveUsd/index.d.ts +5 -5
  26. package/cjs/curveUsd/index.js +17 -17
  27. package/cjs/fluid/index.d.ts +23 -22
  28. package/cjs/fluid/index.js +75 -72
  29. package/cjs/fluid/merkl.d.ts +5 -3
  30. package/cjs/fluid/merkl.js +11 -6
  31. package/cjs/liquity/index.d.ts +4 -4
  32. package/cjs/liquity/index.js +23 -23
  33. package/cjs/liquityV2/index.d.ts +10 -10
  34. package/cjs/liquityV2/index.js +59 -59
  35. package/cjs/llamaLend/index.d.ts +5 -5
  36. package/cjs/llamaLend/index.js +13 -13
  37. package/cjs/maker/index.d.ts +6 -6
  38. package/cjs/maker/index.js +16 -16
  39. package/cjs/morphoBlue/index.d.ts +7 -7
  40. package/cjs/morphoBlue/index.js +28 -26
  41. package/cjs/morphoBlue/merkl.d.ts +5 -3
  42. package/cjs/morphoBlue/merkl.js +6 -8
  43. package/cjs/morphoMidnight/index.d.ts +5 -5
  44. package/cjs/morphoMidnight/index.js +18 -18
  45. package/cjs/portfolio/customDeFiData.js +47 -43
  46. package/cjs/services/merkl.d.ts +44 -2
  47. package/cjs/services/merkl.js +181 -19
  48. package/cjs/services/priceService.d.ts +12 -12
  49. package/cjs/services/priceService.js +30 -29
  50. package/cjs/services/viem.d.ts +10 -4
  51. package/cjs/services/viem.js +18 -18
  52. package/cjs/spark/index.d.ts +4 -4
  53. package/cjs/spark/index.js +9 -9
  54. package/cjs/types/merkl.d.ts +18 -0
  55. package/cjs/types/portfolio.d.ts +1 -1
  56. package/cjs/umbrella/index.d.ts +2 -2
  57. package/cjs/umbrella/index.js +5 -4
  58. package/esm/aaveV2/index.d.ts +4 -4
  59. package/esm/aaveV2/index.js +8 -8
  60. package/esm/aaveV3/index.d.ts +4 -3
  61. package/esm/aaveV3/index.js +15 -11
  62. package/esm/aaveV3/merkl.d.ts +5 -1
  63. package/esm/aaveV3/merkl.js +9 -4
  64. package/esm/aaveV4/index.d.ts +4 -3
  65. package/esm/aaveV4/index.js +20 -17
  66. package/esm/aaveV4/merkl.d.ts +10 -2
  67. package/esm/aaveV4/merkl.js +16 -7
  68. package/esm/claiming/aaveV3.d.ts +2 -2
  69. package/esm/claiming/aaveV3.js +5 -4
  70. package/esm/claiming/king.d.ts +2 -2
  71. package/esm/claiming/king.js +3 -2
  72. package/esm/claiming/spark.d.ts +3 -3
  73. package/esm/claiming/spark.js +8 -7
  74. package/esm/claiming/uniswap.d.ts +2 -2
  75. package/esm/claiming/uniswap.js +3 -2
  76. package/esm/compoundV2/index.d.ts +4 -4
  77. package/esm/compoundV2/index.js +9 -9
  78. package/esm/compoundV3/index.d.ts +5 -4
  79. package/esm/compoundV3/index.js +19 -15
  80. package/esm/compoundV3/merkl.d.ts +1 -1
  81. package/esm/compoundV3/merkl.js +3 -6
  82. package/esm/curveUsd/index.d.ts +5 -5
  83. package/esm/curveUsd/index.js +17 -17
  84. package/esm/fluid/index.d.ts +23 -22
  85. package/esm/fluid/index.js +76 -73
  86. package/esm/fluid/merkl.d.ts +5 -3
  87. package/esm/fluid/merkl.js +12 -7
  88. package/esm/liquity/index.d.ts +4 -4
  89. package/esm/liquity/index.js +23 -23
  90. package/esm/liquityV2/index.d.ts +10 -10
  91. package/esm/liquityV2/index.js +60 -60
  92. package/esm/llamaLend/index.d.ts +5 -5
  93. package/esm/llamaLend/index.js +13 -13
  94. package/esm/maker/index.d.ts +6 -6
  95. package/esm/maker/index.js +16 -16
  96. package/esm/morphoBlue/index.d.ts +7 -7
  97. package/esm/morphoBlue/index.js +29 -27
  98. package/esm/morphoBlue/merkl.d.ts +5 -3
  99. package/esm/morphoBlue/merkl.js +7 -9
  100. package/esm/morphoMidnight/index.d.ts +5 -5
  101. package/esm/morphoMidnight/index.js +18 -18
  102. package/esm/portfolio/customDeFiData.js +49 -45
  103. package/esm/services/merkl.d.ts +44 -2
  104. package/esm/services/merkl.js +171 -18
  105. package/esm/services/priceService.d.ts +12 -12
  106. package/esm/services/priceService.js +31 -30
  107. package/esm/services/viem.d.ts +10 -4
  108. package/esm/services/viem.js +16 -16
  109. package/esm/spark/index.d.ts +4 -4
  110. package/esm/spark/index.js +10 -10
  111. package/esm/types/merkl.d.ts +18 -0
  112. package/esm/types/portfolio.d.ts +1 -1
  113. package/esm/umbrella/index.d.ts +2 -2
  114. package/esm/umbrella/index.js +5 -4
  115. package/package.json +1 -1
  116. package/src/aaveV2/index.ts +7 -7
  117. package/src/aaveV3/index.ts +15 -11
  118. package/src/aaveV3/merkl.ts +9 -4
  119. package/src/aaveV4/index.ts +19 -16
  120. package/src/aaveV4/merkl.ts +16 -7
  121. package/src/claiming/aaveV3.ts +5 -3
  122. package/src/claiming/king.ts +6 -3
  123. package/src/claiming/spark.ts +9 -6
  124. package/src/claiming/uniswap.ts +4 -3
  125. package/src/compoundV2/index.ts +10 -9
  126. package/src/compoundV3/index.ts +20 -14
  127. package/src/compoundV3/merkl.ts +5 -4
  128. package/src/curveUsd/index.ts +19 -17
  129. package/src/fluid/index.ts +88 -70
  130. package/src/fluid/merkl.ts +12 -7
  131. package/src/liquity/index.ts +23 -23
  132. package/src/liquityV2/index.ts +64 -56
  133. package/src/llamaLend/index.ts +15 -13
  134. package/src/maker/index.ts +19 -16
  135. package/src/morphoBlue/index.ts +23 -20
  136. package/src/morphoBlue/merkl.ts +9 -6
  137. package/src/morphoMidnight/index.ts +13 -13
  138. package/src/portfolio/customDeFiData.ts +50 -44
  139. package/src/services/merkl.ts +200 -19
  140. package/src/services/priceService.ts +33 -30
  141. package/src/services/viem.ts +14 -12
  142. package/src/spark/index.ts +11 -8
  143. package/src/types/merkl.ts +20 -0
  144. package/src/types/portfolio.ts +1 -1
  145. package/src/umbrella/index.ts +6 -5
@@ -52,8 +52,8 @@ const addMorphoBlueRewardsToMarketInfo = (marketInfo, rewards) => (Object.assign
52
52
  ...getMorphoRewardIncentives(rewards.borrowApy),
53
53
  ] }) }) }));
54
54
  exports.addMorphoBlueRewardsToMarketInfo = addMorphoBlueRewardsToMarketInfo;
55
- function getMorphoBlueMarketDataInternal(provider, network, selectedMarket) {
56
- return __awaiter(this, void 0, void 0, function* () {
55
+ function getMorphoBlueMarketDataInternal(provider_1, network_1, selectedMarket_1) {
56
+ return __awaiter(this, arguments, void 0, function* (provider, network, selectedMarket, blockNumber = 'latest') {
57
57
  const { loanToken, collateralToken, oracle, irm, lltv, oracleType, } = selectedMarket;
58
58
  const lltvInWei = new decimal_js_1.default(lltv).mul(constants_1.WAD).toString();
59
59
  const loanTokenInfo = (0, tokens_1.getAssetInfoByAddress)(loanToken, network);
@@ -67,8 +67,8 @@ function getMorphoBlueMarketDataInternal(provider, network, selectedMarket) {
67
67
  if (isMainnet) {
68
68
  const feedRegistryContract = (0, contracts_1.FeedRegistryContractViem)(provider, common_1.NetworkNumber.Eth);
69
69
  const [_loanTokenPrice, _marketInfo] = yield Promise.all([
70
- isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, constants_1.USD_QUOTE]),
71
- morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
70
+ isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, constants_1.USD_QUOTE], (0, viem_1.setViemBlockNumber)(blockNumber)),
71
+ morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)], (0, viem_1.setViemBlockNumber)(blockNumber)),
72
72
  ]);
73
73
  marketInfo = _marketInfo;
74
74
  loanTokenPrice = _loanTokenPrice;
@@ -78,8 +78,8 @@ function getMorphoBlueMarketDataInternal(provider, network, selectedMarket) {
78
78
  const feedRegistryContract = (0, contracts_1.DFSFeedRegistryContractViem)(provider, network);
79
79
  const [loanTokenPriceRound, _marketInfo] = yield Promise.all([
80
80
  isHardcodedUsdStable ? Promise.resolve([0, HARDCODED_USD_STABLE_PRICE]) // Normalize to match the expected object structure
81
- : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, constants_1.USD_QUOTE]),
82
- morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
81
+ : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, constants_1.USD_QUOTE], (0, viem_1.setViemBlockNumber)(blockNumber)),
82
+ morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)], (0, viem_1.setViemBlockNumber)(blockNumber)),
83
83
  ]);
84
84
  marketInfo = _marketInfo;
85
85
  loanTokenPrice = loanTokenPriceRound[1].toString();
@@ -138,29 +138,31 @@ function getMorphoBlueMarketDataInternal(provider, network, selectedMarket) {
138
138
  };
139
139
  });
140
140
  }
141
- function _getMorphoBlueMarketData(provider, network, selectedMarket) {
142
- return __awaiter(this, void 0, void 0, function* () {
141
+ function _getMorphoBlueMarketData(provider_1, network_1, selectedMarket_1) {
142
+ return __awaiter(this, arguments, void 0, function* (provider, network, selectedMarket, blockNumber = 'latest') {
143
143
  const [marketInfo, rewards, merklOpportunities] = yield Promise.all([
144
- getMorphoBlueMarketDataInternal(provider, network, selectedMarket),
144
+ getMorphoBlueMarketDataInternal(provider, network, selectedMarket, blockNumber),
145
145
  (0, morphoBlueHelpers_1.getRewardsForMarket)(selectedMarket.marketId, network).catch((error) => {
146
146
  console.error(error);
147
147
  return { supplyApy: '0', borrowApy: '0' };
148
148
  }),
149
- (0, merkl_1.getMorphoBlueMerklOpportunities)(),
149
+ // Merkl rewards are keyed by time: a historical block resolves to its timestamp first (one RPC
150
+ // call, none for 'latest') so the rewards in force at that moment are attached.
151
+ (0, viem_1.getBlockTimestamp)(provider, blockNumber).then((asOfTimestamp) => (0, merkl_1.getMorphoBlueMerklOpportunities)(asOfTimestamp, network)),
150
152
  ]);
151
153
  return (0, merkl_1.addMorphoBlueMerklOpportunitiesToMarketInfo)((0, exports.addMorphoBlueRewardsToMarketInfo)(marketInfo, rewards), selectedMarket, network, merklOpportunities);
152
154
  });
153
155
  }
154
- function _getMorphoBluePortfolioMarketData(provider, network, selectedMarket) {
155
- return getMorphoBlueMarketDataInternal(provider, network, selectedMarket);
156
+ function _getMorphoBluePortfolioMarketData(provider, network, selectedMarket, blockNumber = 'latest') {
157
+ return getMorphoBlueMarketDataInternal(provider, network, selectedMarket, blockNumber);
156
158
  }
157
- function getMorphoBlueMarketData(provider, network, selectedMarket) {
158
- return __awaiter(this, void 0, void 0, function* () {
159
- return _getMorphoBlueMarketData((0, viem_1.getViemProvider)(provider, network), network, selectedMarket);
159
+ function getMorphoBlueMarketData(provider_1, network_1, selectedMarket_1) {
160
+ return __awaiter(this, arguments, void 0, function* (provider, network, selectedMarket, blockNumber = 'latest') {
161
+ return _getMorphoBlueMarketData((0, viem_1.getViemProvider)(provider, network), network, selectedMarket, blockNumber);
160
162
  });
161
163
  }
162
- function getMorphoBluePortfolioMarketData(provider, network, selectedMarket) {
163
- return _getMorphoBluePortfolioMarketData((0, viem_1.getViemProvider)(provider, network), network, selectedMarket);
164
+ function getMorphoBluePortfolioMarketData(provider, network, selectedMarket, blockNumber = 'latest') {
165
+ return _getMorphoBluePortfolioMarketData((0, viem_1.getViemProvider)(provider, network), network, selectedMarket, blockNumber);
164
166
  }
165
167
  const getMorphoBluePositionDataWithMarketInfo = (data, marketInfo) => (Object.assign(Object.assign({}, data), (0, morphoBlueHelpers_1.getMorphoBlueAggregatedPositionData)({
166
168
  usedAssets: data.usedAssets,
@@ -218,8 +220,8 @@ const _getMorphoBlueAccountBalances = (provider, network, block, addressMapping,
218
220
  exports._getMorphoBlueAccountBalances = _getMorphoBlueAccountBalances;
219
221
  const getMorphoBlueAccountBalances = (provider, network, block, addressMapping, address, selectedMarket) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getMorphoBlueAccountBalances)((0, viem_1.getViemProvider)(provider, network), network, block, addressMapping, address, selectedMarket); });
220
222
  exports.getMorphoBlueAccountBalances = getMorphoBlueAccountBalances;
221
- function _getMorphoBlueAccountData(provider, network, account, selectedMarket, marketInfo) {
222
- return __awaiter(this, void 0, void 0, function* () {
223
+ function _getMorphoBlueAccountData(provider_1, network_1, account_1, selectedMarket_1, marketInfo_1) {
224
+ return __awaiter(this, arguments, void 0, function* (provider, network, account, selectedMarket, marketInfo, blockNumber = 'latest') {
223
225
  const { loanToken, collateralToken, oracle, irm, lltv, } = selectedMarket;
224
226
  const lltvInWei = new decimal_js_1.default(lltv).mul(constants_1.WAD).toString();
225
227
  const viewContract = (0, contracts_1.MorphoBlueViewContractViem)(provider, network);
@@ -228,7 +230,7 @@ function _getMorphoBlueAccountData(provider, network, account, selectedMarket, m
228
230
  loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
229
231
  },
230
232
  account
231
- ]));
233
+ ], (0, viem_1.setViemBlockNumber)(blockNumber)));
232
234
  const usedAssets = {};
233
235
  const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
234
236
  const loanTokenSupplied = (0, tokens_1.assetAmountInEth)(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
@@ -258,13 +260,13 @@ function _getMorphoBlueAccountData(provider, network, account, selectedMarket, m
258
260
  return Object.assign({ supplyShares: loanInfo.supplyShares.toString(), borrowShares: loanInfo.borrowShares.toString(), usedAssets }, (0, morphoBlueHelpers_1.getMorphoBlueAggregatedPositionData)({ usedAssets, assetsData: marketInfo.assetsData, marketInfo }));
259
261
  });
260
262
  }
261
- function getMorphoBlueAccountData(provider, network, account, selectedMarket, marketInfo) {
262
- return __awaiter(this, void 0, void 0, function* () {
263
- return _getMorphoBlueAccountData((0, viem_1.getViemProvider)(provider, network), network, account, selectedMarket, marketInfo);
263
+ function getMorphoBlueAccountData(provider_1, network_1, account_1, selectedMarket_1, marketInfo_1) {
264
+ return __awaiter(this, arguments, void 0, function* (provider, network, account, selectedMarket, marketInfo, blockNumber = 'latest') {
265
+ return _getMorphoBlueAccountData((0, viem_1.getViemProvider)(provider, network), network, account, selectedMarket, marketInfo, blockNumber);
264
266
  });
265
267
  }
266
- function getMorphoEarn(provider, network, account, selectedMarket, marketInfo) {
267
- return __awaiter(this, void 0, void 0, function* () {
268
+ function getMorphoEarn(provider_1, network_1, account_1, selectedMarket_1, marketInfo_1) {
269
+ return __awaiter(this, arguments, void 0, function* (provider, network, account, selectedMarket, marketInfo, blockNumber = 'latest') {
268
270
  const { loanToken, collateralToken, oracle, irm, lltv, } = selectedMarket;
269
271
  const lltvInWei = new decimal_js_1.default(lltv).mul(constants_1.WAD).toString();
270
272
  const viewContract = (0, contracts_1.MorphoBlueViewContractViem)(provider, network);
@@ -273,7 +275,7 @@ function getMorphoEarn(provider, network, account, selectedMarket, marketInfo) {
273
275
  loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
274
276
  },
275
277
  account
276
- ]));
278
+ ], (0, viem_1.setViemBlockNumber)(blockNumber)));
277
279
  const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
278
280
  const loanTokenSupplied = (0, tokens_1.assetAmountInEth)(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
279
281
  const loanTokenSuppliedUsd = new decimal_js_1.default(loanTokenSupplied).mul(loanTokenInfo.price).toString();
@@ -24,10 +24,12 @@ export declare enum MorphoBlueMerklOpportunityType {
24
24
  */
25
25
  export declare const addMorphoBlueMerklOpportunitiesToMarketInfo: (marketInfo: MorphoBlueMarketInfo, selectedMarket: MorphoBlueMarketData, chainId: NetworkNumber, opportunities: MerklOpportunity[]) => MorphoBlueMarketInfo;
26
26
  /**
27
- * Fetches live market-scoped Morpho Blue campaigns for all chains. Never throws — on any failure
28
- * it returns an empty list, so Merkl being down can't break market data.
27
+ * Fetches live market-scoped Morpho Blue campaigns for all chains (or one, when `chainId` is given).
28
+ * With `asOfTimestamp` (unix seconds) the campaigns and APRs are the ones Merkl had at that moment
29
+ * instead. Never throws — on any failure it returns an empty list, so Merkl being down can't break
30
+ * market data.
29
31
  */
30
- export declare const getMorphoBlueMerklOpportunities: () => Promise<MerklOpportunity[]>;
32
+ export declare const getMorphoBlueMerklOpportunities: (asOfTimestamp?: number, chainId?: NetworkNumber) => Promise<MerklOpportunity[]>;
31
33
  /**
32
34
  * Fetches live Merkl campaigns and appends the ones for the market to its `assetsData` incentive
33
35
  * arrays. Never throws — on any failure the market info is returned unchanged.
@@ -77,16 +77,14 @@ const addMorphoBlueMerklOpportunitiesToMarketInfo = (marketInfo, selectedMarket,
77
77
  };
78
78
  exports.addMorphoBlueMerklOpportunitiesToMarketInfo = addMorphoBlueMerklOpportunitiesToMarketInfo;
79
79
  /**
80
- * Fetches live market-scoped Morpho Blue campaigns for all chains. Never throws — on any failure
81
- * it returns an empty list, so Merkl being down can't break market data.
80
+ * Fetches live market-scoped Morpho Blue campaigns for all chains (or one, when `chainId` is given).
81
+ * With `asOfTimestamp` (unix seconds) the campaigns and APRs are the ones Merkl had at that moment
82
+ * instead. Never throws — on any failure it returns an empty list, so Merkl being down can't break
83
+ * market data.
82
84
  */
83
- const getMorphoBlueMerklOpportunities = () => __awaiter(void 0, void 0, void 0, function* () {
85
+ const getMorphoBlueMerklOpportunities = (asOfTimestamp, chainId) => __awaiter(void 0, void 0, void 0, function* () {
84
86
  try {
85
- return yield (0, merkl_1.fetchAllMerklOpportunities)({
86
- mainProtocolId: 'morpho',
87
- type: Object.values(MorphoBlueMerklOpportunityType).join(','),
88
- status: types_1.OpportunityStatus.LIVE,
89
- });
87
+ return yield (0, merkl_1.fetchMerklOpportunities)(Object.assign({ mainProtocolId: 'morpho', type: Object.values(MorphoBlueMerklOpportunityType).join(','), status: types_1.OpportunityStatus.LIVE }, (chainId ? { chainId: chainId.toString() } : {})), asOfTimestamp);
90
88
  }
91
89
  catch (e) {
92
90
  console.error('Failed to fetch Morpho Blue Merkl campaigns', e);
@@ -1,13 +1,13 @@
1
1
  import { Client } from 'viem';
2
2
  import { Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances } from '../types/common';
3
3
  import { MorphoMidnightMarketData, MorphoMidnightMarketInfo, MorphoMidnightPositionData } from '../types';
4
- export declare function _getMorphoMidnightMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData): Promise<MorphoMidnightMarketInfo>;
5
- export declare function getMorphoMidnightMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData): Promise<MorphoMidnightMarketInfo>;
6
- export declare function _getMorphoMidnightAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo): Promise<MorphoMidnightPositionData>;
7
- export declare function getMorphoMidnightAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo): Promise<MorphoMidnightPositionData>;
4
+ export declare function _getMorphoMidnightMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData, blockNumber?: Blockish): Promise<MorphoMidnightMarketInfo>;
5
+ export declare function getMorphoMidnightMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData, blockNumber?: Blockish): Promise<MorphoMidnightMarketInfo>;
6
+ export declare function _getMorphoMidnightAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo, blockNumber?: Blockish): Promise<MorphoMidnightPositionData>;
7
+ export declare function getMorphoMidnightAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo, blockNumber?: Blockish): Promise<MorphoMidnightPositionData>;
8
8
  export declare const _getMorphoMidnightAccountBalances: (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoMidnightMarketData, includeCredit?: boolean) => Promise<PositionBalances>;
9
9
  export declare const getMorphoMidnightAccountBalances: (provider: EthereumProvider, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoMidnightMarketData) => Promise<PositionBalances>;
10
- export declare function getMorphoMidnightEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo): Promise<{
10
+ export declare function getMorphoMidnightEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo, blockNumber?: Blockish): Promise<{
11
11
  apy: string;
12
12
  amount: string;
13
13
  amountUsd: string;
@@ -31,8 +31,8 @@ const priceService_1 = require("../services/priceService");
31
31
  const viem_1 = require("../services/viem");
32
32
  const HARDCODED_USD_STABLE_PRICE = '100000000'; // $1 with 8 decimals
33
33
  const nowInSeconds = () => Math.floor(Date.now() / 1000);
34
- function _getMorphoMidnightMarketData(provider, network, selectedMarket) {
35
- return __awaiter(this, void 0, void 0, function* () {
34
+ function _getMorphoMidnightMarketData(provider_1, network_1, selectedMarket_1) {
35
+ return __awaiter(this, arguments, void 0, function* (provider, network, selectedMarket, blockNumber = 'latest') {
36
36
  const { loanToken, collaterals, marketId } = selectedMarket;
37
37
  const loanTokenInfo = (0, tokens_1.getAssetInfoByAddress)(loanToken, network);
38
38
  const loanSym = (0, utils_1.wethToEth)(loanTokenInfo.symbol);
@@ -44,8 +44,8 @@ function _getMorphoMidnightMarketData(provider, network, selectedMarket) {
44
44
  if ((0, utils_1.isMainnetNetwork)(network)) {
45
45
  const feedRegistryContract = (0, contracts_1.FeedRegistryContractViem)(provider, common_1.NetworkNumber.Eth);
46
46
  const [_loanTokenPrice, _marketInfo] = yield Promise.all([
47
- isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, constants_1.USD_QUOTE]),
48
- viewContract.read.getMarketInfo([marketId]),
47
+ isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, constants_1.USD_QUOTE], (0, viem_1.setViemBlockNumber)(blockNumber)),
48
+ viewContract.read.getMarketInfo([marketId], (0, viem_1.setViemBlockNumber)(blockNumber)),
49
49
  ]);
50
50
  marketInfo = _marketInfo;
51
51
  loanTokenPrice = _loanTokenPrice;
@@ -54,8 +54,8 @@ function _getMorphoMidnightMarketData(provider, network, selectedMarket) {
54
54
  // Currently only Base is supported
55
55
  const feedRegistryContract = (0, contracts_1.DFSFeedRegistryContractViem)(provider, network);
56
56
  const [loanTokenPriceRound, _marketInfo] = yield Promise.all([
57
- isHardcodedUsdStable ? Promise.resolve([0, HARDCODED_USD_STABLE_PRICE]) : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, constants_1.USD_QUOTE]),
58
- viewContract.read.getMarketInfo([marketId]),
57
+ isHardcodedUsdStable ? Promise.resolve([0, HARDCODED_USD_STABLE_PRICE]) : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, constants_1.USD_QUOTE], (0, viem_1.setViemBlockNumber)(blockNumber)),
58
+ viewContract.read.getMarketInfo([marketId], (0, viem_1.setViemBlockNumber)(blockNumber)),
59
59
  ]);
60
60
  marketInfo = _marketInfo;
61
61
  loanTokenPrice = loanTokenPriceRound[1].toString();
@@ -125,16 +125,16 @@ function _getMorphoMidnightMarketData(provider, network, selectedMarket) {
125
125
  };
126
126
  });
127
127
  }
128
- function getMorphoMidnightMarketData(provider, network, selectedMarket) {
129
- return __awaiter(this, void 0, void 0, function* () {
130
- return _getMorphoMidnightMarketData((0, viem_1.getViemProvider)(provider, network), network, selectedMarket);
128
+ function getMorphoMidnightMarketData(provider_1, network_1, selectedMarket_1) {
129
+ return __awaiter(this, arguments, void 0, function* (provider, network, selectedMarket, blockNumber = 'latest') {
130
+ return _getMorphoMidnightMarketData((0, viem_1.getViemProvider)(provider, network), network, selectedMarket, blockNumber);
131
131
  });
132
132
  }
133
- function _getMorphoMidnightAccountData(provider, network, account, selectedMarket, marketInfo) {
134
- return __awaiter(this, void 0, void 0, function* () {
133
+ function _getMorphoMidnightAccountData(provider_1, network_1, account_1, selectedMarket_1, marketInfo_1) {
134
+ return __awaiter(this, arguments, void 0, function* (provider, network, account, selectedMarket, marketInfo, blockNumber = 'latest') {
135
135
  const { marketId, collaterals } = selectedMarket;
136
136
  const viewContract = (0, contracts_1.MorphoMidnightViewContractViem)(provider, network);
137
- const positionInfo = yield viewContract.read.getPositionInfo([marketId, account]);
137
+ const positionInfo = yield viewContract.read.getPositionInfo([marketId, account], (0, viem_1.setViemBlockNumber)(blockNumber));
138
138
  const usedAssets = {};
139
139
  const loanTokenData = marketInfo.assetsData[marketInfo.loanToken];
140
140
  const credit = (0, tokens_1.assetAmountInEth)(positionInfo.credit.toString(), marketInfo.loanToken);
@@ -216,9 +216,9 @@ function _getMorphoMidnightAccountData(provider, network, account, selectedMarke
216
216
  borrowInfoStatus, maturity: marketInfo.maturity, isMatured: marketInfo.isMatured }, (0, morphoMidnightHelpers_1.getMorphoMidnightAggregatedPositionData)({ usedAssets, assetsData: assetsDataForApy, marketInfo }));
217
217
  });
218
218
  }
219
- function getMorphoMidnightAccountData(provider, network, account, selectedMarket, marketInfo) {
220
- return __awaiter(this, void 0, void 0, function* () {
221
- return _getMorphoMidnightAccountData((0, viem_1.getViemProvider)(provider, network), network, account, selectedMarket, marketInfo);
219
+ function getMorphoMidnightAccountData(provider_1, network_1, account_1, selectedMarket_1, marketInfo_1) {
220
+ return __awaiter(this, arguments, void 0, function* (provider, network, account, selectedMarket, marketInfo, blockNumber = 'latest') {
221
+ return _getMorphoMidnightAccountData((0, viem_1.getViemProvider)(provider, network), network, account, selectedMarket, marketInfo, blockNumber);
222
222
  });
223
223
  }
224
224
  const _getMorphoMidnightAccountBalances = (provider_1, network_1, block_1, addressMapping_1, address_1, selectedMarket_1, ...args_1) => __awaiter(void 0, [provider_1, network_1, block_1, addressMapping_1, address_1, selectedMarket_1, ...args_1], void 0, function* (provider, network, block, addressMapping, address, selectedMarket, includeCredit = false) {
@@ -253,11 +253,11 @@ const getMorphoMidnightAccountBalances = (provider, network, block, addressMappi
253
253
  exports.getMorphoMidnightAccountBalances = getMorphoMidnightAccountBalances;
254
254
  // Lender-side (credit-only) supply position, mirroring getMorphoEarn. `amount` is the credit face value
255
255
  // redeemable at maturity; `apy` is '0' in MVP because the fixed yield is orderbook-derived, not on-chain.
256
- function getMorphoMidnightEarn(provider, network, account, selectedMarket, marketInfo) {
257
- return __awaiter(this, void 0, void 0, function* () {
256
+ function getMorphoMidnightEarn(provider_1, network_1, account_1, selectedMarket_1, marketInfo_1) {
257
+ return __awaiter(this, arguments, void 0, function* (provider, network, account, selectedMarket, marketInfo, blockNumber = 'latest') {
258
258
  const { marketId } = selectedMarket;
259
259
  const viewContract = (0, contracts_1.MorphoMidnightViewContractViem)(provider, network);
260
- const positionInfo = yield viewContract.read.getPositionInfo([marketId, account]);
260
+ const positionInfo = yield viewContract.read.getPositionInfo([marketId, account], (0, viem_1.setViemBlockNumber)(blockNumber));
261
261
  const loanTokenData = marketInfo.assetsData[marketInfo.loanToken];
262
262
  const credit = (0, tokens_1.assetAmountInEth)(positionInfo.credit.toString(), marketInfo.loanToken);
263
263
  const creditUsd = new decimal_js_1.default(credit).mul(loanTokenData.price).toString();
@@ -44,16 +44,20 @@ const positive = (value) => new decimal_js_1.default(value || '0').gt(0);
44
44
  const supported = (list, network) => (Object.values(list).filter((m) => m.chainIds.includes(network)));
45
45
  function getCustomDeFiData(provider_1, network_1, defaultProvider_1, addresses_1) {
46
46
  return __awaiter(this, arguments, void 0, function* (provider, network, defaultProvider, addresses, options = {}) {
47
- var _a;
47
+ var _a, _b;
48
48
  const { protocols = Object.values(types_1.PortfolioProtocol), fetchStaking = false, fetchRewards = false, returnEmptyEModePositions = false, fetchFluidMarkets = false, isSim = false, } = options;
49
49
  // JSON-RPC body ends up ~4x the calldata cap; 250k keeps it under the ~2.5MB provider limit.
50
50
  const batchSize = (_a = options.batchSize) !== null && _a !== void 0 ? _a : (isSim ? 2000 : 250000);
51
51
  const has = (protocol) => protocols.includes(protocol);
52
52
  const isMainnet = network === common_1.NetworkNumber.Eth;
53
53
  const isFluidSupported = [common_1.NetworkNumber.Eth, common_1.NetworkNumber.Arb, common_1.NetworkNumber.Base, common_1.NetworkNumber.Plasma].includes(network);
54
- const pin = (p) => (options.blockNumber !== undefined ? (0, viem_1.pinProviderBlock)(p, options.blockNumber) : p);
55
- const client = (0, viem_1.getViemProvider)(pin(provider), network, { batch: { multicall: { batchSize } } });
56
- const defaultClient = (0, viem_1.getViemProvider)(pin(defaultProvider), network, { batch: { multicall: { batchSize } } });
54
+ const client = (0, viem_1.getViemProvider)(provider, network, { batch: { multicall: { batchSize } } });
55
+ const defaultClient = (0, viem_1.getViemProvider)(defaultProvider, network, { batch: { multicall: { batchSize } } });
56
+ // Every fetch below takes the block explicitly and passes it to each of its contract reads.
57
+ // Time-keyed sources (Merkl rewards) need the block's timestamp instead, resolved once here (no
58
+ // RPC call for 'latest') and handed to the market fetches so they don't each look it up.
59
+ const blockNumber = (_b = options.blockNumber) !== null && _b !== void 0 ? _b : 'latest';
60
+ const blockTimestamp = yield (0, viem_1.getBlockTimestamp)(client, blockNumber);
57
61
  const aaveV3Markets = has(types_1.PortfolioProtocol.AaveV3)
58
62
  ? [types_1.AaveVersions.AaveV3, types_1.AaveVersions.AaveV3Lido, types_1.AaveVersions.AaveV3Etherfi].map((v) => (0, markets_1.AaveMarkets)(network)[v]).filter((m) => m.chainIds.includes(network))
59
63
  : [];
@@ -145,22 +149,22 @@ function getCustomDeFiData(provider_1, network_1, defaultProvider_1, addresses_1
145
149
  }
146
150
  }))();
147
151
  yield Promise.allSettled([
148
- ...morphoMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.morphoMarketsData[m.value] = yield (0, morphoBlue_1._getMorphoBluePortfolioMarketData)(client, network, m); })),
149
- ...morphoMidnightMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.morphoMidnightMarketsData[m.value] = yield (0, morphoMidnight_1._getMorphoMidnightMarketData)(client, network, m); })),
150
- ...compoundV3Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.compoundV3MarketsData[m.value] = yield (0, compoundV3_1._getCompoundV3MarketsData)(client, network, m, defaultClient); })),
151
- ...sparkMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.sparkMarketsData[m.value] = yield (0, spark_1._getSparkMarketsData)(client, network, m); })),
152
- ...aaveV3Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.aaveV3MarketsData[m.value] = yield (0, aaveV3_1._getAaveV3MarketData)(client, network, m); })),
153
- ...aaveV4Spokes.map((s) => __awaiter(this, void 0, void 0, function* () { markets.aaveV4SpokesData[s.value] = yield (0, aaveV4_1._getAaveV4SpokeData)(client, network, s); })),
154
- ...aaveV2Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.aaveV2MarketsData[m.value] = yield (0, aaveV2_1._getAaveV2MarketsData)(client, network, m); })),
155
- ...compoundV2Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.compoundV2MarketsData[m.value] = yield (0, compoundV2_1._getCompoundV2MarketsData)(client, network); })),
156
- ...crvUsdMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.crvUsdMarketsData[m.value] = yield (0, curveUsd_1._getCurveUsdGlobalData)(client, network, m); })),
157
- ...llamaLendMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.llamaLendMarketsData[m.value] = yield (0, llamaLend_1._getLlamaLendGlobalData)(client, network, m); })),
158
- ...liquityV2Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.liquityV2MarketsData[m.value] = yield (0, liquityV2_1._getLiquityV2MarketData)(client, network, m); })),
152
+ ...morphoMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.morphoMarketsData[m.value] = yield (0, morphoBlue_1._getMorphoBluePortfolioMarketData)(client, network, m, blockNumber); })),
153
+ ...morphoMidnightMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.morphoMidnightMarketsData[m.value] = yield (0, morphoMidnight_1._getMorphoMidnightMarketData)(client, network, m, blockNumber); })),
154
+ ...compoundV3Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.compoundV3MarketsData[m.value] = yield (0, compoundV3_1._getCompoundV3MarketsData)(client, network, m, defaultClient, blockNumber, blockTimestamp); })),
155
+ ...sparkMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.sparkMarketsData[m.value] = yield (0, spark_1._getSparkMarketsData)(client, network, m, blockNumber); })),
156
+ ...aaveV3Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.aaveV3MarketsData[m.value] = yield (0, aaveV3_1._getAaveV3MarketData)(client, network, m, blockNumber, blockTimestamp); })),
157
+ ...aaveV4Spokes.map((s) => __awaiter(this, void 0, void 0, function* () { markets.aaveV4SpokesData[s.value] = yield (0, aaveV4_1._getAaveV4SpokeData)(client, network, s, blockNumber, blockTimestamp); })),
158
+ ...aaveV2Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.aaveV2MarketsData[m.value] = yield (0, aaveV2_1._getAaveV2MarketsData)(client, network, m, blockNumber); })),
159
+ ...compoundV2Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.compoundV2MarketsData[m.value] = yield (0, compoundV2_1._getCompoundV2MarketsData)(client, network, blockNumber); })),
160
+ ...crvUsdMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.crvUsdMarketsData[m.value] = yield (0, curveUsd_1._getCurveUsdGlobalData)(client, network, m, blockNumber); })),
161
+ ...llamaLendMarkets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.llamaLendMarketsData[m.value] = yield (0, llamaLend_1._getLlamaLendGlobalData)(client, network, m, blockNumber); })),
162
+ ...liquityV2Markets.map((m) => __awaiter(this, void 0, void 0, function* () { markets.liquityV2MarketsData[m.value] = yield (0, liquityV2_1._getLiquityV2MarketData)(client, network, m, blockNumber); })),
159
163
  (() => __awaiter(this, void 0, void 0, function* () {
160
164
  if (!fetchFluid || !fetchFluidMarkets)
161
165
  return;
162
166
  try {
163
- markets.fluidMarketsData = yield (0, fluid_1._getAllFluidMarketDataPortfolio)(client, network);
167
+ markets.fluidMarketsData = yield (0, fluid_1._getAllFluidMarketDataPortfolio)(client, network, blockNumber, blockTimestamp);
164
168
  }
165
169
  catch (error) {
166
170
  console.error('Error fetching Fluid markets data:', error);
@@ -170,7 +174,7 @@ function getCustomDeFiData(provider_1, network_1, defaultProvider_1, addresses_1
170
174
  if (!fetchMaker)
171
175
  return;
172
176
  try {
173
- markets.makerMarketsData = yield (0, maker_1._getMakerIlksData)(client, network, markets_1.MakerActiveIlks);
177
+ markets.makerMarketsData = yield (0, maker_1._getMakerIlksData)(client, network, markets_1.MakerActiveIlks, blockNumber);
174
178
  }
175
179
  catch (error) {
176
180
  console.error('Error fetching Maker ilks data:', error);
@@ -179,78 +183,78 @@ function getCustomDeFiData(provider_1, network_1, defaultProvider_1, addresses_1
179
183
  ...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
180
184
  if (!fetchMaker)
181
185
  return;
182
- makerCdps[lower(address)] = yield (0, maker_1._getUserCdps)(client, network, address);
186
+ makerCdps[lower(address)] = yield (0, maker_1._getUserCdps)(client, network, address, blockNumber);
183
187
  })),
184
- ...addresses.map((address) => fetchFluid && run(`Fluid positions for address ${address}`, () => (0, fluid_1._getUserPositionsPortfolio)(client, network, address), (userPositions) => {
188
+ ...addresses.map((address) => fetchFluid && run(`Fluid positions for address ${address}`, () => (0, fluid_1._getUserPositionsPortfolio)(client, network, address, blockNumber), (userPositions) => {
185
189
  for (const position of userPositions) {
186
190
  if (position.userData && positive(position.userData.suppliedUsd))
187
191
  positions[lower(address)].fluid.data[position.userData.nftId] = position.userData;
188
192
  }
189
193
  }, (err) => { positions[lower(address)].fluid = { error: err.error, data: {} }; })),
190
194
  ...(fetchStaking ? [
191
- ...addresses.map((address) => fetchFluid && run(`Fluid lend data for address ${address}`, () => (0, fluid_1._getAllUserEarnPositionsWithFTokens)(client, network, address), (data) => { stakingPositions[lower(address)].fluid = data; }, (err) => { stakingPositions[lower(address)].fluid = err; })),
192
- ...addresses.map((address) => fetchLiquity && run(`Liquity staking data for address ${address}`, () => (0, liquity_1.getLiquityStakingData)(client, network, address), (data) => { stakingPositions[lower(address)].liquity = data; }, (err) => { stakingPositions[lower(address)].liquity = err; })),
193
- ...addresses.map((address) => has(types_1.PortfolioProtocol.AaveV3) && isMainnet && run(`Aave V3 staking data for address ${address}`, () => (0, aaveV3_1.getStakeAaveData)(client, network, address), (data) => { stakingPositions[lower(address)].aaveV3 = data; }, (err) => { stakingPositions[lower(address)].aaveV3 = err; })),
194
- ...addresses.map((address) => has(types_1.PortfolioProtocol.AaveV3) && isMainnet && run(`Umbrella staking data for address ${address}`, () => (0, umbrella_1.getUmbrellaData)(client, network, address), (data) => { stakingPositions[lower(address)].umbrella = data; }, (err) => { stakingPositions[lower(address)].umbrella = err; })),
195
- ...perAddress(liquityV2StakingMarkets, (market, address) => run(`Liquity V2 staking data for address ${address}, market ${market.value}`, () => (0, liquityV2_1.getLiquityV2Staking)(client, network, market.value, address), (data) => { stakingPositions[lower(address)].liquityV2[market.value] = { error: '', data }; }, (err) => { stakingPositions[lower(address)].liquityV2[market.value] = err; })),
195
+ ...addresses.map((address) => fetchFluid && run(`Fluid lend data for address ${address}`, () => (0, fluid_1._getAllUserEarnPositionsWithFTokens)(client, network, address, blockNumber), (data) => { stakingPositions[lower(address)].fluid = data; }, (err) => { stakingPositions[lower(address)].fluid = err; })),
196
+ ...addresses.map((address) => fetchLiquity && run(`Liquity staking data for address ${address}`, () => (0, liquity_1.getLiquityStakingData)(client, network, address, blockNumber), (data) => { stakingPositions[lower(address)].liquity = data; }, (err) => { stakingPositions[lower(address)].liquity = err; })),
197
+ ...addresses.map((address) => has(types_1.PortfolioProtocol.AaveV3) && isMainnet && run(`Aave V3 staking data for address ${address}`, () => (0, aaveV3_1.getStakeAaveData)(client, network, address, blockNumber), (data) => { stakingPositions[lower(address)].aaveV3 = data; }, (err) => { stakingPositions[lower(address)].aaveV3 = err; })),
198
+ ...addresses.map((address) => has(types_1.PortfolioProtocol.AaveV3) && isMainnet && run(`Umbrella staking data for address ${address}`, () => (0, umbrella_1.getUmbrellaData)(client, network, address, blockNumber), (data) => { stakingPositions[lower(address)].umbrella = data; }, (err) => { stakingPositions[lower(address)].umbrella = err; })),
199
+ ...perAddress(liquityV2StakingMarkets, (market, address) => run(`Liquity V2 staking data for address ${address}, market ${market.value}`, () => (0, liquityV2_1.getLiquityV2Staking)(client, network, market.value, address, blockNumber), (data) => { stakingPositions[lower(address)].liquityV2[market.value] = { error: '', data }; }, (err) => { stakingPositions[lower(address)].liquityV2[market.value] = err; })),
196
200
  ] : []),
197
201
  ...(fetchRewards ? [
198
- batchRewards('king', 'King rewards data', () => (0, king_1.getKingRewards)(client, network, addresses), isMainnet),
199
- batchRewards('uniswap', 'Uniswap rewards data', () => (0, uniswap_1.getUniswapRewards)(client, network, addresses), isMainnet),
200
- batchRewards('spk', 'Spark Airdrop rewards data', () => (0, spark_2.fetchSparkAirdropRewards)(client, network, addresses), isMainnet && has(types_1.PortfolioProtocol.Spark)),
202
+ batchRewards('king', 'King rewards data', () => (0, king_1.getKingRewards)(client, network, addresses, blockNumber), isMainnet),
203
+ batchRewards('uniswap', 'Uniswap rewards data', () => (0, uniswap_1.getUniswapRewards)(client, network, addresses, blockNumber), isMainnet),
204
+ batchRewards('spk', 'Spark Airdrop rewards data', () => (0, spark_2.fetchSparkAirdropRewards)(client, network, addresses, blockNumber), isMainnet && has(types_1.PortfolioProtocol.Spark)),
201
205
  batchRewards('ethena', 'Ethena Airdrop rewards data', () => (0, ethena_1.fetchEthenaAirdropRewards)(addresses), isMainnet),
202
206
  ...addresses.map((address) => run(`Merkl rewards data for address ${address}`, () => (0, aaveV3_2.getMerklUnclaimedRewards)(address, network), (data) => { rewardsData[lower(address)].merkl = { error: '', data }; }, (err) => { rewardsData[lower(address)].merkl = err; })),
203
- ...perAddress(aaveV3Markets, (market, address) => run(`Aave V3 rewards data for address ${address}, market ${market.value}`, () => (0, aaveV3_2.getUnclaimedRewardsForAllMarkets)(client, network, address, market.providerAddress), (data) => { rewardsData[lower(address)].aaveV3[market.value] = { error: '', data }; }, (err) => { rewardsData[lower(address)].aaveV3[market.value] = err; })),
207
+ ...perAddress(aaveV3Markets, (market, address) => run(`Aave V3 rewards data for address ${address}, market ${market.value}`, () => (0, aaveV3_2.getUnclaimedRewardsForAllMarkets)(client, network, address, market.providerAddress, blockNumber), (data) => { rewardsData[lower(address)].aaveV3[market.value] = { error: '', data }; }, (err) => { rewardsData[lower(address)].aaveV3[market.value] = err; })),
204
208
  ...perAddress(sparkMarkets, (market, address) => {
205
209
  if (!isMainnet) {
206
210
  rewardsData[lower(address)].spark[market.value] = { error: '', data: [] };
207
211
  return Promise.resolve();
208
212
  }
209
- return run(`Spark rewards data for address ${address}, market ${market.value}`, () => (0, spark_2.fetchSparkRewards)(client, network, address, market.providerAddress), (data) => { rewardsData[lower(address)].spark[market.value] = { error: '', data }; }, (err) => { rewardsData[lower(address)].spark[market.value] = err; });
213
+ return run(`Spark rewards data for address ${address}, market ${market.value}`, () => (0, spark_2.fetchSparkRewards)(client, network, address, market.providerAddress, blockNumber), (data) => { rewardsData[lower(address)].spark[market.value] = { error: '', data }; }, (err) => { rewardsData[lower(address)].spark[market.value] = err; });
210
214
  }),
211
215
  ] : []),
212
216
  ]);
213
217
  yield Promise.all([
214
- ...perAddress(aaveV3Markets, (market, address) => run(`AaveV3 account data for address ${address} on market ${market.value}`, () => (0, aaveV3_1._getAaveV3AccountData)(client, network, address, Object.assign({ selectedMarket: market }, markets.aaveV3MarketsData[market.value])), (data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd))
218
+ ...perAddress(aaveV3Markets, (market, address) => run(`AaveV3 account data for address ${address} on market ${market.value}`, () => (0, aaveV3_1._getAaveV3AccountData)(client, network, address, Object.assign({ selectedMarket: market }, markets.aaveV3MarketsData[market.value]), blockNumber), (data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd))
215
219
  positions[lower(address)].aaveV3[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].aaveV3[market.value] = err; })),
216
- ...perAddress(sparkMarkets, (market, address) => run(`Spark account data for address ${address} on market ${market.value}`, () => (0, spark_1._getSparkAccountData)(client, network, address, { selectedMarket: market, assetsData: markets.sparkMarketsData[market.value].assetsData, eModeCategoriesData: markets.sparkMarketsData[market.value].eModeCategoriesData }), (data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd))
220
+ ...perAddress(sparkMarkets, (market, address) => run(`Spark account data for address ${address} on market ${market.value}`, () => (0, spark_1._getSparkAccountData)(client, network, address, { selectedMarket: market, assetsData: markets.sparkMarketsData[market.value].assetsData, eModeCategoriesData: markets.sparkMarketsData[market.value].eModeCategoriesData }, blockNumber), (data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd))
217
221
  positions[lower(address)].spark[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].spark[market.value] = err; })),
218
- ...perAddress(aaveV4Spokes, (spoke, address) => run(`AaveV4 account data for address ${address} on spoke ${spoke.value}`, () => (0, aaveV4_1._getAaveV4AccountData)(client, network, markets.aaveV4SpokesData[spoke.value], address), (data) => { if (positive(data.suppliedUsd))
222
+ ...perAddress(aaveV4Spokes, (spoke, address) => run(`AaveV4 account data for address ${address} on spoke ${spoke.value}`, () => (0, aaveV4_1._getAaveV4AccountData)(client, network, markets.aaveV4SpokesData[spoke.value], address, blockNumber), (data) => { if (positive(data.suppliedUsd))
219
223
  positions[lower(address)].aaveV4[spoke.value] = { error: '', data }; }, (err) => { positions[lower(address)].aaveV4[spoke.value] = err; })),
220
- ...perAddress(morphoMarkets, (market, address) => run(`MorphoBlue account data for address ${address} on market ${market.value}`, () => (0, morphoBlue_1._getMorphoBlueAccountData)(client, network, address, market, markets.morphoMarketsData[market.value]), (data) => { if (positive(data.suppliedUsd))
224
+ ...perAddress(morphoMarkets, (market, address) => run(`MorphoBlue account data for address ${address} on market ${market.value}`, () => (0, morphoBlue_1._getMorphoBlueAccountData)(client, network, address, market, markets.morphoMarketsData[market.value], blockNumber), (data) => { if (positive(data.suppliedUsd))
221
225
  positions[lower(address)].morphoBlue[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].morphoBlue[market.value] = err; })),
222
- ...(fetchStaking ? perAddress(morphoMarkets, (market, address) => run(`MorphoBlue earn data for address ${address} on market ${market.value}`, () => (0, morphoBlue_1.getMorphoEarn)(client, network, address, market, markets.morphoMarketsData[market.value]), (data) => { if (data && positive(data.amount))
226
+ ...(fetchStaking ? perAddress(morphoMarkets, (market, address) => run(`MorphoBlue earn data for address ${address} on market ${market.value}`, () => (0, morphoBlue_1.getMorphoEarn)(client, network, address, market, markets.morphoMarketsData[market.value], blockNumber), (data) => { if (data && positive(data.amount))
223
227
  stakingPositions[lower(address)].morphoBlue[market.value] = { error: '', data }; }, (err) => { stakingPositions[lower(address)].morphoBlue[market.value] = err; })) : []),
224
228
  ...perAddress(morphoMidnightMarkets, (market, address) => {
225
229
  var _a;
226
230
  if (!((_a = markets.morphoMidnightMarketsData[market.value]) === null || _a === void 0 ? void 0 : _a.isCreated))
227
231
  return Promise.resolve();
228
- return run(`MorphoMidnight account data for address ${address} on market ${market.value}`, () => (0, morphoMidnight_1._getMorphoMidnightAccountData)(client, network, address, market, markets.morphoMidnightMarketsData[market.value]), (data) => { if (positive(data.suppliedUsd))
232
+ return run(`MorphoMidnight account data for address ${address} on market ${market.value}`, () => (0, morphoMidnight_1._getMorphoMidnightAccountData)(client, network, address, market, markets.morphoMidnightMarketsData[market.value], blockNumber), (data) => { if (positive(data.suppliedUsd))
229
233
  positions[lower(address)].morphoMidnight[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].morphoMidnight[market.value] = err; });
230
234
  }),
231
- ...perAddress(compoundV3Markets, (market, address) => run(`CompoundV3 account data for address ${address} on market ${market.value}`, () => (0, compoundV3_1._getCompoundV3AccountData)(client, network, address, constants_1.ZERO_ADDRESS, { selectedMarket: market, assetsData: markets.compoundV3MarketsData[market.value].assetsData }), (data) => { if (positive(data.suppliedUsd))
235
+ ...perAddress(compoundV3Markets, (market, address) => run(`CompoundV3 account data for address ${address} on market ${market.value}`, () => (0, compoundV3_1._getCompoundV3AccountData)(client, network, address, constants_1.ZERO_ADDRESS, { selectedMarket: market, assetsData: markets.compoundV3MarketsData[market.value].assetsData }, blockNumber), (data) => { if (positive(data.suppliedUsd))
232
236
  positions[lower(address)].compoundV3[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].compoundV3[market.value] = err; })),
233
- ...perAddress(compoundV2Markets, (market, address) => run(`CompoundV2 account data for address ${address}`, () => (0, compoundV2_1._getCompoundV2AccountData)(client, network, address, markets.compoundV2MarketsData[market.value].assetsData), (data) => { if (positive(data.suppliedUsd))
237
+ ...perAddress(compoundV2Markets, (market, address) => run(`CompoundV2 account data for address ${address}`, () => (0, compoundV2_1._getCompoundV2AccountData)(client, network, address, markets.compoundV2MarketsData[market.value].assetsData, blockNumber), (data) => { if (positive(data.suppliedUsd))
234
238
  positions[lower(address)].compoundV2[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].compoundV2[market.value] = err; })),
235
- ...perAddress(aaveV2Markets, (market, address) => run(`AaveV2 account data for address ${address}`, () => (0, aaveV2_1._getAaveV2AccountData)(client, network, address, markets.aaveV2MarketsData[market.value].assetsData, market), (data) => { if (positive(data.suppliedUsd))
239
+ ...perAddress(aaveV2Markets, (market, address) => run(`AaveV2 account data for address ${address}`, () => (0, aaveV2_1._getAaveV2AccountData)(client, network, address, markets.aaveV2MarketsData[market.value].assetsData, market, blockNumber), (data) => { if (positive(data.suppliedUsd))
236
240
  positions[lower(address)].aaveV2[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].aaveV2[market.value] = err; })),
237
- ...perAddress(crvUsdMarkets, (market, address) => run(`Curve USD account data for address ${address} on market ${market.value}`, () => (0, curveUsd_1._getCurveUsdUserData)(client, network, address, market, markets.crvUsdMarketsData[market.value].activeBand, markets.crvUsdMarketsData[market.value].borrowRate), (data) => { if (positive(data.suppliedUsd) || positive(data.borrowedUsd))
241
+ ...perAddress(crvUsdMarkets, (market, address) => run(`Curve USD account data for address ${address} on market ${market.value}`, () => (0, curveUsd_1._getCurveUsdUserData)(client, network, address, market, markets.crvUsdMarketsData[market.value].activeBand, markets.crvUsdMarketsData[market.value].borrowRate, blockNumber), (data) => { if (positive(data.suppliedUsd) || positive(data.borrowedUsd))
238
242
  positions[lower(address)].crvUsd[market.value] = { error: '', data }; }, (err) => { positions[lower(address)].crvUsd[market.value] = err; })),
239
- ...perAddress(llamaLendMarkets, (market, address) => run(`LlamaLend account data for address ${address} on market ${market.value}`, () => (0, llamaLend_1._getLlamaLendUserData)(client, network, address, market, markets.llamaLendMarketsData[market.value]), (data) => {
243
+ ...perAddress(llamaLendMarkets, (market, address) => run(`LlamaLend account data for address ${address} on market ${market.value}`, () => (0, llamaLend_1._getLlamaLendUserData)(client, network, address, market, markets.llamaLendMarketsData[market.value], blockNumber), (data) => {
240
244
  if (positive(data.suppliedUsd) || positive(data.borrowedUsd)) {
241
245
  positions[lower(address)].llamaLend[market.value] = { error: '', data: Object.assign(Object.assign({}, data), { borrowRate: markets.llamaLendMarketsData[market.value].borrowRate }) };
242
246
  }
243
247
  }, (err) => { positions[lower(address)].llamaLend[market.value] = err; })),
244
- ...addresses.map((address) => (makerCdps[lower(address)] || []).map((cdpInfo) => run(`Maker CDP data for address ${address} with ID ${cdpInfo.id}`, () => (0, maker_1._getMakerCdpData)(client, network, cdpInfo, markets.makerMarketsData[cdpInfo.ilkLabel]), (data) => { if (data)
248
+ ...addresses.map((address) => (makerCdps[lower(address)] || []).map((cdpInfo) => run(`Maker CDP data for address ${address} with ID ${cdpInfo.id}`, () => (0, maker_1._getMakerCdpData)(client, network, cdpInfo, markets.makerMarketsData[cdpInfo.ilkLabel], blockNumber), (data) => { if (data)
245
249
  positions[lower(address)].maker[cdpInfo.id] = { error: '', data }; }, (err) => { positions[lower(address)].maker[cdpInfo.id] = err; }))).flat(),
246
- ...addresses.map((address) => fetchLiquity && run(`Liquity trove info for address ${address}`, () => (0, liquity_1._getLiquityTroveInfo)(client, network, address), (data) => { if (positive(data.collateral))
250
+ ...addresses.map((address) => fetchLiquity && run(`Liquity trove info for address ${address}`, () => (0, liquity_1._getLiquityTroveInfo)(client, network, address, blockNumber), (data) => { if (positive(data.collateral))
247
251
  positions[lower(address)].liquity = { error: '', data }; }, (err) => { positions[lower(address)].liquity = err; })),
248
252
  ...(fetchStaking && has(types_1.PortfolioProtocol.LiquityV2) ? addresses.map((address) => {
249
253
  if (!isMainnet) {
250
254
  stakingPositions[lower(address)].liquityV2SBoldYBold = { error: '', data: null };
251
255
  return Promise.resolve();
252
256
  }
253
- return run(`sBold/yBold data for address ${address}`, () => (0, liquityV2_1.getLiquitySAndYBold)(client, network, stakingPositions[lower(address)].liquityV2, address), (data) => { stakingPositions[lower(address)].liquityV2SBoldYBold = { error: '', data }; }, (err) => { stakingPositions[lower(address)].liquityV2SBoldYBold = err; });
257
+ return run(`sBold/yBold data for address ${address}`, () => (0, liquityV2_1.getLiquitySAndYBold)(client, network, stakingPositions[lower(address)].liquityV2, address, blockNumber), (data) => { stakingPositions[lower(address)].liquityV2SBoldYBold = { error: '', data }; }, (err) => { stakingPositions[lower(address)].liquityV2SBoldYBold = err; });
254
258
  }) : []),
255
259
  ]);
256
260
  return {
@@ -1,6 +1,48 @@
1
- import { MerklOpportunity } from '../types';
1
+ import { MerklCampaignListItem, MerklOpportunity } from '../types';
2
2
  /**
3
- * Fetches every page matching the query. Merkl returns 20 opportunities by default, so omitting
3
+ * Fetches every opportunity matching the query. Merkl returns 20 opportunities by default, so omitting
4
4
  * `items` and advancing `page` avoids imposing a client-side maximum on the result set.
5
5
  */
6
6
  export declare const fetchAllMerklOpportunities: (query: Record<string, string>) => Promise<MerklOpportunity[]>;
7
+ /** Fetches every campaign matching the query, e.g. `{ mainProtocolId: 'aave', status: 'LIVE,PAST' }`. */
8
+ export declare const fetchAllMerklCampaigns: (query: Record<string, string>) => Promise<MerklCampaignListItem[]>;
9
+ /**
10
+ * Fetches the opportunities with the given Merkl-internal ids, regardless of their current status.
11
+ * Ids Merkl no longer serves (hidden or test campaigns) are simply absent from the result.
12
+ */
13
+ export declare const fetchMerklOpportunitiesByIds: (ids: string[]) => Promise<MerklOpportunity[]>;
14
+ /**
15
+ * Returns the reward APR Merkl recorded for the opportunity at the given unix timestamp (seconds),
16
+ * or `undefined` when no campaign was computing for it then. Records are hourly buckets keyed by
17
+ * their start, newest first, so the bucket of the timestamp's hour carries the value in force at
18
+ * that moment; the window is a day wide to tolerate computation gaps. The window is aligned to the
19
+ * hour, so every block within one hour asks for (and caches) the same records.
20
+ */
21
+ export declare const fetchMerklOpportunityAprAt: (opportunityId: string, timestamp: number) => Promise<number | undefined>;
22
+ /** Drops every cached historical response (campaign lists, opportunities, APR buckets). */
23
+ export declare const clearMerklHistoryCache: () => void;
24
+ /**
25
+ * Reconstructs the opportunities that were live at `timestamp` (unix seconds), shaped like the
26
+ * live listing so the per-protocol reward mappers can consume either without knowing which they got:
27
+ * 1. every LIVE or PAST campaign for the protocol (and chain, when the query names one) is listed
28
+ * once per cache period — the list is block-independent, the exact window check happens here —
29
+ * and the ones whose [start, end] covers the timestamp identify the opportunities rewarded
30
+ * then (the live listing can't: campaigns live then are mostly PAST now and ones live now
31
+ * didn't exist then);
32
+ * 2. those opportunities are loaded by id (works for PAST ones too) and narrowed to `query.type`
33
+ * and `isRelevant`, so no APR history is fetched for opportunities the caller would discard;
34
+ * 3. each one's `apr` is replaced with the value Merkl recorded at the timestamp, and ones with no
35
+ * record then are dropped, since nothing was being computed for them.
36
+ * `status` is forced to LIVE so status filters downstream keep working, `campaigns` carries the
37
+ * covering campaigns, and a reward token breakdown is synthesized from the campaign's reward token
38
+ * when Merkl no longer serves one for the opportunity (it drops them once an opportunity is PAST).
39
+ * `query.status` is ignored: it describes the present, not the requested moment.
40
+ */
41
+ export declare const fetchMerklOpportunitiesAt: (query: Record<string, string>, timestamp: number, isRelevant?: (opportunity: MerklOpportunity) => boolean) => Promise<MerklOpportunity[]>;
42
+ /**
43
+ * Live opportunities when no timestamp is given, otherwise the opportunities as they were at that
44
+ * unix timestamp (seconds) — see `fetchMerklOpportunitiesAt`. `isRelevant` only applies to the
45
+ * historical path, where it saves fetching APR history for opportunities the caller would discard;
46
+ * callers still filter the live listing themselves.
47
+ */
48
+ export declare const fetchMerklOpportunities: (query: Record<string, string>, asOfTimestamp?: number, isRelevant?: (opportunity: MerklOpportunity) => boolean) => Promise<MerklOpportunity[]>;