@defisaver/positions-sdk 2.1.168 → 2.1.169-portfolio-api-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 (94) hide show
  1. package/cjs/aaveV3/index.d.ts +2 -12
  2. package/cjs/aaveV3/sgho.d.ts +2 -16
  3. package/cjs/aaveV4/lend.d.ts +2 -43
  4. package/cjs/claiming/aaveV3.d.ts +2 -2
  5. package/cjs/claiming/ethena.d.ts +2 -1
  6. package/cjs/claiming/king.d.ts +2 -1
  7. package/cjs/claiming/spark.d.ts +2 -2
  8. package/cjs/fluid/index.d.ts +5 -49
  9. package/cjs/liquity/index.d.ts +2 -12
  10. package/cjs/liquityV2/index.d.ts +8 -23
  11. package/cjs/liquityV2/index.js +37 -19
  12. package/cjs/portfolio/index.d.ts +16 -8
  13. package/cjs/portfolio/index.js +458 -520
  14. package/cjs/portfolio/lendingProtocols.d.ts +184 -0
  15. package/cjs/portfolio/lendingProtocols.js +196 -0
  16. package/cjs/savings/index.d.ts +8 -2
  17. package/cjs/savings/index.js +33 -4
  18. package/cjs/types/aave.d.ts +98 -2
  19. package/cjs/types/aaveV4.d.ts +44 -0
  20. package/cjs/types/compound.d.ts +26 -2
  21. package/cjs/types/curveUsd.d.ts +9 -1
  22. package/cjs/types/fluid.d.ts +13 -0
  23. package/cjs/types/index.d.ts +1 -0
  24. package/cjs/types/index.js +1 -0
  25. package/cjs/types/liquity.d.ts +12 -0
  26. package/cjs/types/liquityV2.d.ts +24 -0
  27. package/cjs/types/llamaLend.d.ts +12 -1
  28. package/cjs/types/morphoBlue.d.ts +2 -0
  29. package/cjs/types/portfolio.d.ts +125 -5
  30. package/cjs/types/savings/index.d.ts +9 -1
  31. package/cjs/types/spark.d.ts +21 -1
  32. package/cjs/umbrella/index.d.ts +2 -3
  33. package/esm/aaveV3/index.d.ts +2 -12
  34. package/esm/aaveV3/sgho.d.ts +2 -16
  35. package/esm/aaveV4/lend.d.ts +2 -43
  36. package/esm/claiming/aaveV3.d.ts +2 -2
  37. package/esm/claiming/aaveV3.js +1 -1
  38. package/esm/claiming/ethena.d.ts +2 -1
  39. package/esm/claiming/king.d.ts +2 -1
  40. package/esm/claiming/spark.d.ts +2 -2
  41. package/esm/claiming/spark.js +1 -1
  42. package/esm/fluid/index.d.ts +5 -49
  43. package/esm/liquity/index.d.ts +2 -12
  44. package/esm/liquityV2/index.d.ts +8 -23
  45. package/esm/liquityV2/index.js +35 -18
  46. package/esm/portfolio/index.d.ts +16 -8
  47. package/esm/portfolio/index.js +458 -522
  48. package/esm/portfolio/lendingProtocols.d.ts +184 -0
  49. package/esm/portfolio/lendingProtocols.js +189 -0
  50. package/esm/savings/index.d.ts +8 -2
  51. package/esm/savings/index.js +31 -3
  52. package/esm/types/aave.d.ts +98 -2
  53. package/esm/types/aaveV4.d.ts +44 -0
  54. package/esm/types/compound.d.ts +26 -2
  55. package/esm/types/curveUsd.d.ts +9 -1
  56. package/esm/types/fluid.d.ts +13 -0
  57. package/esm/types/index.d.ts +1 -0
  58. package/esm/types/index.js +1 -0
  59. package/esm/types/liquity.d.ts +12 -0
  60. package/esm/types/liquityV2.d.ts +24 -0
  61. package/esm/types/llamaLend.d.ts +12 -1
  62. package/esm/types/morphoBlue.d.ts +2 -0
  63. package/esm/types/portfolio.d.ts +125 -5
  64. package/esm/types/savings/index.d.ts +9 -1
  65. package/esm/types/spark.d.ts +21 -1
  66. package/esm/umbrella/index.d.ts +2 -3
  67. package/package.json +1 -1
  68. package/src/aaveV3/index.ts +2 -1
  69. package/src/aaveV3/sgho.ts +2 -17
  70. package/src/aaveV4/lend.ts +2 -48
  71. package/src/claiming/aaveV3.ts +4 -2
  72. package/src/claiming/ethena.ts +5 -5
  73. package/src/claiming/king.ts +3 -3
  74. package/src/claiming/spark.ts +6 -4
  75. package/src/fluid/index.ts +4 -3
  76. package/src/liquity/index.ts +2 -2
  77. package/src/liquityV2/index.ts +48 -22
  78. package/src/portfolio/index.ts +306 -331
  79. package/src/portfolio/lendingProtocols.ts +281 -0
  80. package/src/savings/index.ts +41 -4
  81. package/src/types/aave.ts +104 -1
  82. package/src/types/aaveV4.ts +49 -0
  83. package/src/types/compound.ts +38 -2
  84. package/src/types/curveUsd.ts +17 -1
  85. package/src/types/fluid.ts +14 -0
  86. package/src/types/index.ts +1 -0
  87. package/src/types/liquity.ts +13 -1
  88. package/src/types/liquityV2.ts +26 -1
  89. package/src/types/llamaLend.ts +19 -1
  90. package/src/types/morphoBlue.ts +3 -0
  91. package/src/types/portfolio.ts +151 -5
  92. package/src/types/savings/index.ts +12 -1
  93. package/src/types/spark.ts +25 -1
  94. package/src/umbrella/index.ts +2 -1
@@ -3,7 +3,7 @@ import { assetAmountInEth } from '@defisaver/tokens';
3
3
  import { Client } from 'viem';
4
4
  import { UUPSViem } from '../contracts';
5
5
  import { EthAddress, HexString, NetworkNumber } from '../types/common';
6
- import { ClaimType } from '../types/claiming';
6
+ import { ClaimType, KingRewardsClaimableToken } from '../types/claiming';
7
7
 
8
8
  export const fetchKingRewards = async (walletAddress: EthAddress) => {
9
9
  try {
@@ -19,7 +19,7 @@ export const fetchKingRewards = async (walletAddress: EthAddress) => {
19
19
  }
20
20
  };
21
21
 
22
- export const getKingRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => {
22
+ export const getKingRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]): Promise<Record<string, KingRewardsClaimableToken[]>> => {
23
23
  // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
24
24
  const apiDataPromises = walletAddresses.map(address => fetchKingRewards(address));
25
25
  const apiDataArray = await Promise.all(apiDataPromises);
@@ -31,7 +31,7 @@ export const getKingRewards = async (provider: Client, network: NetworkNumber, w
31
31
  const cumulativeResults = await Promise.all(cumulativePromises);
32
32
 
33
33
  // Process results
34
- const results: Record<string, any[]> = {};
34
+ const results: Record<string, KingRewardsClaimableToken[]> = {};
35
35
 
36
36
  for (let i = 0; i < walletAddresses.length; i++) {
37
37
  const walletAddress = walletAddresses[i];
@@ -7,7 +7,9 @@ import {
7
7
  SparkRewardsControllerViem,
8
8
  } from '../contracts';
9
9
  import { EthAddress, NetworkNumber } from '../types/common';
10
- import { ClaimType, SparkAirdropType, SparkRewardsClaimableToken } from '../types/claiming';
10
+ import {
11
+ ClaimType, SparkAirdropClaimableToken, SparkAirdropType, SparkRewardsClaimableToken,
12
+ } from '../types/claiming';
11
13
  import { compareAddresses, getEthAmountForDecimals } from '../services/utils';
12
14
 
13
15
  const IGNITION_REWARDS = '0xCBA0C0a2a0B6Bb11233ec4EA85C5bFfea33e724d';
@@ -50,7 +52,7 @@ export const fetchSparkAirdropRewards = async (
50
52
  provider: Client,
51
53
  network: NetworkNumber,
52
54
  walletAddresses: EthAddress[],
53
- ) => {
55
+ ): Promise<Record<string, SparkAirdropClaimableToken[]>> => {
54
56
  // Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
55
57
  const apiDataPromises = walletAddresses.map(address => fetchSpkAirdropRewards(address));
56
58
  const apiDataArray = await Promise.all(apiDataPromises);
@@ -92,7 +94,7 @@ export const fetchSparkAirdropRewards = async (
92
94
  const cumulativeClaimedAmounts = await getCumulativeClaimedSpkAirdrop(provider, network, contractCallsData);
93
95
 
94
96
  // Process results
95
- const results: Record<string, any[]> = {};
97
+ const results: Record<string, SparkAirdropClaimableToken[]> = {};
96
98
  let contractCallIndex = 0;
97
99
 
98
100
  for (const { walletAddress, data } of allClaimData) {
@@ -101,7 +103,7 @@ export const fetchSparkAirdropRewards = async (
101
103
  continue;
102
104
  }
103
105
 
104
- const processedRewards = [];
106
+ const processedRewards: SparkAirdropClaimableToken[] = [];
105
107
  for (let i = 0; i < data.length; i++) {
106
108
  const rewardInfo = data[i];
107
109
  const assetInfo = getAssetInfoByAddress(rewardInfo.token_address);
@@ -11,6 +11,7 @@ import {
11
11
  FluidAggregatedVaultData,
12
12
  FluidAssetData,
13
13
  FluidAssetsData,
14
+ FluidEarnPositionData,
14
15
  FluidFTokenDataStructOutput,
15
16
  FluidMarketData,
16
17
  FluidMarketInfo,
@@ -1598,7 +1599,7 @@ export const getFluidTokenData = async (
1598
1599
  token: string,
1599
1600
  ) => _getFluidTokenData(getViemProvider(provider, network), network, token);
1600
1601
 
1601
- const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string) => {
1602
+ const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string): FluidEarnPositionData => {
1602
1603
  const decimals = fTokenData.decimals.toString();
1603
1604
  const depositRate = new Dec(getEthAmountForDecimals(fTokenData.convertToShares.toString(), decimals)).toString();
1604
1605
  const withdrawRate = new Dec(getEthAmountForDecimals(fTokenData.convertToAssets.toString(), decimals)).toString();
@@ -1646,7 +1647,7 @@ export const getFluidDepositData = async (
1646
1647
  address: EthAddress,
1647
1648
  ) => _getFluidDepositData(getViemProvider(provider, network), network, token, address);
1648
1649
 
1649
- export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress) => {
1650
+ export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress): Promise<FluidEarnPositionData[]> => {
1650
1651
  const view = FluidViewContractViem(provider, network);
1651
1652
  const [
1652
1653
  [userPositions, fTokensData],
@@ -1665,7 +1666,7 @@ export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, netw
1665
1666
  rewardsData = await rewardsApiResponse.json();
1666
1667
  }
1667
1668
 
1668
- const parsedRes = fTokensData.reduce<ReturnType<typeof parseFDepositTokenData>[]>((acc, fTokenData, i) => {
1669
+ const parsedRes = fTokensData.reduce<FluidEarnPositionData[]>((acc, fTokenData, i) => {
1669
1670
  const userPosition = userPositions[i];
1670
1671
  const deposited = userPosition?.underlyingAssets;
1671
1672
 
@@ -13,7 +13,7 @@ import {
13
13
  LiquityTroveManagerContractViem,
14
14
  LiquityViewContractViem,
15
15
  } from '../contracts';
16
- import { LIQUITY_TROVE_STATUS_ENUM, LiquityTroveInfo } from '../types';
16
+ import { LIQUITY_TROVE_STATUS_ENUM, LiquityStakingData, LiquityTroveInfo } from '../types';
17
17
  import { ZERO_ADDRESS } from '../constants';
18
18
  import { getViemProvider, setViemBlockNumber } from '../services/viem';
19
19
  import { getEthAmountForDecimals } from '../services/utils';
@@ -127,7 +127,7 @@ export const _getLiquityTroveInfo = async (provider: Client, network: NetworkNum
127
127
 
128
128
  export const getLiquityTroveInfo = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress): Promise<LiquityTroveInfo> => _getLiquityTroveInfo(getViemProvider(provider, network, { batch: { multicall: true } }), network, address);
129
129
 
130
- export const getLiquityStakingData = async (provider: Client, network: NetworkNumber, address: EthAddress) => {
130
+ export const getLiquityStakingData = async (provider: Client, network: NetworkNumber, address: EthAddress): Promise<LiquityStakingData> => {
131
131
  const lqtyStakingView = LiquityLQTYStakingViem(provider, network);
132
132
  const stabilityPoolView = LiquityStabilityPoolViem(provider, network);
133
133
  const [
@@ -12,7 +12,7 @@ import {
12
12
  } from '../types/common';
13
13
  import {
14
14
  LIQUITY_V2_TROVE_STATUS_ENUM,
15
- LiquityV2AssetsData, LiquityV2MarketData, LiquityV2MarketInfo, LiquityV2TroveData, LiquityV2UsedAssets,
15
+ LiquityV2AssetsData, LiquityV2MarketData, LiquityV2MarketInfo, LiquityV2SBoldYBoldData, LiquityV2StakingData, LiquityV2TroveData, LiquityV2UsedAssets,
16
16
  LiquityV2Versions,
17
17
  } from '../types';
18
18
  import { getStakingApy, STAKING_ASSETS } from '../staking';
@@ -162,31 +162,35 @@ export const nftContractCreationBlockMapping = {
162
162
  [LiquityV2Versions.LiquityV2REthLegacy]: 21686257,
163
163
  };
164
164
 
165
- const getTransferredTroves = async (provider: PublicClient, network: NetworkNumber, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, market: LiquityV2Versions, account: EthAddress): Promise<{ troveId: string }[]> => {
165
+ interface TroveTransfer {
166
+ from?: EthAddress,
167
+ to?: EthAddress,
168
+ tokenId: string,
169
+ blockNumber: number,
170
+ }
171
+
172
+ /** Every Transfer of a market's trove NFT since the contract was created (or, on a fork, in the last 1000 blocks). */
173
+ const getTroveTransfers = async (provider: PublicClient, network: NetworkNumber, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, market: LiquityV2Versions): Promise<TroveTransfer[]> => {
166
174
  const nftContract = createViemContractFromConfigFunc('LiquityV2TroveNFT', troveNFTAddress)(provider, network);
167
175
  const nftContractCreationBlock = nftContractCreationBlockMapping[market];
168
176
  const currentBlock = +(await provider.getBlockNumber()).toString();
169
177
  const _events = await nftContract.getEvents.Transfer({}, { fromBlock: limitBlocksForEventFetching ? BigInt(currentBlock - 1000) : BigInt(nftContractCreationBlock) });
170
- const events = _events.map((event) => ({
178
+ return _events.map((event) => ({
171
179
  from: event.args.from, to: event.args.to, tokenId: event.args.tokenId!.toString(), blockNumber: +(event.blockNumber.toString()),
172
180
  }));
173
- const userTransferredTroves = events.filter((event) => compareAddresses(event.to, account));
174
-
175
- // check if the last know transfer address is the user
176
- userTransferredTroves.forEach((event, index) => {
177
- const otherTransfers = events.filter((e) => event.blockNumber < e.blockNumber && e.tokenId === event.tokenId);
178
- // @ts-ignore
179
- userTransferredTroves[index].invalid = !!otherTransfers.length;
180
- });
181
- // @ts-ignore
182
- return userTransferredTroves.filter((event) => !event.invalid).map((event) => ({ troveId: event.tokenId }));
183
181
  };
184
182
 
185
- export const _getLiquityV2UserTroveIds = async (provider: PublicClient, network: NetworkNumber, selectedMarket: LiquityV2MarketInfo, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, account: EthAddress): Promise<{ troves: { troveId: string }[], nextFreeTroveIndex: string }> => {
186
- const [{ troves: userTroves, nextFreeTroveIndex }, userTransferredTroves] = await Promise.all([
187
- getUserTroves(provider, network, selectedMarket.isLegacy, account, selectedMarket.marketAddress),
188
- getTransferredTroves(provider, network, troveNFTAddress, limitBlocksForEventFetching, selectedMarket.value, account),
189
- ]);
183
+ /** The troves transferred to an account that it still holds: no later transfer of the same trove. */
184
+ const getAccountTransferredTroves = (events: TroveTransfer[], account: EthAddress): { troveId: string }[] => events
185
+ .filter((event) => compareAddresses(event.to, account))
186
+ .filter((event) => !events.some((e) => event.blockNumber < e.blockNumber && e.tokenId === event.tokenId))
187
+ .map((event) => ({ troveId: event.tokenId }));
188
+
189
+ const getTransferredTroves = async (provider: PublicClient, network: NetworkNumber, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, market: LiquityV2Versions, account: EthAddress): Promise<{ troveId: string }[]> => (
190
+ getAccountTransferredTroves(await getTroveTransfers(provider, network, troveNFTAddress, limitBlocksForEventFetching, market), account));
191
+
192
+ /** The troves an account opened and still owns, then the ones transferred to it, each once. */
193
+ const mergeTroveIds = (userTroves: { troveId: string }[], userTransferredTroves: { troveId: string }[]): { troveId: string }[] => {
190
194
  const troves = [...userTroves.map(({ troveId }) => ({ troveId })), ...userTransferredTroves];
191
195
  const filteredTroves = troves.filter((value, index, self) => index === self.findIndex((t) => (
192
196
  t.troveId === value.troveId
@@ -195,8 +199,30 @@ export const _getLiquityV2UserTroveIds = async (provider: PublicClient, network:
195
199
  const troveIds = filteredTroves.map((trove) => trove.troveId);
196
200
  const troveIdsSet = new Set(troveIds);
197
201
  const troveIdsArray = Array.from(troveIdsSet);
198
- const trovesNoDuplicates = troveIdsArray.map((troveId) => troves.find((trove) => trove.troveId === troveId)) as { troveId: string }[];
199
- return { troves: trovesNoDuplicates, nextFreeTroveIndex };
202
+ return troveIdsArray.map((troveId) => troves.find((trove) => trove.troveId === troveId)) as { troveId: string }[];
203
+ };
204
+
205
+ /**
206
+ * The trove ids of several accounts in one market: the market's NFT transfers are read once for all of them, rather
207
+ * than once per account as _getLiquityV2UserTroveIds does.
208
+ */
209
+ export const _getLiquityV2UsersTroveIds = async (provider: PublicClient, network: NetworkNumber, selectedMarket: LiquityV2MarketInfo, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, accounts: EthAddress[]): Promise<Record<EthAddress, string[]>> => {
210
+ const [userTroves, events] = await Promise.all([
211
+ Promise.all(accounts.map((account) => getUserTroves(provider, network, selectedMarket.isLegacy, account, selectedMarket.marketAddress))),
212
+ getTroveTransfers(provider, network, troveNFTAddress, limitBlocksForEventFetching, selectedMarket.value),
213
+ ]);
214
+ return Object.fromEntries(accounts.map((account, i) => [
215
+ account,
216
+ mergeTroveIds(userTroves[i].troves, getAccountTransferredTroves(events, account)).map(({ troveId }) => troveId),
217
+ ]));
218
+ };
219
+
220
+ export const _getLiquityV2UserTroveIds = async (provider: PublicClient, network: NetworkNumber, selectedMarket: LiquityV2MarketInfo, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, account: EthAddress): Promise<{ troves: { troveId: string }[], nextFreeTroveIndex: string }> => {
221
+ const [{ troves: userTroves, nextFreeTroveIndex }, userTransferredTroves] = await Promise.all([
222
+ getUserTroves(provider, network, selectedMarket.isLegacy, account, selectedMarket.marketAddress),
223
+ getTransferredTroves(provider, network, troveNFTAddress, limitBlocksForEventFetching, selectedMarket.value, account),
224
+ ]);
225
+ return { troves: mergeTroveIds(userTroves, userTransferredTroves), nextFreeTroveIndex };
200
226
  };
201
227
 
202
228
  export const getLiquityV2UserTroveIds = async (
@@ -579,7 +605,7 @@ const calculateSPApy = (
579
605
  return apy;
580
606
  };
581
607
 
582
- export const getLiquityV2Staking = async (provider: Client, network: NetworkNumber, market: LiquityV2Versions, user: EthAddress) => {
608
+ export const getLiquityV2Staking = async (provider: Client, network: NetworkNumber, market: LiquityV2Versions, user: EthAddress): Promise<LiquityV2StakingData> => {
583
609
  const stabilityPoolView = createViemContractFromConfigFunc('LiquityV2StabilityPool', stabilityPoolAddrForMarket[market])(provider, network);
584
610
  const activePoolView = createViemContractFromConfigFunc('LiquityV2ActivePool', activePoolAddrForMarket[market])(provider, network);
585
611
 
@@ -638,7 +664,7 @@ export const getLiquityV2Staking = async (provider: Client, network: NetworkNumb
638
664
  };
639
665
  };
640
666
 
641
- export const getLiquitySAndYBold = async (provider: Client, network: NetworkNumber, markets: any, user: EthAddress) => {
667
+ export const getLiquitySAndYBold = async (provider: Client, network: NetworkNumber, markets: any, user: EthAddress): Promise<LiquityV2SBoldYBoldData> => {
642
668
  const sBold = LiquityV2sBoldVaultViem(provider, network);
643
669
  const yBold = createViemContractFromConfigFunc('Erc4626', '0x9F4330700a36B29952869fac9b33f45EEdd8A3d8')(provider, network);
644
670
  const stYBold = createViemContractFromConfigFunc('Erc4626', '0x23346B04a7f55b8760E5860AA5A77383D63491cD')(provider, network);