@whisk/steakhouse 0.3.9 → 0.4.0

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,429 @@
1
+ import * as gql_tada from 'gql.tada';
2
+ import { ResultOf } from '@whisk/graphql';
3
+ import { WhiskClient } from '@whisk/client';
4
+ import { VaultConfig } from '../metadata/types.js';
5
+ import { Prettify } from './fragments.js';
6
+
7
+ declare const vaultsQuery: gql_tada.TadaDocumentNode<{
8
+ erc4626Vaults: {
9
+ items: ({
10
+ __typename: "GenericErc4626Vault";
11
+ chain: {
12
+ id: number;
13
+ name: string;
14
+ icon: string;
15
+ };
16
+ address: `0x${string}`;
17
+ name: string;
18
+ symbol: string;
19
+ decimals: number;
20
+ icon: string | null;
21
+ priceUsd: number | null;
22
+ asset: {
23
+ __typename?: "Token";
24
+ address: `0x${string}`;
25
+ name: string;
26
+ symbol: string;
27
+ decimals: number;
28
+ icon: string | null;
29
+ priceUsd: number | null;
30
+ };
31
+ totalAssets: {
32
+ raw: bigint;
33
+ formatted: string;
34
+ usd: number | null;
35
+ };
36
+ apyInstant: {
37
+ base: number;
38
+ rewards: {
39
+ asset: {
40
+ __typename?: "Token";
41
+ address: `0x${string}`;
42
+ name: string;
43
+ symbol: string;
44
+ decimals: number;
45
+ icon: string | null;
46
+ priceUsd: number | null;
47
+ };
48
+ apr: number;
49
+ }[];
50
+ fee: number;
51
+ total: number;
52
+ };
53
+ apy1d: {
54
+ base: number;
55
+ rewards: {
56
+ asset: {
57
+ __typename?: "Token";
58
+ address: `0x${string}`;
59
+ name: string;
60
+ symbol: string;
61
+ decimals: number;
62
+ icon: string | null;
63
+ priceUsd: number | null;
64
+ };
65
+ apr: number;
66
+ }[];
67
+ fee: number;
68
+ total: number;
69
+ };
70
+ apy7d: {
71
+ base: number;
72
+ rewards: {
73
+ asset: {
74
+ __typename?: "Token";
75
+ address: `0x${string}`;
76
+ name: string;
77
+ symbol: string;
78
+ decimals: number;
79
+ icon: string | null;
80
+ priceUsd: number | null;
81
+ };
82
+ apr: number;
83
+ }[];
84
+ fee: number;
85
+ total: number;
86
+ };
87
+ apy30d: {
88
+ base: number;
89
+ rewards: {
90
+ asset: {
91
+ __typename?: "Token";
92
+ address: `0x${string}`;
93
+ name: string;
94
+ symbol: string;
95
+ decimals: number;
96
+ icon: string | null;
97
+ priceUsd: number | null;
98
+ };
99
+ apr: number;
100
+ }[];
101
+ fee: number;
102
+ total: number;
103
+ };
104
+ riskAssessment: {
105
+ steakhouse: {
106
+ score: number;
107
+ rating: string;
108
+ } | null;
109
+ };
110
+ } | {
111
+ __typename: "BoxVault";
112
+ chain: {
113
+ id: number;
114
+ name: string;
115
+ icon: string;
116
+ };
117
+ address: `0x${string}`;
118
+ name: string;
119
+ symbol: string;
120
+ decimals: number;
121
+ icon: string | null;
122
+ priceUsd: number | null;
123
+ asset: {
124
+ __typename?: "Token";
125
+ address: `0x${string}`;
126
+ name: string;
127
+ symbol: string;
128
+ decimals: number;
129
+ icon: string | null;
130
+ priceUsd: number | null;
131
+ };
132
+ totalAssets: {
133
+ raw: bigint;
134
+ formatted: string;
135
+ usd: number | null;
136
+ };
137
+ apyInstant: {
138
+ base: number;
139
+ rewards: {
140
+ asset: {
141
+ __typename?: "Token";
142
+ address: `0x${string}`;
143
+ name: string;
144
+ symbol: string;
145
+ decimals: number;
146
+ icon: string | null;
147
+ priceUsd: number | null;
148
+ };
149
+ apr: number;
150
+ }[];
151
+ fee: number;
152
+ total: number;
153
+ };
154
+ apy1d: {
155
+ base: number;
156
+ rewards: {
157
+ asset: {
158
+ __typename?: "Token";
159
+ address: `0x${string}`;
160
+ name: string;
161
+ symbol: string;
162
+ decimals: number;
163
+ icon: string | null;
164
+ priceUsd: number | null;
165
+ };
166
+ apr: number;
167
+ }[];
168
+ fee: number;
169
+ total: number;
170
+ };
171
+ apy7d: {
172
+ base: number;
173
+ rewards: {
174
+ asset: {
175
+ __typename?: "Token";
176
+ address: `0x${string}`;
177
+ name: string;
178
+ symbol: string;
179
+ decimals: number;
180
+ icon: string | null;
181
+ priceUsd: number | null;
182
+ };
183
+ apr: number;
184
+ }[];
185
+ fee: number;
186
+ total: number;
187
+ };
188
+ apy30d: {
189
+ base: number;
190
+ rewards: {
191
+ asset: {
192
+ __typename?: "Token";
193
+ address: `0x${string}`;
194
+ name: string;
195
+ symbol: string;
196
+ decimals: number;
197
+ icon: string | null;
198
+ priceUsd: number | null;
199
+ };
200
+ apr: number;
201
+ }[];
202
+ fee: number;
203
+ total: number;
204
+ };
205
+ riskAssessment: {
206
+ steakhouse: {
207
+ score: number;
208
+ rating: string;
209
+ } | null;
210
+ };
211
+ } | {
212
+ __typename: "MorphoVault";
213
+ chain: {
214
+ id: number;
215
+ name: string;
216
+ icon: string;
217
+ };
218
+ address: `0x${string}`;
219
+ name: string;
220
+ symbol: string;
221
+ decimals: number;
222
+ icon: string | null;
223
+ priceUsd: number | null;
224
+ asset: {
225
+ __typename?: "Token";
226
+ address: `0x${string}`;
227
+ name: string;
228
+ symbol: string;
229
+ decimals: number;
230
+ icon: string | null;
231
+ priceUsd: number | null;
232
+ };
233
+ totalAssets: {
234
+ raw: bigint;
235
+ formatted: string;
236
+ usd: number | null;
237
+ };
238
+ apyInstant: {
239
+ base: number;
240
+ rewards: {
241
+ asset: {
242
+ __typename?: "Token";
243
+ address: `0x${string}`;
244
+ name: string;
245
+ symbol: string;
246
+ decimals: number;
247
+ icon: string | null;
248
+ priceUsd: number | null;
249
+ };
250
+ apr: number;
251
+ }[];
252
+ fee: number;
253
+ total: number;
254
+ };
255
+ apy1d: {
256
+ base: number;
257
+ rewards: {
258
+ asset: {
259
+ __typename?: "Token";
260
+ address: `0x${string}`;
261
+ name: string;
262
+ symbol: string;
263
+ decimals: number;
264
+ icon: string | null;
265
+ priceUsd: number | null;
266
+ };
267
+ apr: number;
268
+ }[];
269
+ fee: number;
270
+ total: number;
271
+ };
272
+ apy7d: {
273
+ base: number;
274
+ rewards: {
275
+ asset: {
276
+ __typename?: "Token";
277
+ address: `0x${string}`;
278
+ name: string;
279
+ symbol: string;
280
+ decimals: number;
281
+ icon: string | null;
282
+ priceUsd: number | null;
283
+ };
284
+ apr: number;
285
+ }[];
286
+ fee: number;
287
+ total: number;
288
+ };
289
+ apy30d: {
290
+ base: number;
291
+ rewards: {
292
+ asset: {
293
+ __typename?: "Token";
294
+ address: `0x${string}`;
295
+ name: string;
296
+ symbol: string;
297
+ decimals: number;
298
+ icon: string | null;
299
+ priceUsd: number | null;
300
+ };
301
+ apr: number;
302
+ }[];
303
+ fee: number;
304
+ total: number;
305
+ };
306
+ riskAssessment: {
307
+ steakhouse: {
308
+ score: number;
309
+ rating: string;
310
+ } | null;
311
+ };
312
+ } | {
313
+ __typename: "MorphoVaultV2";
314
+ chain: {
315
+ id: number;
316
+ name: string;
317
+ icon: string;
318
+ };
319
+ address: `0x${string}`;
320
+ name: string;
321
+ symbol: string;
322
+ decimals: number;
323
+ icon: string | null;
324
+ priceUsd: number | null;
325
+ asset: {
326
+ __typename?: "Token";
327
+ address: `0x${string}`;
328
+ name: string;
329
+ symbol: string;
330
+ decimals: number;
331
+ icon: string | null;
332
+ priceUsd: number | null;
333
+ };
334
+ totalAssets: {
335
+ raw: bigint;
336
+ formatted: string;
337
+ usd: number | null;
338
+ };
339
+ apyInstant: {
340
+ base: number;
341
+ rewards: {
342
+ asset: {
343
+ __typename?: "Token";
344
+ address: `0x${string}`;
345
+ name: string;
346
+ symbol: string;
347
+ decimals: number;
348
+ icon: string | null;
349
+ priceUsd: number | null;
350
+ };
351
+ apr: number;
352
+ }[];
353
+ fee: number;
354
+ total: number;
355
+ };
356
+ apy1d: {
357
+ base: number;
358
+ rewards: {
359
+ asset: {
360
+ __typename?: "Token";
361
+ address: `0x${string}`;
362
+ name: string;
363
+ symbol: string;
364
+ decimals: number;
365
+ icon: string | null;
366
+ priceUsd: number | null;
367
+ };
368
+ apr: number;
369
+ }[];
370
+ fee: number;
371
+ total: number;
372
+ };
373
+ apy7d: {
374
+ base: number;
375
+ rewards: {
376
+ asset: {
377
+ __typename?: "Token";
378
+ address: `0x${string}`;
379
+ name: string;
380
+ symbol: string;
381
+ decimals: number;
382
+ icon: string | null;
383
+ priceUsd: number | null;
384
+ };
385
+ apr: number;
386
+ }[];
387
+ fee: number;
388
+ total: number;
389
+ };
390
+ apy30d: {
391
+ base: number;
392
+ rewards: {
393
+ asset: {
394
+ __typename?: "Token";
395
+ address: `0x${string}`;
396
+ name: string;
397
+ symbol: string;
398
+ decimals: number;
399
+ icon: string | null;
400
+ priceUsd: number | null;
401
+ };
402
+ apr: number;
403
+ }[];
404
+ fee: number;
405
+ total: number;
406
+ };
407
+ riskAssessment: {
408
+ steakhouse: {
409
+ score: number;
410
+ rating: string;
411
+ } | null;
412
+ };
413
+ } | null)[];
414
+ };
415
+ }, {
416
+ keys: {
417
+ protocol: "generic" | "morpho_v1" | "morpho_v2" | "box";
418
+ vaultAddress: `0x${string}`;
419
+ chainId: number;
420
+ }[];
421
+ }, void>;
422
+ type VaultItem = NonNullable<ResultOf<typeof vaultsQuery>["erc4626Vaults"]["items"][number]>;
423
+ type SteakhouseVaultSummary = Prettify<VaultItem & {
424
+ strategy: VaultConfig["strategy"];
425
+ isListed: boolean;
426
+ }>;
427
+ declare function getVaults(client: WhiskClient): Promise<SteakhouseVaultSummary[]>;
428
+
429
+ export { type SteakhouseVaultSummary, getVaults };
@@ -0,0 +1,49 @@
1
+ import { graphql } from "@whisk/graphql";
2
+ import { STEAKHOUSE_VAULTS } from "../metadata/generated/vaults.js";
3
+ import { vaultSummaryFragment } from "./fragments.js";
4
+ const vaultsQuery = graphql(
5
+ `
6
+ query GetSteakhouseVaults($keys: [Erc4626VaultKey!]!) {
7
+ erc4626Vaults(where: { keys: $keys }) {
8
+ items {
9
+ ...VaultSummaryFields
10
+ }
11
+ }
12
+ }
13
+ `,
14
+ [vaultSummaryFragment]
15
+ );
16
+ async function getVaults(client) {
17
+ const configs = STEAKHOUSE_VAULTS;
18
+ const keys = configs.map((v) => ({
19
+ chainId: v.chainId,
20
+ vaultAddress: v.address,
21
+ protocol: v.protocol
22
+ }));
23
+ const result = await client.query(vaultsQuery, { keys });
24
+ const configByChainAndAddress = new Map(
25
+ configs.map((v) => [`${v.chainId}:${v.address.toLowerCase()}`, v])
26
+ );
27
+ const vaults = [];
28
+ for (const item of result.erc4626Vaults.items) {
29
+ if (!item) continue;
30
+ const config = configByChainAndAddress.get(`${item.chain.id}:${item.address.toLowerCase()}`);
31
+ if (!config) {
32
+ console.warn(
33
+ `[getVaults] Vault ${item.address} on chain ${item.chain.id} has no matching config, skipping`
34
+ );
35
+ continue;
36
+ }
37
+ vaults.push({
38
+ ...item,
39
+ name: config.name ?? item.name,
40
+ strategy: config.strategy,
41
+ isListed: config.isListed
42
+ });
43
+ }
44
+ return vaults;
45
+ }
46
+ export {
47
+ getVaults
48
+ };
49
+ //# sourceMappingURL=getVaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/queries/getVaults.ts"],"sourcesContent":["import { graphql, type ResultOf } from \"@whisk/graphql\"\nimport type { SteakhouseClient } from \"../client.js\"\nimport { STEAKHOUSE_VAULTS } from \"../metadata/generated/vaults.js\"\nimport type { VaultConfig } from \"../metadata/types.js\"\nimport { type Prettify, vaultSummaryFragment } from \"./fragments.js\"\n\nconst vaultsQuery = graphql(\n `\n query GetSteakhouseVaults($keys: [Erc4626VaultKey!]!) {\n erc4626Vaults(where: { keys: $keys }) {\n items {\n ...VaultSummaryFields\n }\n }\n }\n`,\n [vaultSummaryFragment],\n)\n\ntype VaultItem = NonNullable<ResultOf<typeof vaultsQuery>[\"erc4626Vaults\"][\"items\"][number]>\n\nexport type SteakhouseVaultSummary = Prettify<\n VaultItem & {\n strategy: VaultConfig[\"strategy\"]\n isListed: boolean\n }\n>\n\nexport async function getVaults(client: SteakhouseClient): Promise<SteakhouseVaultSummary[]> {\n const configs = STEAKHOUSE_VAULTS\n\n const keys = configs.map((v) => ({\n chainId: v.chainId,\n vaultAddress: v.address,\n protocol: v.protocol,\n }))\n\n const result = await client.query(vaultsQuery, { keys })\n\n const configByChainAndAddress = new Map(\n configs.map((v) => [`${v.chainId}:${v.address.toLowerCase()}`, v]),\n )\n\n const vaults: SteakhouseVaultSummary[] = []\n for (const item of result.erc4626Vaults.items) {\n if (!item) continue\n const config = configByChainAndAddress.get(`${item.chain.id}:${item.address.toLowerCase()}`)\n if (!config) {\n console.warn(\n `[getVaults] Vault ${item.address} on chain ${item.chain.id} has no matching config, skipping`,\n )\n continue\n }\n\n vaults.push({\n ...item,\n name: config.name ?? item.name,\n strategy: config.strategy,\n isListed: config.isListed,\n })\n }\n\n return vaults\n}\n"],"mappings":"AAAA,SAAS,eAA8B;AAEvC,SAAS,yBAAyB;AAElC,SAAwB,4BAA4B;AAEpD,MAAM,cAAc;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,CAAC,oBAAoB;AACvB;AAWA,eAAsB,UAAU,QAA6D;AAC3F,QAAM,UAAU;AAEhB,QAAM,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,IAC/B,SAAS,EAAE;AAAA,IACX,cAAc,EAAE;AAAA,IAChB,UAAU,EAAE;AAAA,EACd,EAAE;AAEF,QAAM,SAAS,MAAM,OAAO,MAAM,aAAa,EAAE,KAAK,CAAC;AAEvD,QAAM,0BAA0B,IAAI;AAAA,IAClC,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,QAAQ,YAAY,CAAC,IAAI,CAAC,CAAC;AAAA,EACnE;AAEA,QAAM,SAAmC,CAAC;AAC1C,aAAW,QAAQ,OAAO,cAAc,OAAO;AAC7C,QAAI,CAAC,KAAM;AACX,UAAM,SAAS,wBAAwB,IAAI,GAAG,KAAK,MAAM,EAAE,IAAI,KAAK,QAAQ,YAAY,CAAC,EAAE;AAC3F,QAAI,CAAC,QAAQ;AACX,cAAQ;AAAA,QACN,qBAAqB,KAAK,OAAO,aAAa,KAAK,MAAM,EAAE;AAAA,MAC7D;AACA;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV,GAAG;AAAA,MACH,MAAM,OAAO,QAAQ,KAAK;AAAA,MAC1B,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;","names":[]}
@@ -1,4 +1,9 @@
1
1
  export { GetStatsResultWithHistorical, GetStatsResultWithoutHistorical, getStats } from './getStats.js';
2
+ export { GetVaultVariables, SteakhouseVaultDetail, getVault } from './getVault.js';
3
+ export { GetVaultHistoryVariables, SteakhouseVaultHistory, getVaultHistory } from './getVaultHistory.js';
4
+ export { SteakhouseVaultSummary, getVaults } from './getVaults.js';
2
5
  import '@whisk/client';
3
6
  import 'gql.tada';
4
7
  import '@whisk/graphql';
8
+ import '../metadata/types.js';
9
+ import './fragments.js';
@@ -1,2 +1,5 @@
1
1
  export * from "./getStats.js";
2
+ export * from "./getVault.js";
3
+ export * from "./getVaultHistory.js";
4
+ export * from "./getVaults.js";
2
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/queries/index.ts"],"sourcesContent":["export * from \"./getStats.js\"\n"],"mappings":"AAAA,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../src/queries/index.ts"],"sourcesContent":["export * from \"./getStats.js\"\nexport * from \"./getVault.js\"\nexport * from \"./getVaultHistory.js\"\nexport * from \"./getVaults.js\"\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whisk/steakhouse",
3
- "version": "0.3.9",
3
+ "version": "0.4.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/office-supply-ventures/whisk-sdk.git",
@@ -36,8 +36,8 @@
36
36
  "dependencies": {
37
37
  "@urql/core": "6.0.1",
38
38
  "gql.tada": "1.9.0",
39
- "@whisk/graphql": "0.0.18",
40
- "@whisk/client": "0.0.19"
39
+ "@whisk/client": "0.0.19",
40
+ "@whisk/graphql": "0.0.18"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@tanstack/react-query": ">=5",
@@ -0,0 +1,163 @@
1
+ import { graphql } from "@whisk/graphql"
2
+ import { isAddressEqual } from "viem"
3
+ import { STEAKHOUSE_VAULTS } from "../metadata/generated/vaults.js"
4
+ import type { VaultConfig } from "../metadata/types.js"
5
+
6
+ export type Prettify<T> = { [K in keyof T]: T[K] } & {}
7
+
8
+ export interface VaultKeyVariables {
9
+ chainId: number
10
+ vaultAddress: `0x${string}`
11
+ }
12
+
13
+ export function resolveVaultConfig(variables: VaultKeyVariables): VaultConfig | undefined {
14
+ return STEAKHOUSE_VAULTS.find(
15
+ (v) => v.chainId === variables.chainId && isAddressEqual(v.address, variables.vaultAddress),
16
+ )
17
+ }
18
+
19
+ export const chainFragment = graphql(`
20
+ fragment ChainFields on Chain {
21
+ id
22
+ name
23
+ icon
24
+ }
25
+ `)
26
+
27
+ export const erc20Fragment = graphql(`
28
+ fragment Erc20Fields on Erc20 {
29
+ address
30
+ name
31
+ symbol
32
+ decimals
33
+ icon
34
+ priceUsd
35
+ }
36
+ `)
37
+
38
+ export const tokenAmountFragment = graphql(`
39
+ fragment TokenAmountFields on TokenAmount {
40
+ raw
41
+ formatted
42
+ usd
43
+ }
44
+ `)
45
+
46
+ export const riskAssessmentFragment = graphql(`
47
+ fragment RiskAssessmentFields on RiskAssessment {
48
+ steakhouse {
49
+ score
50
+ rating
51
+ }
52
+ }
53
+ `)
54
+
55
+ export const apyFragment = graphql(
56
+ `
57
+ fragment ApyFields on Apy {
58
+ base
59
+ rewards {
60
+ asset {
61
+ ...Erc20Fields
62
+ }
63
+ apr
64
+ }
65
+ fee
66
+ total
67
+ }
68
+ `,
69
+ [erc20Fragment],
70
+ )
71
+
72
+ export const morphoMarketAllocationFragment = graphql(
73
+ `
74
+ fragment MorphoMarketAllocationFields on MorphoMarket {
75
+ marketId
76
+ name
77
+ loanAsset {
78
+ ...Erc20Fields
79
+ }
80
+ collateralAsset {
81
+ ...Erc20Fields
82
+ yield {
83
+ intrinsicApy
84
+ }
85
+ }
86
+ lltv {
87
+ raw
88
+ formatted
89
+ }
90
+ riskAssessment {
91
+ ...RiskAssessmentFields
92
+ }
93
+ supplyApy {
94
+ ...ApyFields
95
+ }
96
+ supplyApy1d {
97
+ ...ApyFields
98
+ }
99
+ supplyApy7d {
100
+ ...ApyFields
101
+ }
102
+ supplyApy30d {
103
+ ...ApyFields
104
+ }
105
+ }
106
+ `,
107
+ [erc20Fragment, riskAssessmentFragment, apyFragment],
108
+ )
109
+
110
+ export const morphoVaultHistoricalEntryFragment = graphql(
111
+ `
112
+ fragment MorphoVaultHistoricalEntryFields on MorphoVaultHistoricalEntry {
113
+ bucketTimestamp
114
+ totalSupplied {
115
+ ...TokenAmountFields
116
+ }
117
+ supplyApy1d {
118
+ ...ApyFields
119
+ }
120
+ supplyApy7d {
121
+ ...ApyFields
122
+ }
123
+ supplyApy30d {
124
+ ...ApyFields
125
+ }
126
+ }
127
+ `,
128
+ [tokenAmountFragment, apyFragment],
129
+ )
130
+
131
+ export const vaultSummaryFragment = graphql(
132
+ `
133
+ fragment VaultSummaryFields on Erc4626Vault {
134
+ __typename
135
+ chain {
136
+ ...ChainFields
137
+ }
138
+ ...Erc20Fields
139
+ asset {
140
+ ...Erc20Fields
141
+ }
142
+ totalAssets {
143
+ ...TokenAmountFields
144
+ }
145
+ apyInstant: apy(timeframe: instant) {
146
+ ...ApyFields
147
+ }
148
+ apy1d: apy(timeframe: one_day) {
149
+ ...ApyFields
150
+ }
151
+ apy7d: apy(timeframe: seven_days) {
152
+ ...ApyFields
153
+ }
154
+ apy30d: apy(timeframe: thirty_days) {
155
+ ...ApyFields
156
+ }
157
+ riskAssessment {
158
+ ...RiskAssessmentFields
159
+ }
160
+ }
161
+ `,
162
+ [chainFragment, erc20Fragment, tokenAmountFragment, apyFragment, riskAssessmentFragment],
163
+ )