@defisaver/positions-sdk 2.1.72-aave-v4-dev → 2.1.72-aave-v4-3-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.
@@ -0,0 +1,180 @@
1
+ import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
2
+ import { AaveV4ViewContractViem } from '../contracts';
3
+ import { getViemProvider } from '../services/viem';
4
+ import { wethToEth } from '../services/utils';
5
+ import {
6
+ EthAddress,
7
+ EthereumProvider,
8
+ NetworkNumber,
9
+ } from '../types/common';
10
+
11
+ export interface AaveV4TokenizationSpokeData {
12
+ underlyingAsset: EthAddress;
13
+ assetId: string;
14
+ decimals: number;
15
+ spoke: EthAddress;
16
+ spokeActive: boolean;
17
+ spokeHalted: boolean;
18
+ spokeDepositCap: string;
19
+ spokeTotalAssets: string;
20
+ spokeTotalShares: string;
21
+ hub: EthAddress;
22
+ hubLiquidity: string;
23
+ hubDrawnRate: string;
24
+ convertToShares: string;
25
+ convertToAssets: string;
26
+ user: EthAddress;
27
+ userSuppliedAssets: string;
28
+ userSuppliedShares: string;
29
+ }
30
+
31
+ export const AAVE_V4_TOKENIZED_SPOKES: Record<string, EthAddress> = {
32
+ AAVE_CORE: '0x08309234884cF7E015b07Bf22569017Aa035cdeF',
33
+ EURC_CORE: '0x73596dED4B2Eb0aC85e477b3c8dB56FC427E6774',
34
+ GHO_CORE: '0xf7E1f1b43922527e5054bD77E7f863Cf182b194D',
35
+ GHO_PRIME: '0xeF1cAd5c6a2C9cb83c952b4B96bbD35b3F61F18f',
36
+ LBTC_CORE: '0x8f4D423590F22833131e3493bf67A27213398f8e',
37
+ LINK_CORE: '0xBE1197750b423e30137E97d9183065d33E903BE6',
38
+ PT_USDe_PLUS: '0x8cA27Ab284F2aA2BcF33D9129e11c101aD2d16de',
39
+ PT_sUSDe_PLUS: '0xb8A464EC56071a98c854f30fE19CfeCc41FA6233',
40
+ PYUSD_CORE: '0x203FB463087005698d50768FcA837047f738632d',
41
+ RLUSD_CORE: '0xa9afdd0c54fb153CaE39cE86E49626B5e9d15513',
42
+ USDC_CORE: '0xa2e476f4cbB06C7bFA8Ad51bCcbF198cd32CfD35',
43
+ USDC_PLUS: '0x320Bec4fB7a25e64c003A007D0AeF7AB3D6C30d7',
44
+ USDC_PRIME: '0x0A0507F7A1129892b5cf74b8B4e911442c466b87',
45
+ USDG_CORE: '0x87c224256f09a014C1BC3e9FbB094C3AdD8fBaCC',
46
+ USDT_CORE: '0x3f12BD5999b9172550893FF52691c980676f9E73',
47
+ USDT_PLUS: '0xa4E74a78bED2d3ab8971e8AB26fb39f26DD8eEd9',
48
+ USDT_PRIME: '0xF565fB55bc96d65561887898bfeb25C1dE7e06d2',
49
+ USDe_PLUS: '0xA0d346ab2699B689AC67aba5174164A84206BB73',
50
+ WBTC_CORE: '0x837Ab872A665e0CF467d41cF56a054031b4A38bc',
51
+ WBTC_PRIME: '0xeae98b8a1798738182B2123DF1eB93d97BD29F34',
52
+ WETH_CORE: '0x3961a75099E986F59a1a31c6f945061641dFD2b2',
53
+ WETH_PRIME: '0xa411826a6ef5d289c0FAa7d5B45FE8aAB52257F6',
54
+ XAUt_CORE: '0x470341bC0e2B833C54D0120642713BdF762A494F',
55
+ cbBTC_CORE: '0xe8D5E595d5b6b5EFf84B7064765fd0e8DfD214C9',
56
+ cbBTC_PRIME: '0x0E986545150DcDDe46Ea9df355D0fD2af33bd75D',
57
+ frxUSD_CORE: '0x00C8A6a42947Cc4E7B6f27963Cab0143ccaaD2B5',
58
+ frxUSD_PLUS: '0xCAB288d37CAb5a9db7b503F086455276Dcde61F1',
59
+ rsETH_CORE: '0x6eEce89caE2163584bA7Ff9743861B9633c245E0',
60
+ sUSDe_PLUS: '0xdf47fc43c88B06edC47753b7d647ff18037D2F3d',
61
+ weETH_CORE: '0xB67F20bFF413C8E5d633B54BD28899c4c9e33ed0',
62
+ wstETH_CORE: '0x474602394d0B02F43AC3D7C8c5cFc0814b03fd40',
63
+ wstETH_PRIME: '0xAcCdAb49ECB9A801CfF62a92fc80D52339b33770',
64
+ };
65
+
66
+ export const AAVE_V4_TOKENIZED_SPOKE_ADDRESSES: Partial<Record<NetworkNumber, EthAddress[]>> = {
67
+ [NetworkNumber.Eth]: Object.values(AAVE_V4_TOKENIZED_SPOKES),
68
+ };
69
+
70
+ export type AaveV4TokenizedHubKey = 'CORE' | 'PLUS' | 'PRIME';
71
+
72
+ export const aaveV4GetTokenizedHubKey = (hubNameOrKey?: string | null): AaveV4TokenizedHubKey | null => {
73
+ if (!hubNameOrKey) return null;
74
+ const normalized = hubNameOrKey.trim().toUpperCase();
75
+
76
+ // TODO AaveV4 Maybe turn into constants
77
+ if (normalized === 'CORE' || normalized === 'CORE HUB') return 'CORE';
78
+ if (normalized === 'PLUS' || normalized === 'PLUS HUB') return 'PLUS';
79
+ if (normalized === 'PRIME' || normalized === 'PRIME HUB') return 'PRIME';
80
+
81
+ if (normalized.includes('CORE')) return 'CORE';
82
+ if (normalized.includes('PLUS')) return 'PLUS';
83
+ if (normalized.includes('PRIME')) return 'PRIME';
84
+
85
+ return null;
86
+ };
87
+
88
+ export const aaveV4GetTokenizedVaultKey = (
89
+ symbol: string,
90
+ hubNameOrKey?: string | null,
91
+ ): string | null => {
92
+ if (!symbol) return null;
93
+ const hubKey = aaveV4GetTokenizedHubKey(hubNameOrKey);
94
+ if (!hubKey) return null;
95
+
96
+ const normalizedSymbol = symbol.trim().replace(/-/g, '_');
97
+
98
+ return `${normalizedSymbol}_${hubKey}`;
99
+ };
100
+
101
+ export const aaveV4GetTokenizedVaultAddress = (
102
+ network: NetworkNumber,
103
+ symbol: string,
104
+ hubNameOrKey?: string | null,
105
+ ): EthAddress | undefined => {
106
+ if (network !== NetworkNumber.Eth) return undefined;
107
+ const key = aaveV4GetTokenizedVaultKey(symbol, hubNameOrKey);
108
+ if (!key) return undefined;
109
+ return AAVE_V4_TOKENIZED_SPOKES[key];
110
+ };
111
+
112
+ /** Parsed tokenization spoke data with human-readable supplied amounts for display */
113
+ export interface AaveV4TokenizationSpokeDataParsed {
114
+ vaultAddress: EthAddress;
115
+ key: string | null;
116
+ symbol: string;
117
+ hubKey: string;
118
+ userSuppliedAssetsEth: string;
119
+ userSuppliedSharesEth: string;
120
+ userSuppliedAssets: string;
121
+ userSuppliedShares: string;
122
+ underlyingAsset: EthAddress;
123
+ spoke: EthAddress;
124
+ decimals: number;
125
+ }
126
+
127
+ const AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY: Record<string, string> = Object.entries(
128
+ AAVE_V4_TOKENIZED_SPOKES,
129
+ ).reduce((acc, [k, v]) => {
130
+ acc[v.toLowerCase()] = k;
131
+ return acc;
132
+ }, {} as Record<string, string>);
133
+
134
+ /**
135
+ * Fetches tokenization vault data for the given user via getTokenizationSpokesData.
136
+ * Returns parsed data including userSuppliedAssets in human-readable form for each vault.
137
+ */
138
+ export async function getAaveV4TokenizationSpokesData(
139
+ provider: EthereumProvider,
140
+ network: NetworkNumber,
141
+ userAddress: EthAddress,
142
+ ): Promise<AaveV4TokenizationSpokeDataParsed[]> {
143
+ const spokes = AAVE_V4_TOKENIZED_SPOKE_ADDRESSES[network] ?? [];
144
+ if (spokes.length === 0) return [];
145
+
146
+ const client = getViemProvider(provider, network);
147
+ const viewContract = AaveV4ViewContractViem(client, network);
148
+ const raw = await viewContract.read.getTokenizationSpokesData([spokes, userAddress]);
149
+
150
+ return raw.map((r: any, i: number) => {
151
+ const vaultAddress = spokes[i];
152
+ const key = AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY[vaultAddress.toLowerCase()] ?? null;
153
+ const symbol = wethToEth(getAssetInfoByAddress(r.underlyingAsset, network).symbol);
154
+ if (symbol === '?') { // unsupported asset
155
+ return null;
156
+ }
157
+ const hubKey = key ? key.split('_').pop() ?? '' : '';
158
+ const decimals = Number(r.decimals ?? 18);
159
+ const userSuppliedAssetsRaw = r.userSuppliedAssets ?? 0;
160
+ const userSuppliedSharesRaw = r.userSuppliedShares ?? 0;
161
+
162
+ const userSuppliedAssetsEth = assetAmountInEth(userSuppliedAssetsRaw.toString(), symbol);
163
+ const userSuppliedSharesEth = assetAmountInEth(userSuppliedSharesRaw.toString(), symbol);
164
+ return {
165
+ vaultAddress,
166
+ key,
167
+ symbol,
168
+ hubKey,
169
+ userSuppliedAssetsEth,
170
+ userSuppliedSharesEth,
171
+ userSuppliedAssets: userSuppliedAssetsRaw.toString(),
172
+ userSuppliedShares: userSuppliedSharesRaw.toString(),
173
+ underlyingAsset: r.underlyingAsset,
174
+ spoke: r.spoke,
175
+ decimals,
176
+ };
177
+ }).filter(item => item != null);
178
+ }
179
+
180
+
@@ -1,9 +1,14 @@
1
1
  import Dec from 'decimal.js';
2
2
  import { calcLeverageLiqPrice, getAssetsTotal, STABLE_ASSETS } from '../../moneymarket';
3
3
  import {
4
- AaveV4AggregatedPositionData, AaveV4AssetsData, AaveV4ReserveAssetData, AaveV4UsedReserveAsset, AaveV4UsedReserveAssets,
4
+ AaveV4AggregatedPositionData,
5
+ AaveV4AssetsData,
6
+ AaveV4ReserveAssetData,
7
+ AaveV4UsedReserveAsset,
8
+ AaveV4UsedReserveAssets,
9
+ LeverageType,
10
+ NetworkNumber,
5
11
  } from '../../types';
6
- import { LeverageType, NetworkNumber } from '../../types/common';
7
12
 
8
13
  export const aaveV4GetCollateralFactor = (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor: boolean = false): number => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
9
14
 
@@ -28,6 +28,12 @@ export interface AaveV4HubInfo {
28
28
  export interface AaveV4HubAssetOnChainData {
29
29
  assetId: number,
30
30
  drawnRate: bigint,
31
+ liquidity: bigint,
32
+ liquidityFee: number,
33
+ swept: bigint,
34
+ totalDrawn: bigint,
35
+ totalDrawnShares: bigint,
36
+ totalPremiumShares: bigint,
31
37
  }
32
38
 
33
39
  export interface AaveV4HubOnChainData {
@@ -98,6 +104,7 @@ export interface AaveV4ReserveAssetData {
98
104
  spokeHalted: boolean,
99
105
  drawnRate: string,
100
106
  supplyRate: string,
107
+ borrowRate: string,
101
108
  supplyIncentives: IncentiveData[];
102
109
  borrowIncentives: IncentiveData[];
103
110
  canBeBorrowed: boolean;
@@ -158,4 +165,5 @@ export type AaveV4UsedReserveAssets = Record<string, AaveV4UsedReserveAsset>;
158
165
  export interface AaveV4AccountData extends AaveV4AggregatedPositionData {
159
166
  usedAssets: AaveV4UsedReserveAssets,
160
167
  healthFactor: string,
168
+ riskPremiumBps: number,
161
169
  }