@defisaver/positions-sdk 2.1.8 → 2.1.9-dev-spark-2

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.
@@ -22,7 +22,7 @@ import Dec from 'decimal.js';
22
22
  import { assetAmountInWei, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
23
23
  import { aprToApy, calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos, } from '../../moneymarket';
24
24
  import { calculateNetApy } from '../../staking';
25
- import { ethToWeth, wethToEth } from '../../services/utils';
25
+ import { ethToWeth, getNativeAssetFromWrapped, wethToEth } from '../../services/utils';
26
26
  import { SparkViewContractViem } from '../../contracts';
27
27
  import { NetworkNumber } from '../../types/common';
28
28
  import { borrowOperations } from '../../constants';
@@ -30,8 +30,8 @@ import { getViemProvider } from '../../services/viem';
30
30
  export const sparkIsInIsolationMode = ({ usedAssets, assetsData }) => Object.values(usedAssets).some(({ symbol, collateral }) => collateral && assetsData[symbol].isIsolated);
31
31
  export const sparkGetCollSuppliedAssets = ({ usedAssets }) => Object.values(usedAssets).filter(({ isSupplied, collateral }) => isSupplied && collateral);
32
32
  export const sparkGetSuppliableAssets = (_a) => {
33
- var { usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "eModeCategories", "assetsData", "selectedMarket", "network"]);
34
- const data = Object.assign({ usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network }, rest);
33
+ var { usedAssets, eModeCategory, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "assetsData", "selectedMarket", "network"]);
34
+ const data = Object.assign({ usedAssets, eModeCategory, assetsData, selectedMarket, network }, rest);
35
35
  const collAccountAssets = sparkGetCollSuppliedAssets(data);
36
36
  const marketAssets = Object.values(assetsData);
37
37
  if (sparkIsInIsolationMode(data)) {
@@ -41,25 +41,25 @@ export const sparkGetSuppliableAssets = (_a) => {
41
41
  return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated }));
42
42
  };
43
43
  export const sparkGetSuppliableAsCollAssets = (_a) => {
44
- var { usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "eModeCategories", "assetsData", "selectedMarket", "network"]);
45
- return sparkGetSuppliableAssets(Object.assign({ usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network }, rest)).filter(({ canBeCollateral }) => canBeCollateral);
44
+ var { usedAssets, eModeCategory, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "assetsData", "selectedMarket", "network"]);
45
+ return sparkGetSuppliableAssets(Object.assign({ usedAssets, eModeCategory, assetsData, selectedMarket, network }, rest)).filter(({ canBeCollateral }) => canBeCollateral);
46
46
  };
47
- export const sparkGetEmodeMutableProps = ({ eModeCategory, assetsData, }, _asset) => {
48
- var _a;
49
- const asset = wethToEth(_asset);
47
+ export const sparkGetEmodeMutableProps = ({ eModeCategory, eModeCategoriesData, assetsData, }, _asset) => {
48
+ const asset = getNativeAssetFromWrapped(_asset);
50
49
  const assetData = assetsData[asset];
50
+ const eModeCategoryData = (eModeCategoriesData === null || eModeCategoriesData === void 0 ? void 0 : eModeCategoriesData[eModeCategory]) || { collateralAssets: [], collateralFactor: '0', liquidationRatio: '0' };
51
51
  if (eModeCategory === 0
52
- || assetData.eModeCategory !== eModeCategory
53
- || new Dec(((_a = assetData === null || assetData === void 0 ? void 0 : assetData.eModeCategoryData) === null || _a === void 0 ? void 0 : _a.collateralFactor) || 0).eq(0)) {
52
+ || !eModeCategoryData.collateralAssets.includes(asset)
53
+ || new Dec(eModeCategoryData.collateralFactor || 0).eq(0)) {
54
54
  const { liquidationRatio, collateralFactor } = assetData;
55
55
  return ({ liquidationRatio, collateralFactor });
56
56
  }
57
- const { liquidationRatio, collateralFactor } = assetData.eModeCategoryData;
57
+ const { liquidationRatio, collateralFactor } = eModeCategoryData;
58
58
  return ({ liquidationRatio, collateralFactor });
59
59
  };
60
60
  export const sparkGetAggregatedPositionData = (_a) => {
61
- var { usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "eModeCategories", "assetsData", "selectedMarket", "network"]);
62
- const data = Object.assign({ usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network }, rest);
61
+ var { usedAssets, eModeCategory, eModeCategoriesData, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "eModeCategoriesData", "assetsData", "selectedMarket", "network"]);
62
+ const data = Object.assign({ usedAssets, eModeCategory, eModeCategoriesData, assetsData, selectedMarket, network }, rest);
63
63
  const payload = {};
64
64
  payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }) => isSupplied, ({ suppliedUsd }) => suppliedUsd);
65
65
  payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }) => isSupplied && collateral, ({ suppliedUsd }) => suppliedUsd);
@@ -244,17 +244,21 @@ export declare const FluidFTokens: (networkId: NetworkNumber) => {
244
244
  wstETH: string;
245
245
  GHO: string;
246
246
  sUSDS: string;
247
+ USDtb: string;
247
248
  } | {
248
249
  ETH: string;
249
250
  USDC: string;
250
251
  USDT: string;
251
252
  wstETH: string;
252
253
  ARB: string;
254
+ GHO: string;
255
+ sUSDS: string;
253
256
  } | {
254
257
  ETH: string;
255
258
  USDC: string;
256
259
  EURC: string;
257
260
  wstETH: string;
258
261
  sUSDS: string;
262
+ GHO: string;
259
263
  };
260
264
  export declare const getFTokenAddress: (token: string, networkId: NetworkNumber) => any;
@@ -2290,6 +2290,7 @@ const FluidMainnetFTokenAddresses = {
2290
2290
  [FluidMainnetDepositToken.wstETH]: '0x2411802D8BEA09be0aF8fD8D08314a63e706b29C',
2291
2291
  [FluidMainnetDepositToken.GHO]: '0x6A29A46E21C730DcA1d8b23d637c101cec605C5B',
2292
2292
  [FluidMainnetDepositToken.sUSDS]: '0x2BBE31d63E6813E3AC858C04dae43FB2a72B0D11',
2293
+ [FluidMainnetDepositToken.USDtb]: '0x15e8c742614b5D8Db4083A41Df1A14F5D2bFB400',
2293
2294
  };
2294
2295
  const FluidArbitrumFTokenAddresses = {
2295
2296
  [FluidArbitrumDepositToken.ETH]: '0x45Df0656F8aDf017590009d2f1898eeca4F0a205',
@@ -2297,6 +2298,8 @@ const FluidArbitrumFTokenAddresses = {
2297
2298
  [FluidArbitrumDepositToken.USDT]: '0x4A03F37e7d3fC243e3f99341d36f4b829BEe5E03',
2298
2299
  [FluidArbitrumDepositToken.wstETH]: '0x66C25Cd75EBdAA7E04816F643d8E46cecd3183c9',
2299
2300
  [FluidArbitrumDepositToken.ARB]: '0xbE3860FD4c3facDf8ad57Aa8c1A36D6dc4390a49',
2301
+ [FluidArbitrumDepositToken.GHO]: '0x037dFf1C12805707d7c29F163E0F09fC9102657A',
2302
+ [FluidArbitrumDepositToken.sUSDS]: '0x3459fcc94390C3372c0F7B4cD3F8795F0E5aFE96',
2300
2303
  };
2301
2304
  const FluidBaseFTokenAddresses = {
2302
2305
  [FluidBaseDepositToken.ETH]: '0x9272D6153133175175Bc276512B2336BE3931CE9',
@@ -2304,6 +2307,7 @@ const FluidBaseFTokenAddresses = {
2304
2307
  [FluidBaseDepositToken.EURC]: '0x1943FA26360f038230442525Cf1B9125b5DCB401',
2305
2308
  [FluidBaseDepositToken.wstETH]: '0x896E39f0E9af61ECA9dD2938E14543506ef2c2b5',
2306
2309
  [FluidBaseDepositToken.sUSDS]: '0xf62e339f21d8018940f188F6987Bcdf02A849619',
2310
+ [FluidBaseDepositToken.GHO]: '0x8DdbfFA3CFda2355a23d6B11105AC624BDbE3631',
2307
2311
  };
2308
2312
  export const FluidFTokens = (networkId) => {
2309
2313
  switch (networkId) {
@@ -446,7 +446,7 @@ export function getPortfolioData(provider, network, defaultProvider, addresses,
446
446
  }))).flat(),
447
447
  ...sparkMarkets.map((market) => allAddresses.map((address) => __awaiter(this, void 0, void 0, function* () {
448
448
  try {
449
- const accData = yield _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: sparkMarketsData[market.value].assetsData });
449
+ const accData = yield _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: sparkMarketsData[market.value].assetsData, eModeCategoriesData: sparkMarketsData[market.value].eModeCategoriesData });
450
450
  if (new Dec(accData.suppliedUsd).gt(0))
451
451
  positions[address.toLowerCase()].spark[market.value] = { error: '', data: accData };
452
452
  }
@@ -1,6 +1,6 @@
1
1
  import { Client } from 'viem';
2
2
  import { Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances } from '../types/common';
3
- import { SparkEModeCategoryDataMapping, SparkAssetsData, SparkMarketData, SparkMarketsData, SparkPositionData, SparkUsedAssets } from '../types';
3
+ import { SparkEModeCategoryDataMapping, SparkAssetsData, SparkMarketData, SparkMarketsData, SparkPositionData, SparkUsedAssets, EModeCategoriesData } from '../types';
4
4
  export declare const sparkEmodeCategoriesMapping: (extractedState: {
5
5
  assetsData: SparkAssetsData;
6
6
  }, usedAssets: SparkUsedAssets) => {
@@ -32,9 +32,11 @@ export declare const getSparkAccountBalances: (provider: EthereumProvider, netwo
32
32
  export declare const _getSparkAccountData: (provider: Client, network: NetworkNumber, address: EthAddress, extractedState: {
33
33
  selectedMarket: SparkMarketData;
34
34
  assetsData: SparkAssetsData;
35
+ eModeCategoriesData: EModeCategoriesData;
35
36
  }) => Promise<SparkPositionData>;
36
37
  export declare const getSparkAccountData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, extractedState: {
37
38
  selectedMarket: SparkMarketData;
38
39
  assetsData: SparkAssetsData;
40
+ eModeCategoriesData: EModeCategoriesData;
39
41
  }) => Promise<SparkPositionData>;
40
42
  export declare const getSparkFullPositionData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, market: SparkMarketData) => Promise<SparkPositionData>;
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import Dec from 'decimal.js';
11
11
  import { assetAmountInEth, assetAmountInWei, getAssetInfo } from '@defisaver/tokens';
12
- import { IncentiveKind, NetworkNumber, } from '../types/common';
12
+ import { IncentiveKind, } from '../types/common';
13
13
  import { ethToWeth, wethToEth, wethToEthByAddress, } from '../services/utils';
14
14
  import { calculateNetApy, getStakingApy, STAKING_ASSETS, } from '../staking';
15
15
  import { SparkViewContractViem, SparkIncentiveDataProviderContractViem, createViemContractFromConfigFunc, } from '../contracts';
@@ -22,7 +22,6 @@ export const sparkEmodeCategoriesMapping = (extractedState, usedAssets) => {
22
22
  const usedAssetsValues = Object.values(usedAssets);
23
23
  const categoriesMapping = {};
24
24
  Object.values(assetsData).forEach((a) => {
25
- var _a;
26
25
  const borrowingOnlyFromCategory = a.eModeCategory === 0
27
26
  ? true
28
27
  : !usedAssetsValues.filter(u => u.isBorrowed && u.eModeCategory !== a.eModeCategory).length;
@@ -33,8 +32,6 @@ export const sparkEmodeCategoriesMapping = (extractedState, usedAssets) => {
33
32
  enteringTerms,
34
33
  canEnterCategory: !enteringTerms.includes(false),
35
34
  id: a.eModeCategory,
36
- data: a.eModeCategoryData,
37
- assets: a.eModeCategory === 0 ? [] : [...(((_a = categoriesMapping[a.eModeCategory]) === null || _a === void 0 ? void 0 : _a.assets) || []), a.symbol],
38
35
  enabledData: {
39
36
  ratio: afterEnteringCategory.ratio,
40
37
  liqRatio: afterEnteringCategory.liqRatio,
@@ -49,18 +46,17 @@ export const _getSparkMarketsData = (provider, network, selectedMarket) => __awa
49
46
  const marketAddress = selectedMarket.providerAddress;
50
47
  const loanInfoContract = SparkViewContractViem(provider, network);
51
48
  const sparkIncentivesContract = SparkIncentiveDataProviderContractViem(provider, network);
52
- const [loanInfo, _rewardInfo] = yield Promise.all([
49
+ // eslint-disable-next-line prefer-const
50
+ let [loanInfo, rewardInfo] = yield Promise.all([
53
51
  loanInfoContract.read.getFullTokensInfo([marketAddress, selectedMarket.assets.map(a => getAssetInfo(ethToWeth(a)).address)]),
54
- network === NetworkNumber.Opt ? sparkIncentivesContract.read.getReservesIncentivesData([marketAddress]) : [],
52
+ sparkIncentivesContract.read.getReservesIncentivesData([marketAddress]),
55
53
  ]);
56
- let rewardInfo = [];
57
- if (network === NetworkNumber.Opt) {
58
- rewardInfo = rewardInfo.reduce((all, market) => {
59
- // eslint-disable-next-line no-param-reassign
60
- all[market.underlyingAsset] = market;
61
- return all;
62
- }, {});
63
- }
54
+ rewardInfo = rewardInfo.reduce((all, market) => {
55
+ // eslint-disable-next-line no-param-reassign
56
+ all[market.underlyingAsset] = market;
57
+ return all;
58
+ }, {});
59
+ const eModeCategoriesData = {};
64
60
  const assetsData = yield Promise.all(loanInfo
65
61
  .map((market, i) => __awaiter(void 0, void 0, void 0, function* () {
66
62
  const symbol = selectedMarket.assets[i];
@@ -75,6 +71,15 @@ export const _getSparkMarketsData = (provider, network, selectedMarket) => __awa
75
71
  if (new Dec(marketLiquidity).lt(0)) {
76
72
  marketLiquidity = '0';
77
73
  }
74
+ eModeCategoriesData[+market.emodeCategory.toString()] = {
75
+ id: +market.emodeCategory.toString(),
76
+ label: market.label,
77
+ liquidationBonus: new Dec(market.liquidationBonus).div(10000).toString(),
78
+ liquidationRatio: new Dec(market.liquidationThreshold).div(10000).toString(),
79
+ collateralFactor: new Dec(market.ltv).div(10000).toString(),
80
+ collateralAssets: eModeCategoriesData[+market.emodeCategory.toString()] ? [...eModeCategoriesData[+market.emodeCategory.toString()].collateralAssets, selectedMarket.assets[i]] : [selectedMarket.assets[i]],
81
+ borrowAssets: eModeCategoriesData[+market.emodeCategory.toString()] ? [...eModeCategoriesData[+market.emodeCategory.toString()].borrowAssets, selectedMarket.assets[i]] : [selectedMarket.assets[i]],
82
+ };
78
83
  return ({
79
84
  symbol: selectedMarket.assets[i],
80
85
  isIsolated: new Dec(market.debtCeilingForIsolationMode.toString()).gt(0),
@@ -109,13 +114,6 @@ export const _getSparkMarketsData = (provider, network, selectedMarket) => __awa
109
114
  isolationModeBorrowingEnabled: market.isolationModeBorrowingEnabled,
110
115
  isFlashLoanEnabled: market.isFlashLoanEnabled,
111
116
  aTokenAddress: market.aTokenAddress,
112
- eModeCategoryData: {
113
- label: market.label,
114
- liquidationBonus: new Dec(market.liquidationBonus).div(10000).toString(),
115
- liquidationRatio: new Dec(market.liquidationThreshold).div(10000).toString(),
116
- collateralFactor: new Dec(market.ltv).div(10000).toString(),
117
- priceSource: market.priceSource,
118
- },
119
117
  supplyIncentives: [],
120
118
  borrowIncentives: [],
121
119
  });
@@ -147,7 +145,7 @@ export const _getSparkMarketsData = (provider, network, selectedMarket) => __awa
147
145
  return;
148
146
  rewardForMarket.aIncentiveData.rewardsTokenInformation.forEach(supplyRewardData => {
149
147
  if (supplyRewardData) {
150
- if (supplyRewardData.emissionEndTimestamp * 1000 < Date.now())
148
+ if (+(supplyRewardData.emissionEndTimestamp.toString()) * 1000 < Date.now())
151
149
  return;
152
150
  const supplyEmissionPerSecond = supplyRewardData.emissionPerSecond;
153
151
  const supplyRewardPrice = new Dec(supplyRewardData.rewardPriceFeed).div(Math.pow(10, supplyRewardData.priceFeedDecimals))
@@ -168,7 +166,7 @@ export const _getSparkMarketsData = (provider, network, selectedMarket) => __awa
168
166
  });
169
167
  rewardForMarket.vIncentiveData.rewardsTokenInformation.forEach(borrowRewardData => {
170
168
  if (borrowRewardData) {
171
- if (borrowRewardData.emissionEndTimestamp * 1000 < Date.now())
169
+ if (+(borrowRewardData.emissionEndTimestamp.toString()) * 1000 < Date.now())
172
170
  return;
173
171
  const supplyEmissionPerSecond = borrowRewardData.emissionPerSecond;
174
172
  const supplyRewardPrice = new Dec(borrowRewardData.rewardPriceFeed).div(Math.pow(10, borrowRewardData.priceFeedDecimals))
@@ -200,7 +198,9 @@ export const _getSparkMarketsData = (provider, network, selectedMarket) => __awa
200
198
  .forEach((assetData, i) => {
201
199
  payload[assetData.symbol] = Object.assign(Object.assign({}, assetData), { sortIndex: i });
202
200
  });
203
- return { assetsData: payload };
201
+ eModeCategoriesData[0].collateralAssets = Object.values(payload).map(a => a.symbol);
202
+ eModeCategoriesData[0].borrowAssets = Object.values(payload).map(a => a.symbol);
203
+ return { assetsData: payload, eModeCategoriesData };
204
204
  });
205
205
  export const getSparkMarketsData = (provider, network, selectedMarket) => __awaiter(void 0, void 0, void 0, function* () { return _getSparkMarketsData(getViemProvider(provider, network), network, selectedMarket); });
206
206
  export const EMPTY_SPARK_DATA = {
@@ -336,6 +336,6 @@ export const _getSparkAccountData = (provider, network, address, extractedState)
336
336
  export const getSparkAccountData = (provider, network, address, extractedState) => __awaiter(void 0, void 0, void 0, function* () { return _getSparkAccountData(getViemProvider(provider, network), network, address, extractedState); });
337
337
  export const getSparkFullPositionData = (provider, network, address, market) => __awaiter(void 0, void 0, void 0, function* () {
338
338
  const marketData = yield getSparkMarketsData(provider, network, market);
339
- const positionData = yield getSparkAccountData(provider, network, address, { assetsData: marketData.assetsData, selectedMarket: market });
339
+ const positionData = yield getSparkAccountData(provider, network, address, { assetsData: marketData.assetsData, selectedMarket: market, eModeCategoriesData: marketData.eModeCategoriesData });
340
340
  return positionData;
341
341
  });
@@ -149,21 +149,25 @@ export declare enum FluidMainnetDepositToken {
149
149
  USDC = "USDC",
150
150
  USDT = "USDT",
151
151
  GHO = "GHO",
152
- sUSDS = "sUSDS"
152
+ sUSDS = "sUSDS",
153
+ USDtb = "USDtb"
153
154
  }
154
155
  export declare enum FluidArbitrumDepositToken {
155
156
  ETH = "ETH",
156
157
  wstETH = "wstETH",
157
158
  USDC = "USDC",
158
159
  USDT = "USDT",
159
- ARB = "ARB"
160
+ ARB = "ARB",
161
+ GHO = "GHO",
162
+ sUSDS = "sUSDS"
160
163
  }
161
164
  export declare enum FluidBaseDepositToken {
162
165
  ETH = "ETH",
163
166
  USDC = "USDC",
164
167
  wstETH = "wstETH",
165
168
  EURC = "EURC",
166
- sUSDS = "sUSDS"
169
+ sUSDS = "sUSDS",
170
+ GHO = "GHO"
167
171
  }
168
172
  export type FluidDepositTokenByNetwork = {
169
173
  [NetworkNumber.Eth]: FluidMainnetDepositToken;
@@ -133,6 +133,7 @@ export var FluidMainnetDepositToken;
133
133
  FluidMainnetDepositToken["USDT"] = "USDT";
134
134
  FluidMainnetDepositToken["GHO"] = "GHO";
135
135
  FluidMainnetDepositToken["sUSDS"] = "sUSDS";
136
+ FluidMainnetDepositToken["USDtb"] = "USDtb";
136
137
  })(FluidMainnetDepositToken || (FluidMainnetDepositToken = {}));
137
138
  export var FluidArbitrumDepositToken;
138
139
  (function (FluidArbitrumDepositToken) {
@@ -141,6 +142,8 @@ export var FluidArbitrumDepositToken;
141
142
  FluidArbitrumDepositToken["USDC"] = "USDC";
142
143
  FluidArbitrumDepositToken["USDT"] = "USDT";
143
144
  FluidArbitrumDepositToken["ARB"] = "ARB";
145
+ FluidArbitrumDepositToken["GHO"] = "GHO";
146
+ FluidArbitrumDepositToken["sUSDS"] = "sUSDS";
144
147
  })(FluidArbitrumDepositToken || (FluidArbitrumDepositToken = {}));
145
148
  export var FluidBaseDepositToken;
146
149
  (function (FluidBaseDepositToken) {
@@ -149,6 +152,7 @@ export var FluidBaseDepositToken;
149
152
  FluidBaseDepositToken["wstETH"] = "wstETH";
150
153
  FluidBaseDepositToken["EURC"] = "EURC";
151
154
  FluidBaseDepositToken["sUSDS"] = "sUSDS";
155
+ FluidBaseDepositToken["GHO"] = "GHO";
152
156
  })(FluidBaseDepositToken || (FluidBaseDepositToken = {}));
153
157
  export var FluidVaultType;
154
158
  (function (FluidVaultType) {
@@ -1,3 +1,4 @@
1
+ import { EModeCategoriesData } from './aave';
1
2
  import { EthAddress, MMAssetData, MMPositionData, MMUsedAsset, NetworkNumber } from './common';
2
3
  export declare enum SparkVersions {
3
4
  SparkV1 = "v1default"
@@ -13,8 +14,6 @@ export interface SparkEModeCategoryDataMapping {
13
14
  enteringTerms: boolean[];
14
15
  canEnterCategory: boolean;
15
16
  id: number;
16
- data: SparkEModeCategoryData;
17
- assets: string[];
18
17
  enabledData: {
19
18
  ratio: string;
20
19
  liqRatio: string;
@@ -45,7 +44,6 @@ export interface SparkAssetData extends MMAssetData {
45
44
  usageAsCollateralEnabled: boolean;
46
45
  isIsolated: boolean;
47
46
  eModeCategory: number;
48
- eModeCategoryData: SparkEModeCategoryData;
49
47
  liquidationRatio: string;
50
48
  }
51
49
  export interface SparkAssetsData {
@@ -53,6 +51,7 @@ export interface SparkAssetsData {
53
51
  }
54
52
  export type SparkMarketsData = {
55
53
  assetsData: SparkAssetsData;
54
+ eModeCategoriesData: EModeCategoriesData;
56
55
  };
57
56
  export interface SparkUsedAsset extends MMUsedAsset {
58
57
  stableBorrowRate: string;
@@ -71,7 +70,7 @@ export interface SparkUsedAssets {
71
70
  export interface SparkHelperCommon {
72
71
  usedAssets: SparkUsedAssets;
73
72
  eModeCategory: number;
74
- eModeCategories?: object;
73
+ eModeCategoriesData?: EModeCategoriesData;
75
74
  assetsData: SparkAssetsData;
76
75
  selectedMarket?: SparkMarketData;
77
76
  network?: NetworkNumber;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/positions-sdk",
3
- "version": "2.1.8",
3
+ "version": "2.1.9-dev-spark-2",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -12,7 +12,7 @@
12
12
  "dev": "tsc -p tsconfig.json --watch",
13
13
  "lint": "eslint src/ --fix",
14
14
  "lint-check": "eslint src/",
15
- "test": "mocha tests/*",
15
+ "test": "mocha tests/spark.ts",
16
16
  "test-single": "mocha ./tests/$npm_config_name.ts",
17
17
  "test:debugger": "mocha --inspect-brk tests/*",
18
18
  "version-bump": "git commit -am \"Version bump to $(npm version patch | cut -c 2-)\""
@@ -1458,21 +1458,20 @@ export const getFluidTokenData = async (
1458
1458
  token: string,
1459
1459
  ) => _getFluidTokenData(getViemProvider(provider, network), network, token);
1460
1460
 
1461
- const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, fTokenAddress?: string) => {
1462
- const supplyRate = new Dec(fTokenData.supplyRate).div(100).toString();
1463
- const rewardsRate = new Dec(fTokenData.rewardsRate).div(1e12).toString();
1461
+ const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string) => {
1464
1462
  const decimals = fTokenData.decimals.toString();
1465
-
1466
1463
  const depositRate = new Dec(getEthAmountForDecimals(fTokenData.convertToShares.toString(), decimals)).toString();
1467
1464
  const withdrawRate = new Dec(getEthAmountForDecimals(fTokenData.convertToAssets.toString(), decimals)).toString();
1468
-
1465
+ const supplyRate = new Dec(apiData?.supplyRate || '0').div(100).toString();
1466
+ const rewardRates = apiData?.rewards?.reduce((acc: Dec, item: any) => acc.add(new Dec(item.rate || '0').div(100)), new Dec(0)) || '0';
1467
+ const stakeRate = new Dec(apiData?.asset?.stakingApr || '0').div(100).toString();
1469
1468
  return {
1470
1469
  fTokenAddress,
1471
1470
  fTokenSymbol: fTokenData.symbol,
1472
1471
  decimals,
1473
1472
  totalDeposited: getEthAmountForDecimals(fTokenData.totalAssets.toString(), decimals),
1474
1473
  withdrawable: getEthAmountForDecimals(fTokenData.withdrawable.toString(), decimals),
1475
- apy: new Dec(supplyRate).add(rewardsRate).toString(),
1474
+ apy: new Dec(supplyRate).plus(rewardRates).plus(stakeRate).toString(),
1476
1475
  depositRate,
1477
1476
  withdrawRate,
1478
1477
  deposited: getEthAmountForDecimals(userPosition.underlyingAssets.toString(), decimals),
@@ -1483,9 +1482,21 @@ const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPos
1483
1482
  export const _getFluidDepositData = async (provider: Client, network: NetworkNumber, token: string, address: EthAddress) => {
1484
1483
  const view = FluidViewContractViem(provider, network);
1485
1484
  const fTokenAddress = getFTokenAddress(token, network);
1486
- const [userPosition, fTokenData] = await view.read.getUserEarnPositionWithFToken([fTokenAddress, address]);
1485
+ const [
1486
+ [userPosition, fTokenData],
1487
+ rewardsApiResponse,
1488
+ ] = await Promise.all([
1489
+ view.read.getUserEarnPositionWithFToken([fTokenAddress, address]),
1490
+ fetch(`https://api.fluid.instadapp.io/v2/lending/${network}/tokens/${fTokenAddress}`),
1491
+ ]);
1492
+ let rewardsData = { rewards: [] };
1493
+ if (!rewardsApiResponse.ok) {
1494
+ console.log('External API Failure: Failed to fetch fluid rewards APY');
1495
+ } else {
1496
+ rewardsData = await rewardsApiResponse.json();
1497
+ }
1487
1498
 
1488
- return parseFDepositTokenData(fTokenData, userPosition, fTokenAddress);
1499
+ return parseFDepositTokenData(fTokenData, userPosition, rewardsData, fTokenAddress);
1489
1500
  };
1490
1501
 
1491
1502
  export const getFluidDepositData = async (
@@ -1497,7 +1508,22 @@ export const getFluidDepositData = async (
1497
1508
 
1498
1509
  export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress) => {
1499
1510
  const view = FluidViewContractViem(provider, network);
1500
- const [userPositions, fTokensData] = await view.read.getAllUserEarnPositionsWithFTokens([user]);
1511
+ const [
1512
+ [userPositions, fTokensData],
1513
+ rewardsApiResponse,
1514
+ ] = await Promise.all([
1515
+ view.read.getAllUserEarnPositionsWithFTokens([user]),
1516
+ fetch(`https://api.fluid.instadapp.io/v2/lending/${network}/tokens`),
1517
+ ]);
1518
+
1519
+ let rewardsData = {
1520
+ data: [{ address: ZERO_ADDRESS, rewards: [] }],
1521
+ };
1522
+ if (!rewardsApiResponse.ok) {
1523
+ console.log('External API Failure: Failed to fetch fluid rewards APY');
1524
+ } else {
1525
+ rewardsData = await rewardsApiResponse.json();
1526
+ }
1501
1527
 
1502
1528
  const parsedRes = fTokensData.reduce<ReturnType<typeof parseFDepositTokenData>[]>((acc, fTokenData, i) => {
1503
1529
  const userPosition = userPositions[i];
@@ -1505,7 +1531,8 @@ export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, netw
1505
1531
 
1506
1532
  if (Number(deposited) > 0) {
1507
1533
  const fTokenAddress = fTokenData.tokenAddress;
1508
- acc.push(parseFDepositTokenData(fTokenData, userPosition, fTokenAddress));
1534
+ const apiData = rewardsData.data.find((item: any) => compareAddresses(item.address, fTokenAddress));
1535
+ acc.push(parseFDepositTokenData(fTokenData, userPosition, apiData, fTokenAddress));
1509
1536
  }
1510
1537
 
1511
1538
  return acc;
@@ -1572,19 +1599,22 @@ const tokensWithoutChainlinkPrices = ['sUSDS', 'USDA', 'ezETH', 'rsETH', 'weETHs
1572
1599
 
1573
1600
  const handleTokenWithoutChainlinkPrice = (token: string, prices: Record<string, string>) => {
1574
1601
  if (token === 'sUSDS') {
1575
- return new Dec('105276929').div(1e8).toString();
1602
+ return new Dec('107057929').div(1e8).toString();
1576
1603
  }
1577
1604
  if (token === 'USDA') {
1578
1605
  return new Dec('100000000').div(1e8).toString();
1579
1606
  }
1607
+ if (token === 'wstUSR') {
1608
+ return new Dec('111280000').div(1e8).toString();
1609
+ }
1580
1610
  if (token === 'ezETH') {
1581
- return new Dec(prices.ETH).mul(1.049).toString();
1611
+ return new Dec(prices.ETH).mul(1.06).toString();
1582
1612
  }
1583
1613
  if (token === 'rsETH') {
1584
- return new Dec(prices.wstETH).mul(1.0454).toString();
1614
+ return new Dec(prices.wstETH).mul(1.0557).toString();
1585
1615
  }
1586
1616
  if (token === 'weETHs') {
1587
- return new Dec(prices.wstETH).mul(1.026).toString();
1617
+ return new Dec(prices.wstETH).mul(1.032).toString();
1588
1618
  }
1589
1619
  if (token === 'LBTC') {
1590
1620
  return prices.WBTC;
@@ -8,7 +8,7 @@ import {
8
8
  SparkAssetsData, SparkHelperCommon, SparkMarketData, SparkUsedAssets,
9
9
  } from '../../types';
10
10
  import { calculateNetApy } from '../../staking';
11
- import { ethToWeth, wethToEth } from '../../services/utils';
11
+ import { ethToWeth, getNativeAssetFromWrapped, wethToEth } from '../../services/utils';
12
12
  import { SparkViewContractViem } from '../../contracts';
13
13
  import { EthAddress, EthereumProvider, NetworkNumber } from '../../types/common';
14
14
  import { borrowOperations } from '../../constants';
@@ -19,10 +19,10 @@ export const sparkIsInIsolationMode = ({ usedAssets, assetsData }: { usedAssets:
19
19
  export const sparkGetCollSuppliedAssets = ({ usedAssets }: { usedAssets: SparkUsedAssets }) => Object.values(usedAssets).filter(({ isSupplied, collateral }) => isSupplied && collateral);
20
20
 
21
21
  export const sparkGetSuppliableAssets = ({
22
- usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network, ...rest
22
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest
23
23
  }: SparkHelperCommon) => {
24
24
  const data = {
25
- usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network, ...rest,
25
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
26
26
  };
27
27
 
28
28
  const collAccountAssets = sparkGetCollSuppliedAssets(data);
@@ -37,41 +37,44 @@ export const sparkGetSuppliableAssets = ({
37
37
  };
38
38
 
39
39
  export const sparkGetSuppliableAsCollAssets = ({
40
- usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network, ...rest
40
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest
41
41
  }: SparkHelperCommon) => sparkGetSuppliableAssets({
42
- usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network, ...rest,
42
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
43
43
  }).filter(({ canBeCollateral }) => canBeCollateral);
44
44
 
45
45
  export const sparkGetEmodeMutableProps = ({
46
46
  eModeCategory,
47
+ eModeCategoriesData,
47
48
  assetsData,
48
49
  }: SparkHelperCommon, _asset: string) => {
49
- const asset = wethToEth(_asset);
50
+ const asset = getNativeAssetFromWrapped(_asset);
50
51
 
51
52
  const assetData = assetsData[asset];
53
+ const eModeCategoryData: { collateralAssets: string[], collateralFactor: string, liquidationRatio: string } = eModeCategoriesData?.[eModeCategory] || { collateralAssets: [], collateralFactor: '0', liquidationRatio: '0' };
54
+
52
55
  if (
53
56
  eModeCategory === 0
54
- || assetData.eModeCategory !== eModeCategory
55
- || new Dec(assetData?.eModeCategoryData?.collateralFactor || 0).eq(0)
57
+ || !eModeCategoryData.collateralAssets.includes(asset)
58
+ || new Dec(eModeCategoryData.collateralFactor || 0).eq(0)
56
59
  ) {
57
60
  const { liquidationRatio, collateralFactor } = assetData;
58
61
  return ({ liquidationRatio, collateralFactor });
59
62
  }
60
- const { liquidationRatio, collateralFactor } = assetData.eModeCategoryData;
63
+ const { liquidationRatio, collateralFactor } = eModeCategoryData;
61
64
  return ({ liquidationRatio, collateralFactor });
62
65
  };
63
66
 
64
67
  export const sparkGetAggregatedPositionData = ({
65
68
  usedAssets,
66
69
  eModeCategory,
67
- eModeCategories,
70
+ eModeCategoriesData,
68
71
  assetsData,
69
72
  selectedMarket,
70
73
  network,
71
74
  ...rest
72
75
  }: SparkHelperCommon): SparkAggregatedPositionData => {
73
76
  const data = {
74
- usedAssets, eModeCategory, eModeCategories, assetsData, selectedMarket, network, ...rest,
77
+ usedAssets, eModeCategory, eModeCategoriesData, assetsData, selectedMarket, network, ...rest,
75
78
  };
76
79
  const payload = {} as SparkAggregatedPositionData;
77
80
  payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
@@ -2421,6 +2421,7 @@ const FluidMainnetFTokenAddresses = {
2421
2421
  [FluidMainnetDepositToken.wstETH]: '0x2411802D8BEA09be0aF8fD8D08314a63e706b29C',
2422
2422
  [FluidMainnetDepositToken.GHO]: '0x6A29A46E21C730DcA1d8b23d637c101cec605C5B',
2423
2423
  [FluidMainnetDepositToken.sUSDS]: '0x2BBE31d63E6813E3AC858C04dae43FB2a72B0D11',
2424
+ [FluidMainnetDepositToken.USDtb]: '0x15e8c742614b5D8Db4083A41Df1A14F5D2bFB400',
2424
2425
  };
2425
2426
 
2426
2427
  const FluidArbitrumFTokenAddresses = {
@@ -2429,6 +2430,8 @@ const FluidArbitrumFTokenAddresses = {
2429
2430
  [FluidArbitrumDepositToken.USDT]: '0x4A03F37e7d3fC243e3f99341d36f4b829BEe5E03',
2430
2431
  [FluidArbitrumDepositToken.wstETH]: '0x66C25Cd75EBdAA7E04816F643d8E46cecd3183c9',
2431
2432
  [FluidArbitrumDepositToken.ARB]: '0xbE3860FD4c3facDf8ad57Aa8c1A36D6dc4390a49',
2433
+ [FluidArbitrumDepositToken.GHO]: '0x037dFf1C12805707d7c29F163E0F09fC9102657A',
2434
+ [FluidArbitrumDepositToken.sUSDS]: '0x3459fcc94390C3372c0F7B4cD3F8795F0E5aFE96',
2432
2435
  };
2433
2436
 
2434
2437
  const FluidBaseFTokenAddresses = {
@@ -2437,6 +2440,7 @@ const FluidBaseFTokenAddresses = {
2437
2440
  [FluidBaseDepositToken.EURC]: '0x1943FA26360f038230442525Cf1B9125b5DCB401',
2438
2441
  [FluidBaseDepositToken.wstETH]: '0x896E39f0E9af61ECA9dD2938E14543506ef2c2b5',
2439
2442
  [FluidBaseDepositToken.sUSDS]: '0xf62e339f21d8018940f188F6987Bcdf02A849619',
2443
+ [FluidBaseDepositToken.GHO]: '0x8DdbfFA3CFda2355a23d6B11105AC624BDbE3631',
2440
2444
  };
2441
2445
 
2442
2446
  export const FluidFTokens = (networkId: NetworkNumber) => {
@@ -456,7 +456,7 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
456
456
  })).flat(),
457
457
  ...sparkMarkets.map((market) => allAddresses.map(async (address) => {
458
458
  try {
459
- const accData = await _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: sparkMarketsData[market.value].assetsData });
459
+ const accData = await _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: sparkMarketsData[market.value].assetsData, eModeCategoriesData: sparkMarketsData[market.value].eModeCategoriesData });
460
460
  if (new Dec(accData.suppliedUsd).gt(0)) positions[address.toLowerCase() as EthAddress].spark[market.value] = { error: '', data: accData };
461
461
  } catch (error) {
462
462
  console.error(`Error fetching Spark account data for address ${address} on market ${market.value}:`, error);