@kasufinance/kasu-sdk 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.json +90 -0
  3. package/.github/workflows/ci.yml +0 -0
  4. package/.github/workflows/main.yml +43 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +28 -0
  7. package/abis/IClearingCoordinator.abi.json +410 -0
  8. package/abis/IERC20Metadata.abi.json +224 -0
  9. package/abis/IFeeManager.abi.json +66 -0
  10. package/abis/IKSULocking.abi.json +754 -0
  11. package/abis/IKasuAllowList.abi.json +455 -0
  12. package/abis/IKasuController.abi.json +423 -0
  13. package/abis/IKasuNFTs.abi.json +1523 -0
  14. package/abis/IKsuPrice.abi.json +15 -0
  15. package/abis/ILendingPool.abi.json +1431 -0
  16. package/abis/ILendingPoolFactory.abi.json +97 -0
  17. package/abis/ILendingPoolManager.abi.json +1347 -0
  18. package/abis/ILendingPoolTranche.abi.json +1317 -0
  19. package/abis/IPriceFeed.abi.json +1 -0
  20. package/abis/ISystemVariables.abi.json +431 -0
  21. package/abis/IUserLoyaltyRewards.abi.json +288 -0
  22. package/abis/IUserManager.abi.json +321 -0
  23. package/abis/KSULockBonus.abi.json +91 -0
  24. package/abis/KasuPoolExternalTVL.abi.json +812 -0
  25. package/abis/Swapper.abi.json +146 -0
  26. package/copy-abi.ps1 +15 -0
  27. package/dist/bundle.cjs.js +21646 -0
  28. package/dist/bundle.esm.js +21644 -0
  29. package/dist/contracts/IClearingCoordinatorAbi.d.ts +169 -0
  30. package/dist/contracts/IClearingCoordinatorAbi.js +1 -0
  31. package/dist/contracts/IERC20MetadataAbi.d.ts +162 -0
  32. package/dist/contracts/IERC20MetadataAbi.js +1 -0
  33. package/dist/contracts/IFeeManagerAbi.d.ts +96 -0
  34. package/dist/contracts/IFeeManagerAbi.js +1 -0
  35. package/dist/contracts/IKSULockingAbi.d.ts +466 -0
  36. package/dist/contracts/IKSULockingAbi.js +1 -0
  37. package/dist/contracts/IKasuAllowListAbi.d.ts +304 -0
  38. package/dist/contracts/IKasuAllowListAbi.js +1 -0
  39. package/dist/contracts/IKasuControllerAbi.d.ts +309 -0
  40. package/dist/contracts/IKasuControllerAbi.js +1 -0
  41. package/dist/contracts/IKasuNFTsAbi.d.ts +1121 -0
  42. package/dist/contracts/IKasuNFTsAbi.js +1 -0
  43. package/dist/contracts/IKsuPriceAbi.d.ts +42 -0
  44. package/dist/contracts/IKsuPriceAbi.js +1 -0
  45. package/dist/contracts/ILendingPoolAbi.d.ts +968 -0
  46. package/dist/contracts/ILendingPoolAbi.js +1 -0
  47. package/dist/contracts/ILendingPoolFactoryAbi.d.ts +103 -0
  48. package/dist/contracts/ILendingPoolFactoryAbi.js +1 -0
  49. package/dist/contracts/ILendingPoolManagerAbi.d.ts +779 -0
  50. package/dist/contracts/ILendingPoolManagerAbi.js +1 -0
  51. package/dist/contracts/ILendingPoolTrancheAbi.d.ts +752 -0
  52. package/dist/contracts/ILendingPoolTrancheAbi.js +1 -0
  53. package/dist/contracts/ISystemVariablesAbi.d.ts +378 -0
  54. package/dist/contracts/ISystemVariablesAbi.js +1 -0
  55. package/dist/contracts/IUserLoyaltyRewardsAbi.d.ts +248 -0
  56. package/dist/contracts/IUserLoyaltyRewardsAbi.js +1 -0
  57. package/dist/contracts/IUserManagerAbi.d.ts +270 -0
  58. package/dist/contracts/IUserManagerAbi.js +1 -0
  59. package/dist/contracts/KSULockBonusAbi.d.ts +61 -0
  60. package/dist/contracts/KSULockBonusAbi.js +1 -0
  61. package/dist/contracts/KasuPoolExternalTVLAbi.d.ts +411 -0
  62. package/dist/contracts/KasuPoolExternalTVLAbi.js +1 -0
  63. package/dist/contracts/SwapperAbi.d.ts +120 -0
  64. package/dist/contracts/SwapperAbi.js +1 -0
  65. package/dist/contracts/common.d.ts +21 -0
  66. package/dist/contracts/common.js +1 -0
  67. package/dist/contracts/factories/IClearingCoordinatorAbi__factory.d.ts +320 -0
  68. package/dist/contracts/factories/IClearingCoordinatorAbi__factory.js +423 -0
  69. package/dist/contracts/factories/IERC20MetadataAbi__factory.d.ts +178 -0
  70. package/dist/contracts/factories/IERC20MetadataAbi__factory.js +237 -0
  71. package/dist/contracts/factories/IFeeManagerAbi__factory.d.ts +59 -0
  72. package/dist/contracts/factories/IFeeManagerAbi__factory.js +79 -0
  73. package/dist/contracts/factories/IKSULockingAbi__factory.d.ts +588 -0
  74. package/dist/contracts/factories/IKSULockingAbi__factory.js +767 -0
  75. package/dist/contracts/factories/IKasuAllowListAbi__factory.d.ts +354 -0
  76. package/dist/contracts/factories/IKasuAllowListAbi__factory.js +468 -0
  77. package/dist/contracts/factories/IKasuControllerAbi__factory.d.ts +339 -0
  78. package/dist/contracts/factories/IKasuControllerAbi__factory.js +436 -0
  79. package/dist/contracts/factories/IKasuNFTsAbi__factory.d.ts +1629 -0
  80. package/dist/contracts/factories/IKasuNFTsAbi__factory.js +2108 -0
  81. package/dist/contracts/factories/IKsuPriceAbi__factory.d.ts +18 -0
  82. package/dist/contracts/factories/IKsuPriceAbi__factory.js +28 -0
  83. package/dist/contracts/factories/ILendingPoolAbi__factory.d.ts +1109 -0
  84. package/dist/contracts/factories/ILendingPoolAbi__factory.js +1444 -0
  85. package/dist/contracts/factories/ILendingPoolFactoryAbi__factory.d.ts +81 -0
  86. package/dist/contracts/factories/ILendingPoolFactoryAbi__factory.js +110 -0
  87. package/dist/contracts/factories/ILendingPoolManagerAbi__factory.d.ts +1045 -0
  88. package/dist/contracts/factories/ILendingPoolManagerAbi__factory.js +1360 -0
  89. package/dist/contracts/factories/ILendingPoolTrancheAbi__factory.d.ts +1015 -0
  90. package/dist/contracts/factories/ILendingPoolTrancheAbi__factory.js +1330 -0
  91. package/dist/contracts/factories/ISystemVariablesAbi__factory.d.ts +338 -0
  92. package/dist/contracts/factories/ISystemVariablesAbi__factory.js +444 -0
  93. package/dist/contracts/factories/IUserLoyaltyRewardsAbi__factory.d.ts +230 -0
  94. package/dist/contracts/factories/IUserLoyaltyRewardsAbi__factory.js +301 -0
  95. package/dist/contracts/factories/IUserManagerAbi__factory.d.ts +250 -0
  96. package/dist/contracts/factories/IUserManagerAbi__factory.js +334 -0
  97. package/dist/contracts/factories/KSULockBonusAbi__factory.d.ts +76 -0
  98. package/dist/contracts/factories/KSULockBonusAbi__factory.js +104 -0
  99. package/dist/contracts/factories/KasuPoolExternalTVLAbi__factory.d.ts +631 -0
  100. package/dist/contracts/factories/KasuPoolExternalTVLAbi__factory.js +825 -0
  101. package/dist/contracts/factories/SwapperAbi__factory.d.ts +120 -0
  102. package/dist/contracts/factories/SwapperAbi__factory.js +159 -0
  103. package/dist/contracts/factories/index.d.ts +18 -0
  104. package/dist/contracts/factories/index.js +21 -0
  105. package/dist/contracts/index.d.ts +37 -0
  106. package/dist/contracts/index.js +19 -0
  107. package/dist/index.d.ts +17 -0
  108. package/dist/index.js +16 -0
  109. package/dist/sdk-config.d.ts +22 -0
  110. package/dist/sdk-config.js +9 -0
  111. package/dist/services/DataService/data-service.d.ts +37 -0
  112. package/dist/services/DataService/data-service.js +586 -0
  113. package/dist/services/DataService/directus-types.d.ts +187 -0
  114. package/dist/services/DataService/directus-types.js +1 -0
  115. package/dist/services/DataService/queries.d.ts +7 -0
  116. package/dist/services/DataService/queries.js +158 -0
  117. package/dist/services/DataService/subgraph-types.d.ts +95 -0
  118. package/dist/services/DataService/subgraph-types.js +1 -0
  119. package/dist/services/DataService/types.d.ts +169 -0
  120. package/dist/services/DataService/types.js +1 -0
  121. package/dist/services/Locking/locking.d.ts +61 -0
  122. package/dist/services/Locking/locking.js +344 -0
  123. package/dist/services/Locking/queries.d.ts +10 -0
  124. package/dist/services/Locking/queries.js +108 -0
  125. package/dist/services/Locking/types.d.ts +117 -0
  126. package/dist/services/Locking/types.js +1 -0
  127. package/dist/services/Portfolio/portfolio.d.ts +22 -0
  128. package/dist/services/Portfolio/portfolio.js +325 -0
  129. package/dist/services/Portfolio/queries.d.ts +2 -0
  130. package/dist/services/Portfolio/queries.js +164 -0
  131. package/dist/services/Portfolio/types.d.ts +206 -0
  132. package/dist/services/Portfolio/types.js +1 -0
  133. package/dist/services/Swapper/swapper.d.ts +11 -0
  134. package/dist/services/Swapper/swapper.js +97 -0
  135. package/dist/services/Swapper/types.d.ts +51 -0
  136. package/dist/services/Swapper/types.js +1 -0
  137. package/dist/services/UserLending/helper.d.ts +2 -0
  138. package/dist/services/UserLending/helper.js +16 -0
  139. package/dist/services/UserLending/queries.d.ts +8 -0
  140. package/dist/services/UserLending/queries.js +188 -0
  141. package/dist/services/UserLending/subgraph-types.d.ts +147 -0
  142. package/dist/services/UserLending/subgraph-types.js +6 -0
  143. package/dist/services/UserLending/types.d.ts +102 -0
  144. package/dist/services/UserLending/types.js +13 -0
  145. package/dist/services/UserLending/user-lending.d.ts +55 -0
  146. package/dist/services/UserLending/user-lending.js +490 -0
  147. package/dist/services/shared.d.ts +1 -0
  148. package/dist/services/shared.js +11 -0
  149. package/dist/tests/sample.test.d.ts +1 -0
  150. package/dist/tests/sample.test.js +32 -0
  151. package/index.ts +2 -0
  152. package/jest-config.ts +9 -0
  153. package/jest.config.js +8 -0
  154. package/package.json +49 -0
  155. package/rollup.config.js +45 -0
  156. package/src/contracts/IClearingCoordinatorAbi.ts +406 -0
  157. package/src/contracts/IERC20MetadataAbi.ts +364 -0
  158. package/src/contracts/IFeeManagerAbi.ts +182 -0
  159. package/src/contracts/IKSULockingAbi.ts +965 -0
  160. package/src/contracts/IKasuAllowListAbi.ts +605 -0
  161. package/src/contracts/IKasuControllerAbi.ts +703 -0
  162. package/src/contracts/IKasuNFTsAbi.ts +2744 -0
  163. package/src/contracts/IKsuPriceAbi.ts +87 -0
  164. package/src/contracts/ILendingPoolAbi.ts +2081 -0
  165. package/src/contracts/ILendingPoolFactoryAbi.ts +161 -0
  166. package/src/contracts/ILendingPoolManagerAbi.ts +1917 -0
  167. package/src/contracts/ILendingPoolTrancheAbi.ts +1911 -0
  168. package/src/contracts/ISystemVariablesAbi.ts +908 -0
  169. package/src/contracts/IUserLoyaltyRewardsAbi.ts +544 -0
  170. package/src/contracts/IUserManagerAbi.ts +612 -0
  171. package/src/contracts/KSULockBonusAbi.ts +124 -0
  172. package/src/contracts/KasuPoolExternalTVLAbi.ts +1071 -0
  173. package/src/contracts/SwapperAbi.ts +266 -0
  174. package/src/contracts/common.ts +44 -0
  175. package/src/contracts/factories/IClearingCoordinatorAbi__factory.ts +438 -0
  176. package/src/contracts/factories/IERC20MetadataAbi__factory.ts +248 -0
  177. package/src/contracts/factories/IFeeManagerAbi__factory.ts +90 -0
  178. package/src/contracts/factories/IKSULockingAbi__factory.ts +778 -0
  179. package/src/contracts/factories/IKasuAllowListAbi__factory.ts +479 -0
  180. package/src/contracts/factories/IKasuControllerAbi__factory.ts +447 -0
  181. package/src/contracts/factories/IKasuNFTsAbi__factory.ts +2116 -0
  182. package/src/contracts/factories/IKsuPriceAbi__factory.ts +36 -0
  183. package/src/contracts/factories/ILendingPoolAbi__factory.ts +1455 -0
  184. package/src/contracts/factories/ILendingPoolFactoryAbi__factory.ts +125 -0
  185. package/src/contracts/factories/ILendingPoolManagerAbi__factory.ts +1375 -0
  186. package/src/contracts/factories/ILendingPoolTrancheAbi__factory.ts +1345 -0
  187. package/src/contracts/factories/ISystemVariablesAbi__factory.ts +455 -0
  188. package/src/contracts/factories/IUserLoyaltyRewardsAbi__factory.ts +316 -0
  189. package/src/contracts/factories/IUserManagerAbi__factory.ts +345 -0
  190. package/src/contracts/factories/KSULockBonusAbi__factory.ts +115 -0
  191. package/src/contracts/factories/KasuPoolExternalTVLAbi__factory.ts +840 -0
  192. package/src/contracts/factories/SwapperAbi__factory.ts +167 -0
  193. package/src/contracts/factories/index.ts +21 -0
  194. package/src/contracts/index.ts +40 -0
  195. package/src/index.ts +27 -0
  196. package/src/sdk-config.ts +35 -0
  197. package/src/services/DataService/data-service.ts +1017 -0
  198. package/src/services/DataService/directus-types.ts +199 -0
  199. package/src/services/DataService/queries.ts +165 -0
  200. package/src/services/DataService/subgraph-types.ts +104 -0
  201. package/src/services/DataService/types.ts +184 -0
  202. package/src/services/Locking/locking.ts +541 -0
  203. package/src/services/Locking/queries.ts +118 -0
  204. package/src/services/Locking/types.ts +141 -0
  205. package/src/services/Portfolio/portfolio.ts +593 -0
  206. package/src/services/Portfolio/queries.ts +166 -0
  207. package/src/services/Portfolio/types.ts +220 -0
  208. package/src/services/Swapper/swapper.ts +158 -0
  209. package/src/services/Swapper/types.ts +54 -0
  210. package/src/services/UserLending/helper.ts +28 -0
  211. package/src/services/UserLending/queries.ts +196 -0
  212. package/src/services/UserLending/subgraph-types.ts +173 -0
  213. package/src/services/UserLending/types.ts +123 -0
  214. package/src/services/UserLending/user-lending.ts +933 -0
  215. package/src/services/shared.ts +11 -0
  216. package/src/tests/sample.test.ts +44 -0
  217. package/tsconfig.json +27 -0
  218. package/tsconfig.tsbuildinfo +1 -0
  219. package/versioner.sh +6 -0
@@ -0,0 +1,933 @@
1
+ import {
2
+ authentication,
3
+ AuthenticationClient,
4
+ createDirectus,
5
+ DirectusClient,
6
+ readItems,
7
+ rest,
8
+ RestClient,
9
+ } from '@directus/sdk';
10
+ import { Provider } from '@ethersproject/providers';
11
+ import {
12
+ BigNumber,
13
+ BigNumberish,
14
+ BytesLike,
15
+ ContractTransaction,
16
+ ethers,
17
+ Signer,
18
+ } from 'ethers';
19
+ import {
20
+ defaultAbiCoder,
21
+ formatEther,
22
+ formatUnits,
23
+ parseEther,
24
+ parseUnits,
25
+ } from 'ethers/lib/utils';
26
+ import { GraphQLClient } from 'graphql-request';
27
+
28
+ import {
29
+ IClearingCoordinatorAbi,
30
+ IClearingCoordinatorAbi__factory,
31
+ IKasuAllowListAbi__factory,
32
+ ILendingPoolAbi__factory,
33
+ ILendingPoolManagerAbi,
34
+ ILendingPoolManagerAbi__factory,
35
+ ILendingPoolTrancheAbi,
36
+ ILendingPoolTrancheAbi__factory,
37
+ ISystemVariablesAbi,
38
+ ISystemVariablesAbi__factory,
39
+ IUserLoyaltyRewardsAbi,
40
+ IUserLoyaltyRewardsAbi__factory,
41
+ IUserManagerAbi,
42
+ IUserManagerAbi__factory,
43
+ } from '../../contracts';
44
+ import { SdkConfig } from '../../sdk-config';
45
+ import { DataService } from '../DataService/data-service';
46
+ import { DirectusSchema } from '../DataService/directus-types';
47
+
48
+ import { mapUserRequestEventType } from './helper';
49
+ import {
50
+ currentEpochDepositedAmountQuery,
51
+ currentEpochFtdAmountQuery,
52
+ currentFtdBalanceQuery,
53
+ lendingPoolUserDetailsQuery,
54
+ portfolioUserTrancheDetailsQuery,
55
+ totalUserLoyaltyRewardsQuery,
56
+ trancheUserDetailsQuery,
57
+ userRequestsQuery,
58
+ } from './queries';
59
+ import {
60
+ CurrentEpochDepositedAmountSubgraph,
61
+ CurrentEpochFtdAmountSubgraph,
62
+ CurrentFtdBalanceSubgraph,
63
+ LendingPoolUserDetailsSubgraph,
64
+ PortfolioTrancheUserDetailsSubgraph,
65
+ TotalUserLoyaltyRewardsSubgraph,
66
+ TrancheUserDetailsSubgraph,
67
+ UserRequestsSubgraph,
68
+ } from './subgraph-types';
69
+ import {
70
+ PortfolioUserTrancheBalance,
71
+ UserApyBonus,
72
+ UserPoolBalance,
73
+ UserRequest,
74
+ UserRequestEvent,
75
+ UserTrancheBalance,
76
+ } from './types';
77
+
78
+ export class UserLending {
79
+ private readonly _graph: GraphQLClient;
80
+
81
+ private readonly _directus: DirectusClient<DirectusSchema> &
82
+ AuthenticationClient<DirectusSchema> &
83
+ RestClient<DirectusSchema>;
84
+ private _dataService: DataService;
85
+ private readonly _userManagerAbi: IUserManagerAbi;
86
+ private readonly _lendingPoolManagerAbi: ILendingPoolManagerAbi;
87
+ private readonly _userLoyaltyRewardsAbi: IUserLoyaltyRewardsAbi;
88
+ private readonly _clearingCoordinatorAbi: IClearingCoordinatorAbi;
89
+ private readonly _systemVariablesAbi: ISystemVariablesAbi;
90
+
91
+ readonly _signerOrProvider: Signer | Provider;
92
+
93
+ constructor(
94
+ private _kasuConfig: SdkConfig,
95
+ signerOrProvider: Signer | Provider,
96
+ ) {
97
+ this._signerOrProvider = signerOrProvider;
98
+ this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
99
+ this._userManagerAbi = IUserManagerAbi__factory.connect(
100
+ _kasuConfig.contracts.UserManager,
101
+ signerOrProvider,
102
+ );
103
+ this._lendingPoolManagerAbi = ILendingPoolManagerAbi__factory.connect(
104
+ _kasuConfig.contracts.LendingPoolManager,
105
+ signerOrProvider,
106
+ );
107
+ this._userLoyaltyRewardsAbi = IUserLoyaltyRewardsAbi__factory.connect(
108
+ _kasuConfig.contracts.UserLoyaltyRewards,
109
+ signerOrProvider,
110
+ );
111
+ this._clearingCoordinatorAbi = IClearingCoordinatorAbi__factory.connect(
112
+ _kasuConfig.contracts.ClearingCoordinator,
113
+ signerOrProvider,
114
+ );
115
+ this._systemVariablesAbi = ISystemVariablesAbi__factory.connect(
116
+ _kasuConfig.contracts.SystemVariables,
117
+ signerOrProvider,
118
+ );
119
+ this._dataService = new DataService(_kasuConfig, signerOrProvider);
120
+ this._directus = createDirectus<DirectusSchema>(_kasuConfig.directusUrl)
121
+ .with(authentication())
122
+ .with(rest());
123
+ }
124
+
125
+ async getUserTotalPendingAndActiveDepositedAmount(
126
+ user: string,
127
+ ): Promise<[BigNumber, BigNumber]> {
128
+ return await this._userManagerAbi.userTotalPendingAndActiveDepositedAmount(
129
+ user,
130
+ );
131
+ }
132
+
133
+ async getUserTotalPendingAndActiveDepositedAmountForCurrentEpoch(
134
+ user: string,
135
+ ): Promise<[BigNumber, BigNumber]> {
136
+ return await this._userManagerAbi.userTotalPendingAndActiveDepositedAmountForCurrentEpoch(
137
+ user,
138
+ );
139
+ }
140
+
141
+ async hasUserRKSU(user: string): Promise<boolean> {
142
+ return await this._userManagerAbi.hasUserRKSU(user);
143
+ }
144
+
145
+ buildKycSignatureParams(
146
+ userAddress: `0x${string}`,
147
+ chainId: string,
148
+ ): {
149
+ contractAbi: IKasuAllowListAbi__factory;
150
+ contractAddress: string;
151
+ functionName: string;
152
+ args: BytesLike[];
153
+ userAddress: string;
154
+ chainId: string;
155
+ } {
156
+ const address = userAddress.toLowerCase() as `0x${string}`;
157
+
158
+ return {
159
+ contractAbi: IKasuAllowListAbi__factory.abi,
160
+ contractAddress:
161
+ this._kasuConfig.contracts.KasuAllowList.toLowerCase() as `0x${string}`,
162
+ functionName: 'verifyUserKyc',
163
+ args: [address],
164
+ userAddress: address,
165
+ chainId,
166
+ };
167
+ }
168
+
169
+ buildDepositSwapData(
170
+ fromToken: string,
171
+ fromAmount: string,
172
+ routerAddress: string,
173
+ swapCallData: string,
174
+ minAmountOut: string,
175
+ ): BytesLike {
176
+ return defaultAbiCoder.encode(
177
+ [
178
+ 'tuple(address[], uint256[], (address, address,bytes)[], uint256)',
179
+ ],
180
+ [
181
+ [
182
+ [fromToken],
183
+ [fromAmount],
184
+ [[routerAddress, fromToken, swapCallData]],
185
+ minAmountOut,
186
+ ],
187
+ ],
188
+ );
189
+ }
190
+
191
+ async requestDepositWithKyc(
192
+ lendingPool: string,
193
+ tranche: string,
194
+ maxAmount: BigNumberish,
195
+ swapData: BytesLike,
196
+ fixedTermConfigId: BigNumberish,
197
+ depositData: BytesLike,
198
+ kycData: {
199
+ blockExpiration: BigNumberish;
200
+ signature: BytesLike;
201
+ },
202
+ ethValue: string,
203
+ ): Promise<ContractTransaction> {
204
+ return await this._lendingPoolManagerAbi.requestDepositWithKyc(
205
+ lendingPool,
206
+ tranche,
207
+ maxAmount,
208
+ swapData,
209
+ fixedTermConfigId,
210
+ depositData,
211
+ kycData,
212
+ {
213
+ value: ethValue,
214
+ },
215
+ );
216
+ }
217
+
218
+ async requestDeposit(
219
+ lendingPool: string,
220
+ tranche: string,
221
+ amount: BigNumberish,
222
+ swapData: BytesLike,
223
+ fixedTermConfigId: BigNumberish,
224
+ depositData: BytesLike,
225
+ ): Promise<ContractTransaction> {
226
+ return await this._lendingPoolManagerAbi.requestDeposit(
227
+ lendingPool,
228
+ tranche,
229
+ amount,
230
+ swapData,
231
+ fixedTermConfigId,
232
+ depositData,
233
+ );
234
+ }
235
+
236
+ async withdrawAtExpiry(
237
+ lendingPool: string,
238
+ fixedTermDepositId: string,
239
+ ): Promise<ContractTransaction> {
240
+ return await this._lendingPoolManagerAbi.requestFixedTermDepositWithdrawal(
241
+ lendingPool,
242
+ fixedTermDepositId,
243
+ );
244
+ }
245
+
246
+ async lockDepositForFixedTerm(
247
+ lendingPool: string,
248
+ tranche: string,
249
+ amount: BigNumberish,
250
+ fixedTermConfigId: BigNumberish,
251
+ ): Promise<ContractTransaction> {
252
+ const trancheContract: ILendingPoolTrancheAbi =
253
+ ILendingPoolTrancheAbi__factory.connect(
254
+ tranche,
255
+ this._signerOrProvider,
256
+ );
257
+
258
+ const shareAmount = await trancheContract.convertToShares(amount);
259
+
260
+ return await this._lendingPoolManagerAbi.lockDepositForFixedTerm(
261
+ lendingPool,
262
+ tranche,
263
+ shareAmount,
264
+ fixedTermConfigId,
265
+ );
266
+ }
267
+
268
+ async cancelDepositRequest(
269
+ lendingPool: string,
270
+ dNftID: BigNumberish,
271
+ ): Promise<ContractTransaction> {
272
+ return await this._lendingPoolManagerAbi.cancelDepositRequest(
273
+ lendingPool,
274
+ dNftID,
275
+ );
276
+ }
277
+
278
+ async requestWithdrawal(
279
+ lendingPool: string,
280
+ tranche: string,
281
+ amount: BigNumberish,
282
+ ): Promise<ContractTransaction> {
283
+ return await this._lendingPoolManagerAbi.requestWithdrawal(
284
+ lendingPool,
285
+ tranche,
286
+ amount,
287
+ );
288
+ }
289
+
290
+ async requestWithdrawalInUSDC(
291
+ lendingPool: string,
292
+ tranche: string,
293
+ usdcAmount: BigNumberish,
294
+ ): Promise<ContractTransaction> {
295
+ const trancheContract: ILendingPoolTrancheAbi =
296
+ ILendingPoolTrancheAbi__factory.connect(
297
+ tranche,
298
+ this._signerOrProvider,
299
+ );
300
+ const shareAmount = await trancheContract.convertToShares(usdcAmount);
301
+
302
+ return await this._lendingPoolManagerAbi.requestWithdrawal(
303
+ lendingPool,
304
+ tranche,
305
+ shareAmount,
306
+ );
307
+ }
308
+
309
+ async requestWithdrawalMax(
310
+ lendingPool: string,
311
+ tranche: string,
312
+ user: string,
313
+ ): Promise<ContractTransaction> {
314
+ const trancheContract: ILendingPoolTrancheAbi =
315
+ ILendingPoolTrancheAbi__factory.connect(
316
+ tranche,
317
+ this._signerOrProvider,
318
+ );
319
+ const userShares = await trancheContract['balanceOf(address)'](user);
320
+
321
+ return await this._lendingPoolManagerAbi.requestWithdrawal(
322
+ lendingPool,
323
+ tranche,
324
+ userShares,
325
+ );
326
+ }
327
+
328
+ async cancelWithdrawalRequest(
329
+ lendingPool: string,
330
+ dNftID: BigNumberish,
331
+ ): Promise<ContractTransaction> {
332
+ return await this._lendingPoolManagerAbi.cancelWithdrawalRequest(
333
+ lendingPool,
334
+ dNftID,
335
+ );
336
+ }
337
+
338
+ async claimRepaidLoss(
339
+ lendingPool: string,
340
+ tranche: string,
341
+ lossId: BigNumberish,
342
+ ): Promise<ContractTransaction> {
343
+ return await this._lendingPoolManagerAbi.claimRepaidLoss(
344
+ lendingPool,
345
+ tranche,
346
+ lossId,
347
+ );
348
+ }
349
+
350
+ async getUserRequests(
351
+ userAddress: `0x${string}`,
352
+ epochId: string,
353
+ ): Promise<UserRequest[]> {
354
+ const trancheNames: string[][] = [
355
+ ['Senior'],
356
+ ['Junior', 'Senior'],
357
+ ['Junior', 'Mezzanine', 'Senior'],
358
+ ];
359
+
360
+ const [subgraphResult, directusResult] = await Promise.all([
361
+ this._graph.request<UserRequestsSubgraph>(userRequestsQuery, {
362
+ userAddress: userAddress.toLowerCase(),
363
+ unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS,
364
+ epochId,
365
+ }),
366
+ this._directus.request(
367
+ readItems('PoolOverview', {
368
+ fields: ['id', 'poolName', 'subheading'],
369
+ }),
370
+ ),
371
+ ]);
372
+
373
+ const retn: UserRequest[] = [];
374
+
375
+ for (const userRequest of subgraphResult.userRequests) {
376
+ const directusPool = directusResult.find(
377
+ ({ id }) => id === userRequest.lendingPool.id,
378
+ );
379
+
380
+ const trancheName =
381
+ trancheNames[userRequest.lendingPool.tranches.length - 1][
382
+ parseInt(userRequest.tranche.orderId)
383
+ ];
384
+
385
+ const events: UserRequestEvent[] = [];
386
+
387
+ for (const event of userRequest.userRequestEvents) {
388
+ let totalRequested = '0';
389
+ let totalAccepted = '0';
390
+ let totalRejected = '0';
391
+
392
+ const eventTrancheId = event.tranche.id;
393
+ const eventTrancheName =
394
+ trancheNames[userRequest.lendingPool.tranches.length - 1][
395
+ parseInt(event.tranche.orderId)
396
+ ];
397
+
398
+ if (eventTrancheId !== userRequest.tranche.id) {
399
+ event.type = 'DepositReallocated';
400
+ }
401
+
402
+ const assetAmount =
403
+ event.assetAmount ??
404
+ this.convertSharesToAssets(
405
+ event.sharesAmount,
406
+ userRequest.tranche.balance,
407
+ userRequest.tranche.shares,
408
+ ).toString();
409
+
410
+ switch (event.type) {
411
+ case 'DepositAccepted':
412
+ case 'WithdrawalAccepted':
413
+ case 'DepositReallocated':
414
+ case 'ImmediateWithdrawalExecuted':
415
+ totalAccepted = assetAmount;
416
+ break;
417
+ case 'DepositCancelled':
418
+ case 'WithdrawalCancelled':
419
+ case 'DepositRejected':
420
+ totalRejected = assetAmount;
421
+ break;
422
+
423
+ case 'DepositInitiated':
424
+ case 'WithdrawalInitiated':
425
+ case 'DepositIncreased':
426
+ case 'WithdrawalIncreased':
427
+ totalRequested = assetAmount;
428
+ break;
429
+ }
430
+
431
+ const eventTranche =
432
+ userRequest.lendingPool.configuration.tranchesConfig.find(
433
+ (trancheConfig) =>
434
+ trancheConfig.id === event.tranche.id,
435
+ );
436
+
437
+ // shouldn't be possible, just adding type checking here
438
+ if (!eventTranche) continue;
439
+
440
+ const interestRate = eventTranche
441
+ .lendingPoolTrancheInterestRateUpdates.length
442
+ ? eventTranche.lendingPoolTrancheInterestRateUpdates[0]
443
+ .epochInterestRate
444
+ : eventTranche.interestRate;
445
+
446
+ const baseApy =
447
+ this._dataService.calculateApyForTranche(interestRate);
448
+
449
+ events.push({
450
+ id: event.id,
451
+ requestType: mapUserRequestEventType(event.type),
452
+ timestamp: parseInt(event.createdOn),
453
+ totalRequested,
454
+ totalAccepted,
455
+ totalRejected,
456
+ assetAmount,
457
+ index: parseInt(event.index),
458
+ transactionHash: event.transactionHash,
459
+ trancheName: eventTrancheName,
460
+ trancheId: event.tranche.id,
461
+ apy: baseApy.toString(),
462
+ epochId: event.epochId,
463
+ });
464
+ }
465
+
466
+ const tranche =
467
+ userRequest.lendingPool.configuration.tranchesConfig.find(
468
+ (trancheConfig) =>
469
+ trancheConfig.id === userRequest.tranche.id,
470
+ );
471
+
472
+ // shouldn't be possible, just adding type checking here
473
+ if (!tranche) continue;
474
+
475
+ const interestRate = tranche.lendingPoolTrancheInterestRateUpdates
476
+ .length
477
+ ? tranche.lendingPoolTrancheInterestRateUpdates[0]
478
+ .epochInterestRate
479
+ : tranche.interestRate;
480
+
481
+ const baseApy =
482
+ this._dataService.calculateApyForTranche(interestRate);
483
+
484
+ const ftdConfig = tranche.lendingPoolTrancheFixedTermConfigs.find(
485
+ (config) => config.configId === userRequest.fixedTermConfigId,
486
+ );
487
+
488
+ let fixedTermConfig: UserRequest['fixedTermConfig'];
489
+
490
+ if (ftdConfig) {
491
+ const fixedTermApy = this._dataService.calculateApyForTranche(
492
+ ftdConfig.epochInterestRate,
493
+ );
494
+
495
+ fixedTermConfig = {
496
+ configId: ftdConfig.configId,
497
+ apy: fixedTermApy.toString(),
498
+ epochLockDuration: ftdConfig.epochLockDuration,
499
+ epochInterestRate: ftdConfig.epochInterestRate,
500
+ };
501
+ }
502
+
503
+ const poolName =
504
+ directusPool?.poolName ?? userRequest.lendingPool.name;
505
+
506
+ const userRequestBase: UserRequest = {
507
+ id: userRequest.id,
508
+ userId: userRequest.user.id,
509
+ lendingPool: {
510
+ id: userRequest.lendingPool.id,
511
+ name: directusPool?.subheading
512
+ ? `${poolName} - ${directusPool.subheading}`
513
+ : poolName,
514
+ tranches: userRequest.lendingPool.tranches,
515
+ },
516
+ requestType:
517
+ userRequest.type === 'DepositRequest'
518
+ ? 'Deposit'
519
+ : 'Withdrawal',
520
+ trancheName: trancheName,
521
+ trancheId: userRequest.tranche.id,
522
+ requestedAmount: parseUnits(userRequest.tranche.shares).isZero()
523
+ ? userRequest.amountRequested
524
+ : this.convertSharesToAssets(
525
+ userRequest.amountRequested,
526
+ userRequest.tranche.balance,
527
+ userRequest.tranche.shares,
528
+ ).toString(),
529
+ acceptedAmount: userRequest.amountAccepted,
530
+ rejectedAmount: userRequest.amountRejected,
531
+ status: userRequest.status,
532
+ timestamp: parseInt(userRequest.createdOn),
533
+ canCancel: await this.isCancelable(
534
+ userRequest.status,
535
+ userRequest.lendingPool.id,
536
+ ),
537
+ nftId: userRequest.nftId,
538
+ events: events,
539
+ fixedTermConfig,
540
+ apy: baseApy.toString(),
541
+ };
542
+
543
+ retn.push(userRequestBase);
544
+ }
545
+
546
+ return retn;
547
+ }
548
+
549
+ async getCurrentEpoch(): Promise<string> {
550
+ const currentEpochNumber =
551
+ await this._systemVariablesAbi.currentEpochNumber();
552
+
553
+ return currentEpochNumber.toString();
554
+ }
555
+
556
+ async getCurrentFtdBalance(
557
+ poolId: string,
558
+ userId: string,
559
+ ): Promise<Map<string, number[]>> {
560
+ const currentFtdBalance: CurrentFtdBalanceSubgraph =
561
+ await this._graph.request(currentFtdBalanceQuery, {
562
+ userId: userId.toLowerCase(),
563
+ poolId: poolId.toLowerCase(),
564
+ });
565
+
566
+ const trancheMap = new Map<string, number[]>();
567
+
568
+ for (const userFTD of currentFtdBalance.userLendingPoolTrancheFixedTermDepositLocks) {
569
+ const ftdID = parseFloat(
570
+ userFTD.lendingPoolTrancheFixedTermConfig.configId,
571
+ );
572
+
573
+ const trancheID =
574
+ userFTD.lendingPoolTrancheFixedTermConfig.lendingPoolTranche.id.toLowerCase();
575
+
576
+ const totalSupply = userFTD.lendingPool.tranches.reduce(
577
+ (total, cur) => total.add(parseEther(cur.shares)),
578
+ BigNumber.from(0),
579
+ );
580
+
581
+ const amount = this.convertSharesToAssets(
582
+ userFTD.trancheShares,
583
+ userFTD.lendingPool.balance,
584
+ formatEther(totalSupply),
585
+ );
586
+
587
+ const item = trancheMap.get(trancheID) ?? [];
588
+
589
+ if (item[ftdID]) {
590
+ item[ftdID] += parseFloat(amount);
591
+ } else {
592
+ item[ftdID] = parseFloat(amount);
593
+ }
594
+
595
+ trancheMap.set(trancheID, item);
596
+ }
597
+
598
+ return trancheMap;
599
+ }
600
+
601
+ async getCurrentEpochFtdAmount(
602
+ poolIds: string[],
603
+ userId: string,
604
+ currentEpoch: string,
605
+ ): Promise<Map<string, string[]>> {
606
+ const currentEpochFtdAmountRes: CurrentEpochFtdAmountSubgraph =
607
+ await this._graph.request(currentEpochFtdAmountQuery, {
608
+ userId: userId.toLowerCase(),
609
+ poolIds: poolIds.map((id) => id.toLowerCase()),
610
+ currentEpoch: parseFloat(currentEpoch),
611
+ });
612
+
613
+ const currentEpochFtdAmounts = new Map<string, string[]>();
614
+
615
+ for (const userRequest of currentEpochFtdAmountRes.userRequests) {
616
+ const ftdID = parseFloat(userRequest.fixedTermConfigId);
617
+
618
+ const item = currentEpochFtdAmounts.get(userRequest.tranche.id);
619
+
620
+ const amountRequested = this.convertSharesToAssets(
621
+ userRequest.amountRequested,
622
+ userRequest.tranche.balance,
623
+ userRequest.tranche.shares,
624
+ );
625
+
626
+ if (item) {
627
+ const clonedItem = [...item];
628
+
629
+ clonedItem[ftdID] = amountRequested;
630
+
631
+ currentEpochFtdAmounts.set(userRequest.tranche.id, clonedItem);
632
+
633
+ continue;
634
+ }
635
+ const ftdAmounts: string[] = [];
636
+
637
+ ftdAmounts[ftdID] = amountRequested;
638
+
639
+ currentEpochFtdAmounts.set(userRequest.tranche.id, ftdAmounts);
640
+ }
641
+
642
+ return currentEpochFtdAmounts;
643
+ }
644
+
645
+ async getCurrentEpochDepositedAmount(
646
+ lendingPoolIds: string[],
647
+ userId: string,
648
+ ): Promise<Map<string, string>> {
649
+ const currentEpochDepositedAmountRes: CurrentEpochDepositedAmountSubgraph =
650
+ await this._graph.request(currentEpochDepositedAmountQuery, {
651
+ ids: lendingPoolIds.map((poolId) => `${poolId}-${userId}`),
652
+ });
653
+
654
+ const amountMap = new Map<string, string>();
655
+
656
+ if (
657
+ !currentEpochDepositedAmountRes.lendingPoolUserDetails_collection
658
+ ?.length
659
+ )
660
+ return amountMap;
661
+
662
+ const lendingPoolTrancheUserDetails =
663
+ currentEpochDepositedAmountRes.lendingPoolUserDetails_collection.flatMap(
664
+ ({ lendingPoolTrancheUserDetails }) =>
665
+ lendingPoolTrancheUserDetails,
666
+ );
667
+
668
+ for (const {
669
+ tranche,
670
+ totalPendingDepositAmount,
671
+ } of lendingPoolTrancheUserDetails) {
672
+ amountMap.set(tranche.id.toLowerCase(), totalPendingDepositAmount);
673
+ }
674
+
675
+ return amountMap;
676
+ }
677
+
678
+ convertSharesToAssets(
679
+ sharesAmount: string,
680
+ totalAssets: string,
681
+ totalSupply: string,
682
+ ): string {
683
+ if (parseUnits(totalSupply).isZero()) return '0';
684
+
685
+ return formatUnits(
686
+ parseUnits(sharesAmount)
687
+ .mul(parseUnits(totalAssets.toString()))
688
+ .div(parseUnits(totalSupply.toString())),
689
+ );
690
+ }
691
+
692
+ async isClearingPending(poolId: string): Promise<boolean> {
693
+ return await this._clearingCoordinatorAbi.isLendingPoolClearingPending(
694
+ poolId,
695
+ );
696
+ }
697
+
698
+ async isCancelable(
699
+ status: string,
700
+ lendingPoolId: string,
701
+ ): Promise<boolean> {
702
+ if (status === 'Processed') return false;
703
+
704
+ const isClearingPending = await this.isClearingPending(lendingPoolId);
705
+
706
+ return !isClearingPending;
707
+ }
708
+
709
+ async getUserPoolBalance(
710
+ user: string,
711
+ poolIds: string[],
712
+ provider?: Provider,
713
+ ): Promise<UserPoolBalance[]> {
714
+ const poolBalances: {
715
+ poolId: string;
716
+ balance: Promise<BigNumber>;
717
+ }[] = [];
718
+
719
+ for (const poolId of poolIds) {
720
+ const lendingPool = ILendingPoolAbi__factory.connect(
721
+ poolId,
722
+ provider ?? this._signerOrProvider,
723
+ );
724
+ if (
725
+ this._kasuConfig.UNUSED_LENDING_POOL_IDS.includes(
726
+ poolId.toLowerCase(),
727
+ )
728
+ ) {
729
+ console.error('This pool is no longer in used');
730
+ continue;
731
+ }
732
+
733
+ poolBalances.push({
734
+ poolId,
735
+ balance: lendingPool.userBalance(user),
736
+ });
737
+ }
738
+
739
+ const [userDetailsSubgraph, balances] = await Promise.all([
740
+ this._graph.request<LendingPoolUserDetailsSubgraph>(
741
+ lendingPoolUserDetailsQuery,
742
+ {
743
+ userAddress: user.toLowerCase(),
744
+ },
745
+ ),
746
+ Promise.all(
747
+ poolBalances.map(async ({ balance, poolId }) => ({
748
+ poolId,
749
+ balance: await balance,
750
+ })),
751
+ ),
752
+ ]);
753
+
754
+ if (!userDetailsSubgraph.user?.lendingPoolUserDetails) {
755
+ return poolIds.map((poolId) => ({
756
+ poolId,
757
+ yieldEarned: 0,
758
+ balance: BigNumber.from(0),
759
+ }));
760
+ }
761
+
762
+ return userDetailsSubgraph.user.lendingPoolUserDetails.map(
763
+ ({
764
+ lendingPool,
765
+ totalAcceptedDeposits,
766
+ totalAcceptedWithdrawnAmount,
767
+ }) => {
768
+ const balance =
769
+ balances.find(
770
+ ({ poolId }) =>
771
+ poolId.toLowerCase() ===
772
+ lendingPool.id.toLowerCase(),
773
+ )?.balance ?? BigNumber.from(0);
774
+
775
+ return {
776
+ poolId: lendingPool.id,
777
+ yieldEarned:
778
+ parseFloat(ethers.utils.formatUnits(balance, 6)) -
779
+ parseFloat(totalAcceptedDeposits) -
780
+ -parseFloat(totalAcceptedWithdrawnAmount),
781
+ balance,
782
+ };
783
+ },
784
+ );
785
+ }
786
+
787
+ async getPortfolioUserTrancheBalances(
788
+ user: string,
789
+ ): Promise<PortfolioUserTrancheBalance> {
790
+ const userDetails: PortfolioTrancheUserDetailsSubgraph =
791
+ await this._graph.request(portfolioUserTrancheDetailsQuery, {
792
+ userAddress: user.toLowerCase(),
793
+ });
794
+
795
+ const mapper = new Map<
796
+ string,
797
+ {
798
+ trancheId: string;
799
+ yieldEarned: number;
800
+ userBalance: string;
801
+ }[]
802
+ >();
803
+
804
+ if (!userDetails.user) return mapper;
805
+
806
+ for (const lendingPoolUserDetail of userDetails.user
807
+ .lendingPoolUserDetails) {
808
+ const tranches: {
809
+ trancheId: string;
810
+ yieldEarned: number;
811
+ userBalance: string;
812
+ }[] = [];
813
+
814
+ for (const trancheDetail of lendingPoolUserDetail.lendingPoolTrancheUserDetails) {
815
+ let yieldEarned = 0;
816
+
817
+ let userBalance = '0';
818
+
819
+ if (trancheDetail) {
820
+ userBalance = this.convertSharesToAssets(
821
+ trancheDetail.shares,
822
+ trancheDetail.tranche.balance,
823
+ trancheDetail.tranche.shares,
824
+ );
825
+
826
+ const totalAcceptedDeposits = parseFloat(
827
+ trancheDetail.totalAcceptedDeposits,
828
+ );
829
+
830
+ const totalAcceptedWithdrawals = parseFloat(
831
+ trancheDetail.totalAcceptedWithdrawnAmount,
832
+ );
833
+
834
+ yieldEarned =
835
+ parseFloat(userBalance) -
836
+ totalAcceptedDeposits -
837
+ -totalAcceptedWithdrawals;
838
+
839
+ tranches.push({
840
+ trancheId: trancheDetail.tranche.id,
841
+ yieldEarned,
842
+ userBalance,
843
+ });
844
+ }
845
+ }
846
+ mapper.set(lendingPoolUserDetail.lendingPool.id, tranches);
847
+ }
848
+
849
+ return mapper;
850
+ }
851
+
852
+ async getUserTrancheBalance(
853
+ user: string,
854
+ poolId: string,
855
+ trancheId: string,
856
+ ): Promise<UserTrancheBalance> {
857
+ const tranche = ILendingPoolTrancheAbi__factory.connect(
858
+ trancheId,
859
+ this._signerOrProvider,
860
+ );
861
+
862
+ const [availableToWithdraw, userDetails] = await Promise.all([
863
+ tranche.maxWithdraw(user),
864
+ this._graph.request(trancheUserDetailsQuery, {
865
+ userAddress: `${poolId}-${user}-${trancheId}`,
866
+ }),
867
+ ]);
868
+
869
+ const userDetailsSubgraph = userDetails as TrancheUserDetailsSubgraph;
870
+
871
+ let yieldEarned = 0;
872
+
873
+ let userBalance = '0';
874
+
875
+ if (
876
+ userDetailsSubgraph.lendingPoolTrancheUserDetails &&
877
+ !parseUnits(
878
+ userDetailsSubgraph.lendingPoolTrancheUserDetails.tranche
879
+ .shares,
880
+ ).isZero()
881
+ ) {
882
+ userBalance = this.convertSharesToAssets(
883
+ userDetailsSubgraph.lendingPoolTrancheUserDetails.shares,
884
+ userDetailsSubgraph.lendingPoolTrancheUserDetails.tranche
885
+ .balance,
886
+ userDetailsSubgraph.lendingPoolTrancheUserDetails.tranche
887
+ .shares,
888
+ );
889
+
890
+ const totalAcceptedDeposits = parseFloat(
891
+ userDetailsSubgraph.lendingPoolTrancheUserDetails
892
+ .totalAcceptedDeposits,
893
+ );
894
+
895
+ const totalAcceptedWithdrawals = parseFloat(
896
+ userDetailsSubgraph.lendingPoolTrancheUserDetails
897
+ .totalAcceptedWithdrawnAmount,
898
+ );
899
+
900
+ yieldEarned =
901
+ parseFloat(userBalance) -
902
+ totalAcceptedDeposits -
903
+ -totalAcceptedWithdrawals;
904
+ }
905
+
906
+ return {
907
+ userId: user,
908
+ address: trancheId,
909
+ yieldEarned,
910
+ balance: userBalance,
911
+ availableToWithdraw,
912
+ trancheId,
913
+ };
914
+ }
915
+
916
+ async getUserApyBonus(user: string): Promise<UserApyBonus> {
917
+ const subgraphResult: TotalUserLoyaltyRewardsSubgraph =
918
+ await this._graph.request(totalUserLoyaltyRewardsQuery, {
919
+ userAddress: user,
920
+ });
921
+ if (!subgraphResult.user) {
922
+ return {
923
+ balance: BigNumber.from(0),
924
+ lifetime: 0,
925
+ };
926
+ }
927
+ const balance = await this._userLoyaltyRewardsAbi.userRewards(user);
928
+ return {
929
+ balance: balance,
930
+ lifetime: parseFloat(subgraphResult.user.totalUserLoyaltyRewards),
931
+ };
932
+ }
933
+ }