@berachain/berajs 0.2.8-beta.7 → 0.2.8-beta.8

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 (140) hide show
  1. package/dist/abi/exports.cjs +4452 -1
  2. package/dist/abi/exports.cjs.map +1 -1
  3. package/dist/abi/exports.mjs +4452 -1
  4. package/dist/abi/exports.mjs.map +1 -1
  5. package/dist/actions/exports.cjs +913 -1
  6. package/dist/actions/exports.cjs.map +1 -1
  7. package/dist/actions/exports.mjs +913 -1
  8. package/dist/actions/exports.mjs.map +1 -1
  9. package/dist/chunk-2R73G2PO.mjs +4698 -0
  10. package/dist/{chunk-MASD43N5.mjs.map → chunk-2R73G2PO.mjs.map} +1 -1
  11. package/dist/chunk-3M47ZRXT.mjs +417 -0
  12. package/dist/{chunk-ESAVA5OD.mjs.map → chunk-3M47ZRXT.mjs.map} +1 -1
  13. package/dist/chunk-4GFN4LEP.mjs +97 -0
  14. package/dist/{chunk-5W7UKRHX.mjs.map → chunk-4GFN4LEP.mjs.map} +1 -1
  15. package/dist/chunk-5N7QQS55.cjs +130 -0
  16. package/dist/chunk-5N7QQS55.cjs.map +1 -0
  17. package/dist/chunk-5NMATIH4.mjs +130 -0
  18. package/dist/{chunk-SSPFPAWX.mjs.map → chunk-5NMATIH4.mjs.map} +1 -1
  19. package/dist/chunk-7QKRRIHI.mjs +1844 -0
  20. package/dist/{chunk-RSDCKN4Q.mjs.map → chunk-7QKRRIHI.mjs.map} +1 -1
  21. package/dist/chunk-7TFV6UKF.mjs +24 -0
  22. package/dist/{chunk-MK5NS5B5.mjs.map → chunk-7TFV6UKF.mjs.map} +1 -1
  23. package/dist/chunk-A4FPM7U3.cjs +63 -0
  24. package/dist/chunk-A4FPM7U3.cjs.map +1 -0
  25. package/dist/chunk-BDHINMWQ.cjs +417 -0
  26. package/dist/chunk-BDHINMWQ.cjs.map +1 -0
  27. package/dist/chunk-BEHP54S3.cjs +24 -0
  28. package/dist/chunk-BEHP54S3.cjs.map +1 -0
  29. package/dist/chunk-EGDXV2PT.cjs +36 -0
  30. package/dist/chunk-EGDXV2PT.cjs.map +1 -0
  31. package/dist/chunk-EWBKSMPG.cjs +13 -0
  32. package/dist/chunk-EWBKSMPG.cjs.map +1 -0
  33. package/dist/chunk-F6ZW7ZDD.cjs +403 -0
  34. package/dist/chunk-F6ZW7ZDD.cjs.map +1 -0
  35. package/dist/chunk-FTXTRUYT.cjs +170 -0
  36. package/dist/chunk-FTXTRUYT.cjs.map +1 -0
  37. package/dist/chunk-GLWPRM33.mjs +13 -0
  38. package/dist/{chunk-575OK77P.mjs.map → chunk-GLWPRM33.mjs.map} +1 -1
  39. package/dist/chunk-GWSTVITN.mjs +572 -0
  40. package/dist/{chunk-NLVWRMGD.mjs.map → chunk-GWSTVITN.mjs.map} +1 -1
  41. package/dist/chunk-H3Z37RYU.cjs +15 -0
  42. package/dist/chunk-H3Z37RYU.cjs.map +1 -0
  43. package/dist/chunk-I3FTWD6I.mjs +170 -0
  44. package/dist/{chunk-JDZGYU5T.mjs.map → chunk-I3FTWD6I.mjs.map} +1 -1
  45. package/dist/chunk-JA4DHMTG.mjs +15 -0
  46. package/dist/{chunk-OGBD5YOG.mjs.map → chunk-JA4DHMTG.mjs.map} +1 -1
  47. package/dist/chunk-KL6YZ5VR.mjs +63 -0
  48. package/dist/{chunk-OGJMSGB2.mjs.map → chunk-KL6YZ5VR.mjs.map} +1 -1
  49. package/dist/chunk-MXWPP6MS.cjs +572 -0
  50. package/dist/chunk-MXWPP6MS.cjs.map +1 -0
  51. package/dist/chunk-SGZP4O6R.mjs +135 -0
  52. package/dist/{chunk-6K252BGM.mjs.map → chunk-SGZP4O6R.mjs.map} +1 -1
  53. package/dist/chunk-TDW5SPXR.cjs +244 -0
  54. package/dist/chunk-TDW5SPXR.cjs.map +1 -0
  55. package/dist/chunk-TGK3IXDN.cjs +169 -0
  56. package/dist/chunk-TGK3IXDN.cjs.map +1 -0
  57. package/dist/chunk-TJEW6YCJ.cjs +97 -0
  58. package/dist/chunk-TJEW6YCJ.cjs.map +1 -0
  59. package/dist/chunk-VA3BQ34H.mjs +403 -0
  60. package/dist/{chunk-UENDEN3M.mjs.map → chunk-VA3BQ34H.mjs.map} +1 -1
  61. package/dist/chunk-VA5L5FDG.mjs +36 -0
  62. package/dist/{chunk-3MZ7MLKF.mjs.map → chunk-VA5L5FDG.mjs.map} +1 -1
  63. package/dist/chunk-XSGCRLSD.cjs +1844 -0
  64. package/dist/chunk-XSGCRLSD.cjs.map +1 -0
  65. package/dist/chunk-XV3GG3HC.cjs +135 -0
  66. package/dist/chunk-XV3GG3HC.cjs.map +1 -0
  67. package/dist/chunk-Y5B224UX.cjs +4698 -0
  68. package/dist/chunk-Y5B224UX.cjs.map +1 -0
  69. package/dist/chunk-ZBTRKBSI.mjs +169 -0
  70. package/dist/{chunk-CWKDFUFR.mjs.map → chunk-ZBTRKBSI.mjs.map} +1 -1
  71. package/dist/chunk-ZCEFC2TK.mjs +244 -0
  72. package/dist/{chunk-NAXAZJJY.mjs.map → chunk-ZCEFC2TK.mjs.map} +1 -1
  73. package/dist/contexts/exports.cjs +82 -1
  74. package/dist/contexts/exports.cjs.map +1 -1
  75. package/dist/contexts/exports.mjs +82 -1
  76. package/dist/contexts/exports.mjs.map +1 -1
  77. package/dist/enum/exports.cjs +58 -1
  78. package/dist/enum/exports.cjs.map +1 -1
  79. package/dist/enum/exports.mjs +58 -1
  80. package/dist/enum/exports.mjs.map +1 -1
  81. package/dist/errors/exports.cjs +38 -1
  82. package/dist/errors/exports.cjs.map +1 -1
  83. package/dist/errors/exports.mjs +38 -1
  84. package/dist/hooks/exports.cjs +8332 -3
  85. package/dist/hooks/exports.cjs.map +1 -1
  86. package/dist/hooks/exports.mjs +8332 -3
  87. package/dist/hooks/exports.mjs.map +1 -1
  88. package/dist/utils/exports.cjs +786 -1
  89. package/dist/utils/exports.cjs.map +1 -1
  90. package/dist/utils/exports.mjs +786 -1
  91. package/dist/utils/exports.mjs.map +1 -1
  92. package/package.json +1 -1
  93. package/dist/chunk-3MZ7MLKF.mjs +0 -2
  94. package/dist/chunk-53TSJM6P.cjs +0 -2
  95. package/dist/chunk-53TSJM6P.cjs.map +0 -1
  96. package/dist/chunk-575OK77P.mjs +0 -2
  97. package/dist/chunk-5W7UKRHX.mjs +0 -2
  98. package/dist/chunk-6K252BGM.mjs +0 -2
  99. package/dist/chunk-CWKDFUFR.mjs +0 -2
  100. package/dist/chunk-D6L7LTA2.cjs +0 -2
  101. package/dist/chunk-D6L7LTA2.cjs.map +0 -1
  102. package/dist/chunk-DDEQFR3M.cjs +0 -2
  103. package/dist/chunk-DDEQFR3M.cjs.map +0 -1
  104. package/dist/chunk-DKY4QPWU.cjs +0 -2
  105. package/dist/chunk-DKY4QPWU.cjs.map +0 -1
  106. package/dist/chunk-DTBJO6VT.cjs +0 -2
  107. package/dist/chunk-DTBJO6VT.cjs.map +0 -1
  108. package/dist/chunk-ESAVA5OD.mjs +0 -2
  109. package/dist/chunk-JDZGYU5T.mjs +0 -2
  110. package/dist/chunk-JLFBRMOF.cjs +0 -2
  111. package/dist/chunk-JLFBRMOF.cjs.map +0 -1
  112. package/dist/chunk-KT6L4K4K.cjs +0 -2
  113. package/dist/chunk-KT6L4K4K.cjs.map +0 -1
  114. package/dist/chunk-MASD43N5.mjs +0 -4
  115. package/dist/chunk-MGGPHKA2.cjs +0 -4
  116. package/dist/chunk-MGGPHKA2.cjs.map +0 -1
  117. package/dist/chunk-MK5NS5B5.mjs +0 -2
  118. package/dist/chunk-NAXAZJJY.mjs +0 -2
  119. package/dist/chunk-NLVWRMGD.mjs +0 -2
  120. package/dist/chunk-OGBD5YOG.mjs +0 -2
  121. package/dist/chunk-OGJMSGB2.mjs +0 -2
  122. package/dist/chunk-OIYXOKTT.cjs +0 -2
  123. package/dist/chunk-OIYXOKTT.cjs.map +0 -1
  124. package/dist/chunk-OUD27MU7.cjs +0 -2
  125. package/dist/chunk-OUD27MU7.cjs.map +0 -1
  126. package/dist/chunk-QFLDL4UV.cjs +0 -2
  127. package/dist/chunk-QFLDL4UV.cjs.map +0 -1
  128. package/dist/chunk-RSDCKN4Q.mjs +0 -2
  129. package/dist/chunk-RWOICHRW.cjs +0 -2
  130. package/dist/chunk-RWOICHRW.cjs.map +0 -1
  131. package/dist/chunk-SSPFPAWX.mjs +0 -2
  132. package/dist/chunk-UENDEN3M.mjs +0 -2
  133. package/dist/chunk-UFIM7WQ4.cjs +0 -2
  134. package/dist/chunk-UFIM7WQ4.cjs.map +0 -1
  135. package/dist/chunk-WRFDB3QJ.cjs +0 -2
  136. package/dist/chunk-WRFDB3QJ.cjs.map +0 -1
  137. package/dist/chunk-XNJLSA6P.cjs +0 -2
  138. package/dist/chunk-XNJLSA6P.cjs.map +0 -1
  139. package/dist/chunk-ZYXVUXFQ.cjs +0 -2
  140. package/dist/chunk-ZYXVUXFQ.cjs.map +0 -1
@@ -0,0 +1,4698 @@
1
+ import {
2
+ pythAbi
3
+ } from "./chunk-GWSTVITN.mjs";
4
+ import {
5
+ BeraTracing,
6
+ NotFoundError,
7
+ TransactionFailedError
8
+ } from "./chunk-5NMATIH4.mjs";
9
+ import {
10
+ BeraMonitoring,
11
+ assertAddress,
12
+ assertDefined,
13
+ assertPublicClient,
14
+ initBeraError
15
+ } from "./chunk-ZBTRKBSI.mjs";
16
+ import {
17
+ CAP_LIMIT_BUFFER,
18
+ DEFAULT_METAMASK_GAS_LIMIT,
19
+ beraFetch,
20
+ beraFetchJson,
21
+ bignumber_js_default,
22
+ calculateTimestampFromDays,
23
+ days,
24
+ formatTimeLeft,
25
+ getErrorResponse,
26
+ getPythDefaultUpdateFee,
27
+ getSafeNumber,
28
+ getTestClient,
29
+ msToSeconds,
30
+ seconds,
31
+ yearsInSeconds
32
+ } from "./chunk-3M47ZRXT.mjs";
33
+ import {
34
+ beraToken,
35
+ getHoneyToken,
36
+ isToken,
37
+ parseBaseArgs
38
+ } from "./chunk-4GFN4LEP.mjs";
39
+ import {
40
+ BeraError,
41
+ InvalidArgumentError,
42
+ RequestError,
43
+ commonAbiErrors,
44
+ parseDecodedError,
45
+ parseViemError
46
+ } from "./chunk-7QKRRIHI.mjs";
47
+
48
+ // src/actions/bend/getConvertToAssets.ts
49
+ import { formatEther } from "viem";
50
+ import { metaMorphoV11Abi as metaMorphoAbi } from "@berachain/abis/bend-metamorpho/metaMorphoV11";
51
+ async function getConvertToAssets({
52
+ sharesAmount,
53
+ vaultAddress,
54
+ publicClient
55
+ }) {
56
+ const convertToAssets = await publicClient.readContract({
57
+ address: vaultAddress,
58
+ abi: metaMorphoAbi,
59
+ functionName: "convertToAssets",
60
+ args: [sharesAmount]
61
+ });
62
+ return { raw: convertToAssets, formatted: formatEther(convertToAssets) };
63
+ }
64
+
65
+ // src/actions/clients/BeraApolloClient.ts
66
+ import {
67
+ ApolloClient,
68
+ ServerError
69
+ } from "@apollo/client";
70
+ import { appConfig } from "@berachain/config/internal";
71
+ var BeraApolloClient = class extends ApolloClient {
72
+ /**
73
+ * The URL of the endpoint. Used for error reporting only.
74
+ */
75
+ url;
76
+ constructor(options) {
77
+ super(options);
78
+ this.url = options.url;
79
+ }
80
+ async query(options) {
81
+ const queryName = getQueryName(options.query);
82
+ const endpoint = {
83
+ url: this.url,
84
+ type: "graphql"
85
+ };
86
+ const tags = {
87
+ "operation.type": "query",
88
+ "operation.source.url": endpoint.url,
89
+ "operation.source.type": endpoint.type,
90
+ "operation.source.queryName": queryName
91
+ };
92
+ try {
93
+ const executeQuery = () => super.query(
94
+ options
95
+ );
96
+ const res = await BeraTracing.startSpan(
97
+ {
98
+ name: `GraphQL ${queryName}`,
99
+ op: "BeraApolloClient.query",
100
+ attributes: tags
101
+ },
102
+ executeQuery
103
+ );
104
+ if (res.error || res.data === void 0) {
105
+ throw new BeraError({
106
+ level: "fatal",
107
+ tags,
108
+ message: "Bera Apollo Client: No data returned from query, but error should be thrown since errorPolicy is none"
109
+ });
110
+ }
111
+ return { data: res.data };
112
+ } catch (error) {
113
+ !appConfig.env.isProduction && console.error("BeraApolloClient error", error);
114
+ if (ServerError.is(error)) {
115
+ throw new RequestError({
116
+ // reason: error,
117
+ response: error.response,
118
+ cause: error,
119
+ statusCode: error.statusCode,
120
+ endpoint,
121
+ tags
122
+ });
123
+ }
124
+ if (error instanceof TypeError) {
125
+ throw new RequestError({
126
+ level: "fatal",
127
+ reason: "TypeError",
128
+ response: error,
129
+ cause: error,
130
+ endpoint,
131
+ tags
132
+ });
133
+ }
134
+ throw new RequestError({
135
+ response: error,
136
+ tags,
137
+ cause: error,
138
+ endpoint
139
+ });
140
+ }
141
+ }
142
+ };
143
+ function getQueryName(queryDefinition) {
144
+ const likelyNode = queryDefinition.definitions.find(
145
+ (def) => def.kind === "OperationDefinition"
146
+ );
147
+ return likelyNode?.name?.value;
148
+ }
149
+
150
+ // src/actions/clients/getApolloClient.ts
151
+ import { InMemoryCache } from "@apollo/client";
152
+ import { HttpLink } from "@apollo/client/link/http";
153
+ import { getUriFromLink } from "@berachain/config";
154
+ import { currentDapp } from "@berachain/config/internal";
155
+ import apiResults from "@berachain/graphql/dex/api";
156
+ import { gql } from "@apollo/client";
157
+ function applyStellateClientName(url) {
158
+ const headers = typeof url === "string" ? void 0 : url.headers;
159
+ const isDapp = !!currentDapp;
160
+ const isTest = process.env.VERCEL_ENV === "test";
161
+ return {
162
+ uri: getUriFromLink(url),
163
+ headers: {
164
+ ...headers,
165
+ "x-graphql-client-name": `berachain.${isDapp ? "dapps" : isTest ? "test" : (
166
+ // this tracks usage of the berajs package in other packages
167
+ "berajs"
168
+ )}`,
169
+ "x-graphql-client-version": `${process.env.VERCEL_TARGET_ENV}.${process.env.VERCEL_GIT_COMMIT_SHA}`
170
+ }
171
+ };
172
+ }
173
+ function getClient(endpoint, {
174
+ ssrMode,
175
+ inMemoryCacheOptions
176
+ } = {}) {
177
+ const url = getUriFromLink(endpoint);
178
+ const headers = typeof endpoint === "string" ? void 0 : endpoint.headers;
179
+ return new BeraApolloClient({
180
+ url,
181
+ link: new HttpLink({
182
+ uri: url,
183
+ headers
184
+ }),
185
+ defaultOptions: {
186
+ query: {
187
+ // With the default none error policy, an error causes the promise to reject.
188
+ errorPolicy: "none",
189
+ fetchPolicy: "no-cache"
190
+ }
191
+ },
192
+ cache: new InMemoryCache(inMemoryCacheOptions),
193
+ ssrMode
194
+ });
195
+ }
196
+ function getApolloClient(clientName, { ...args }) {
197
+ const { config } = parseBaseArgs(args);
198
+ switch (clientName) {
199
+ case "api":
200
+ return getClient(applyStellateClientName(config.api), {
201
+ inMemoryCacheOptions: {
202
+ possibleTypes: apiResults.possibleTypes
203
+ }
204
+ });
205
+ case "bend.whisk":
206
+ if (!config.bend.whiskApi) {
207
+ throw new BeraError({
208
+ message: "Bend whisk API is not configured on this chain",
209
+ level: "error"
210
+ });
211
+ }
212
+ return getClient(config.bend.whiskApi);
213
+ case "honey.subgraph":
214
+ return getClient(config.honey.subgraph);
215
+ case "pol.subgraph":
216
+ return getClient(config.pol.subgraph);
217
+ case "pol.fees":
218
+ return getClient(config.pol.feesSubgraph);
219
+ case "governance.subgraph":
220
+ return getClient(config.governance.subgraph);
221
+ case "bex.subgraph":
222
+ return getClient(config.bex.subgraph);
223
+ }
224
+ }
225
+
226
+ // src/actions/dex/aggregators/base.ts
227
+ import { formatUnits, isAddress, zeroAddress } from "viem";
228
+ var BaseAggregator = class _BaseAggregator {
229
+ static PATH_NOT_FOUND_REASON = "NO_SWAP_PATHS";
230
+ needsAccountForQuote = false;
231
+ notFoundMessages = [];
232
+ config;
233
+ chainId;
234
+ constructor(args = {}) {
235
+ const { config, chainId } = parseBaseArgs(args);
236
+ this.config = config;
237
+ this.chainId = chainId;
238
+ }
239
+ /**
240
+ * Identifies the url of the last sent request. Might not have all query params.
241
+ * Mainly used for error reporting.
242
+ */
243
+ url = "";
244
+ /**
245
+ * return wbera for native tokens to accomodate the aggregator's router logic
246
+ */
247
+ parseAddresses(tokenIn, tokenOut) {
248
+ if (!isAddress(tokenIn) || !isAddress(tokenOut)) {
249
+ throw new BeraError({
250
+ message: `Invalid address: ${tokenIn} or ${tokenOut}`,
251
+ level: "error"
252
+ });
253
+ }
254
+ return {
255
+ tokenInAddress: isToken(tokenIn, "BERA") ? this.config.tokens.wbera : tokenIn,
256
+ tokenOutAddress: isToken(tokenOut, "BERA") ? this.config.tokens.wbera : tokenOut,
257
+ isTokenInNative: isToken(tokenIn, "BERA"),
258
+ isTokenOutNative: isToken(tokenOut, "BERA")
259
+ };
260
+ }
261
+ /**
262
+ * Calculate input amount after fees.
263
+ *
264
+ * @returns Amount in wad format
265
+ */
266
+ getAmountAfterFees(amount, aggregatorsFeeBps) {
267
+ if (aggregatorsFeeBps === void 0) {
268
+ throw new BeraError({
269
+ message: "aggregatorsFeeBps is required",
270
+ level: "error"
271
+ });
272
+ }
273
+ const fees = new bignumber_js_default(amount).times(aggregatorsFeeBps).dividedBy(1e4).toFixed(0, bignumber_js_default.ROUND_DOWN);
274
+ return new bignumber_js_default(amount).minus(fees).toFixed(0, bignumber_js_default.ROUND_DOWN);
275
+ }
276
+ /**
277
+ * Formats input data for aggregator swaps
278
+ */
279
+ getInputData({
280
+ tokenIn,
281
+ amountIn,
282
+ isNative,
283
+ isPermit2Approval = false,
284
+ permit2SpenderAddress
285
+ }) {
286
+ return {
287
+ tokenIn,
288
+ amountIn: BigInt(amountIn),
289
+ isNative,
290
+ isPermit2Approval,
291
+ permit2SpenderAddress: permit2SpenderAddress ?? zeroAddress
292
+ };
293
+ }
294
+ /**
295
+ * Calculate min amount out
296
+ */
297
+ getMinAmountOut(amountOut, slippage) {
298
+ if (slippage === void 0) {
299
+ throw new BeraError({
300
+ message: "slippage is required",
301
+ level: "error"
302
+ });
303
+ }
304
+ const minAmountOut = new bignumber_js_default(amountOut).times(1 - slippage / 100);
305
+ if (minAmountOut.isNaN() || minAmountOut.isZero()) {
306
+ return 0n;
307
+ }
308
+ return BigInt(minAmountOut.toFixed(0));
309
+ }
310
+ parseAllowanceRequirements({
311
+ tokenIn,
312
+ rawAmount,
313
+ spender
314
+ }) {
315
+ return isToken(tokenIn, "BERA") ? [] : [
316
+ {
317
+ token: tokenIn,
318
+ amount: {
319
+ raw: rawAmount,
320
+ formatted: formatUnits(BigInt(rawAmount), tokenIn.decimals)
321
+ },
322
+ spender
323
+ }
324
+ ];
325
+ }
326
+ /**
327
+ * Check if chain is supported
328
+ */
329
+ checkChainSupport({
330
+ tokenIn,
331
+ tokenOut
332
+ }) {
333
+ if (this.supportedChains === null) {
334
+ return true;
335
+ }
336
+ return this.supportedChains.includes(tokenIn.chainId) && this.supportedChains.includes(tokenOut.chainId);
337
+ }
338
+ assertChainSupport({
339
+ tokenIn,
340
+ tokenOut,
341
+ underlyingToken
342
+ }) {
343
+ if (!this.checkChainSupport({ tokenIn, tokenOut, underlyingToken })) {
344
+ throw new BeraError({
345
+ message: `${this.name} does not support tokens chain ID: ${tokenIn.chainId} and ${tokenOut.chainId}`,
346
+ level: "error"
347
+ });
348
+ }
349
+ }
350
+ async fetch(url, options) {
351
+ try {
352
+ return beraFetch(
353
+ { url, name: this.name, type: this.type },
354
+ {
355
+ method: "GET",
356
+ headers: {
357
+ "Content-Type": "application/json"
358
+ },
359
+ ...options
360
+ }
361
+ );
362
+ } catch (err) {
363
+ const error = initBeraError({ cause: err });
364
+ if (this.notFoundMessages.some((message) => error.message.includes(message))) {
365
+ error.reason = _BaseAggregator.PATH_NOT_FOUND_REASON;
366
+ }
367
+ throw error;
368
+ }
369
+ }
370
+ };
371
+
372
+ // src/actions/dex/b-sdk.ts
373
+ import {
374
+ API_CHAIN_NAMES,
375
+ BALANCER_QUERIES,
376
+ BALANCER_RELAYER,
377
+ BalancerApi,
378
+ CHAINS,
379
+ COMPOSABLE_STABLE_POOL_FACTORY,
380
+ NATIVE_ASSETS,
381
+ Token,
382
+ VAULT,
383
+ WEIGHTED_POOL_FACTORY_BALANCER_V2
384
+ } from "@berachain-foundation/berancer-sdk";
385
+ import { zeroAddress as zeroAddress2 } from "viem";
386
+ import { berachain, berachainBepolia } from "viem/chains";
387
+ import { chainConfigs } from "@berachain/config/internal";
388
+ for (const chain of Object.keys(chainConfigs)) {
389
+ const { config, chainId } = parseBaseArgs({
390
+ chainId: Number(chain)
391
+ });
392
+ API_CHAIN_NAMES[chainId] = config.bex.chainName;
393
+ CHAINS[chainId] = chainId === berachain.id ? berachain : berachainBepolia;
394
+ BALANCER_RELAYER[chainId] = config.bex.relayer;
395
+ VAULT[chainId] = config.bex.vault;
396
+ BALANCER_QUERIES[chainId] = config.bex.queries;
397
+ WEIGHTED_POOL_FACTORY_BALANCER_V2[chainId] = zeroAddress2;
398
+ COMPOSABLE_STABLE_POOL_FACTORY[chainId] = zeroAddress2;
399
+ const nativeToken = new Token(
400
+ chainId,
401
+ zeroAddress2,
402
+ beraToken.decimals,
403
+ beraToken.name,
404
+ beraToken.symbol,
405
+ config.tokens.wbera
406
+ );
407
+ NATIVE_ASSETS[chainId] = nativeToken;
408
+ }
409
+
410
+ // src/actions/dex/getAllPools.ts
411
+ import {
412
+ GetPools
413
+ } from "@berachain/graphql/dex/api";
414
+ import {
415
+ GqlPoolOrderBy,
416
+ GqlPoolOrderDirection
417
+ } from "@berachain/graphql/pol/api";
418
+ async function getAllPools({
419
+ textSearch,
420
+ chain,
421
+ first,
422
+ orderBy,
423
+ orderDirection,
424
+ skip,
425
+ fetchPolicy,
426
+ userAddress,
427
+ blacklistedPoolIds,
428
+ ...args
429
+ } = {}) {
430
+ const { config } = parseBaseArgs(args);
431
+ const bexApiGraphqlClient = getApolloClient("api", args);
432
+ const pools = await bexApiGraphqlClient.query({
433
+ query: GetPools,
434
+ variables: {
435
+ textSearch,
436
+ chain: chain ?? config.bex.chainName,
437
+ first,
438
+ orderBy: orderBy ?? GqlPoolOrderBy.TotalLiquidity,
439
+ orderDirection: orderDirection ?? GqlPoolOrderDirection.Desc,
440
+ skip,
441
+ userAddress,
442
+ blacklistedPoolIds
443
+ },
444
+ fetchPolicy
445
+ });
446
+ return {
447
+ pools: pools.data.poolGetPools ?? [],
448
+ count: pools.data.count ?? 0
449
+ };
450
+ }
451
+
452
+ // src/actions/dex/getApiPool.ts
453
+ import {
454
+ GetPool
455
+ } from "@berachain/graphql/dex/api";
456
+ async function getApiPool({
457
+ poolId,
458
+ account,
459
+ ...args
460
+ }) {
461
+ const { config } = parseBaseArgs(args);
462
+ const bexApiGraphqlClient = getApolloClient("api", args);
463
+ const pool = await bexApiGraphqlClient.query({
464
+ query: GetPool,
465
+ variables: {
466
+ id: poolId,
467
+ userAddress: account,
468
+ chain: config.bex.chainName
469
+ },
470
+ fetchPolicy: "no-cache"
471
+ // If we cache it seems to return an empty response
472
+ });
473
+ const data = pool.data.poolGetPool;
474
+ if (!data) {
475
+ throw new Error(`Pool not found for id: ${poolId} and user ${account}`);
476
+ }
477
+ return data;
478
+ }
479
+
480
+ // src/actions/dex/getGlobalLiquidityAndSwapVolume.ts
481
+ import {
482
+ GetGlobalLiquidityAndSwapVolume
483
+ } from "@berachain/graphql/dex/api";
484
+ async function getGlobalLiquidityAndSwapVolume(args = {}) {
485
+ const { config } = parseBaseArgs(args);
486
+ const bexApiGraphqlClient = getApolloClient("api", args);
487
+ const response = await bexApiGraphqlClient.query({
488
+ query: GetGlobalLiquidityAndSwapVolume,
489
+ variables: {
490
+ chain: config.bex.chainName
491
+ }
492
+ });
493
+ return response.data;
494
+ }
495
+
496
+ // src/actions/dex/getPoolPausedState.ts
497
+ import { weightedPoolV4Abi_V2 } from "@berachain-foundation/berancer-sdk";
498
+ async function getPoolPausedState({
499
+ publicClient,
500
+ poolAddress
501
+ }) {
502
+ const abi = weightedPoolV4Abi_V2;
503
+ const results = await publicClient.multicall({
504
+ contracts: [
505
+ {
506
+ address: poolAddress,
507
+ abi,
508
+ functionName: "inRecoveryMode"
509
+ },
510
+ {
511
+ address: poolAddress,
512
+ abi,
513
+ functionName: "getPausedState"
514
+ }
515
+ ],
516
+ allowFailure: false
517
+ // NOTE: this disallows partial failures of the multicall
518
+ });
519
+ return {
520
+ isPoolInRecoveryMode: results[0],
521
+ isPoolPaused: results[1][0]
522
+ };
523
+ }
524
+
525
+ // src/actions/dex/getOnChainPool.ts
526
+ import {
527
+ stablePoolAbi_V3,
528
+ vaultV2Abi,
529
+ weightedPoolFactoryAbi_V3,
530
+ weightedPoolV4Abi_V2 as weightedPoolV4Abi_V22
531
+ } from "@berachain-foundation/berancer-sdk";
532
+ import {
533
+ erc20Abi,
534
+ formatEther as formatEther2,
535
+ formatUnits as formatUnits2,
536
+ isAddress as isAddress2,
537
+ isHex
538
+ } from "viem";
539
+ import { GqlPoolType } from "@berachain/graphql/pol/api";
540
+ async function getOnChainPool({
541
+ poolId,
542
+ publicClient,
543
+ ...args
544
+ }) {
545
+ const { config } = parseBaseArgs(args);
546
+ const address = poolId.slice(0, 42);
547
+ if (!isAddress2(address) || !isHex(poolId)) {
548
+ throw new InvalidArgumentError({
549
+ property: "poolId",
550
+ value: poolId,
551
+ expected: "Hex"
552
+ });
553
+ }
554
+ try {
555
+ const [
556
+ name,
557
+ poolTokens,
558
+ totalSupply,
559
+ swapFee,
560
+ _version,
561
+ _decimals,
562
+ isComposableStable,
563
+ isWeighted,
564
+ poolPausedState
565
+ ] = await Promise.all([
566
+ publicClient.readContract({
567
+ address,
568
+ abi: erc20Abi,
569
+ functionName: "name"
570
+ }),
571
+ publicClient.readContract({
572
+ address: config.bex.vault,
573
+ abi: vaultV2Abi,
574
+ functionName: "getPoolTokens",
575
+ args: [poolId]
576
+ }),
577
+ publicClient.readContract({
578
+ address,
579
+ abi: erc20Abi,
580
+ functionName: "totalSupply"
581
+ }),
582
+ publicClient.readContract({
583
+ address,
584
+ abi: weightedPoolV4Abi_V22,
585
+ functionName: "getSwapFeePercentage"
586
+ }),
587
+ publicClient.readContract({
588
+ address,
589
+ abi: weightedPoolV4Abi_V22,
590
+ functionName: "version"
591
+ }),
592
+ publicClient.readContract({
593
+ address,
594
+ abi: weightedPoolV4Abi_V22,
595
+ functionName: "decimals"
596
+ }),
597
+ publicClient.readContract({
598
+ address: config.bex.factories.composableStable,
599
+ abi: weightedPoolFactoryAbi_V3,
600
+ functionName: "isPoolFromFactory",
601
+ args: [address]
602
+ }),
603
+ publicClient.readContract({
604
+ address: config.bex.factories.weighted,
605
+ abi: weightedPoolFactoryAbi_V3,
606
+ functionName: "isPoolFromFactory",
607
+ args: [address]
608
+ }),
609
+ getPoolPausedState({ publicClient, poolAddress: address })
610
+ ]);
611
+ const decimals = Number(_decimals);
612
+ const version = JSON.parse(_version);
613
+ let virtualSupply;
614
+ let weights;
615
+ let amplificationParameter;
616
+ if (isComposableStable) {
617
+ [virtualSupply, amplificationParameter] = await Promise.all([
618
+ publicClient.readContract({
619
+ address,
620
+ abi: [
621
+ {
622
+ type: "function",
623
+ name: "getActualSupply",
624
+ stateMutability: "view",
625
+ inputs: [],
626
+ outputs: [
627
+ {
628
+ type: "uint256"
629
+ }
630
+ ]
631
+ }
632
+ ],
633
+ functionName: "getActualSupply"
634
+ }),
635
+ // NOTE: it is possible to pull this from the subgraph, but not using GqlPoolBase, we'd have to query a specific pool type.
636
+ publicClient.readContract({
637
+ address,
638
+ abi: stablePoolAbi_V3,
639
+ functionName: "getAmplificationParameter"
640
+ })
641
+ ]);
642
+ } else if (version.name === "WeightedPool") {
643
+ weights = await publicClient.readContract({
644
+ address,
645
+ abi: weightedPoolV4Abi_V22,
646
+ functionName: "getNormalizedWeights"
647
+ });
648
+ }
649
+ if (!isComposableStable && !isWeighted) {
650
+ throw new Error(`Pool ${address} is not a valid BEX pool`);
651
+ }
652
+ return {
653
+ name,
654
+ address,
655
+ id: poolId,
656
+ poolTokens: [
657
+ poolTokens[0],
658
+ poolTokens[1].map(String),
659
+ Number(poolTokens[2])
660
+ ],
661
+ totalSupply: formatUnits2(virtualSupply ?? totalSupply, decimals),
662
+ swapFee: formatEther2(swapFee),
663
+ decimals,
664
+ weights: weights?.map((weight) => formatEther2(weight)),
665
+ version,
666
+ factory: isComposableStable ? config.bex.factories.composableStable : config.bex.factories.weighted,
667
+ type: isComposableStable ? GqlPoolType.Stable : GqlPoolType.Weighted,
668
+ amplificationParameter: amplificationParameter ? [
669
+ // raw value
670
+ Number(amplificationParameter[0]),
671
+ // is updating
672
+ amplificationParameter[1],
673
+ // precision factor
674
+ Number(amplificationParameter[2])
675
+ ] : void 0,
676
+ pausedState: poolPausedState
677
+ };
678
+ } catch (e) {
679
+ throw initBeraError({ cause: e });
680
+ }
681
+ }
682
+
683
+ // src/actions/dex/getPoolEvents.ts
684
+ import {
685
+ GetPoolEvents
686
+ } from "@berachain/graphql/dex/api";
687
+ async function getPoolEvents({
688
+ poolId,
689
+ typeInArray,
690
+ ...args
691
+ }) {
692
+ const { config } = parseBaseArgs(args);
693
+ const bexApiGraphqlClient = getApolloClient("api", args);
694
+ const response = await bexApiGraphqlClient.query({
695
+ query: GetPoolEvents,
696
+ variables: {
697
+ poolId,
698
+ typeIn: typeInArray,
699
+ chain: config.bex.chainName
700
+ }
701
+ });
702
+ return response.data;
703
+ }
704
+
705
+ // src/actions/dex/getPoolHistoricalData.ts
706
+ import { isHex as isHex2 } from "viem";
707
+ import {
708
+ GetPoolHistoricalData
709
+ } from "@berachain/graphql/dex/api";
710
+ async function getPoolHistoricalData({
711
+ poolId,
712
+ chain,
713
+ ...args
714
+ }) {
715
+ if (!poolId || !isHex2(poolId))
716
+ throw new InvalidArgumentError({
717
+ property: "poolId",
718
+ value: poolId,
719
+ expected: "hex string"
720
+ });
721
+ const bexApiGraphqlClient = getApolloClient("api", args);
722
+ const { data } = await bexApiGraphqlClient.query({
723
+ query: GetPoolHistoricalData,
724
+ variables: { poolId, chain }
725
+ });
726
+ return data.poolGetSnapshots;
727
+ }
728
+
729
+ // src/actions/governance/checkProposalField.ts
730
+ import { isAddress as isAddress3, isHex as isHex3 } from "viem";
731
+ function checkProposalField({
732
+ fieldOrType,
733
+ value,
734
+ required = true,
735
+ baseUrl,
736
+ components
737
+ }) {
738
+ const notRequiredAbiTypes = ["bool", "string"];
739
+ if (!notRequiredAbiTypes.includes(fieldOrType) && required && (value === void 0 || value === null || value === "")) {
740
+ return "Required" /* REQUIRED */;
741
+ }
742
+ if (fieldOrType.startsWith("uint") || fieldOrType.startsWith("int")) {
743
+ if (typeof value !== "string") {
744
+ return "Invalid amount" /* INVALID_AMOUNT */;
745
+ }
746
+ try {
747
+ const valueBN = BigInt(value);
748
+ if (fieldOrType.startsWith("uint")) {
749
+ if (valueBN < 0n) {
750
+ return "Negative amount" /* NEGATIVE_AMOUNT */;
751
+ }
752
+ }
753
+ } catch {
754
+ return "Invalid amount" /* INVALID_AMOUNT */;
755
+ }
756
+ return null;
757
+ }
758
+ switch (fieldOrType) {
759
+ case "string":
760
+ if (value !== void 0 && typeof value !== "string") {
761
+ return "Invalid amount" /* INVALID_AMOUNT */;
762
+ }
763
+ return null;
764
+ case "bool":
765
+ if (typeof value !== "boolean") {
766
+ return "Invalid amount" /* INVALID_AMOUNT */;
767
+ }
768
+ return null;
769
+ case "title":
770
+ if (typeof value !== "string" || value.length === 0) {
771
+ return "Required" /* REQUIRED */;
772
+ }
773
+ return null;
774
+ case "description":
775
+ if (typeof value !== "string" || value.length === 0) {
776
+ return "Required" /* REQUIRED */;
777
+ }
778
+ return null;
779
+ case "forumLink": {
780
+ if (typeof value !== "string" || value.length === 0) {
781
+ return "Required" /* REQUIRED */;
782
+ }
783
+ if (!URL.canParse(value)) {
784
+ return "Invalid address" /* INVALID_ADDRESS */;
785
+ }
786
+ const base = new URL(baseUrl);
787
+ if (!value.startsWith(base.toString())) {
788
+ return "Must be a berachain forum link" /* INVALID_BASEPATH */;
789
+ }
790
+ return null;
791
+ }
792
+ case "address":
793
+ if (typeof value !== "string" || !isAddress3(value, { strict: true })) {
794
+ return "Invalid address" /* INVALID_ADDRESS */;
795
+ }
796
+ return null;
797
+ case "hex":
798
+ if (typeof value !== "string" || !isHex3(value, { strict: true })) {
799
+ return "Invalid address" /* INVALID_ADDRESS */;
800
+ }
801
+ return null;
802
+ case "abi":
803
+ if (typeof value !== "string") {
804
+ return "Invalid ABI" /* INVALID_ABI */;
805
+ }
806
+ try {
807
+ JSON.parse(value);
808
+ } catch {
809
+ return "Invalid ABI" /* INVALID_ABI */;
810
+ }
811
+ return null;
812
+ case "action":
813
+ if (typeof value !== "string" || !isAddress3(value, { strict: true })) {
814
+ return "Invalid address" /* INVALID_ADDRESS */;
815
+ }
816
+ return null;
817
+ case "tuple":
818
+ if (typeof value === "object" && Array.isArray(components)) {
819
+ const errors = {};
820
+ for (const component of components) {
821
+ const abiParam = component;
822
+ const name = abiParam.name;
823
+ errors[name] = checkProposalField({
824
+ fieldOrType: abiParam.type,
825
+ value: value[name],
826
+ components: abiParam.components
827
+ });
828
+ }
829
+ if (Object.values(errors).every((v) => v === null)) {
830
+ return null;
831
+ }
832
+ return errors;
833
+ }
834
+ return null;
835
+ case "tuple[]":
836
+ if (Array.isArray(value)) {
837
+ const errors = value.map(
838
+ (v) => checkProposalField({
839
+ fieldOrType: "tuple",
840
+ value: v,
841
+ components
842
+ })
843
+ );
844
+ if (errors.every((v) => v === null)) {
845
+ return null;
846
+ }
847
+ return errors;
848
+ }
849
+ return null;
850
+ case "logoURI": {
851
+ if (value === void 0 || value === "") {
852
+ return null;
853
+ }
854
+ if (typeof value !== "string" || !URL.canParse(value) || new URL(value).protocol !== "https:") {
855
+ return "Must be HTTPS or IPFS" /* MUST_BE_HTTPS_OR_IPFS */;
856
+ }
857
+ return null;
858
+ }
859
+ case "url": {
860
+ if (value === void 0 || value === "") {
861
+ return null;
862
+ }
863
+ if (typeof value !== "string" || !URL.canParse(value) || new URL(value).protocol !== "https:") {
864
+ return "Must be HTTPS" /* MUST_BE_HTTPS */;
865
+ }
866
+ return null;
867
+ }
868
+ default:
869
+ console.error(`Invalid field or type: ${fieldOrType}`);
870
+ return null;
871
+ }
872
+ }
873
+
874
+ // src/actions/governance/computeActualStatus.ts
875
+ import {
876
+ ProposalStatus
877
+ } from "@berachain/graphql/governance";
878
+ var GOVERNANCE_ACCELERATE_PROPOSAL = false;
879
+ var MOCKED_PROPOSAL_STATUSES = [
880
+ ProposalStatus.Active,
881
+ ProposalStatus.PendingQueue,
882
+ ProposalStatus.PendingExecution,
883
+ ProposalStatus.Defeated,
884
+ ProposalStatus.QuorumNotReached
885
+ ];
886
+ function computeActualStatus(proposal, proposalOnChainState) {
887
+ const timestampInSeconds = Date.now() / 1e3;
888
+ if (proposalOnChainState !== void 0) {
889
+ if (proposal.status === ProposalStatus.CanceledByGuardian) {
890
+ return ProposalStatus.CanceledByGuardian;
891
+ }
892
+ if (proposalOnChainState === 2 /* Canceled */) {
893
+ if (Number(proposal.voteStartAt) < timestampInSeconds)
894
+ return ProposalStatus.CanceledByUser;
895
+ return ProposalStatus.CanceledByGuardian;
896
+ }
897
+ if (proposalOnChainState === 3 /* Defeated */) {
898
+ if (!proposal.pollResult) {
899
+ return ProposalStatus.QuorumNotReached;
900
+ }
901
+ if (
902
+ // Quorum might be null if no votes were cast.
903
+ !proposal.quorum || BigInt(proposal.quorum) > BigInt(proposal.pollResult.totalTowardsQuorum)
904
+ ) {
905
+ return ProposalStatus.QuorumNotReached;
906
+ }
907
+ return ProposalStatus.Defeated;
908
+ }
909
+ if (proposalOnChainState === 4 /* Succeeded */) {
910
+ return ProposalStatus.PendingQueue;
911
+ }
912
+ if (proposalOnChainState === 5 /* Queued */) {
913
+ if (Number(proposal.queueEnd) < Date.now() / 1e3) {
914
+ return ProposalStatus.PendingExecution;
915
+ }
916
+ return ProposalStatus.InQueue;
917
+ }
918
+ if (proposalOnChainState === 6 /* Expired */) {
919
+ console.warn("Unexpected expired state on proposal id: ", proposal.id);
920
+ return ProposalStatus.Defeated;
921
+ }
922
+ }
923
+ if (proposal.status === ProposalStatus.InQueue) {
924
+ if (Number(proposal.queueEnd) < Date.now() / 1e3) {
925
+ return ProposalStatus.PendingExecution;
926
+ }
927
+ }
928
+ if (GOVERNANCE_ACCELERATE_PROPOSAL && proposalOnChainState === 1 /* Active */ && proposal.quorum && BigInt(proposal.quorum) < BigInt(proposal.pollResult.totalTowardsQuorum) && Number(proposal.pollResult.forPercentage) > Number(proposal.pollResult.againstPercentage)) {
929
+ return ProposalStatus.PendingQueue;
930
+ }
931
+ if (proposal.status === ProposalStatus.Pending) {
932
+ if (Number(proposal.voteStartAt) < timestampInSeconds && Number(proposal.voteEndAt) > timestampInSeconds) {
933
+ return ProposalStatus.Active;
934
+ }
935
+ if (Number(proposal.voteEndAt) < timestampInSeconds) {
936
+ if (!proposal.pollResult) {
937
+ return ProposalStatus.QuorumNotReached;
938
+ }
939
+ if (!proposal.quorum || BigInt(proposal.quorum) > BigInt(proposal.pollResult.totalTowardsQuorum)) {
940
+ return ProposalStatus.QuorumNotReached;
941
+ }
942
+ if (proposal.pollResult?.against > proposal.pollResult?.for) {
943
+ return ProposalStatus.Defeated;
944
+ }
945
+ return ProposalStatus.PendingQueue;
946
+ }
947
+ return ProposalStatus.Pending;
948
+ }
949
+ if (proposal.status === ProposalStatus.Active && Number(proposal.voteEndAt) < timestampInSeconds) {
950
+ if (!proposal.quorum || BigInt(proposal.quorum) > BigInt(proposal.pollResult.totalTowardsQuorum)) {
951
+ return ProposalStatus.QuorumNotReached;
952
+ }
953
+ if (BigInt(proposal.pollResult?.against ?? 0n) > BigInt(proposal.pollResult?.for ?? 0n)) {
954
+ return ProposalStatus.Defeated;
955
+ }
956
+ return ProposalStatus.PendingQueue;
957
+ }
958
+ if (proposal.status === ProposalStatus.InQueue) {
959
+ if (Number(proposal.queueEnd) < Date.now() / 1e3) {
960
+ return ProposalStatus.PendingExecution;
961
+ }
962
+ }
963
+ return proposal.status;
964
+ }
965
+
966
+ // src/actions/governance/getAllProposals.ts
967
+ import {
968
+ GetProposals,
969
+ SearchProposals
970
+ } from "@berachain/graphql/governance";
971
+ async function getAllProposals({
972
+ where,
973
+ orderBy,
974
+ orderDirection,
975
+ offset = 0,
976
+ perPage = 20,
977
+ text,
978
+ ...args
979
+ }) {
980
+ try {
981
+ if (perPage > 1e3) {
982
+ throw new Error("perPage must be less than 1000");
983
+ }
984
+ const governanceClient = getApolloClient("governance.subgraph", args);
985
+ const [response] = await Promise.all([
986
+ text ? governanceClient.query({
987
+ query: SearchProposals,
988
+ variables: {
989
+ offset,
990
+ limit: perPage,
991
+ where,
992
+ text
993
+ }
994
+ }) : governanceClient.query(
995
+ {
996
+ query: GetProposals,
997
+ variables: {
998
+ offset,
999
+ limit: perPage,
1000
+ where,
1001
+ orderBy,
1002
+ orderDirection
1003
+ }
1004
+ }
1005
+ )
1006
+ ]);
1007
+ return response.data.proposals.map((p) => ({
1008
+ ...p,
1009
+ status: computeActualStatus(p)
1010
+ }));
1011
+ } catch (e) {
1012
+ console.error("getAllProposals:", e);
1013
+ throw e;
1014
+ }
1015
+ }
1016
+
1017
+ // src/actions/governance/getBodyErrors.ts
1018
+ function getBodyErrors({
1019
+ proposal,
1020
+ currentTopic
1021
+ }) {
1022
+ const e = {};
1023
+ e.title = checkProposalField({
1024
+ fieldOrType: "title",
1025
+ value: proposal.title
1026
+ });
1027
+ e.description = checkProposalField({
1028
+ fieldOrType: "description",
1029
+ value: proposal.description
1030
+ });
1031
+ e.forumLink = checkProposalField({
1032
+ fieldOrType: "forumLink",
1033
+ value: proposal.forumLink,
1034
+ baseUrl: currentTopic.forumLink
1035
+ });
1036
+ return e;
1037
+ }
1038
+
1039
+ // src/actions/governance/getProposalDetails.ts
1040
+ import {
1041
+ GetProposal
1042
+ } from "@berachain/graphql/governance";
1043
+ async function getProposalDetails({
1044
+ proposalId,
1045
+ ...args
1046
+ }) {
1047
+ const governanceClient = getApolloClient("governance.subgraph", args);
1048
+ const res = await governanceClient.query({
1049
+ query: GetProposal,
1050
+ variables: {
1051
+ id: proposalId
1052
+ }
1053
+ });
1054
+ if (!res.data.proposal) {
1055
+ return void 0;
1056
+ }
1057
+ return {
1058
+ ...res.data.proposal,
1059
+ status: computeActualStatus(res.data.proposal)
1060
+ };
1061
+ }
1062
+
1063
+ // src/actions/governance/parseProposalBody.ts
1064
+ import graymatter from "gray-matter";
1065
+ function parseLegacyBody(s) {
1066
+ const pattern = /#(?:([\w-]+)# )?(.+)\n([\s\S]*)/;
1067
+ const match = s.match(pattern);
1068
+ if (match) {
1069
+ const type = match[1] || null;
1070
+ const title = match[2];
1071
+ const content = match[3].replace("\n", "<br />");
1072
+ return {
1073
+ type,
1074
+ title,
1075
+ content
1076
+ };
1077
+ }
1078
+ throw new Error("Invalid proposal body");
1079
+ }
1080
+ function parseProposalBody(proposal) {
1081
+ if (!proposal) {
1082
+ return {
1083
+ isFrontMatter: false,
1084
+ data: { title: "Loading..." },
1085
+ content: "",
1086
+ matter: "",
1087
+ language: "",
1088
+ orig: "",
1089
+ stringify: () => ""
1090
+ };
1091
+ }
1092
+ const body = proposal?.description ?? "";
1093
+ if (graymatter.test(body)) {
1094
+ return { ...graymatter(body), isFrontMatter: true };
1095
+ }
1096
+ try {
1097
+ const legacyBody = parseLegacyBody(body);
1098
+ return {
1099
+ isFrontMatter: false,
1100
+ data: { title: legacyBody.title },
1101
+ content: legacyBody.content,
1102
+ matter: "",
1103
+ language: "",
1104
+ orig: body,
1105
+ stringify: () => body
1106
+ };
1107
+ } catch {
1108
+ return {
1109
+ isFrontMatter: false,
1110
+ data: {
1111
+ title: proposal?.description?.split("\n")[0].slice(0, 100)
1112
+ },
1113
+ content: body,
1114
+ matter: "",
1115
+ language: "",
1116
+ orig: body,
1117
+ stringify: () => body
1118
+ };
1119
+ }
1120
+ }
1121
+
1122
+ // src/actions/governance/getProposalFromTx.ts
1123
+ import {
1124
+ parseEventLogs
1125
+ } from "viem";
1126
+ import { berachainGovernanceAbi as governanceAbi } from "@berachain/abis/gov/berachainGovernance";
1127
+ import {
1128
+ ProposalStatus as ProposalStatus2
1129
+ } from "@berachain/graphql/governance";
1130
+ async function getProposalFromTx(args) {
1131
+ assertPublicClient(args.publicClient);
1132
+ let tx;
1133
+ if ("tx" in args) {
1134
+ tx = args.tx;
1135
+ } else {
1136
+ tx = await args.publicClient.getTransactionReceipt({ hash: args.txHash });
1137
+ }
1138
+ const creationEvent = tx?.logs ? parseEventLogs({
1139
+ abi: governanceAbi,
1140
+ logs: tx.logs,
1141
+ eventName: "ProposalCreated"
1142
+ })?.at(0) : void 0;
1143
+ if (!tx || !creationEvent) {
1144
+ return null;
1145
+ }
1146
+ const block = await args.publicClient.getBlock({
1147
+ blockNumber: tx.blockNumber
1148
+ });
1149
+ const fm = parseProposalBody({
1150
+ description: creationEvent?.args.description
1151
+ });
1152
+ return {
1153
+ id: String(creationEvent.args.proposalId),
1154
+ proposalId: String(creationEvent?.args.proposalId),
1155
+ createdAt: block.timestamp.toString(),
1156
+ title: fm.data.title,
1157
+ createdAtBlock: block.timestamp.toString(),
1158
+ voteStartAt: String(creationEvent?.args.voteStart),
1159
+ voteEndAt: String(creationEvent?.args.voteEnd),
1160
+ proposer: creationEvent?.args.proposer,
1161
+ description: fm.content,
1162
+ unverifiedForumLink: fm.data.forumLink,
1163
+ pollResult: {
1164
+ for: "0",
1165
+ forVotersCount: 0,
1166
+ forPercentage: "0",
1167
+ against: "0",
1168
+ againstVotersCount: 0,
1169
+ againstPercentage: "0",
1170
+ abstain: "0",
1171
+ abstainVotersCount: 0,
1172
+ abstainPercentage: "0",
1173
+ total: "0",
1174
+ totalVotersCount: 0,
1175
+ totalTowardsQuorum: "0"
1176
+ },
1177
+ status: ProposalStatus2.Pending,
1178
+ quorum: null,
1179
+ topics: fm.data.topics,
1180
+ votes: [],
1181
+ executableCalls: creationEvent?.args.targets.map(
1182
+ (target, index) => ({
1183
+ __typename: "ExecutableCall",
1184
+ id: `${tx.transactionHash}-${index}`,
1185
+ target,
1186
+ value: String(creationEvent?.args.values[index]),
1187
+ calldata: creationEvent?.args.calldatas[index]
1188
+ })
1189
+ ),
1190
+ timelock: void 0
1191
+ };
1192
+ }
1193
+
1194
+ // src/actions/governance/getProposalVotes.ts
1195
+ import {
1196
+ GetProposalVotes
1197
+ } from "@berachain/graphql/governance";
1198
+ async function getProposalVotes({
1199
+ variables,
1200
+ ...args
1201
+ }) {
1202
+ const governanceClient = getApolloClient("governance.subgraph", args);
1203
+ return governanceClient.query({
1204
+ query: GetProposalVotes,
1205
+ variables
1206
+ });
1207
+ }
1208
+
1209
+ // src/actions/honey/getChartData.ts
1210
+ import {
1211
+ Aggregation_Interval,
1212
+ GetChartData
1213
+ } from "@berachain/graphql/honey";
1214
+ async function getChartData({
1215
+ days: days2,
1216
+ ...args
1217
+ }) {
1218
+ const client = getApolloClient("honey.subgraph", args);
1219
+ const res = await client.query(
1220
+ {
1221
+ query: GetChartData,
1222
+ variables: {
1223
+ interval: Aggregation_Interval.Day,
1224
+ first: days2
1225
+ }
1226
+ }
1227
+ );
1228
+ return res.data;
1229
+ }
1230
+
1231
+ // src/actions/honey/getCollateralWeights.ts
1232
+ import { honeyFactoryAbi } from "@berachain/abis/honey/honeyFactory";
1233
+ async function getCollateralWeights({
1234
+ client,
1235
+ collateralList,
1236
+ ...args
1237
+ }) {
1238
+ const { config } = parseBaseArgs(args);
1239
+ try {
1240
+ const collateralWeights = await client.readContract({
1241
+ address: config.honey.factory,
1242
+ abi: honeyFactoryAbi,
1243
+ functionName: "getWeights"
1244
+ });
1245
+ const weightsWithAddress = collateralList.reduce(
1246
+ (agg, key, idx) => Object.assign(agg, { [key.address]: collateralWeights[idx] }),
1247
+ {}
1248
+ );
1249
+ return weightsWithAddress;
1250
+ } catch (e) {
1251
+ console.log(e);
1252
+ throw e;
1253
+ }
1254
+ }
1255
+
1256
+ // src/actions/tokens/getTokenInformation.ts
1257
+ import { erc20Abi as erc20Abi2 } from "viem";
1258
+ async function getTokenInformation({
1259
+ address,
1260
+ publicClient,
1261
+ chainId
1262
+ }) {
1263
+ try {
1264
+ assertPublicClient(publicClient);
1265
+ const [decimals, name, symbol] = await Promise.all([
1266
+ publicClient.readContract({
1267
+ address,
1268
+ abi: erc20Abi2,
1269
+ functionName: "decimals"
1270
+ }),
1271
+ publicClient.readContract({
1272
+ address,
1273
+ abi: erc20Abi2,
1274
+ functionName: "name"
1275
+ }),
1276
+ publicClient.readContract({
1277
+ address,
1278
+ abi: erc20Abi2,
1279
+ functionName: "symbol"
1280
+ })
1281
+ ]);
1282
+ return {
1283
+ address,
1284
+ decimals,
1285
+ name,
1286
+ symbol,
1287
+ chainId
1288
+ };
1289
+ } catch (e) {
1290
+ throw initBeraError({ cause: e });
1291
+ }
1292
+ }
1293
+
1294
+ // src/actions/honey/getHoneyCollaterals.ts
1295
+ import { honeyFactoryAbi as honeyFactoryAbi2 } from "@berachain/abis/honey/honeyFactory";
1296
+ async function getHoneyCollaterals({
1297
+ client,
1298
+ tokenData,
1299
+ preferredCollateralOrder,
1300
+ ...args
1301
+ }) {
1302
+ const { config } = parseBaseArgs(args);
1303
+ const [amountOfCollaterals, referenceCollateralAddress] = await Promise.all([
1304
+ client.readContract({
1305
+ address: config.honey.factory,
1306
+ abi: honeyFactoryAbi2,
1307
+ functionName: "numRegisteredAssets"
1308
+ }),
1309
+ client.readContract({
1310
+ address: config.honey.factory,
1311
+ abi: honeyFactoryAbi2,
1312
+ functionName: "referenceCollateral"
1313
+ })
1314
+ ]);
1315
+ const promiseList = [];
1316
+ for (let i = 0; i < amountOfCollaterals; i++) {
1317
+ promiseList.push(
1318
+ client.readContract({
1319
+ address: config.honey.factory,
1320
+ abi: honeyFactoryAbi2,
1321
+ functionName: "registeredAssets",
1322
+ args: [BigInt(i)]
1323
+ })
1324
+ );
1325
+ }
1326
+ const collaterals = await Promise.all(promiseList);
1327
+ const collateralsTokens = await Promise.all(
1328
+ collaterals.map((coll) => {
1329
+ const token = tokenData?.find((token2) => isToken(token2, coll));
1330
+ if (token) {
1331
+ return token;
1332
+ }
1333
+ return getTokenInformation({
1334
+ address: coll,
1335
+ chainId: config.chainId,
1336
+ publicClient: client
1337
+ });
1338
+ })
1339
+ );
1340
+ const collateralTokens = collateralsTokens.filter((coll) => !!coll).sort((a, b) => {
1341
+ return collaterals.indexOf(a.address) - collaterals.indexOf(b.address);
1342
+ }).map((coll, idx) => ({
1343
+ ...coll,
1344
+ order: idx
1345
+ }));
1346
+ if (preferredCollateralOrder?.length) {
1347
+ const newCollateralOrder = [];
1348
+ for (const override of preferredCollateralOrder) {
1349
+ const newFirstCollateral = collateralTokens.find(
1350
+ (coll) => isToken(coll.address, override.address)
1351
+ );
1352
+ if (newFirstCollateral) {
1353
+ newCollateralOrder.push(newFirstCollateral);
1354
+ collateralTokens.splice(
1355
+ collateralTokens.indexOf(newFirstCollateral),
1356
+ 1
1357
+ );
1358
+ }
1359
+ }
1360
+ collateralTokens.unshift(...newCollateralOrder);
1361
+ }
1362
+ const referenceCollateral = collateralTokens.find(
1363
+ (coll) => isToken(coll, referenceCollateralAddress)
1364
+ );
1365
+ if (!collateralTokens) {
1366
+ throw new Error("Collateral tokens not found");
1367
+ }
1368
+ if (!referenceCollateral) {
1369
+ throw new Error("Reference collateral address not found");
1370
+ }
1371
+ return {
1372
+ collaterals: collateralTokens,
1373
+ referenceCollateral
1374
+ };
1375
+ }
1376
+
1377
+ // src/actions/honey/isBadCollateralAsset.ts
1378
+ import { parseUnits } from "viem";
1379
+ import { honeyFactoryAbi as honeyFactoryAbi3 } from "@berachain/abis/honey/honeyFactory";
1380
+ import { honeyFactoryReaderAbi } from "@berachain/abis/honey/honeyFactoryReader";
1381
+ async function isBadCollateralAsset({
1382
+ client,
1383
+ collateral,
1384
+ latestPrices,
1385
+ isPythWrapperEnabled,
1386
+ ...args
1387
+ }) {
1388
+ const { config } = parseBaseArgs(args);
1389
+ try {
1390
+ const isBadCollateralCall = client.readContract({
1391
+ address: config.honey.factory,
1392
+ abi: honeyFactoryAbi3,
1393
+ functionName: "isBadCollateralAsset",
1394
+ args: [collateral.address]
1395
+ });
1396
+ let isPeggedCall = client.readContract({
1397
+ address: config.honey.factory,
1398
+ abi: honeyFactoryAbi3,
1399
+ functionName: "isPegged",
1400
+ args: [collateral.address]
1401
+ });
1402
+ if (isPythWrapperEnabled && latestPrices) {
1403
+ const prices = latestPrices.prices.map((price) => parseUnits(price, 18));
1404
+ isPeggedCall = client.readContract({
1405
+ address: config.honey.reader,
1406
+ abi: honeyFactoryReaderAbi,
1407
+ functionName: "isPeggedWithPrice",
1408
+ args: [collateral.address, prices[0]]
1409
+ });
1410
+ }
1411
+ const [badCollateralResult, isPeggedResult] = await Promise.all([
1412
+ isBadCollateralCall,
1413
+ isPeggedCall
1414
+ ]);
1415
+ return {
1416
+ isBlacklisted: badCollateralResult,
1417
+ isDepegged: !isPeggedResult
1418
+ // invert the result to get the correct value
1419
+ };
1420
+ } catch (e) {
1421
+ console.log(e);
1422
+ throw e;
1423
+ }
1424
+ }
1425
+
1426
+ // src/actions/honey/getGlobalCapLimit.ts
1427
+ import { parseEther as parseEther2 } from "viem";
1428
+ import { honeyFactoryAbi as honeyFactoryAbi5 } from "@berachain/abis/honey/honeyFactory";
1429
+
1430
+ // src/actions/honey/getSharesWithoutFees.ts
1431
+ import { parseEther } from "viem";
1432
+ import { collateralVaultAbi } from "@berachain/abis/honey/collateralVault";
1433
+ import { honeyFactoryAbi as honeyFactoryAbi4 } from "@berachain/abis/honey/honeyFactory";
1434
+ async function getSharesWithoutFees({
1435
+ client,
1436
+ asset,
1437
+ amount,
1438
+ ...args
1439
+ }) {
1440
+ const { config } = parseBaseArgs(args);
1441
+ try {
1442
+ const [vault, fees] = await Promise.all([
1443
+ client.readContract({
1444
+ address: config.honey.factory,
1445
+ abi: honeyFactoryAbi4,
1446
+ functionName: "vaults",
1447
+ args: [asset]
1448
+ }),
1449
+ client.readContract({
1450
+ address: config.honey.factory,
1451
+ abi: honeyFactoryAbi4,
1452
+ functionName: "collectedFees",
1453
+ args: [config.honey.factory, asset]
1454
+ })
1455
+ ]);
1456
+ const balance = await client.readContract({
1457
+ address: vault,
1458
+ abi: collateralVaultAbi,
1459
+ functionName: "balanceOf",
1460
+ args: [config.honey.factory]
1461
+ });
1462
+ return balance + parseEther(amount ?? "0") - fees;
1463
+ } catch (e) {
1464
+ console.log(e);
1465
+ throw e;
1466
+ }
1467
+ }
1468
+
1469
+ // src/actions/honey/getGlobalCapLimit.ts
1470
+ var ONE_HUNDRED_PERCENT = parseEther2("1");
1471
+ async function getGlobalCapLimit({
1472
+ client,
1473
+ asset,
1474
+ amount,
1475
+ isMint,
1476
+ isPythWrapperEnabled,
1477
+ latestPrices,
1478
+ ...args
1479
+ }) {
1480
+ const { config } = parseBaseArgs(args);
1481
+ try {
1482
+ const globalCap = await client.readContract({
1483
+ address: config.honey.factory,
1484
+ abi: honeyFactoryAbi5,
1485
+ functionName: "globalCap"
1486
+ });
1487
+ if (globalCap >= ONE_HUNDRED_PERCENT) {
1488
+ return false;
1489
+ }
1490
+ const [{ collaterals: registeredAssets }, weights] = await Promise.all([
1491
+ getHoneyCollaterals({
1492
+ client
1493
+ }),
1494
+ getWeights({ client, asset, amount, latestPrices, isPythWrapperEnabled })
1495
+ ]);
1496
+ if (!weights) {
1497
+ return void 0;
1498
+ }
1499
+ for (const idx in weights) {
1500
+ if (isMint && isToken(registeredAssets[idx], asset) || !isMint && isToken(registeredAssets[idx], asset)) {
1501
+ const weight = weights[idx];
1502
+ if (weight > globalCap - CAP_LIMIT_BUFFER) {
1503
+ return true;
1504
+ }
1505
+ }
1506
+ }
1507
+ return false;
1508
+ } catch (e) {
1509
+ console.log(e);
1510
+ throw e;
1511
+ }
1512
+ }
1513
+ async function getWeights({
1514
+ client,
1515
+ asset,
1516
+ amount,
1517
+ latestPrices,
1518
+ isPythWrapperEnabled
1519
+ }) {
1520
+ const { collaterals: registeredAssets } = await getHoneyCollaterals({
1521
+ client
1522
+ });
1523
+ let sum = 0n;
1524
+ const weights = [];
1525
+ for (const singleAsset of registeredAssets) {
1526
+ const isBad = await isBadCollateralAsset({
1527
+ client,
1528
+ collateral: asset,
1529
+ latestPrices,
1530
+ isPythWrapperEnabled
1531
+ });
1532
+ if (isBad?.isBlacklisted || isBad?.isDepegged) {
1533
+ continue;
1534
+ }
1535
+ const share = await getSharesWithoutFees({
1536
+ client,
1537
+ asset: singleAsset.address,
1538
+ amount: isToken(singleAsset, asset) ? amount : "0"
1539
+ });
1540
+ if (!share) {
1541
+ continue;
1542
+ }
1543
+ sum += share;
1544
+ weights.push(share);
1545
+ }
1546
+ if (sum === 0n) {
1547
+ return weights;
1548
+ }
1549
+ for (const idx in registeredAssets) {
1550
+ weights[idx] = parseEther2(weights[idx].toString()) / sum;
1551
+ }
1552
+ return weights;
1553
+ }
1554
+
1555
+ // src/actions/honey/getHoneyGlobalData.ts
1556
+ import {
1557
+ GetGlobalData
1558
+ } from "@berachain/graphql/honey";
1559
+ async function getHoneyGlobalData({
1560
+ ...args
1561
+ } = {}) {
1562
+ const client = getApolloClient("honey.subgraph", args);
1563
+ const result = await client.query({
1564
+ query: GetGlobalData
1565
+ });
1566
+ return result.data;
1567
+ }
1568
+
1569
+ // src/actions/honey/getHoneyPreview.ts
1570
+ import { parseUnits as parseUnits2 } from "viem";
1571
+ import { honeyFactoryReaderAbi as honeyFactoryReaderAbi2 } from "@berachain/abis/honey/honeyFactoryReader";
1572
+ var HoneyPreviewMethod = /* @__PURE__ */ ((HoneyPreviewMethod2) => {
1573
+ HoneyPreviewMethod2["Mint"] = "previewMintHoney";
1574
+ HoneyPreviewMethod2["MintWithPrice"] = "previewMintHoneyWithPrices";
1575
+ HoneyPreviewMethod2["RequiredCollateral"] = "previewMintCollaterals";
1576
+ HoneyPreviewMethod2["RequiredCollateralWithPrice"] = "previewMintCollateralsWithPrices";
1577
+ HoneyPreviewMethod2["Redeem"] = "previewRedeemCollaterals";
1578
+ HoneyPreviewMethod2["RedeemWithPrice"] = "previewRedeemCollateralsWithPrices";
1579
+ HoneyPreviewMethod2["HoneyToRedeem"] = "previewRedeemHoney";
1580
+ HoneyPreviewMethod2["HoneyToRedeemWithPrice"] = "previewRedeemHoneyWithPrices";
1581
+ return HoneyPreviewMethod2;
1582
+ })(HoneyPreviewMethod || {});
1583
+ async function getHoneyPreview({
1584
+ client,
1585
+ collateral,
1586
+ collateralList,
1587
+ amount,
1588
+ method,
1589
+ latestPrices,
1590
+ isPythWrapperEnabled,
1591
+ ...baseArgs
1592
+ }) {
1593
+ const { config } = parseBaseArgs(baseArgs);
1594
+ try {
1595
+ const isAmountHoney = method === "previewMintHoney" /* Mint */ || method === "previewRedeemHoney" /* HoneyToRedeem */ || method === "previewMintHoneyWithPrices" /* MintWithPrice */ || method === "previewRedeemHoneyWithPrices" /* HoneyToRedeemWithPrice */;
1596
+ const formattedAmount = parseUnits2(
1597
+ amount,
1598
+ isAmountHoney ? collateral.decimals : 18
1599
+ );
1600
+ let formattedResult;
1601
+ let args = [collateral.address, formattedAmount];
1602
+ if (isPythWrapperEnabled && latestPrices) {
1603
+ const prices = latestPrices.prices.map((price) => parseUnits2(price, 18));
1604
+ args = [collateral.address, formattedAmount, prices];
1605
+ }
1606
+ if (isAmountHoney) {
1607
+ const result = await client.readContract({
1608
+ address: config.honey.reader,
1609
+ abi: honeyFactoryReaderAbi2,
1610
+ functionName: method,
1611
+ args
1612
+ });
1613
+ formattedResult = {
1614
+ collaterals: result[0],
1615
+ honey: result[1]
1616
+ };
1617
+ } else {
1618
+ const result = await client.readContract({
1619
+ address: config.honey.reader,
1620
+ abi: honeyFactoryReaderAbi2,
1621
+ functionName: method,
1622
+ args
1623
+ });
1624
+ formattedResult = {
1625
+ collaterals: result,
1626
+ honey: formattedAmount
1627
+ };
1628
+ }
1629
+ const amountsWithAddress = collateralList.reduce(
1630
+ (agg, key) => {
1631
+ const idx = key.order;
1632
+ if (key.address === collateral.address && formattedResult.collaterals[idx] === BigInt(0)) {
1633
+ return Object.assign(agg, {
1634
+ [key.address]: formattedResult.collaterals[0]
1635
+ });
1636
+ }
1637
+ return Object.assign(agg, {
1638
+ [key.address]: formattedResult.collaterals[idx]
1639
+ });
1640
+ },
1641
+ {}
1642
+ );
1643
+ if (amountsWithAddress[collateral.address] === BigInt(0)) {
1644
+ amountsWithAddress[collateral.address] = formattedResult.collaterals[0];
1645
+ }
1646
+ return {
1647
+ collaterals: amountsWithAddress,
1648
+ honey: formattedResult.honey
1649
+ };
1650
+ } catch (e) {
1651
+ console.log("error", e);
1652
+ throw e;
1653
+ }
1654
+ }
1655
+
1656
+ // src/actions/honey/getHoneyVaultsBalance.ts
1657
+ import { formatUnits as formatUnits3 } from "viem";
1658
+ import { collateralVaultAbi as collateralVaultAbi2 } from "@berachain/abis/honey/collateralVault";
1659
+ import { honeyFactoryAbi as honeyFactoryAbi6 } from "@berachain/abis/honey/honeyFactory";
1660
+ async function getHoneyVaultsBalance({
1661
+ client,
1662
+ collateralList,
1663
+ honeyFactoryAddress,
1664
+ ...args
1665
+ }) {
1666
+ const { config } = parseBaseArgs(args);
1667
+ const factory = honeyFactoryAddress ?? config.honey.factory;
1668
+ const vaults = await Promise.all(
1669
+ collateralList.map(async (coll) => {
1670
+ const vault = await client.readContract({
1671
+ address: config.honey.factory,
1672
+ abi: honeyFactoryAbi6,
1673
+ functionName: "vaults",
1674
+ args: [coll.address]
1675
+ });
1676
+ const [
1677
+ shares,
1678
+ // this is most likely 0 since we're sending fees to PolFeeCollector
1679
+ // here for future proofing
1680
+ feeShares,
1681
+ // if balance is held in a custodian, we need to return the custodian address
1682
+ [isCustodian, custodianAddress]
1683
+ ] = await Promise.all([
1684
+ client.readContract({
1685
+ address: vault,
1686
+ abi: collateralVaultAbi2,
1687
+ functionName: "balanceOf",
1688
+ args: [factory]
1689
+ }),
1690
+ client.readContract({
1691
+ address: factory,
1692
+ abi: honeyFactoryAbi6,
1693
+ functionName: "collectedAssetFees",
1694
+ args: [coll.address]
1695
+ }),
1696
+ client.readContract({
1697
+ address: vault,
1698
+ abi: collateralVaultAbi2,
1699
+ functionName: "custodyInfo"
1700
+ })
1701
+ ]);
1702
+ const balance = await client.readContract({
1703
+ address: vault,
1704
+ abi: collateralVaultAbi2,
1705
+ functionName: "convertToAssets",
1706
+ args: [shares - feeShares]
1707
+ });
1708
+ return {
1709
+ ...coll,
1710
+ balance: {
1711
+ raw: balance.toString(),
1712
+ formatted: formatUnits3(balance, coll.decimals)
1713
+ },
1714
+ vault: isCustodian ? custodianAddress : vault
1715
+ };
1716
+ })
1717
+ );
1718
+ return vaults;
1719
+ }
1720
+
1721
+ // src/actions/honey/getPythLatestPrices.ts
1722
+ import { HermesClient } from "@pythnetwork/hermes-client";
1723
+ import { formatUnits as formatUnits4 } from "viem";
1724
+ var pythEndpoint = "https://hermes.pyth.network";
1725
+ async function getPythLatestPrices({
1726
+ priceFeedId
1727
+ }) {
1728
+ const hermesClient = new HermesClient(pythEndpoint, {});
1729
+ const updates = await hermesClient.getLatestPriceUpdates(priceFeedId, {
1730
+ encoding: "hex",
1731
+ parsed: true
1732
+ });
1733
+ return {
1734
+ calldata: updates.binary.data.map((d) => `0x${d}`),
1735
+ prices: updates.parsed?.flatMap(
1736
+ (p) => formatUnits4(BigInt(p.price.price), p.price.expo * -1)
1737
+ ) ?? []
1738
+ };
1739
+ }
1740
+
1741
+ // src/actions/honey/getRelativeCapLimit.ts
1742
+ import { parseEther as parseEther3 } from "viem";
1743
+ import { honeyFactoryAbi as honeyFactoryAbi7 } from "@berachain/abis/honey/honeyFactory";
1744
+ async function getRelativeCapLimit({
1745
+ client,
1746
+ asset,
1747
+ amount,
1748
+ isMint,
1749
+ referenceCollateral,
1750
+ ...args
1751
+ }) {
1752
+ const { config } = parseBaseArgs(args);
1753
+ if (asset === referenceCollateral.address) {
1754
+ return false;
1755
+ }
1756
+ try {
1757
+ const [assetRelativeCap] = await Promise.all([
1758
+ client.readContract({
1759
+ address: config.honey.factory,
1760
+ abi: honeyFactoryAbi7,
1761
+ functionName: "relativeCap",
1762
+ args: [asset]
1763
+ })
1764
+ ]);
1765
+ const [assetBalance, referenceCollateralBalance] = await Promise.all([
1766
+ getSharesWithoutFees({
1767
+ client,
1768
+ asset,
1769
+ amount: isMint ? amount : void 0
1770
+ }),
1771
+ getSharesWithoutFees({
1772
+ client,
1773
+ asset: referenceCollateral.address,
1774
+ amount: isMint ? void 0 : amount
1775
+ })
1776
+ ]);
1777
+ if (referenceCollateralBalance === 0n) {
1778
+ return assetBalance !== 0n;
1779
+ }
1780
+ const weight = parseEther3((assetBalance ?? 0n).toString()) / (referenceCollateralBalance ?? 0n);
1781
+ if (weight >= assetRelativeCap - CAP_LIMIT_BUFFER) {
1782
+ return true;
1783
+ }
1784
+ return false;
1785
+ } catch (e) {
1786
+ console.log(e);
1787
+ throw e;
1788
+ }
1789
+ }
1790
+
1791
+ // src/actions/pyth/getUpdateFee.ts
1792
+ async function getPythUpdateFee({
1793
+ client,
1794
+ priceFeedId,
1795
+ ...args
1796
+ }) {
1797
+ const { config } = parseBaseArgs(args);
1798
+ try {
1799
+ const result = await client.readContract({
1800
+ address: config.external.pyth,
1801
+ abi: pythAbi,
1802
+ functionName: "getUpdateFee",
1803
+ args: [priceFeedId]
1804
+ });
1805
+ return result;
1806
+ } catch (e) {
1807
+ console.error("getPythUpdateFee", e);
1808
+ throw e;
1809
+ }
1810
+ }
1811
+
1812
+ // src/actions/honey/getSwapPayload.ts
1813
+ import {
1814
+ parseUnits as parseUnits3
1815
+ } from "viem";
1816
+ import { honeyFactoryAbi as honeyFactoryAbi8 } from "@berachain/abis/honey/honeyFactory";
1817
+ import { honeyFactoryPythWrapperAbi as pythWrapperAbi } from "@berachain/abis/honey/honeyFactoryPythWrapper";
1818
+ var getSwapPayload = async ({
1819
+ state,
1820
+ publicClient,
1821
+ priceFeedMap,
1822
+ collateralList,
1823
+ isPythWrapperEnabled,
1824
+ ...args
1825
+ }) => {
1826
+ const { config } = parseBaseArgs(args);
1827
+ const honeyToken = getHoneyToken(args);
1828
+ const { actionType, fromAmount, collaterals, isBasketModeEnabled: isBasketModeEnabled2 } = state;
1829
+ const destinationContractAddress = isPythWrapperEnabled ? config.honey.pythWrapper : config.honey.factory;
1830
+ const pairMainAddress = collateralList.map((coll) => coll.address);
1831
+ if (fromAmount[0] && !!pairMainAddress.length) {
1832
+ const isMint = actionType === "mint";
1833
+ if (isPythWrapperEnabled && publicClient && priceFeedMap) {
1834
+ const latestPrices = await getPythLatestPrices({
1835
+ priceFeedId: Object.values(priceFeedMap)
1836
+ });
1837
+ const calldata = latestPrices.calldata;
1838
+ let pythUpdateFee = 0n;
1839
+ try {
1840
+ pythUpdateFee = await getPythUpdateFee({
1841
+ client: publicClient,
1842
+ priceFeedId: calldata
1843
+ });
1844
+ } catch {
1845
+ pythUpdateFee = getPythDefaultUpdateFee(collaterals.length);
1846
+ }
1847
+ return ({ account }) => {
1848
+ const pythPayload = [
1849
+ calldata,
1850
+ collaterals[0]?.address,
1851
+ parseUnits3(
1852
+ fromAmount[0],
1853
+ (isMint ? collaterals[0]?.decimals : honeyToken?.decimals) ?? 18
1854
+ ),
1855
+ account,
1856
+ !!isBasketModeEnabled2
1857
+ ];
1858
+ return {
1859
+ address: destinationContractAddress,
1860
+ abi: pythWrapperAbi,
1861
+ functionName: isMint ? "mint" : "redeem",
1862
+ params: pythPayload,
1863
+ value: pythUpdateFee
1864
+ };
1865
+ };
1866
+ }
1867
+ return ({ account }) => {
1868
+ const defaultPayload = [
1869
+ collaterals[0]?.address,
1870
+ parseUnits3(
1871
+ fromAmount[0],
1872
+ (isMint ? collaterals[0]?.decimals : honeyToken?.decimals) ?? 18
1873
+ ),
1874
+ account,
1875
+ !!isBasketModeEnabled2
1876
+ ];
1877
+ return {
1878
+ value: 0n,
1879
+ address: destinationContractAddress,
1880
+ abi: honeyFactoryAbi8,
1881
+ functionName: isMint ? "mint" : "redeem",
1882
+ params: defaultPayload
1883
+ };
1884
+ };
1885
+ }
1886
+ throw new Error("Something went wrong while creating the Honey swap payload");
1887
+ };
1888
+
1889
+ // src/actions/honey/isBasketModeEnabled.ts
1890
+ import { parseUnits as parseUnits4 } from "viem";
1891
+ import { honeyFactoryAbi as honeyFactoryAbi9 } from "@berachain/abis/honey/honeyFactory";
1892
+ import { honeyFactoryReaderAbi as honeyFactoryReaderAbi3 } from "@berachain/abis/honey/honeyFactoryReader";
1893
+ async function isBasketModeEnabled({
1894
+ client,
1895
+ isMint,
1896
+ collateralList,
1897
+ latestPrices,
1898
+ isPythWrapperEnabled,
1899
+ ...args
1900
+ }) {
1901
+ const { config } = parseBaseArgs(args);
1902
+ if (isPythWrapperEnabled && latestPrices) {
1903
+ if (collateralList.length === 0) return void 0;
1904
+ const prices = latestPrices.prices.map((price) => parseUnits4(price, 18));
1905
+ const isActive2 = await client.readContract({
1906
+ address: config.honey.reader,
1907
+ abi: honeyFactoryReaderAbi3,
1908
+ functionName: "isBasketModeEnabledWithPrices",
1909
+ args: [isMint, prices]
1910
+ });
1911
+ return isActive2;
1912
+ }
1913
+ const isActive = await client.readContract({
1914
+ address: config.honey.factory,
1915
+ abi: honeyFactoryAbi9,
1916
+ functionName: "isBasketModeEnabled",
1917
+ args: [isMint]
1918
+ });
1919
+ return isActive;
1920
+ }
1921
+
1922
+ // src/actions/misc/getBlockTimestamp.ts
1923
+ async function getBlockTimestamp({
1924
+ block,
1925
+ currentBlock,
1926
+ blockTime,
1927
+ publicClient
1928
+ }) {
1929
+ assertDefined(block, "block");
1930
+ assertPublicClient(publicClient);
1931
+ if (currentBlock > block) {
1932
+ const blockData = await publicClient.getBlock({
1933
+ blockNumber: BigInt(block),
1934
+ includeTransactions: false
1935
+ });
1936
+ return {
1937
+ timestamp: Number(blockData.timestamp)
1938
+ };
1939
+ }
1940
+ const ts = msToSeconds(Date.now()) + blockTime * (Number(block) - Number(currentBlock));
1941
+ return {
1942
+ timestamp: ts
1943
+ };
1944
+ }
1945
+
1946
+ // src/actions/pol/getRewardVaultRewards.ts
1947
+ import { formatUnits as formatUnits5 } from "viem";
1948
+ import { rewardVaultAbi } from "@berachain/abis/pol/rewards/rewardVault";
1949
+ var RewardVaultDistributionMode = /* @__PURE__ */ ((RewardVaultDistributionMode2) => {
1950
+ RewardVaultDistributionMode2["Duration"] = "duration";
1951
+ RewardVaultDistributionMode2["TargetRate"] = "targetRate";
1952
+ RewardVaultDistributionMode2["TargetApr"] = "targetApr";
1953
+ return RewardVaultDistributionMode2;
1954
+ })(RewardVaultDistributionMode || {});
1955
+ async function getRewardVaultRewards(address, publicClient) {
1956
+ const [
1957
+ rewardsDuration,
1958
+ manager,
1959
+ rewardRate,
1960
+ periodFinish,
1961
+ targetRewardsPerSecond,
1962
+ minRewardDurationForTargetRate
1963
+ ] = await Promise.all([
1964
+ publicClient.readContract({
1965
+ address,
1966
+ abi: rewardVaultAbi,
1967
+ functionName: "rewardsDuration"
1968
+ }),
1969
+ publicClient.readContract({
1970
+ address,
1971
+ abi: rewardVaultAbi,
1972
+ functionName: "rewardVaultManager"
1973
+ }),
1974
+ publicClient.readContract({
1975
+ address,
1976
+ abi: rewardVaultAbi,
1977
+ functionName: "rewardRate"
1978
+ }),
1979
+ publicClient.readContract({
1980
+ address,
1981
+ abi: rewardVaultAbi,
1982
+ functionName: "periodFinish"
1983
+ }),
1984
+ publicClient.readContract({
1985
+ address,
1986
+ abi: rewardVaultAbi,
1987
+ functionName: "targetRewardsPerSecond"
1988
+ }),
1989
+ publicClient.readContract({
1990
+ address,
1991
+ abi: rewardVaultAbi,
1992
+ functionName: "minRewardDurationForTargetRate"
1993
+ })
1994
+ ]);
1995
+ const availableRewards = rewardRate * (periodFinish - BigInt(msToSeconds(Date.now()))) / 10n ** 18n;
1996
+ return {
1997
+ rewardsDuration: Number(rewardsDuration),
1998
+ mode: targetRewardsPerSecond === 0n ? "duration" /* Duration */ : "targetRate" /* TargetRate */,
1999
+ manager,
2000
+ // 36 decimals for the reward rate
2001
+ rewardRate: formatUnits5(rewardRate, 36),
2002
+ periodFinish: Number(periodFinish),
2003
+ // 36 decimals for the reward rate
2004
+ availableRewards: formatUnits5(availableRewards, 18),
2005
+ minRewardDurationForTargetRate: Number(minRewardDurationForTargetRate),
2006
+ targetRewardsPerSecond: formatUnits5(targetRewardsPerSecond, 36)
2007
+ };
2008
+ }
2009
+
2010
+ // src/actions/pol/getBgtAprSimulation.ts
2011
+ function _getApr(tvl, bgtPrice, rewardRate) {
2012
+ return tvl ? rewardRate * bgtPrice * yearsInSeconds(1) / tvl : null;
2013
+ }
2014
+ function _getRewardRate(apr, bgtPrice, tvl) {
2015
+ return tvl ? apr * tvl / (bgtPrice * yearsInSeconds(1)) : 0;
2016
+ }
2017
+ function getBgtAprSimulation({
2018
+ availableRewards,
2019
+ periodFinish,
2020
+ tvl,
2021
+ bgtPrice,
2022
+ MIN_REWARD_DURATION,
2023
+ MAX_REWARD_DURATION,
2024
+ ...args
2025
+ }) {
2026
+ const currentTime = msToSeconds(Date.now());
2027
+ if (currentTime > periodFinish) {
2028
+ return {
2029
+ apr: 0,
2030
+ duration: 0,
2031
+ rewardRate: 0,
2032
+ targetRate: null,
2033
+ periodFinish: 0,
2034
+ mode: null
2035
+ };
2036
+ }
2037
+ if (args.mode === "targetRate" || args.mode === "targetApr") {
2038
+ let rewardRate;
2039
+ const {
2040
+ minRewardDurationForTargetRate: _providedMinRewardDurationForTargetRate,
2041
+ currentDuration
2042
+ } = args;
2043
+ if (args.mode === "targetRate") {
2044
+ rewardRate = args.rewardRate;
2045
+ } else {
2046
+ rewardRate = _getRewardRate(args.apr, bgtPrice, tvl);
2047
+ }
2048
+ if (rewardRate === 0) {
2049
+ const newDuration = Math.min(currentDuration, MAX_REWARD_DURATION);
2050
+ const rewardRate2 = availableRewards ? availableRewards / newDuration : 0;
2051
+ return {
2052
+ apr: _getApr(tvl, bgtPrice, rewardRate2),
2053
+ // When switching to duration mode, the current duration will be used if it's in the allowed range.
2054
+ // Current duration on chain can never be lower than MIN_REWARD_DURATION, so we just check the max.
2055
+ duration: newDuration,
2056
+ rewardRate: rewardRate2,
2057
+ targetRate: null,
2058
+ periodFinish: newDuration + currentTime,
2059
+ mode: "duration" /* Duration */
2060
+ };
2061
+ }
2062
+ const minRewardDurationForTargetRate = (
2063
+ // minRewardDurationForTargetRate might be zero the first time the target rate is set.
2064
+ // If it's not set, we use the max reward duration.
2065
+ _providedMinRewardDurationForTargetRate || MIN_REWARD_DURATION
2066
+ );
2067
+ const duration2 = availableRewards ? availableRewards / rewardRate : 0;
2068
+ if (duration2 < minRewardDurationForTargetRate) {
2069
+ const rewardRate2 = availableRewards ? availableRewards / minRewardDurationForTargetRate : 0;
2070
+ return {
2071
+ apr: _getApr(tvl, bgtPrice, rewardRate2),
2072
+ duration: minRewardDurationForTargetRate,
2073
+ rewardRate: rewardRate2,
2074
+ targetRate: rewardRate2.toString(),
2075
+ periodFinish: minRewardDurationForTargetRate + currentTime,
2076
+ mode: null
2077
+ };
2078
+ }
2079
+ return {
2080
+ apr: _getApr(tvl, bgtPrice, rewardRate),
2081
+ duration: duration2,
2082
+ rewardRate,
2083
+ targetRate: rewardRate.toString(),
2084
+ periodFinish: duration2 + currentTime,
2085
+ mode: null
2086
+ };
2087
+ }
2088
+ const { duration } = args;
2089
+ const newRewardRate = availableRewards / duration;
2090
+ const apr = _getApr(tvl, bgtPrice, newRewardRate);
2091
+ return {
2092
+ apr,
2093
+ mode: null,
2094
+ targetRate: null,
2095
+ duration,
2096
+ rewardRate: newRewardRate,
2097
+ periodFinish: duration + currentTime
2098
+ };
2099
+ }
2100
+
2101
+ // src/actions/pol/getEarnedStakedBeraVault.ts
2102
+ async function getEarnedStakedBeraVault({
2103
+ address,
2104
+ account,
2105
+ ...args
2106
+ }) {
2107
+ const { config } = parseBaseArgs(args);
2108
+ const url = `${config.staking}/vaults/${address}/earnings/${account}`;
2109
+ return beraFetchJson({ url, type: "rest" });
2110
+ }
2111
+
2112
+ // src/actions/pol/getRewardVaults.ts
2113
+ import { formatUnits as formatUnits6 } from "viem";
2114
+ import { rewardVaultAbi as rewardVaultAbi2 } from "@berachain/abis/pol/rewards/rewardVault";
2115
+ import {
2116
+ GetVaults
2117
+ } from "@berachain/graphql/pol/api";
2118
+ async function getRewardVaults({
2119
+ filter,
2120
+ publicClient,
2121
+ ...args
2122
+ } = {}) {
2123
+ const bexApiGraphqlClient = getApolloClient("api", args);
2124
+ const res = await bexApiGraphqlClient.query({
2125
+ query: GetVaults,
2126
+ variables: filter
2127
+ });
2128
+ const incentives = await Promise.allSettled(
2129
+ res.data.polGetRewardVaults.vaults.map(async (vault) => {
2130
+ if (!publicClient) return void 0;
2131
+ return Promise.allSettled(
2132
+ vault.activeIncentives.map(
2133
+ (incentive) => publicClient.readContract({
2134
+ abi: rewardVaultAbi2,
2135
+ address: vault.address,
2136
+ functionName: "incentives",
2137
+ args: [incentive.tokenAddress]
2138
+ })
2139
+ )
2140
+ );
2141
+ })
2142
+ );
2143
+ const vaults = res.data.polGetRewardVaults.vaults.map((vault, index) => {
2144
+ let totalIncentiveInUsdc = 0;
2145
+ const incentivesArray = vault.activeIncentives.map((apiIncentive, incIdx) => {
2146
+ const tokenPrice = Number(apiIncentive.remainingAmountUsd) && Number(apiIncentive.remainingAmount) ? Number(apiIncentive.remainingAmountUsd) / Number(apiIncentive.remainingAmount) : 0;
2147
+ const remainingAmount = incentives[index]?.status === "fulfilled" && incentives[index]?.value?.[incIdx]?.status === "fulfilled" ? formatUnits6(
2148
+ BigInt(incentives[index].value[incIdx].value[2]),
2149
+ apiIncentive.token.decimals
2150
+ ) : apiIncentive.remainingAmount;
2151
+ totalIncentiveInUsdc += Number(remainingAmount) * Number(tokenPrice);
2152
+ return {
2153
+ ...apiIncentive,
2154
+ remainingAmount
2155
+ };
2156
+ });
2157
+ return {
2158
+ ...vault,
2159
+ dynamicData: {
2160
+ ...vault.dynamicData,
2161
+ allTimeReceivedBGTAmount: vault.dynamicData?.allTimeReceivedBGTAmount ?? "0",
2162
+ bgtCapturePercentage: vault.dynamicData?.bgtCapturePercentage ?? "0",
2163
+ activeIncentivesValueUsd: totalIncentiveInUsdc.toString(),
2164
+ activeIncentivesRateUsd: vault.dynamicData?.activeIncentivesRateUsd ?? "0",
2165
+ bgtCapturePerBlock: vault.dynamicData?.bgtCapturePerBlock ?? "0"
2166
+ },
2167
+ activeIncentives: incentivesArray
2168
+ };
2169
+ });
2170
+ return {
2171
+ pagination: res.data.polGetRewardVaults.pagination,
2172
+ gaugeList: vaults
2173
+ };
2174
+ }
2175
+
2176
+ // src/actions/pol/getBGTGlobalInfo.ts
2177
+ import {
2178
+ GlobalData
2179
+ } from "@berachain/graphql/pol/api";
2180
+ async function getBGTGlobalInfo(args = {}) {
2181
+ const { config } = parseBaseArgs(args);
2182
+ const bexApiGraphqlClient = getApolloClient("api", args);
2183
+ const apiRes = await bexApiGraphqlClient.query({
2184
+ query: GlobalData,
2185
+ variables: {
2186
+ chain: config.bex.chainName
2187
+ }
2188
+ });
2189
+ const data = apiRes.data;
2190
+ return {
2191
+ ...data.polGetGlobalInfo,
2192
+ top3EmittingValidators: apiRes.data.top3EmittingValidators.validators,
2193
+ allValidatorsCount: apiRes.data.allValidatorsCount.pagination.totalCount
2194
+ };
2195
+ }
2196
+
2197
+ // src/actions/pol/getBgtTokenTotalBoosts.ts
2198
+ import { formatEther as formatEther3 } from "viem";
2199
+ import { bgtAbi } from "@berachain/abis/pol/bgt";
2200
+ async function getBgtTokenTotalBoosts({
2201
+ publicClient,
2202
+ ...args
2203
+ }) {
2204
+ const { config } = parseBaseArgs(args);
2205
+ assertPublicClient(publicClient);
2206
+ try {
2207
+ const result = await publicClient.readContract({
2208
+ address: config.tokens.bgt,
2209
+ abi: bgtAbi,
2210
+ functionName: "totalBoosts",
2211
+ args: []
2212
+ });
2213
+ return formatEther3(result);
2214
+ } catch (error) {
2215
+ console.log(error);
2216
+ throw error;
2217
+ }
2218
+ }
2219
+
2220
+ // src/actions/pol/getBgtTokenTotalSupply.ts
2221
+ import { erc20Abi as erc20Abi3, formatEther as formatEther4 } from "viem";
2222
+ async function getBgtTokenTotalSupply({
2223
+ publicClient,
2224
+ ...args
2225
+ }) {
2226
+ const { config } = parseBaseArgs(args);
2227
+ assertPublicClient(publicClient);
2228
+ try {
2229
+ const result = await publicClient.readContract({
2230
+ address: config.tokens.bgt,
2231
+ abi: erc20Abi3,
2232
+ functionName: "totalSupply",
2233
+ args: []
2234
+ });
2235
+ return formatEther4(result ?? 0n);
2236
+ } catch (error) {
2237
+ console.log(error);
2238
+ throw error;
2239
+ }
2240
+ }
2241
+
2242
+ // src/actions/pol/getGlobalCuttingBoard.ts
2243
+ import {
2244
+ GqlRewardVaultOrderBy,
2245
+ GqlRewardVaultOrderDirection
2246
+ } from "@berachain/graphql/pol/api";
2247
+ async function getGlobalCuttingBoard(threshold) {
2248
+ const { gaugeList } = await getRewardVaults({
2249
+ filter: {
2250
+ // TODO sort by bgt capture percentage
2251
+ orderBy: GqlRewardVaultOrderBy.Apr,
2252
+ orderDirection: GqlRewardVaultOrderDirection.Desc,
2253
+ pageSize: threshold,
2254
+ where: {
2255
+ includeNonWhitelisted: false
2256
+ }
2257
+ }
2258
+ });
2259
+ return gaugeList;
2260
+ }
2261
+
2262
+ // src/actions/pol/getGlobalData.ts
2263
+ async function getGlobalData(publicClient) {
2264
+ const [
2265
+ globalDataRes,
2266
+ globalCuttingBoardRes,
2267
+ bgtTotalSupplyRes,
2268
+ bgtTotalBoostsRes
2269
+ ] = await Promise.allSettled([
2270
+ getBGTGlobalInfo(),
2271
+ getGlobalCuttingBoard(300),
2272
+ getBgtTokenTotalSupply({
2273
+ publicClient
2274
+ }),
2275
+ getBgtTokenTotalBoosts({
2276
+ publicClient
2277
+ })
2278
+ ]);
2279
+ if (globalDataRes.status === "rejected") {
2280
+ BeraMonitoring.captureException(
2281
+ initBeraError({ cause: globalDataRes.reason, level: "warning" })
2282
+ );
2283
+ }
2284
+ if (globalCuttingBoardRes.status === "rejected") {
2285
+ BeraMonitoring.captureException(
2286
+ initBeraError({ cause: globalCuttingBoardRes.reason, level: "warning" })
2287
+ );
2288
+ }
2289
+ if (bgtTotalSupplyRes.status === "rejected") {
2290
+ BeraMonitoring.captureException(
2291
+ initBeraError({ cause: bgtTotalSupplyRes.reason, level: "warning" })
2292
+ );
2293
+ }
2294
+ if (bgtTotalBoostsRes.status === "rejected") {
2295
+ BeraMonitoring.captureException(
2296
+ initBeraError({ cause: bgtTotalBoostsRes.reason, level: "warning" })
2297
+ );
2298
+ }
2299
+ return {
2300
+ bgtTotalSupply: bgtTotalSupplyRes.status === "fulfilled" ? bgtTotalSupplyRes.value : void 0,
2301
+ globalCuttingBoard: globalCuttingBoardRes.status === "fulfilled" ? globalCuttingBoardRes.value : [],
2302
+ bgtTotalBoosts: bgtTotalBoostsRes.status === "fulfilled" ? bgtTotalBoostsRes.value : void 0,
2303
+ ...globalDataRes.status === "fulfilled" ? globalDataRes.value : {}
2304
+ };
2305
+ }
2306
+
2307
+ // src/actions/pol/getIncentiveFeeClaimStats.ts
2308
+ import {
2309
+ GetIncentiveFeeClaimStats
2310
+ } from "@berachain/graphql/pol/fees";
2311
+ async function getIncentiveFeeClaimStats({
2312
+ ...args
2313
+ }) {
2314
+ const bgtClient = getApolloClient("pol.fees", args);
2315
+ const { data } = await bgtClient.query({
2316
+ query: GetIncentiveFeeClaimStats
2317
+ });
2318
+ if (data.incentiveFeeClaims.length > 0) {
2319
+ const sumAllClaims = data?.incentiveFeeClaims.reduce(
2320
+ (acc, curr) => acc + Number(curr.payoutAmount),
2321
+ 3e4
2322
+ // this is due to a bug in the subgraph, where the first claim of 50_000 was counted as 20_000, once hunter pushed the fix we can upgrade it.
2323
+ );
2324
+ const claimsInLast24Hours = data?.incentiveFeeClaims.filter(
2325
+ (claim) => Number(claim.timestamp) / 1e3 > Date.now() - days(1)
2326
+ );
2327
+ const sumClaimsInLast24Hours = claimsInLast24Hours.reduce(
2328
+ (acc, curr) => acc + Number(curr.payoutAmount),
2329
+ 0
2330
+ );
2331
+ return {
2332
+ sumAllClaims,
2333
+ sumClaimsInLast24Hours
2334
+ };
2335
+ }
2336
+ return {
2337
+ sumAllClaims: 0,
2338
+ sumClaimsInLast24Hours: 0
2339
+ };
2340
+ }
2341
+
2342
+ // src/actions/pol/getMarkets.ts
2343
+ async function getMarkets(args = {}) {
2344
+ const { config } = parseBaseArgs(args);
2345
+ try {
2346
+ const markets = await fetch(config.lists.rewardVaultList);
2347
+ const temp = await markets.json();
2348
+ if (!temp.protocols) {
2349
+ throw new Error("Missing protocols in market list");
2350
+ }
2351
+ return {
2352
+ marketList: temp.protocols,
2353
+ marketDictionary: temp.protocols.reduce(
2354
+ (acc, item) => {
2355
+ acc[item.name] = item;
2356
+ return acc;
2357
+ },
2358
+ {}
2359
+ )
2360
+ };
2361
+ } catch (error) {
2362
+ console.error("Error fetching validator information", error);
2363
+ throw error;
2364
+ }
2365
+ }
2366
+
2367
+ // src/actions/pol/getRewardProofsByValidator.ts
2368
+ async function getRewardProofsByValidator({
2369
+ account,
2370
+ validator,
2371
+ page = 1,
2372
+ perPage = 1e3,
2373
+ ...args
2374
+ }) {
2375
+ const { config } = parseBaseArgs(args);
2376
+ const result = await fetch(
2377
+ `${config.pol.bribeBoostApi}/api/v1/wallets/${account.toLowerCase()}/proofs/validator/${validator.toLowerCase()}?page=${page}&per_page=${perPage}`,
2378
+ {
2379
+ cache: "no-store"
2380
+ }
2381
+ );
2382
+ if (!result.ok) {
2383
+ const error = await getErrorResponse(result);
2384
+ throw new BeraError({
2385
+ message: "Failed to fetch proofs on server",
2386
+ cause: {
2387
+ error,
2388
+ result,
2389
+ account,
2390
+ validator
2391
+ },
2392
+ reason: error?.reason
2393
+ });
2394
+ }
2395
+ const data = await result.json();
2396
+ return data;
2397
+ }
2398
+
2399
+ // src/actions/pol/getRewardTokenToBeraRate.ts
2400
+ import { formatUnits as formatUnits7, parseUnits as parseUnits5 } from "viem";
2401
+ import { wberaStakerVaultAbi as stakeBeraVaultAbi } from "@berachain/abis/pol/wberaStakerVault";
2402
+ async function getRewardTokenToBeraRate({
2403
+ address,
2404
+ publicClient
2405
+ }) {
2406
+ assertPublicClient(publicClient);
2407
+ return publicClient.readContract({
2408
+ address,
2409
+ abi: stakeBeraVaultAbi,
2410
+ functionName: "previewRedeem",
2411
+ args: [parseUnits5("1", 18)]
2412
+ }).then((rate) => Number(formatUnits7(rate, 18))).catch(() => 0);
2413
+ }
2414
+
2415
+ // src/actions/pol/getRewardVault.ts
2416
+ import {
2417
+ GetRewardVault
2418
+ } from "@berachain/graphql/pol/api";
2419
+ async function getRewardVault({
2420
+ address,
2421
+ chainName,
2422
+ ...args
2423
+ }) {
2424
+ const { config } = parseBaseArgs(args);
2425
+ const resolvedChainName = chainName ?? config.bex.chainName;
2426
+ const bexApiGraphqlClient = getApolloClient("api", args);
2427
+ const { data } = await bexApiGraphqlClient.query({
2428
+ query: GetRewardVault,
2429
+ variables: {
2430
+ vaultId: address,
2431
+ chain: resolvedChainName
2432
+ }
2433
+ });
2434
+ if (!data?.rewardVault) {
2435
+ throw new NotFoundError({
2436
+ resource: "Reward vault",
2437
+ id: address,
2438
+ chainId: config.chainId
2439
+ });
2440
+ }
2441
+ return data.rewardVault;
2442
+ }
2443
+
2444
+ // src/actions/pol/getRewardVaultIncentives.ts
2445
+ import { isSameAddress } from "@berachain-foundation/berancer-sdk";
2446
+ import {
2447
+ erc20Abi as erc20Abi4,
2448
+ formatUnits as formatUnits8
2449
+ } from "viem";
2450
+ import { rewardVaultAbi as rewardVaultAbi3 } from "@berachain/abis/pol/rewards/rewardVault";
2451
+ function multicallResult(result, fallback) {
2452
+ return result.status === "success" ? result.result : fallback;
2453
+ }
2454
+ async function getRewardVaultIncentives({
2455
+ address,
2456
+ stakingToken,
2457
+ publicClient
2458
+ }) {
2459
+ const whitelistedTokens = await publicClient.readContract({
2460
+ address,
2461
+ abi: rewardVaultAbi3,
2462
+ functionName: "getWhitelistedTokens"
2463
+ });
2464
+ const hasStakingTokenAsIncentiveToken = whitelistedTokens.findIndex(
2465
+ (token) => isSameAddress(stakingToken, token)
2466
+ ) !== -1;
2467
+ const totalSupply = hasStakingTokenAsIncentiveToken ? await publicClient.readContract({
2468
+ address,
2469
+ abi: rewardVaultAbi3,
2470
+ functionName: "totalSupply"
2471
+ }) : 0n;
2472
+ const incentives = await Promise.allSettled(
2473
+ whitelistedTokens.map(async (token) => {
2474
+ const [incentiveInfo, decimals, name, symbol, totalBalance] = await publicClient.multicall({
2475
+ allowFailure: true,
2476
+ contracts: [
2477
+ {
2478
+ address,
2479
+ abi: rewardVaultAbi3,
2480
+ functionName: "incentives",
2481
+ args: [token]
2482
+ },
2483
+ {
2484
+ address: token,
2485
+ abi: erc20Abi4,
2486
+ functionName: "decimals"
2487
+ },
2488
+ {
2489
+ address: token,
2490
+ abi: erc20Abi4,
2491
+ functionName: "name"
2492
+ },
2493
+ {
2494
+ address: token,
2495
+ abi: erc20Abi4,
2496
+ functionName: "symbol"
2497
+ },
2498
+ {
2499
+ address: token,
2500
+ abi: erc20Abi4,
2501
+ functionName: "balanceOf",
2502
+ args: [address]
2503
+ }
2504
+ ]
2505
+ });
2506
+ if (incentiveInfo.status === "failure") {
2507
+ throw new BeraError({
2508
+ cause: incentiveInfo.error,
2509
+ message: "Failed to get incentive info. This is not possible.",
2510
+ level: "error",
2511
+ extra: {
2512
+ token,
2513
+ address
2514
+ }
2515
+ });
2516
+ }
2517
+ const [minIncentiveRate, incentiveRate, remainingAmount, manager] = incentiveInfo.result;
2518
+ const decimalsResult = multicallResult(decimals, 18);
2519
+ return {
2520
+ token,
2521
+ manager,
2522
+ minIncentiveRate: formatUnits8(minIncentiveRate, decimalsResult),
2523
+ incentiveRate: formatUnits8(incentiveRate, decimalsResult),
2524
+ remainingAmount: formatUnits8(remainingAmount, decimalsResult),
2525
+ name: multicallResult(name, void 0),
2526
+ symbol: multicallResult(symbol, void 0),
2527
+ decimals: decimalsResult,
2528
+ pendingAmount: isSameAddress(stakingToken, token) ? formatUnits8(
2529
+ multicallResult(totalBalance, 0n) - totalSupply - remainingAmount,
2530
+ decimalsResult
2531
+ ) : formatUnits8(
2532
+ multicallResult(totalBalance, 0n) - remainingAmount,
2533
+ decimalsResult
2534
+ )
2535
+ };
2536
+ })
2537
+ );
2538
+ incentives.forEach((result, index) => {
2539
+ if (result.status === "rejected") {
2540
+ BeraMonitoring.captureException(
2541
+ new BeraError({
2542
+ reason: result.reason,
2543
+ message: "Incorrect incentives token received.",
2544
+ level: "error",
2545
+ extra: {
2546
+ token: whitelistedTokens[index],
2547
+ address,
2548
+ error: result.reason
2549
+ }
2550
+ })
2551
+ );
2552
+ }
2553
+ });
2554
+ return incentives.map((result) => result.status === "fulfilled" ? result.value : null).filter((incentive) => incentive !== null);
2555
+ }
2556
+
2557
+ // src/actions/pol/getRewardVaultStakingToken.ts
2558
+ import { rewardVaultAbi as rewardVaultAbi4 } from "@berachain/abis/pol/rewards/rewardVault";
2559
+ async function getRewardVaultStakingToken({
2560
+ address,
2561
+ publicClient
2562
+ }) {
2563
+ const vaultAddress = await publicClient.readContract({
2564
+ address,
2565
+ abi: rewardVaultAbi4,
2566
+ functionName: "stakeToken"
2567
+ });
2568
+ return vaultAddress;
2569
+ }
2570
+
2571
+ // src/actions/pol/getStakedBeraAPR.ts
2572
+ import {
2573
+ GetSWberaVaultMetadata,
2574
+ GqlSWberaVaultMetadataResolution
2575
+ } from "@berachain/graphql/pol/api";
2576
+ function getResolution(window) {
2577
+ if (window === "DAY") {
2578
+ return GqlSWberaVaultMetadataResolution.OneDay;
2579
+ }
2580
+ return GqlSWberaVaultMetadataResolution.SevenDays;
2581
+ }
2582
+ async function getStakedBeraAPR({
2583
+ window,
2584
+ ...args
2585
+ }) {
2586
+ const { config } = parseBaseArgs(args);
2587
+ const bexApiGraphqlClient = getApolloClient("api", args);
2588
+ try {
2589
+ const data = await bexApiGraphqlClient.query({
2590
+ query: GetSWberaVaultMetadata,
2591
+ variables: {
2592
+ chain: config.bex.chainName,
2593
+ resolution: getResolution(window ?? "DAY")
2594
+ }
2595
+ });
2596
+ const { apr } = data.data.polGetSWberaVaultMetadata;
2597
+ return Number(apr);
2598
+ } catch (error) {
2599
+ console.error("Failed to get SW Bera APR", error);
2600
+ throw error;
2601
+ }
2602
+ }
2603
+
2604
+ // src/actions/pol/getStakedBeraSnapshots.ts
2605
+ import {
2606
+ GetSWberaVaultSnapshots,
2607
+ GqlVaultSnapshotDataRange
2608
+ } from "@berachain/graphql/pol/api";
2609
+ async function getStakedBeraSnapshots({
2610
+ chain,
2611
+ range = GqlVaultSnapshotDataRange.ThirtyDays,
2612
+ ...args
2613
+ } = {}) {
2614
+ const { config } = parseBaseArgs(args);
2615
+ const bexApiGraphqlClient = getApolloClient("api", args);
2616
+ try {
2617
+ const data = await bexApiGraphqlClient.query({
2618
+ query: GetSWberaVaultSnapshots,
2619
+ variables: {
2620
+ chain: chain ?? config.bex.chainName,
2621
+ range
2622
+ }
2623
+ });
2624
+ return data.data.polGetSWberaVaultSnapshots;
2625
+ } catch (error) {
2626
+ console.error("Failed to get SW Bera Snapshots", error);
2627
+ throw error;
2628
+ }
2629
+ }
2630
+
2631
+ // src/actions/pol/getStakeWithdrawalCooldown.ts
2632
+ import { wberaStakerVaultAbi as stakeBeraVaultAbi2 } from "@berachain/abis/pol/wberaStakerVault";
2633
+ async function getStakeWithdrawalCooldown({
2634
+ publicClient,
2635
+ address
2636
+ }) {
2637
+ const lockPeriod = await publicClient.readContract({
2638
+ address,
2639
+ abi: stakeBeraVaultAbi2,
2640
+ functionName: "WITHDRAWAL_COOLDOWN"
2641
+ });
2642
+ return Number(lockPeriod);
2643
+ }
2644
+
2645
+ // src/actions/pol/getSWBeraVaultMetadata.ts
2646
+ import { erc20Abi as erc20Abi5, erc4626Abi } from "viem";
2647
+ async function getSWBeraVaultMetadata({
2648
+ address,
2649
+ underlyingAsset,
2650
+ publicClient,
2651
+ blockTime
2652
+ }) {
2653
+ assertPublicClient(publicClient);
2654
+ const hoursWindow = 26;
2655
+ try {
2656
+ const currentBlock = await publicClient.getBlock({ blockTag: "latest" });
2657
+ const blocksPerWindow = Math.floor(hoursWindow * 60 * 60 / blockTime);
2658
+ const blockWindowAgo = currentBlock.number - BigInt(blocksPerWindow);
2659
+ const [
2660
+ curretTotalAssets,
2661
+ currentTotalSupply,
2662
+ currentOneShareWorth,
2663
+ currentTVL,
2664
+ totalAssets24HoursAgo,
2665
+ totalSupply24HoursAgo,
2666
+ oneShareWorthWindowAgo,
2667
+ tvl24HoursAgo,
2668
+ underlyingTotalSupply,
2669
+ lockPeriod,
2670
+ incentiveFeeClaimStats
2671
+ ] = await Promise.all([
2672
+ publicClient.readContract({
2673
+ address,
2674
+ abi: erc4626Abi,
2675
+ functionName: "totalAssets"
2676
+ }),
2677
+ publicClient.readContract({
2678
+ address,
2679
+ abi: erc4626Abi,
2680
+ functionName: "totalSupply"
2681
+ }),
2682
+ publicClient.readContract({
2683
+ address,
2684
+ abi: erc4626Abi,
2685
+ functionName: "previewRedeem",
2686
+ args: [10n ** 18n],
2687
+ blockNumber: currentBlock.number
2688
+ }),
2689
+ publicClient.readContract({
2690
+ address: underlyingAsset,
2691
+ abi: erc20Abi5,
2692
+ functionName: "balanceOf",
2693
+ args: [address]
2694
+ }),
2695
+ publicClient.readContract({
2696
+ address,
2697
+ abi: erc4626Abi,
2698
+ functionName: "totalAssets",
2699
+ blockNumber: blockWindowAgo
2700
+ }),
2701
+ publicClient.readContract({
2702
+ address,
2703
+ abi: erc20Abi5,
2704
+ functionName: "totalSupply",
2705
+ blockNumber: blockWindowAgo
2706
+ }),
2707
+ publicClient.readContract({
2708
+ address,
2709
+ abi: erc4626Abi,
2710
+ functionName: "previewRedeem",
2711
+ args: [10n ** 18n],
2712
+ blockNumber: blockWindowAgo
2713
+ }),
2714
+ publicClient.readContract({
2715
+ address: underlyingAsset,
2716
+ abi: erc20Abi5,
2717
+ functionName: "balanceOf",
2718
+ args: [address],
2719
+ blockNumber: blockWindowAgo
2720
+ }),
2721
+ publicClient.readContract({
2722
+ address: underlyingAsset,
2723
+ abi: erc20Abi5,
2724
+ functionName: "totalSupply"
2725
+ }),
2726
+ getStakeWithdrawalCooldown({
2727
+ publicClient,
2728
+ address
2729
+ }),
2730
+ getIncentiveFeeClaimStats({})
2731
+ ]);
2732
+ const exchangeRateWindowAgo = new bignumber_js_default(
2733
+ oneShareWorthWindowAgo.toString()
2734
+ );
2735
+ const currentExchangeRate = new bignumber_js_default(currentOneShareWorth.toString());
2736
+ return {
2737
+ address,
2738
+ current: {
2739
+ exchangeRate: currentExchangeRate.toString(),
2740
+ totalSupply: new bignumber_js_default(currentTotalSupply.toString()).dividedBy(1e18).toString(),
2741
+ totalAssets: new bignumber_js_default(curretTotalAssets.toString()).dividedBy(1e18).toString(),
2742
+ tvl: new bignumber_js_default(currentTVL.toString()).dividedBy(1e18).toString()
2743
+ },
2744
+ previous: {
2745
+ exchangeRate: exchangeRateWindowAgo.toString(),
2746
+ totalSupply: new bignumber_js_default(totalSupply24HoursAgo.toString()).dividedBy(1e18).toString(),
2747
+ totalAssets: new bignumber_js_default(totalAssets24HoursAgo.toString()).dividedBy(1e18).toString(),
2748
+ tvl: new bignumber_js_default(tvl24HoursAgo.toString()).dividedBy(1e18).toString()
2749
+ },
2750
+ totalWBeraIssued: new bignumber_js_default(underlyingTotalSupply.toString()).dividedBy(1e18).toString(),
2751
+ lockPeriod,
2752
+ totalBuyBacks: incentiveFeeClaimStats.sumAllClaims,
2753
+ totalBuyBacksInLast24Hours: incentiveFeeClaimStats.sumClaimsInLast24Hours
2754
+ };
2755
+ } catch (error) {
2756
+ console.error("Failed to get SW Bera Vault Metadata", error);
2757
+ throw error;
2758
+ }
2759
+ }
2760
+
2761
+ // src/actions/pol/getSWBeraWithdrawal.ts
2762
+ import { wberaStakerVaultAbi as stakeBeraVaultAbi3 } from "@berachain/abis/pol/wberaStakerVault";
2763
+ function getTimeUntil(targetTime) {
2764
+ const currentTime = Date.now();
2765
+ const timeDiff = targetTime * 1e3 - currentTime;
2766
+ if (timeDiff <= 0) {
2767
+ return;
2768
+ }
2769
+ const totalSeconds = msToSeconds(timeDiff);
2770
+ return formatTimeLeft(totalSeconds, true, true);
2771
+ }
2772
+ async function getSWBeraWithdrawal({
2773
+ contractAddress,
2774
+ accountAddress,
2775
+ publicClient,
2776
+ version
2777
+ }) {
2778
+ const withdrawalRequests = [];
2779
+ function withdrawalRequestV1Helper(withdrawalRequest, lockPeriod) {
2780
+ const [assets, _shares, timestamp] = withdrawalRequest;
2781
+ const withdrawalAmount = assets;
2782
+ const readyTime = Number(timestamp) + Number(lockPeriod);
2783
+ const currentTime = msToSeconds(Date.now());
2784
+ const timeLeft = readyTime - currentTime;
2785
+ if (withdrawalAmount > 0) {
2786
+ const timeRemaining = getTimeUntil(timeLeft <= 0 ? 0 : readyTime);
2787
+ withdrawalRequests.push({
2788
+ receiptTokenAddress: contractAddress,
2789
+ withdrawalAmount,
2790
+ timeRemaining
2791
+ });
2792
+ }
2793
+ }
2794
+ switch (version) {
2795
+ case "V1": {
2796
+ const [withdrawalRequest, lockPeriod] = await Promise.all([
2797
+ publicClient.readContract({
2798
+ address: contractAddress,
2799
+ abi: stakeBeraVaultAbi3,
2800
+ functionName: "withdrawalRequests",
2801
+ args: [accountAddress]
2802
+ }),
2803
+ getStakeWithdrawalCooldown({
2804
+ publicClient,
2805
+ address: contractAddress
2806
+ })
2807
+ ]);
2808
+ withdrawalRequestV1Helper(withdrawalRequest, lockPeriod);
2809
+ return withdrawalRequests;
2810
+ }
2811
+ case "V2": {
2812
+ const [withdrawalRequestIds, lockPeriod] = await Promise.all([
2813
+ publicClient.readContract({
2814
+ address: contractAddress,
2815
+ abi: stakeBeraVaultAbi3,
2816
+ functionName: "getERC721WithdrawalRequestIds",
2817
+ args: [accountAddress]
2818
+ }),
2819
+ getStakeWithdrawalCooldown({
2820
+ publicClient,
2821
+ address: contractAddress
2822
+ })
2823
+ ]);
2824
+ if (isToken(contractAddress, "SWBERA")) {
2825
+ const withdrawalRequestV1 = await publicClient.readContract({
2826
+ address: contractAddress,
2827
+ abi: stakeBeraVaultAbi3,
2828
+ functionName: "withdrawalRequests",
2829
+ args: [accountAddress]
2830
+ });
2831
+ withdrawalRequestV1Helper(withdrawalRequestV1, lockPeriod);
2832
+ }
2833
+ const withdrawalResults = await Promise.all(
2834
+ withdrawalRequestIds.map(
2835
+ async (withdrawalRequestId) => {
2836
+ const withdrawalRequest = await publicClient.readContract({
2837
+ address: contractAddress,
2838
+ abi: stakeBeraVaultAbi3,
2839
+ functionName: "getERC721WithdrawalRequest",
2840
+ args: [withdrawalRequestId]
2841
+ });
2842
+ const { assets, requestTime: timestamp } = withdrawalRequest;
2843
+ if (!assets || !timestamp)
2844
+ throw new Error("Invalid withdrawal request");
2845
+ const withdrawalAmount = assets;
2846
+ const readyTime = Number(timestamp) + Number(lockPeriod);
2847
+ const currentTime = msToSeconds(Date.now());
2848
+ const timeLeft = readyTime - currentTime;
2849
+ if (withdrawalAmount > 0) {
2850
+ const timeRemaining = getTimeUntil(timeLeft <= 0 ? 0 : readyTime);
2851
+ return {
2852
+ withdrawalAmount,
2853
+ timeRemaining,
2854
+ withdrawalRequestId,
2855
+ receiptTokenAddress: contractAddress
2856
+ };
2857
+ }
2858
+ return null;
2859
+ }
2860
+ )
2861
+ );
2862
+ const filteredRequests = withdrawalResults.filter(
2863
+ (request) => request !== null
2864
+ );
2865
+ withdrawalRequests.push(...filteredRequests);
2866
+ return withdrawalRequests;
2867
+ }
2868
+ }
2869
+ }
2870
+
2871
+ // src/actions/pol/getTotalStakedAmount.ts
2872
+ import { wberaStakerVaultAbi as stakeBeraVaultAbi4 } from "@berachain/abis/pol/wberaStakerVault";
2873
+ async function getTotalStakedAmount({
2874
+ vaultAddresses,
2875
+ publicClient
2876
+ }) {
2877
+ assertPublicClient(publicClient);
2878
+ try {
2879
+ const totalAssets = await Promise.all(
2880
+ vaultAddresses.map(async (address) => {
2881
+ return publicClient.readContract({
2882
+ address,
2883
+ abi: stakeBeraVaultAbi4,
2884
+ functionName: "totalAssets"
2885
+ });
2886
+ })
2887
+ );
2888
+ const stakedAmount = vaultAddresses.reduce(
2889
+ (acc, address, index) => {
2890
+ acc[address] = totalAssets[index];
2891
+ return acc;
2892
+ },
2893
+ {}
2894
+ );
2895
+ return stakedAmount;
2896
+ } catch (error) {
2897
+ console.error("Failed to get total staked amount", error);
2898
+ throw error;
2899
+ }
2900
+ }
2901
+
2902
+ // src/actions/pol/getUserClaimableIncentives.ts
2903
+ async function getUserClaimableIncentives({
2904
+ account,
2905
+ ...args
2906
+ }) {
2907
+ const { config } = parseBaseArgs(args);
2908
+ const result = await fetch(
2909
+ `${config.pol.bribeBoostApi}/api/v1/wallets/${account.toLowerCase()}/rewards/aggregation`,
2910
+ {
2911
+ cache: "no-store"
2912
+ }
2913
+ );
2914
+ if (!result.ok) {
2915
+ const error = await getErrorResponse(result);
2916
+ throw new BeraError({
2917
+ message: "Failed to fetch incentives on server",
2918
+ cause: { error, result, account },
2919
+ reason: error?.error
2920
+ });
2921
+ }
2922
+ return result.json();
2923
+ }
2924
+
2925
+ // src/actions/pol/getUserVaultsReward.ts
2926
+ import { rewardVaultAbi as rewardVaultAbi5 } from "@berachain/abis/pol/rewards/rewardVault";
2927
+ async function getUserVaultsReward({
2928
+ account,
2929
+ vaultAddress,
2930
+ publicClient
2931
+ }) {
2932
+ if (!publicClient) throw new Error("Missing public client");
2933
+ if (!account) throw new Error("Missing user account");
2934
+ if (!vaultAddress) throw new Error("Missing vault address");
2935
+ return publicClient.readContract({
2936
+ address: vaultAddress,
2937
+ abi: rewardVaultAbi5,
2938
+ functionName: "earned",
2939
+ args: [account]
2940
+ });
2941
+ }
2942
+
2943
+ // src/actions/pol/getUserVaultInfo.ts
2944
+ import { formatEther as formatEther5 } from "viem";
2945
+
2946
+ // src/actions/pol/getUserVaultsBalance.ts
2947
+ import { rewardVaultAbi as rewardVaultAbi6 } from "@berachain/abis/pol/rewards/rewardVault";
2948
+ async function getUserVaultsBalance({
2949
+ account,
2950
+ vaultAddress,
2951
+ publicClient
2952
+ }) {
2953
+ assertPublicClient(publicClient);
2954
+ assertAddress(account, "account");
2955
+ assertAddress(vaultAddress, "vaultAddress");
2956
+ try {
2957
+ const [balance, delegated] = await Promise.all([
2958
+ publicClient.readContract({
2959
+ address: vaultAddress,
2960
+ abi: rewardVaultAbi6,
2961
+ functionName: "balanceOf",
2962
+ args: [account]
2963
+ }),
2964
+ publicClient.readContract({
2965
+ address: vaultAddress,
2966
+ abi: rewardVaultAbi6,
2967
+ functionName: "getTotalDelegateStaked",
2968
+ args: [account]
2969
+ })
2970
+ ]);
2971
+ return { balance, delegated };
2972
+ } catch (error) {
2973
+ console.log(error);
2974
+ throw error;
2975
+ }
2976
+ }
2977
+
2978
+ // src/actions/pol/getVaultsSupply.ts
2979
+ import { rewardVaultAbi as rewardVaultAbi7 } from "@berachain/abis/pol/rewards/rewardVault";
2980
+ async function getVaultsSupply({
2981
+ vaultAddress,
2982
+ publicClient
2983
+ }) {
2984
+ if (!publicClient) throw new Error("Missing public client");
2985
+ if (!vaultAddress) throw new Error("Missing vault address");
2986
+ try {
2987
+ const result = await publicClient.readContract({
2988
+ address: vaultAddress,
2989
+ abi: rewardVaultAbi7,
2990
+ functionName: "totalSupply",
2991
+ args: []
2992
+ });
2993
+ return result;
2994
+ } catch (error) {
2995
+ console.log(error);
2996
+ throw error;
2997
+ }
2998
+ }
2999
+
3000
+ // src/actions/pol/getUserVaultInfo.ts
3001
+ async function getUserVaultInfo({
3002
+ account,
3003
+ vaultAddress,
3004
+ publicClient
3005
+ }) {
3006
+ const [userBalance, userReward, totalSupply] = await Promise.all([
3007
+ getUserVaultsBalance({
3008
+ account,
3009
+ vaultAddress,
3010
+ publicClient
3011
+ }),
3012
+ getUserVaultsReward({
3013
+ account,
3014
+ vaultAddress,
3015
+ publicClient
3016
+ }),
3017
+ getVaultsSupply({
3018
+ vaultAddress,
3019
+ publicClient
3020
+ })
3021
+ ]);
3022
+ const withdrawableBalance = userBalance.balance - userBalance.delegated;
3023
+ const percentage = totalSupply > 0n ? Number(
3024
+ Number.parseFloat(formatEther5(userBalance.balance)) / Number.parseFloat(formatEther5(totalSupply))
3025
+ ).toString() : "0";
3026
+ return {
3027
+ balance: userBalance.balance,
3028
+ delegatedBalance: userBalance.delegated,
3029
+ withdrawableBalance,
3030
+ rewards: formatEther5(userReward),
3031
+ percentage
3032
+ };
3033
+ }
3034
+
3035
+ // src/actions/pol/getUserVaults.ts
3036
+ import { formatUnits as formatUnits9 } from "viem";
3037
+ import { rewardVaultAbi as rewardVaultAbi8 } from "@berachain/abis/pol/rewards/rewardVault";
3038
+ import {
3039
+ GetUserVaults
3040
+ } from "@berachain/graphql/pol/api";
3041
+ async function getUserVaults({
3042
+ account,
3043
+ publicClient,
3044
+ ...args
3045
+ }) {
3046
+ const { config } = parseBaseArgs(args);
3047
+ const bexApiGraphqlClient = getApolloClient("api", args);
3048
+ const res = await bexApiGraphqlClient.query({
3049
+ query: GetUserVaults,
3050
+ variables: {
3051
+ userId: account,
3052
+ chain: config.bex.chainName
3053
+ }
3054
+ });
3055
+ const deposits = res.data?.userVaultDeposits?.deposits;
3056
+ if (!deposits) {
3057
+ return {
3058
+ totalBgtRewards: "0",
3059
+ vaults: [],
3060
+ totalStakedValue: 0
3061
+ };
3062
+ }
3063
+ const [earnedResult, balanceResult] = await Promise.all([
3064
+ // Fetch pending BGT rewards for each vault
3065
+ publicClient.multicall({
3066
+ allowFailure: false,
3067
+ contracts: deposits.map(
3068
+ (deposit) => ({
3069
+ address: deposit.vaultAddress,
3070
+ abi: rewardVaultAbi8,
3071
+ functionName: "earned",
3072
+ args: [account]
3073
+ })
3074
+ )
3075
+ }),
3076
+ // Fetch user balance of each vault
3077
+ publicClient.multicall({
3078
+ allowFailure: false,
3079
+ contracts: deposits.map(
3080
+ (deposit) => ({
3081
+ address: deposit.vaultAddress,
3082
+ abi: rewardVaultAbi8,
3083
+ functionName: "balanceOf",
3084
+ args: [account]
3085
+ })
3086
+ )
3087
+ })
3088
+ ]);
3089
+ const { userVaults, total } = deposits.reduce(
3090
+ (acc, deposit, index) => {
3091
+ const item = earnedResult[index];
3092
+ const balanceItem = balanceResult[index];
3093
+ acc.total += item;
3094
+ if (!deposit.vault) {
3095
+ BeraMonitoring.captureException(
3096
+ new BeraError({
3097
+ message: "Deposit data from API is missing vault",
3098
+ level: "error",
3099
+ extra: {
3100
+ deposit
3101
+ }
3102
+ })
3103
+ );
3104
+ console.error("Deposit data from API is missing vault", deposit);
3105
+ return acc;
3106
+ }
3107
+ if (item > 0n || balanceItem > 0n) {
3108
+ const stakingTokenPrice = deposit.vault.dynamicData?.tvl && // If staked amount is 0, we don't want to divide by 0
3109
+ Number(deposit.vault.stakingTokenAmount) !== 0 ? Number(deposit.vault.dynamicData?.tvl ?? 0) / Number(deposit.vault.stakingTokenAmount) : null;
3110
+ acc.userVaults.push({
3111
+ ...deposit,
3112
+ vault: deposit.vault,
3113
+ unclaimedBgt: formatUnits9(item, 18),
3114
+ formattedBalance: formatUnits9(
3115
+ balanceItem,
3116
+ deposit.vault.stakingToken.decimals
3117
+ ),
3118
+ stakingTokenPrice
3119
+ });
3120
+ }
3121
+ return acc;
3122
+ },
3123
+ {
3124
+ userVaults: [],
3125
+ total: 0n
3126
+ }
3127
+ );
3128
+ const sortedUserVaults = [...userVaults].sort((a, b) => {
3129
+ if (a.vault.isVaultWhitelisted && !b.vault.isVaultWhitelisted) {
3130
+ return -1;
3131
+ }
3132
+ if (!a.vault.isVaultWhitelisted && b.vault.isVaultWhitelisted) {
3133
+ return 1;
3134
+ }
3135
+ const aUnclaimed = Number.parseFloat(a.unclaimedBgt);
3136
+ const bUnclaimed = Number.parseFloat(b.unclaimedBgt);
3137
+ return bUnclaimed - aUnclaimed;
3138
+ });
3139
+ const totalStakedValue = sortedUserVaults.reduce((acc, vault) => {
3140
+ const tvl = Number(vault.vault.dynamicData?.tvl ?? 0);
3141
+ if (tvl === 0) {
3142
+ return acc;
3143
+ }
3144
+ const stakingTokenAmount = Number.parseFloat(
3145
+ vault.vault.stakingTokenAmount
3146
+ );
3147
+ const stakingTokenPrice = tvl / stakingTokenAmount;
3148
+ return acc + stakingTokenPrice * Number(vault.formattedBalance);
3149
+ }, 0);
3150
+ return {
3151
+ totalStakedValue,
3152
+ totalBgtRewards: formatUnits9(total, 18),
3153
+ vaults: sortedUserVaults
3154
+ };
3155
+ }
3156
+
3157
+ // src/actions/pol/getVaultHistory.ts
3158
+ import {
3159
+ GetVaultHistory
3160
+ } from "@berachain/graphql/pol/api";
3161
+ async function getVaultHistory({
3162
+ vault,
3163
+ chain,
3164
+ ...args
3165
+ }) {
3166
+ const { config } = parseBaseArgs(args);
3167
+ const bexApiGraphqlClient = getApolloClient("api", args);
3168
+ const result = await bexApiGraphqlClient.query({
3169
+ query: GetVaultHistory,
3170
+ variables: {
3171
+ ...args,
3172
+ vaultId: vault,
3173
+ chain: chain ?? config.bex.chainName
3174
+ }
3175
+ });
3176
+ return result.data.polGetRewardVaultSnapshots;
3177
+ }
3178
+
3179
+ // src/actions/pol/getVaultValidators.ts
3180
+ import {
3181
+ GetVaultValidators
3182
+ } from "@berachain/graphql/pol/api";
3183
+ async function getVaultValidators({
3184
+ address,
3185
+ onlyActiveValidators,
3186
+ ...args
3187
+ }) {
3188
+ const bexApiGraphqlClient = getApolloClient("api", args);
3189
+ const result = await bexApiGraphqlClient.query({
3190
+ query: GetVaultValidators,
3191
+ variables: { vaultId: address, isActive: onlyActiveValidators }
3192
+ });
3193
+ return result.data.validators.validators ?? [];
3194
+ }
3195
+
3196
+ // src/actions/prices/getTokenCurrentPrices.ts
3197
+ import { getAddress, zeroAddress as zeroAddress3 } from "viem";
3198
+ import {
3199
+ GetTokenCurrentPrices
3200
+ } from "@berachain/graphql/dex/api";
3201
+ async function getTokenCurrentPrices({
3202
+ addressIn: _addressIn,
3203
+ ...args
3204
+ }) {
3205
+ const { config, chainId } = parseBaseArgs(args);
3206
+ const addressIn = _addressIn.map((a) => a.toLowerCase()).filter((addr, idx, arr) => addr && arr.indexOf(addr) === idx);
3207
+ const bexApiGraphqlClient = getApolloClient("api", args);
3208
+ const { data } = await bexApiGraphqlClient.query({
3209
+ query: GetTokenCurrentPrices,
3210
+ variables: {
3211
+ chains: [config.bex.chainName],
3212
+ addressIn
3213
+ }
3214
+ });
3215
+ return data.tokenGetCurrentPrices.reduce(
3216
+ (map, tokenInformation) => {
3217
+ if (!tokenInformation.price || !tokenInformation.address) {
3218
+ return map;
3219
+ }
3220
+ const formattedAddress = tokenInformation.address;
3221
+ map[getAddress(formattedAddress)] = {
3222
+ price: getSafeNumber(tokenInformation.price.toString()),
3223
+ updatedAt: tokenInformation.updatedAt,
3224
+ chainId
3225
+ };
3226
+ map[formattedAddress.toLowerCase()] = {
3227
+ price: getSafeNumber(tokenInformation.price.toString()),
3228
+ updatedAt: tokenInformation.updatedAt,
3229
+ chainId
3230
+ };
3231
+ if (isToken(formattedAddress, "WBERA")) {
3232
+ map[zeroAddress3] = {
3233
+ price: getSafeNumber(tokenInformation.price.toString()),
3234
+ updatedAt: tokenInformation.updatedAt,
3235
+ chainId
3236
+ };
3237
+ map[config.tokens.bgt.toLowerCase()] = {
3238
+ price: getSafeNumber(tokenInformation.price.toString()),
3239
+ updatedAt: tokenInformation.updatedAt,
3240
+ chainId
3241
+ };
3242
+ map[config.tokens.bgt] = {
3243
+ price: getSafeNumber(tokenInformation.price.toString()),
3244
+ updatedAt: tokenInformation.updatedAt,
3245
+ chainId
3246
+ };
3247
+ }
3248
+ return map;
3249
+ },
3250
+ {}
3251
+ );
3252
+ }
3253
+
3254
+ // src/actions/tokens/getAllowances.ts
3255
+ import { getPublicClient } from "@wagmi/core";
3256
+ import {
3257
+ erc20Abi as erc20Abi6,
3258
+ formatUnits as formatUnits10
3259
+ } from "viem";
3260
+ async function getAllowances({
3261
+ items: itemsList,
3262
+ account,
3263
+ config
3264
+ }) {
3265
+ assertDefined(itemsList, "items");
3266
+ assertDefined(config, "config");
3267
+ assertDefined(account, "account");
3268
+ const tokensByChainId = Object.groupBy(
3269
+ itemsList,
3270
+ (item) => item.token.chainId
3271
+ );
3272
+ const res = await Promise.allSettled(
3273
+ Object.entries(tokensByChainId).map(async ([chainId, items]) => {
3274
+ if (!items) return [];
3275
+ const publicClient = getPublicClient(config, {
3276
+ chainId: Number(chainId)
3277
+ });
3278
+ assertPublicClient(publicClient, `publicClient ${chainId}`);
3279
+ const result = await publicClient.multicall({
3280
+ contracts: items.map(
3281
+ (item) => ({
3282
+ address: item.token.address,
3283
+ abi: erc20Abi6,
3284
+ functionName: "allowance",
3285
+ args: [account, item.spender]
3286
+ })
3287
+ )
3288
+ });
3289
+ const allowances = result.map((item, index) => {
3290
+ const token = items[index];
3291
+ if (item.error) {
3292
+ return void 0;
3293
+ }
3294
+ const resultAllowanceToken = {
3295
+ token: token.token,
3296
+ spender: token.spender,
3297
+ amount: token.amount,
3298
+ allowance: {
3299
+ raw: item.result.toString(),
3300
+ formatted: formatUnits10(item.result, token.token.decimals)
3301
+ },
3302
+ needsApproval: item.result < BigInt(token.amount.raw)
3303
+ };
3304
+ return resultAllowanceToken;
3305
+ });
3306
+ return allowances.filter((i) => Boolean(i));
3307
+ })
3308
+ );
3309
+ return res.flatMap(
3310
+ (result) => result.status === "fulfilled" ? result.value : void 0
3311
+ ).filter((i) => Boolean(i));
3312
+ }
3313
+
3314
+ // src/actions/transactions/beraWriteContract.ts
3315
+ import {
3316
+ getPublicClient as getPublicClient2,
3317
+ getWalletClient,
3318
+ switchChain
3319
+ } from "@wagmi/core";
3320
+ import {
3321
+ BaseError,
3322
+ createWalletClient,
3323
+ decodeErrorResult,
3324
+ HttpRequestError,
3325
+ http
3326
+ } from "viem";
3327
+ import { ChainId, defaultChainId } from "@berachain/config/internal";
3328
+
3329
+ // src/errors/getRevertReason.ts
3330
+ import {
3331
+ AbiFunctionSignatureNotFoundError,
3332
+ decodeFunctionData
3333
+ } from "viem";
3334
+ async function getRevertReason({
3335
+ publicClient,
3336
+ abi: providedAbi,
3337
+ ...params
3338
+ }) {
3339
+ const abi = [...commonAbiErrors, ...providedAbi ?? []];
3340
+ let blockNumber;
3341
+ let to;
3342
+ let account;
3343
+ let value;
3344
+ let data;
3345
+ let functionName;
3346
+ let args;
3347
+ if ("txHash" in params) {
3348
+ const tx = await publicClient.getTransaction({
3349
+ hash: params.txHash
3350
+ });
3351
+ if (!tx.to)
3352
+ throw new InvalidArgumentError({
3353
+ property: "tx",
3354
+ value: tx,
3355
+ expected: "Transaction",
3356
+ message: "Trying to get revert reason for a contract creation"
3357
+ });
3358
+ data = tx.input;
3359
+ to = tx.to;
3360
+ account = tx.from;
3361
+ value = tx.value;
3362
+ blockNumber = tx.blockNumber;
3363
+ } else {
3364
+ blockNumber = params.blockNumber;
3365
+ to = params.to;
3366
+ account = params.account;
3367
+ value = params.value;
3368
+ if ("data" in params) {
3369
+ data = params.data;
3370
+ } else if ("functionName" in params && "args" in params) {
3371
+ functionName = params.functionName;
3372
+ args = params.args;
3373
+ } else if (!value) {
3374
+ throw new InvalidArgumentError({
3375
+ property: "dataOrFunctionNameAndArgs",
3376
+ value: params,
3377
+ expected: "Hex or FunctionName and Args"
3378
+ });
3379
+ }
3380
+ }
3381
+ try {
3382
+ if (!abi) {
3383
+ if (data) {
3384
+ await publicClient.call({
3385
+ data,
3386
+ to,
3387
+ account,
3388
+ blockNumber,
3389
+ value
3390
+ });
3391
+ } else {
3392
+ throw new Error("Data is required if abi is not provided");
3393
+ }
3394
+ }
3395
+ if ("functionName" in params && "args" in params && params.functionName) {
3396
+ functionName = params.functionName;
3397
+ args = params.args;
3398
+ } else if (data) {
3399
+ if (!abi) {
3400
+ const res = await publicClient.call({
3401
+ data,
3402
+ to,
3403
+ account,
3404
+ blockNumber,
3405
+ value
3406
+ });
3407
+ throw new Error(
3408
+ `Getting revert reason for successful simulation. Data: ${data}`,
3409
+ { cause: res }
3410
+ );
3411
+ }
3412
+ try {
3413
+ const decoded = decodeFunctionData({
3414
+ abi,
3415
+ data
3416
+ });
3417
+ functionName = decoded.functionName;
3418
+ args = decoded.args;
3419
+ } catch (e) {
3420
+ if (e instanceof AbiFunctionSignatureNotFoundError) {
3421
+ await publicClient.call({
3422
+ data,
3423
+ to,
3424
+ account,
3425
+ blockNumber,
3426
+ value
3427
+ });
3428
+ }
3429
+ throw new Error("Data is required if abi is not provided");
3430
+ }
3431
+ } else {
3432
+ throw new Error("No data or function name and args provided");
3433
+ }
3434
+ if (abi && functionName) {
3435
+ await publicClient.simulateContract({
3436
+ functionName,
3437
+ args,
3438
+ abi,
3439
+ address: to,
3440
+ account,
3441
+ blockNumber
3442
+ });
3443
+ throw new TransactionFailedError({
3444
+ message: `Getting revert reason for successful simulation`,
3445
+ functionName,
3446
+ to,
3447
+ txHash: "txHash" in params ? params.txHash : void 0,
3448
+ input: params
3449
+ });
3450
+ }
3451
+ throw new Error("No data or function name and args provided");
3452
+ } catch (error) {
3453
+ if (error instanceof Error) {
3454
+ return parseViemError({ error, abi, revertIfUnknown: true });
3455
+ }
3456
+ throw error;
3457
+ }
3458
+ }
3459
+
3460
+ // src/actions/transactions/beraWriteContract.ts
3461
+ var defaultPollingInterval = seconds(1);
3462
+ var increaseByPercentage = (value, percentage) => {
3463
+ return value * (100n + BigInt(percentage)) / 100n;
3464
+ };
3465
+ function parseNonce({
3466
+ nonceResult,
3467
+ onWarning
3468
+ }) {
3469
+ if (nonceResult.status === "fulfilled") {
3470
+ if (nonceResult.value && nonceResult.value > Number.MAX_SAFE_INTEGER) {
3471
+ onWarning?.(
3472
+ new BeraError({
3473
+ message: "Nonce is too large. No nonce will be provided to avoid IntegerOutOfRangeError.",
3474
+ cause: nonceResult.value,
3475
+ level: "debug"
3476
+ })
3477
+ );
3478
+ return void 0;
3479
+ }
3480
+ return nonceResult.value;
3481
+ }
3482
+ return void 0;
3483
+ }
3484
+ function isImpersonateAccount(chainId = defaultChainId) {
3485
+ return chainId === ChainId.BEPOLIA ? process.env.NEXT_PUBLIC_80069_ANVIL_IMPERSONATE_ACCOUNT === "true" : process.env.NEXT_PUBLIC_80094_ANVIL_IMPERSONATE_ACCOUNT === "true";
3486
+ }
3487
+ async function beraWriteContract(args) {
3488
+ if (process.env.NODE_ENV === "development" && !args.contractName && // let's avoid this for eip5972 calls
3489
+ args.address && !("calls" in args || args.calls)) {
3490
+ console.warn(
3491
+ "beraWriteContract: Contract name is required. Either update the contract mapping in devrel or provide a contract name in ContractName enum",
3492
+ "This is a development error and will be thrown in development mode only."
3493
+ );
3494
+ throw new InvalidArgumentError({
3495
+ property: "contractName",
3496
+ value: args.contractName,
3497
+ expected: "ContractName",
3498
+ displayMessage: `[DEV] Contract name is required as it's not mapped in the devrel's contract mapping ${args.address}`,
3499
+ level: "error"
3500
+ });
3501
+ }
3502
+ const {
3503
+ address,
3504
+ calls,
3505
+ value,
3506
+ gasLimit,
3507
+ onLoading,
3508
+ onSuccess,
3509
+ onWarning,
3510
+ onError,
3511
+ onSubmission,
3512
+ wagmiConfig,
3513
+ walletClient: _walletClient,
3514
+ account: argsAccount,
3515
+ txConfirmationTimeout = 12e4,
3516
+ chainId = defaultChainId,
3517
+ impersonateAccount = isImpersonateAccount(chainId),
3518
+ errorsAbi: _errorsAbi = [],
3519
+ pollingInterval = defaultPollingInterval,
3520
+ ...rest
3521
+ } = args;
3522
+ onLoading?.(args);
3523
+ const data = "data" in rest ? rest.data : void 0;
3524
+ const globalAbi = [
3525
+ ...commonAbiErrors,
3526
+ ..._errorsAbi,
3527
+ ..."abi" in rest && rest.abi && Array.isArray(rest.abi) ? rest.abi : []
3528
+ ];
3529
+ let walletClient = _walletClient;
3530
+ if (!wagmiConfig) {
3531
+ onError?.(
3532
+ new InvalidArgumentError({
3533
+ property: "wagmiConfig",
3534
+ value: wagmiConfig,
3535
+ expected: "Config"
3536
+ }),
3537
+ args
3538
+ );
3539
+ return;
3540
+ }
3541
+ const isLocalAccount = walletClient?.account?.type === "local";
3542
+ if (!isLocalAccount) {
3543
+ try {
3544
+ await switchChain(wagmiConfig, { chainId });
3545
+ } catch (e) {
3546
+ const error = e;
3547
+ onError?.(
3548
+ new BeraError({
3549
+ cause: error,
3550
+ displayMessage: "There was an error switching to the chain."
3551
+ }),
3552
+ args
3553
+ );
3554
+ return;
3555
+ }
3556
+ }
3557
+ if (!walletClient) {
3558
+ try {
3559
+ walletClient = await getWalletClient(wagmiConfig, { chainId });
3560
+ } catch (e) {
3561
+ onError?.(
3562
+ new BeraError({
3563
+ cause: e,
3564
+ displayMessage: "There was an error connecting to the wallet."
3565
+ }),
3566
+ args
3567
+ );
3568
+ return;
3569
+ }
3570
+ }
3571
+ if (!walletClient) {
3572
+ onError?.(
3573
+ new InvalidArgumentError({
3574
+ displayMessage: "There was an error connecting to the wallet.",
3575
+ property: "walletClient",
3576
+ value: walletClient,
3577
+ expected: "WalletClient"
3578
+ }),
3579
+ args
3580
+ );
3581
+ return;
3582
+ }
3583
+ const account = argsAccount || walletClient.account;
3584
+ if (!account) {
3585
+ onError?.(
3586
+ new InvalidArgumentError({
3587
+ property: "account",
3588
+ value: account,
3589
+ expected: "Account"
3590
+ }),
3591
+ args
3592
+ );
3593
+ return;
3594
+ }
3595
+ const accountAddress = typeof account === "string" ? account : account.address;
3596
+ const publicClient = getPublicClient2(wagmiConfig, {
3597
+ chainId
3598
+ });
3599
+ try {
3600
+ assertPublicClient(publicClient);
3601
+ } catch (error) {
3602
+ onError?.(error, args);
3603
+ return;
3604
+ }
3605
+ if (impersonateAccount) {
3606
+ const testClient = getTestClient(chainId);
3607
+ await testClient.impersonateAccount({
3608
+ address: accountAddress
3609
+ });
3610
+ walletClient = createWalletClient({
3611
+ transport: http(testClient.transport.url),
3612
+ account,
3613
+ chain: walletClient.chain
3614
+ });
3615
+ }
3616
+ let txHash;
3617
+ const input = {
3618
+ calls: "calls" in rest ? rest.calls : void 0,
3619
+ params: "params" in rest ? rest.params : void 0,
3620
+ value,
3621
+ data: "data" in rest ? rest.data : void 0
3622
+ };
3623
+ try {
3624
+ const noncePromise = publicClient.getTransactionCount({
3625
+ address: accountAddress,
3626
+ /**
3627
+ * We won't use pending any more because if someone previously send a txn with a higher nonce, this won't be executed
3628
+ * unless all the previous nonces are executed.
3629
+ *
3630
+ * This will lead to a UX issue where the user thinks the txn was not sent because it's pending forever.
3631
+ *
3632
+ * The only case where pending is needed is if chain is halted or the user is sending multiple transactions at the same time.
3633
+ * However, it's less likely to happen.
3634
+ *
3635
+ * A lot of waitForTransactionReceipt were timing out, and maybe it was related to that.
3636
+ */
3637
+ blockTag: "latest"
3638
+ }).catch(() => void 0);
3639
+ const sharedTxProperties = {
3640
+ account: accountAddress,
3641
+ to: address,
3642
+ address,
3643
+ chainId,
3644
+ value
3645
+ };
3646
+ if (calls) {
3647
+ const parsedCalls = calls.map((call) => {
3648
+ if ("abi" in call && Array.isArray(globalAbi)) {
3649
+ globalAbi.push(...call.abi);
3650
+ }
3651
+ if ("data" in call) {
3652
+ return {
3653
+ to: call.address,
3654
+ data: call.data,
3655
+ value: call.value ?? 0n
3656
+ };
3657
+ }
3658
+ if ("abi" in call && "functionName" in call) {
3659
+ const params = "params" in call ? call.params : void 0;
3660
+ return {
3661
+ to: call.address,
3662
+ abi: call.abi,
3663
+ functionName: call.functionName,
3664
+ args: params,
3665
+ value: call.value ?? 0n
3666
+ };
3667
+ }
3668
+ return {
3669
+ to: call.address,
3670
+ value: call.value ?? 0n
3671
+ };
3672
+ });
3673
+ if (args.enableSimulateCalls) {
3674
+ const res = await publicClient.simulateCalls({
3675
+ calls: parsedCalls,
3676
+ account
3677
+ });
3678
+ const failedCallIndex = res.results.findIndex(
3679
+ (result) => result.status === "failure"
3680
+ );
3681
+ if (failedCallIndex !== -1) {
3682
+ if (res.block.number === null) {
3683
+ throw new InvalidArgumentError({
3684
+ property: "blockNumber",
3685
+ value: res.block.number,
3686
+ expected: "bigint",
3687
+ message: "Block number is null"
3688
+ });
3689
+ }
3690
+ const failedCall = res.results[failedCallIndex];
3691
+ const { reason: decodedReason } = failedCall.data && failedCall.data !== "0x" ? {
3692
+ reason: parseDecodedError(
3693
+ decodeErrorResult({
3694
+ data: failedCall.data,
3695
+ abi: globalAbi
3696
+ })
3697
+ )
3698
+ } : parseViemError({
3699
+ error: failedCall.error,
3700
+ revertIfUnknown: false,
3701
+ abi: globalAbi
3702
+ });
3703
+ onError?.(
3704
+ new TransactionFailedError({
3705
+ cause: failedCall.error,
3706
+ txHash,
3707
+ chainId,
3708
+ reason: decodedReason,
3709
+ abi: globalAbi,
3710
+ input,
3711
+ blockNumber: res.block.number
3712
+ }),
3713
+ args
3714
+ );
3715
+ return;
3716
+ }
3717
+ }
3718
+ if (process.env.NODE_ENV === "test") {
3719
+ throw new InvalidArgumentError({
3720
+ displayMessage: "Batch calls are not supported in test environment",
3721
+ expected: "not test",
3722
+ property: "NODE_ENV",
3723
+ value: process.env.NODE_ENV,
3724
+ level: "fatal"
3725
+ });
3726
+ }
3727
+ const request = await walletClient.sendCalls({
3728
+ calls: parsedCalls,
3729
+ account,
3730
+ // This is needed to ensure that the transaction is atomic
3731
+ // If this was not set, we might have a list of receipts instead of a single one
3732
+ forceAtomic: true
3733
+ });
3734
+ onSubmission?.({ id: request.id }, args);
3735
+ const callStatus = await walletClient.waitForCallsStatus({
3736
+ id: request.id,
3737
+ pollingInterval,
3738
+ timeout: txConfirmationTimeout
3739
+ });
3740
+ if (callStatus.status === "success") {
3741
+ const receipt = callStatus.receipts?.[0];
3742
+ if (!receipt) {
3743
+ throw new BeraError({
3744
+ message: "Call status is success but no receipt was found",
3745
+ cause: callStatus,
3746
+ level: "error",
3747
+ reason: "CALL_STATUS_SUCCESS_BUT_NO_RECEIPT"
3748
+ });
3749
+ }
3750
+ onSuccess?.(receipt, args);
3751
+ return receipt;
3752
+ }
3753
+ console.error("wallet_sendCalls: Call failed", callStatus);
3754
+ throw new TransactionFailedError({
3755
+ cause: callStatus,
3756
+ level: "error",
3757
+ input,
3758
+ txHash,
3759
+ abi: globalAbi,
3760
+ chainId
3761
+ });
3762
+ }
3763
+ if (data) {
3764
+ const [simulationResult, estimatedGas, nonceResult] = await Promise.allSettled([
3765
+ publicClient.call({
3766
+ ...sharedTxProperties,
3767
+ data
3768
+ }),
3769
+ gasLimit ?? publicClient.estimateGas({
3770
+ ...sharedTxProperties,
3771
+ data
3772
+ }),
3773
+ noncePromise
3774
+ ]);
3775
+ if (simulationResult.status === "rejected") {
3776
+ throw simulationResult.reason;
3777
+ }
3778
+ const gas = estimatedGas.status === "fulfilled" ? increaseByPercentage(estimatedGas.value, 10) : DEFAULT_METAMASK_GAS_LIMIT;
3779
+ txHash = await walletClient.sendTransaction({
3780
+ data,
3781
+ to: address,
3782
+ account,
3783
+ gas,
3784
+ chainId,
3785
+ nonce: parseNonce({
3786
+ nonceResult,
3787
+ onWarning(e) {
3788
+ onWarning?.(e, args);
3789
+ }
3790
+ }),
3791
+ value
3792
+ });
3793
+ onSubmission?.({ txHash }, args);
3794
+ } else if ("abi" in rest && "functionName" in rest) {
3795
+ const { abi, functionName } = rest;
3796
+ const params = "params" in rest ? rest.params : void 0;
3797
+ const [simulationResult, gasEstimateResult, nonceResult] = await Promise.allSettled([
3798
+ // @ts-expect-error nested type issues. Be careful when changing this.
3799
+ publicClient.simulateContract({
3800
+ ...sharedTxProperties,
3801
+ abi: globalAbi,
3802
+ functionName,
3803
+ args: params,
3804
+ account
3805
+ }),
3806
+ // Only estimate gas if no gasLimit is provided
3807
+ gasLimit ?? // @ts-expect-error nested type issues. Be careful when changing this.
3808
+ publicClient.estimateContractGas({
3809
+ ...sharedTxProperties,
3810
+ abi: globalAbi,
3811
+ functionName,
3812
+ args: params
3813
+ }),
3814
+ noncePromise
3815
+ ]);
3816
+ if (simulationResult.status === "rejected") {
3817
+ throw simulationResult.reason;
3818
+ }
3819
+ const estimatedGas = gasLimit ?? (gasEstimateResult.status === "fulfilled" ? increaseByPercentage(gasEstimateResult.value, 10) : DEFAULT_METAMASK_GAS_LIMIT);
3820
+ txHash = await walletClient.writeContract({
3821
+ ...simulationResult.value.request,
3822
+ chainId,
3823
+ gas: estimatedGas,
3824
+ nonce: parseNonce({
3825
+ nonceResult,
3826
+ onWarning(e) {
3827
+ onWarning?.(e, args);
3828
+ }
3829
+ })
3830
+ });
3831
+ onSubmission?.({ txHash }, args);
3832
+ } else {
3833
+ const [nonceResult] = await Promise.allSettled([noncePromise]);
3834
+ txHash = await walletClient.sendTransaction({
3835
+ chainId,
3836
+ to: address,
3837
+ value,
3838
+ account,
3839
+ nonce: parseNonce({
3840
+ nonceResult,
3841
+ onWarning(e) {
3842
+ onWarning?.(e, args);
3843
+ }
3844
+ })
3845
+ });
3846
+ onSubmission?.({ txHash }, args);
3847
+ }
3848
+ if (process.env.NODE_ENV === "test") {
3849
+ const testClient = getTestClient(chainId);
3850
+ await testClient.mine({ blocks: 1 });
3851
+ }
3852
+ const confirmationReceipt = await publicClient.waitForTransactionReceipt({
3853
+ hash: txHash,
3854
+ pollingInterval,
3855
+ timeout: txConfirmationTimeout,
3856
+ confirmations: 1
3857
+ });
3858
+ if (confirmationReceipt.status === "success") {
3859
+ onSuccess?.(confirmationReceipt, args);
3860
+ } else {
3861
+ const revertReason = await getRevertReason({
3862
+ publicClient,
3863
+ blockNumber: confirmationReceipt.blockNumber,
3864
+ to: address,
3865
+ account: accountAddress,
3866
+ abi: globalAbi,
3867
+ args: "params" in rest ? rest.params : void 0,
3868
+ functionName: "functionName" in rest ? rest.functionName : void 0,
3869
+ value,
3870
+ data
3871
+ });
3872
+ if (process.env.NODE_ENV === "test") {
3873
+ console.error("beraWriteContract: Revert reason", revertReason);
3874
+ }
3875
+ onError?.(
3876
+ new TransactionFailedError({
3877
+ reason: revertReason.reason,
3878
+ txHash,
3879
+ receipt: confirmationReceipt,
3880
+ to: address,
3881
+ functionName: "functionName" in rest ? rest.functionName : void 0,
3882
+ input,
3883
+ chainId,
3884
+ abi: globalAbi,
3885
+ blockNumber: confirmationReceipt.blockNumber
3886
+ }),
3887
+ args
3888
+ );
3889
+ }
3890
+ return confirmationReceipt;
3891
+ } catch (e) {
3892
+ if (e instanceof BeraError) {
3893
+ onError?.(e, args);
3894
+ } else if (e instanceof Error) {
3895
+ const viemError = parseViemError({
3896
+ error: e,
3897
+ revertIfUnknown: false,
3898
+ abi: globalAbi
3899
+ });
3900
+ if (viemError && viemError.rootCause instanceof BaseError && "url" in viemError.rootCause) {
3901
+ onError?.(
3902
+ new RequestError({
3903
+ cause: viemError.rootCause,
3904
+ response: void 0,
3905
+ endpoint: {
3906
+ url: viemError.rootCause.url,
3907
+ type: "rpc"
3908
+ },
3909
+ statusCode: viemError.rootCause instanceof HttpRequestError ? viemError.rootCause.status : void 0
3910
+ }),
3911
+ args
3912
+ );
3913
+ return;
3914
+ }
3915
+ onError?.(
3916
+ new TransactionFailedError({
3917
+ cause: e,
3918
+ to: address,
3919
+ txHash,
3920
+ chainId,
3921
+ abi: globalAbi,
3922
+ functionName: "functionName" in rest ? rest.functionName : void 0,
3923
+ input
3924
+ }),
3925
+ args
3926
+ );
3927
+ } else {
3928
+ onError?.(
3929
+ new TransactionFailedError({
3930
+ cause: e,
3931
+ txHash,
3932
+ to: address,
3933
+ chainId,
3934
+ functionName: "functionName" in rest ? rest.functionName : void 0,
3935
+ input,
3936
+ abi: globalAbi
3937
+ }),
3938
+ args
3939
+ );
3940
+ }
3941
+ }
3942
+ }
3943
+
3944
+ // src/actions/validators/getAllValidators.ts
3945
+ import {
3946
+ GetValidators
3947
+ } from "@berachain/graphql/pol/api";
3948
+ async function getAllValidators({
3949
+ variables = {},
3950
+ ...args
3951
+ } = {}) {
3952
+ const { config } = parseBaseArgs(args);
3953
+ const bexApiGraphqlClient = getApolloClient("api", args);
3954
+ const result = await bexApiGraphqlClient.query({
3955
+ query: GetValidators,
3956
+ variables: {
3957
+ chain: config.bex.chainName,
3958
+ ...variables
3959
+ }
3960
+ });
3961
+ return result.data;
3962
+ }
3963
+
3964
+ // src/actions/validators/getApiEnrichedAllocation.ts
3965
+ import { isAddressEqual } from "viem";
3966
+ async function getApiEnrichedAllocation({
3967
+ allocation
3968
+ }) {
3969
+ const vaults = await getRewardVaults({
3970
+ filter: {
3971
+ where: {
3972
+ vaultAddressIn: allocation.weights.map((weight) => weight.receiver)
3973
+ }
3974
+ }
3975
+ });
3976
+ const startBlock = allocation?.start.blockNumber ?? 0;
3977
+ return allocation?.weights.map(
3978
+ (allocation2) => {
3979
+ return {
3980
+ percentage: allocation2.percentage,
3981
+ receiver: allocation2.receiver,
3982
+ startBlock,
3983
+ receivingVault: vaults?.gaugeList.find(
3984
+ (vault) => isAddressEqual(vault.address, allocation2.receiver)
3985
+ )
3986
+ };
3987
+ }
3988
+ );
3989
+ }
3990
+
3991
+ // src/actions/validators/getApiValidator.ts
3992
+ import {
3993
+ GetValidator
3994
+ } from "@berachain/graphql/pol/api";
3995
+ async function getApiValidator({
3996
+ id,
3997
+ ...args
3998
+ }) {
3999
+ const { config } = parseBaseArgs(args);
4000
+ const bexApiGraphqlClient = getApolloClient("api", args);
4001
+ const results = await bexApiGraphqlClient.query({
4002
+ query: GetValidator,
4003
+ variables: {
4004
+ id,
4005
+ chain: config.bex.chainName
4006
+ }
4007
+ });
4008
+ return results.data;
4009
+ }
4010
+
4011
+ // src/actions/validators/getDailyValidatorBlockStats.ts
4012
+ import {
4013
+ GetValidatorBlockStats
4014
+ } from "@berachain/graphql/pol/subgraph";
4015
+ async function getDailyValidatorBlockStats({
4016
+ pubKey,
4017
+ first = 1,
4018
+ ...args
4019
+ }) {
4020
+ const bgtClient = getApolloClient("pol.subgraph", args);
4021
+ try {
4022
+ const result = await bgtClient.query({
4023
+ query: GetValidatorBlockStats,
4024
+ variables: {
4025
+ pubKey,
4026
+ first
4027
+ }
4028
+ });
4029
+ return result.data;
4030
+ } catch (e) {
4031
+ console.error("GetValidatorBlockStats:", e);
4032
+ throw e;
4033
+ }
4034
+ }
4035
+
4036
+ // src/actions/validators/getValidatorRewardAllocation.ts
4037
+ import { beraChefAbi } from "@berachain/abis/pol/rewards/beraChef";
4038
+ function formatValidatorRewardAllocation(raw, startTs) {
4039
+ return {
4040
+ start: {
4041
+ blockNumber: Number(raw.startBlock),
4042
+ timestamp: raw.startBlock !== 0n ? startTs : 0
4043
+ },
4044
+ weights: raw.weights.map((weight) => ({
4045
+ receiver: weight.receiver,
4046
+ percentage: Number(weight.percentageNumerator) / 1e4
4047
+ }))
4048
+ };
4049
+ }
4050
+ function isSameRewardAllocation(a, b) {
4051
+ return a.start.blockNumber === b.start.blockNumber && a.weights.every(
4052
+ (weight, index) => weight.percentage === b.weights[index].percentage
4053
+ );
4054
+ }
4055
+ async function getValidatorRewardAllocation({
4056
+ client,
4057
+ pubKey,
4058
+ ...args
4059
+ }) {
4060
+ const { config } = parseBaseArgs(args);
4061
+ try {
4062
+ const [rawActiveRewardAllocation, rawSetRewardAllocation] = await Promise.all([
4063
+ client.readContract({
4064
+ address: config.pol.beraChef,
4065
+ abi: beraChefAbi,
4066
+ functionName: "getActiveRewardAllocation",
4067
+ args: [pubKey]
4068
+ }),
4069
+ client.readContract({
4070
+ address: config.pol.beraChef,
4071
+ abi: beraChefAbi,
4072
+ functionName: "getSetActiveRewardAllocation",
4073
+ args: [pubKey]
4074
+ })
4075
+ ]);
4076
+ const [lastRaUpdateActive, lastRaUpdateSet] = await Promise.all([
4077
+ rawActiveRewardAllocation.startBlock !== 0n ? client.getBlock({
4078
+ blockNumber: BigInt(rawActiveRewardAllocation.startBlock)
4079
+ }) : { timestamp: 0 },
4080
+ rawSetRewardAllocation.startBlock !== 0n ? client.getBlock({
4081
+ blockNumber: BigInt(rawSetRewardAllocation.startBlock)
4082
+ }) : { timestamp: 0 }
4083
+ ]);
4084
+ const activeRewardAllocation = formatValidatorRewardAllocation(
4085
+ rawActiveRewardAllocation,
4086
+ Number(lastRaUpdateActive.timestamp)
4087
+ );
4088
+ const setRewardAllocation = formatValidatorRewardAllocation(
4089
+ rawSetRewardAllocation,
4090
+ Number(lastRaUpdateSet.timestamp)
4091
+ );
4092
+ let isBaseline = false;
4093
+ if (setRewardAllocation.start.blockNumber === 0) {
4094
+ isBaseline = true;
4095
+ } else {
4096
+ isBaseline = !isSameRewardAllocation(
4097
+ setRewardAllocation,
4098
+ activeRewardAllocation
4099
+ );
4100
+ }
4101
+ return {
4102
+ activeRewardAllocation,
4103
+ setRewardAllocation,
4104
+ isBaseline,
4105
+ isNeverSet: setRewardAllocation?.start.blockNumber === 0
4106
+ };
4107
+ } catch (e) {
4108
+ console.log("getValidatorRewardAllocation:", e);
4109
+ throw e;
4110
+ }
4111
+ }
4112
+
4113
+ // src/actions/validators/getDefaultRewardAllocation.ts
4114
+ import { beraChefAbi as beraChefAbi2 } from "@berachain/abis/pol/rewards/beraChef";
4115
+ function isDefaultRewardAllocation(rewardAllocation) {
4116
+ return rewardAllocation.start.blockNumber === 0;
4117
+ }
4118
+ async function getDefaultRewardAllocation({
4119
+ client,
4120
+ ...args
4121
+ }) {
4122
+ const { config } = parseBaseArgs(args);
4123
+ const rawDefaultRewardAllocation = await client.readContract({
4124
+ address: config.pol.beraChef,
4125
+ abi: beraChefAbi2,
4126
+ functionName: "getDefaultRewardAllocation",
4127
+ args: []
4128
+ });
4129
+ return formatValidatorRewardAllocation(
4130
+ { ...rawDefaultRewardAllocation, startBlock: 0n },
4131
+ 0
4132
+ );
4133
+ }
4134
+
4135
+ // src/actions/validators/getStakingPoolBatch.ts
4136
+ async function getStakingPoolBatch({
4137
+ client,
4138
+ valPubKey
4139
+ }) {
4140
+ return 5614;
4141
+ }
4142
+
4143
+ // src/actions/validators/getUserBoostsOnValidator.ts
4144
+ import { formatEther as formatEther6 } from "viem";
4145
+ import { bgtAbi as bgtAbi2 } from "@berachain/abis/pol/bgt";
4146
+ async function getUserBoostsOnValidator({
4147
+ account,
4148
+ pubkey,
4149
+ publicClient,
4150
+ ...args
4151
+ }) {
4152
+ const { config } = parseBaseArgs(args);
4153
+ if (!account) {
4154
+ throw new Error("account is required");
4155
+ }
4156
+ if (!publicClient) {
4157
+ throw new Error("publicClient is required");
4158
+ }
4159
+ const [activeBoostAmount, queuedBoostAmount, queuedDropBoostAmount] = await Promise.all([
4160
+ publicClient.readContract({
4161
+ address: config.tokens.bgt,
4162
+ abi: bgtAbi2,
4163
+ functionName: "boosted",
4164
+ args: [account, pubkey]
4165
+ }),
4166
+ publicClient.readContract({
4167
+ address: config.tokens.bgt,
4168
+ abi: bgtAbi2,
4169
+ functionName: "boostedQueue",
4170
+ args: [account, pubkey]
4171
+ }),
4172
+ publicClient.readContract({
4173
+ address: config.tokens.bgt,
4174
+ abi: bgtAbi2,
4175
+ functionName: "dropBoostQueue",
4176
+ args: [account, pubkey]
4177
+ })
4178
+ ]);
4179
+ const droppableBoostAmount = activeBoostAmount - queuedDropBoostAmount[1];
4180
+ return {
4181
+ pubkey,
4182
+ droppableBoostAmount: formatEther6(droppableBoostAmount),
4183
+ activeBoostAmount: formatEther6(activeBoostAmount),
4184
+ queuedBoostAmount: formatEther6(queuedBoostAmount[1]),
4185
+ queuedDropBoostAmount: formatEther6(queuedDropBoostAmount[1]),
4186
+ queuedBoostStartBlock: queuedBoostAmount[0],
4187
+ queuedDropBoostStartBlock: queuedDropBoostAmount[0],
4188
+ hasPendingBoosts: queuedBoostAmount[1] > 0n || queuedDropBoostAmount[1] > 0n,
4189
+ hasActiveBoosts: activeBoostAmount > 0n,
4190
+ hasDroppableBoosts: droppableBoostAmount > 0n
4191
+ };
4192
+ }
4193
+
4194
+ // src/actions/validators/getUserActiveValidators.ts
4195
+ import { formatEther as formatEther7, parseEther as parseEther4 } from "viem";
4196
+
4197
+ // src/actions/validators/getUserBoosts.ts
4198
+ import {
4199
+ GetUserValidatorInformation
4200
+ } from "@berachain/graphql/pol/api";
4201
+ async function getUserBoosts({
4202
+ account,
4203
+ ...args
4204
+ }) {
4205
+ const { config } = parseBaseArgs(args);
4206
+ const apiClient = getApolloClient("api", args);
4207
+ return apiClient.query({
4208
+ query: GetUserValidatorInformation,
4209
+ variables: {
4210
+ address: account.toLowerCase(),
4211
+ chain: config.bex.chainName
4212
+ }
4213
+ });
4214
+ }
4215
+
4216
+ // src/actions/validators/getUserActiveValidators.ts
4217
+ async function getUserActiveValidators({
4218
+ account,
4219
+ publicClient,
4220
+ chain,
4221
+ ...args
4222
+ }) {
4223
+ const { config } = parseBaseArgs(args);
4224
+ const resolvedChain = chain ?? config.bex.chainName;
4225
+ const userBoosts = await getUserBoosts({ account });
4226
+ const [validatorInfoList, onChainBoosts] = await Promise.all([
4227
+ getAllValidators({
4228
+ variables: {
4229
+ chain: resolvedChain,
4230
+ where: {
4231
+ idIn: userBoosts.data.polGetValidatorBoosts.boosts.map(
4232
+ (t) => t.validatorId
4233
+ )
4234
+ }
4235
+ }
4236
+ }),
4237
+ Promise.all(
4238
+ userBoosts.data.polGetValidatorBoosts.boosts.filter(
4239
+ (t) => (
4240
+ // there's an edge case here where api doesn't return the pubkey
4241
+ // because the user might have boosted a pubkey that doesn't exist
4242
+ // api doesn't return the pubkey in this case, but we're choosing to filter them out
4243
+ !!t.validator
4244
+ )
4245
+ ).map(
4246
+ (t) => getUserBoostsOnValidator({
4247
+ account,
4248
+ pubkey: t.validator.pubkey,
4249
+ publicClient
4250
+ })
4251
+ )
4252
+ )
4253
+ ]);
4254
+ return validatorInfoList?.validators.validators.map((validator) => {
4255
+ const userDeposited = onChainBoosts.find(
4256
+ (data) => data.pubkey.toLowerCase() === validator.pubkey.toLowerCase()
4257
+ );
4258
+ if (!userDeposited) {
4259
+ throw new Error("User deposited not found");
4260
+ }
4261
+ const droppableBoostAmount = parseEther4(userDeposited?.activeBoostAmount ?? "0") - parseEther4(userDeposited?.queuedDropBoostAmount);
4262
+ return {
4263
+ ...validator,
4264
+ userBoosts: {
4265
+ pubkey: userDeposited.pubkey,
4266
+ activeBoostAmount: userDeposited?.activeBoostAmount,
4267
+ queuedBoostAmount: userDeposited?.queuedBoostAmount,
4268
+ queuedBoostStartBlock: Number(userDeposited?.queuedBoostStartBlock),
4269
+ queuedDropBoostAmount: userDeposited?.queuedDropBoostAmount,
4270
+ queuedDropBoostStartBlock: Number(
4271
+ userDeposited?.queuedDropBoostStartBlock
4272
+ ),
4273
+ droppableBoostAmount: formatEther7(droppableBoostAmount),
4274
+ hasPendingBoosts: Number(userDeposited?.queuedBoostAmount) > 0 || Number(userDeposited?.queuedDropBoostAmount) > 0,
4275
+ hasActiveBoosts: Number(userDeposited?.activeBoostAmount) > 0,
4276
+ hasDroppableBoosts: droppableBoostAmount > 0n
4277
+ }
4278
+ };
4279
+ });
4280
+ }
4281
+
4282
+ // src/actions/validators/getUserStakingPositions.ts
4283
+ var snowTestWalletPositions = [
4284
+ {
4285
+ validatorAddress: "0x8f51e63d9921a461be29e73dca1c2385e1adc5943fbb36ded4ba96025ee8a783184d1118da08171f6ea831153c878a6d",
4286
+ earning: 0.045,
4287
+ staked: {
4288
+ amount: 16114000000000000000n,
4289
+ formattedAmount: "161.14"
4290
+ },
4291
+ rewards: {
4292
+ amount: 15214000000000000000n,
4293
+ formattedAmount: "152.14"
4294
+ }
4295
+ },
4296
+ {
4297
+ staked: {
4298
+ amount: 141514000000000000000n,
4299
+ formattedAmount: "1415.14"
4300
+ },
4301
+ validatorAddress: "0x97b21253b17f4e814fe7505c15c18e68c85ab2477274ad370a762df50e3eb4cb1a48451e089bc22e158d7448549a8ab9",
4302
+ earning: 0.045,
4303
+ rewards: {
4304
+ amount: 15414000000000000000n,
4305
+ formattedAmount: "154.14"
4306
+ },
4307
+ queueData: {
4308
+ stake: [
4309
+ {
4310
+ amount: 16159000000000000000n,
4311
+ formattedAmount: "161.59"
4312
+ }
4313
+ ],
4314
+ unstake: [
4315
+ {
4316
+ amount: 16159000000000000000n,
4317
+ formattedAmount: "161.59",
4318
+ timestamp: msToSeconds(Date.now() - 72e6)
4319
+ }
4320
+ ]
4321
+ }
4322
+ },
4323
+ {
4324
+ staked: {
4325
+ amount: 141514000000000000000n,
4326
+ formattedAmount: "1415.14"
4327
+ },
4328
+ validatorAddress: "0xa2705d6b27891f3f5651f26547d1bb79e256f95f249d1ad717cef087d77d38b037e5d6dbaa2538930fd0731ec9b02f3a",
4329
+ earning: 0.145,
4330
+ rewards: {
4331
+ amount: 15414000000000000000n,
4332
+ formattedAmount: "154.14"
4333
+ },
4334
+ queueData: {
4335
+ unstake: [
4336
+ {
4337
+ amount: 16159000000000000000n,
4338
+ formattedAmount: "161.59",
4339
+ timestamp: msToSeconds(Date.now() - 72e6)
4340
+ }
4341
+ ]
4342
+ }
4343
+ },
4344
+ {
4345
+ staked: {
4346
+ amount: 141514000000000000000n,
4347
+ formattedAmount: "1415.14"
4348
+ },
4349
+ validatorAddress: "0xa2705d6b27891f3f5651f26547d1bb79e256f95f249d1ad717cef087d77d38b037e5d6dbaa2538930fd0731ec9b02f3a",
4350
+ earning: 0.145,
4351
+ rewards: {
4352
+ amount: 15414000000000000000n,
4353
+ formattedAmount: "154.14"
4354
+ },
4355
+ queueData: {
4356
+ unstake: [
4357
+ {
4358
+ amount: 16159000000000000000n,
4359
+ formattedAmount: "161.59",
4360
+ timestamp: msToSeconds(Date.now() - 72e6)
4361
+ }
4362
+ ]
4363
+ }
4364
+ },
4365
+ {
4366
+ staked: {
4367
+ amount: 141514000000000000000n,
4368
+ formattedAmount: "1415.14"
4369
+ },
4370
+ validatorAddress: "0xa2705d6b27891f3f5651f26547d1bb79e256f95f249d1ad717cef087d77d38b037e5d6dbaa2538930fd0731ec9b02f3a",
4371
+ earning: 0.145,
4372
+ rewards: {
4373
+ amount: 15414000000000000000n,
4374
+ formattedAmount: "154.14"
4375
+ },
4376
+ queueData: {
4377
+ unstake: [
4378
+ {
4379
+ amount: 16159000000000000000n,
4380
+ formattedAmount: "161.59",
4381
+ timestamp: msToSeconds(Date.now() - 72e6)
4382
+ }
4383
+ ]
4384
+ }
4385
+ },
4386
+ {
4387
+ staked: {
4388
+ amount: 141514000000000000000n,
4389
+ formattedAmount: "1415.14"
4390
+ },
4391
+ validatorAddress: "0xa2705d6b27891f3f5651f26547d1bb79e256f95f249d1ad717cef087d77d38b037e5d6dbaa2538930fd0731ec9b02f3a",
4392
+ earning: 0.145,
4393
+ rewards: {
4394
+ amount: 15414000000000000000n,
4395
+ formattedAmount: "154.14"
4396
+ },
4397
+ queueData: {
4398
+ unstake: [
4399
+ {
4400
+ amount: 16159000000000000000n,
4401
+ formattedAmount: "161.59",
4402
+ timestamp: msToSeconds(Date.now() - 72e6)
4403
+ }
4404
+ ]
4405
+ }
4406
+ },
4407
+ {
4408
+ staked: {
4409
+ amount: 141514000000000000000n,
4410
+ formattedAmount: "1415.14"
4411
+ },
4412
+ validatorAddress: "0xa2705d6b27891f3f5651f26547d1bb79e256f95f249d1ad717cef087d77d38b037e5d6dbaa2538930fd0731ec9b02f3a",
4413
+ earning: 0.145,
4414
+ rewards: {
4415
+ amount: 15414000000000000000n,
4416
+ formattedAmount: "154.14"
4417
+ },
4418
+ queueData: {
4419
+ unstake: [
4420
+ {
4421
+ amount: 16159000000000000000n,
4422
+ formattedAmount: "161.59",
4423
+ timestamp: msToSeconds(Date.now() - 72e6)
4424
+ }
4425
+ ]
4426
+ }
4427
+ },
4428
+ {
4429
+ staked: {
4430
+ amount: 241514000000000000000n,
4431
+ formattedAmount: "2415.14"
4432
+ },
4433
+ validatorAddress: "0xa4e4b63514f54d61da5197359f11ff1fc2930788ba2ffdd30c2fc059cbe0221020197bf9446b16ac347f36c7517a8686",
4434
+ earning: 0.145,
4435
+ rewards: {
4436
+ amount: 15414000000000000000n,
4437
+ formattedAmount: "154.14"
4438
+ },
4439
+ queueData: {
4440
+ unstake: [
4441
+ {
4442
+ amount: 1159000000000000000n,
4443
+ formattedAmount: "11.59",
4444
+ timestamp: msToSeconds(Date.now() - 36e6)
4445
+ }
4446
+ ]
4447
+ }
4448
+ },
4449
+ {
4450
+ validatorAddress: "0xb0511ec039591e98bd4e183ba70b85572214a7ad8ca1a43e96ad3495d3821054927bc542e5482ec9733e35b7ef0b1f03",
4451
+ earning: 0.045,
4452
+ staked: {
4453
+ amount: 141514000000000000000n,
4454
+ formattedAmount: "1415.14"
4455
+ },
4456
+ rewards: {
4457
+ amount: 15414000000000000000n,
4458
+ formattedAmount: "154.14"
4459
+ },
4460
+ queueData: {
4461
+ stake: [
4462
+ {
4463
+ amount: 1159000000000000000n,
4464
+ formattedAmount: "11.59"
4465
+ }
4466
+ ]
4467
+ }
4468
+ }
4469
+ ];
4470
+ async function getUserStakingPositions(account) {
4471
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
4472
+ if (account === "0x4C368fFE3650379d6318C8d4630bc51f8Ad12bB6") {
4473
+ return snowTestWalletPositions;
4474
+ }
4475
+ return [];
4476
+ }
4477
+
4478
+ // src/actions/validators/getValidatorAnalytics.ts
4479
+ import {
4480
+ GetValidatorAnalytics
4481
+ } from "@berachain/graphql/pol/subgraph";
4482
+ async function getValidatorAnalytics({
4483
+ pubkey,
4484
+ dayRange,
4485
+ ...args
4486
+ }) {
4487
+ const bgtClient = getApolloClient("pol.subgraph", args);
4488
+ const result = await bgtClient.query({
4489
+ query: GetValidatorAnalytics,
4490
+ variables: {
4491
+ pubKey: pubkey,
4492
+ timestamp: calculateTimestampFromDays(dayRange).toString()
4493
+ }
4494
+ });
4495
+ return result.data;
4496
+ }
4497
+
4498
+ // src/actions/validators/getValidatorCommission.ts
4499
+ import { beraChefAbi as beraChefAbi3 } from "@berachain/abis/pol/rewards/beraChef";
4500
+ async function getValidatorCommission({
4501
+ client,
4502
+ pubKey,
4503
+ ...args
4504
+ }) {
4505
+ const { config } = parseBaseArgs(args);
4506
+ const result = await client.readContract({
4507
+ address: config.pol.beraChef,
4508
+ abi: beraChefAbi3,
4509
+ functionName: "getValCommissionOnIncentiveTokens",
4510
+ args: [pubKey]
4511
+ });
4512
+ return Number(result ?? 0n) / 1e4;
4513
+ }
4514
+
4515
+ // src/actions/validators/getValidatorEstimatedBgtPerYear.ts
4516
+ var getValidatorEstimatedBgtPerYear = (validator, totalStakedBeraAmount, blockTime) => {
4517
+ if (!totalStakedBeraAmount || !validator) return 0;
4518
+ const estimatedBlocksPerYear = yearsInSeconds(1) / blockTime;
4519
+ const estimatedValidatorBlocksPerYear = totalStakedBeraAmount ? estimatedBlocksPerYear * (Number(validator.dynamicData?.stakedBeraAmount) / totalStakedBeraAmount) : 0;
4520
+ return estimatedValidatorBlocksPerYear * Number.parseFloat(validator.dynamicData?.rewardRate ?? "0");
4521
+ };
4522
+
4523
+ // src/actions/validators/getValidatorOperatorAddress.ts
4524
+ import { beaconDepositAbi } from "@berachain/abis/pol/beaconDeposit";
4525
+ async function getValidatorOperatorAddress({
4526
+ client,
4527
+ pubKey,
4528
+ ...args
4529
+ }) {
4530
+ const { config } = parseBaseArgs(args);
4531
+ try {
4532
+ const result = await client.readContract({
4533
+ address: config.depositContract,
4534
+ abi: beaconDepositAbi,
4535
+ functionName: "getOperator",
4536
+ args: [pubKey]
4537
+ });
4538
+ return result;
4539
+ } catch (e) {
4540
+ console.log("getValidatorOperatorAddress:", e);
4541
+ throw e;
4542
+ }
4543
+ }
4544
+
4545
+ // src/actions/validators/getValidatorQueuedCommission.ts
4546
+ import { beraChefAbi as beraChefAbi4 } from "@berachain/abis/pol/rewards/beraChef";
4547
+ async function getValidatorQueuedCommission({
4548
+ client,
4549
+ pubKey,
4550
+ ...args
4551
+ }) {
4552
+ const { config } = parseBaseArgs(args);
4553
+ const result = await client.readContract({
4554
+ address: config.pol.beraChef,
4555
+ abi: beraChefAbi4,
4556
+ functionName: "getValQueuedCommissionOnIncentiveTokens",
4557
+ args: [pubKey]
4558
+ });
4559
+ return {
4560
+ blockNumberLast: result.blockNumberLast,
4561
+ commissionRate: Number(result.commissionRate) / 1e4
4562
+ };
4563
+ }
4564
+
4565
+ // src/actions/validators/getValidatorQueuedOperatorAddress.ts
4566
+ import { beaconDepositAbi as beaconDepositAbi2 } from "@berachain/abis/pol/beaconDeposit";
4567
+ async function getValidatorQueuedOperatorAddress({
4568
+ client,
4569
+ pubKey,
4570
+ ...args
4571
+ }) {
4572
+ const { config } = parseBaseArgs(args);
4573
+ try {
4574
+ const result = await client.readContract({
4575
+ address: config.depositContract,
4576
+ abi: beaconDepositAbi2,
4577
+ functionName: "queuedOperator",
4578
+ args: [pubKey]
4579
+ });
4580
+ return result;
4581
+ } catch (e) {
4582
+ console.log("getValidatorQueuedOperatorAddress:", e);
4583
+ throw e;
4584
+ }
4585
+ }
4586
+
4587
+ // src/actions/validators/getValidatorQueuedRewardAllocation.ts
4588
+ import { beraChefAbi as beraChefAbi5 } from "@berachain/abis/pol/rewards/beraChef";
4589
+ async function getValidatorQueuedRewardAllocation({
4590
+ client,
4591
+ pubKey,
4592
+ ...args
4593
+ }) {
4594
+ const { config } = parseBaseArgs(args);
4595
+ try {
4596
+ const result = await client.readContract({
4597
+ address: config.pol.beraChef,
4598
+ abi: beraChefAbi5,
4599
+ functionName: "getQueuedRewardAllocation",
4600
+ args: [pubKey]
4601
+ });
4602
+ return formatValidatorRewardAllocation(result, 0);
4603
+ } catch (e) {
4604
+ console.log("getValidatorQueuedRewardAllocation:", e);
4605
+ throw e;
4606
+ }
4607
+ }
4608
+
4609
+ export {
4610
+ getConvertToAssets,
4611
+ BeraApolloClient,
4612
+ getApolloClient,
4613
+ gql,
4614
+ BaseAggregator,
4615
+ BalancerApi,
4616
+ getAllPools,
4617
+ getApiPool,
4618
+ getGlobalLiquidityAndSwapVolume,
4619
+ getPoolPausedState,
4620
+ getOnChainPool,
4621
+ getPoolEvents,
4622
+ getPoolHistoricalData,
4623
+ checkProposalField,
4624
+ MOCKED_PROPOSAL_STATUSES,
4625
+ computeActualStatus,
4626
+ getAllProposals,
4627
+ getBodyErrors,
4628
+ getProposalDetails,
4629
+ parseProposalBody,
4630
+ getProposalFromTx,
4631
+ getProposalVotes,
4632
+ getChartData,
4633
+ getCollateralWeights,
4634
+ getTokenInformation,
4635
+ getHoneyCollaterals,
4636
+ isBadCollateralAsset,
4637
+ getGlobalCapLimit,
4638
+ getHoneyGlobalData,
4639
+ HoneyPreviewMethod,
4640
+ getHoneyPreview,
4641
+ getHoneyVaultsBalance,
4642
+ getPythLatestPrices,
4643
+ getRelativeCapLimit,
4644
+ getPythUpdateFee,
4645
+ getSwapPayload,
4646
+ isBasketModeEnabled,
4647
+ getBlockTimestamp,
4648
+ RewardVaultDistributionMode,
4649
+ getRewardVaultRewards,
4650
+ getBgtAprSimulation,
4651
+ getEarnedStakedBeraVault,
4652
+ getRewardVaults,
4653
+ getGlobalData,
4654
+ getIncentiveFeeClaimStats,
4655
+ getMarkets,
4656
+ getRewardProofsByValidator,
4657
+ getRewardTokenToBeraRate,
4658
+ getRewardVault,
4659
+ getRewardVaultIncentives,
4660
+ getRewardVaultStakingToken,
4661
+ getStakedBeraAPR,
4662
+ getStakedBeraSnapshots,
4663
+ getStakeWithdrawalCooldown,
4664
+ getSWBeraVaultMetadata,
4665
+ getSWBeraWithdrawal,
4666
+ getTotalStakedAmount,
4667
+ getUserClaimableIncentives,
4668
+ getUserVaultsReward,
4669
+ getUserVaultInfo,
4670
+ getUserVaults,
4671
+ getVaultHistory,
4672
+ getVaultValidators,
4673
+ getTokenCurrentPrices,
4674
+ getAllowances,
4675
+ isImpersonateAccount,
4676
+ beraWriteContract,
4677
+ getAllValidators,
4678
+ getApiEnrichedAllocation,
4679
+ getApiValidator,
4680
+ getDailyValidatorBlockStats,
4681
+ formatValidatorRewardAllocation,
4682
+ isSameRewardAllocation,
4683
+ getValidatorRewardAllocation,
4684
+ isDefaultRewardAllocation,
4685
+ getDefaultRewardAllocation,
4686
+ getStakingPoolBatch,
4687
+ getUserBoostsOnValidator,
4688
+ getUserActiveValidators,
4689
+ getUserStakingPositions,
4690
+ getValidatorAnalytics,
4691
+ getValidatorCommission,
4692
+ getValidatorEstimatedBgtPerYear,
4693
+ getValidatorOperatorAddress,
4694
+ getValidatorQueuedCommission,
4695
+ getValidatorQueuedOperatorAddress,
4696
+ getValidatorQueuedRewardAllocation
4697
+ };
4698
+ //# sourceMappingURL=chunk-2R73G2PO.mjs.map