@berachain/berajs 0.2.9 → 0.2.11

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 (182) hide show
  1. package/dist/{HoneyConfigProvider-Dkj-_a5x.d.ts → HoneyConfigProvider-COOuDNra.d.ts} +1 -1
  2. package/dist/actions/clients/exports.d.ts +77 -1
  3. package/dist/actions/clients/exports.mjs +13 -4
  4. package/dist/actions/exports.d.ts +121 -39
  5. package/dist/actions/exports.mjs +75 -34
  6. package/dist/actions/governance/exports.d.ts +3 -11
  7. package/dist/actions/governance/exports.mjs +3 -3
  8. package/dist/actions/server/exports.mjs +4 -4
  9. package/dist/{chunk-4Z4AK6SH.mjs → chunk-3JJLQ2JX.mjs} +3 -3
  10. package/dist/{chunk-EXIUPSFN.mjs → chunk-7YVNSDXG.mjs} +2 -2
  11. package/dist/{chunk-WXXOISTU.mjs → chunk-AUOPN6NK.mjs} +1 -1
  12. package/dist/{chunk-75M6TF7M.mjs → chunk-DQRH5VE3.mjs} +1 -1
  13. package/dist/{chunk-CDFWPU2R.mjs → chunk-E7YFXBBQ.mjs} +0 -124
  14. package/dist/{chunk-AFN4CVD3.mjs → chunk-GUURQAME.mjs} +1 -1
  15. package/dist/{chunk-KQUMKB66.mjs → chunk-GY6B3PD5.mjs} +1 -1
  16. package/dist/{chunk-HSSJKHZ4.mjs → chunk-HYDP32P6.mjs} +3 -3
  17. package/dist/{chunk-NPBQLVL3.mjs → chunk-IXIBY5FP.mjs} +2 -2
  18. package/dist/{chunk-J5I45WGQ.mjs → chunk-KHXJDYA4.mjs} +7 -0
  19. package/dist/chunk-MRQGHXAN.mjs +54 -0
  20. package/dist/{chunk-FFB5LFDW.mjs → chunk-QVHEM4BG.mjs} +2 -2
  21. package/dist/{chunk-3EARVV7K.mjs → chunk-SXUNCX5E.mjs} +22 -9
  22. package/dist/chunk-UD5IUNCW.mjs +34 -0
  23. package/dist/{chunk-QJIXTYTZ.mjs → chunk-VAA2FVPP.mjs} +162 -41
  24. package/dist/chunk-Y6THHG77.mjs +126 -0
  25. package/dist/{chunk-XIYN6AL6.mjs → chunk-ZLTMIFCZ.mjs} +10 -5
  26. package/dist/contexts/exports.d.ts +2 -2
  27. package/dist/contexts/exports.mjs +11 -9
  28. package/dist/enum/exports.d.ts +8 -2
  29. package/dist/errors/exports.mjs +5 -5
  30. package/dist/getProposalVotes-DAUrdX2n.d.ts +12 -0
  31. package/dist/{getValidatorQueuedOperatorAddress-Dw5KN5sh.d.ts → getValidatorQueuedOperatorAddress-Cxt-DlL_.d.ts} +2 -2
  32. package/dist/{global.d-BuGDKh4k.d.ts → global.d-q_LQWQqs.d.ts} +2 -4
  33. package/dist/hooks/exports.d.ts +114 -164
  34. package/dist/hooks/exports.mjs +535 -522
  35. package/dist/hooks/governance/exports.d.ts +20 -15
  36. package/dist/hooks/governance/exports.mjs +43 -41
  37. package/dist/{pol.d-CqPA9K6m.d.ts → pol.d-CeRgXBL8.d.ts} +33 -8
  38. package/dist/types/exports.d.ts +5 -5
  39. package/dist/{useHoneySwapState-vFmuFF0g.d.ts → useHoneySwapState-twi7NTaO.d.ts} +1 -1
  40. package/dist/utils/exports.d.ts +2 -2
  41. package/dist/utils/exports.mjs +15 -9
  42. package/package.json +9 -8
  43. package/src/actions/bend/getMaxDeposit.ts +28 -2
  44. package/src/actions/clients/exports.ts +3 -0
  45. package/src/actions/clients/fetchBeep.ts +34 -0
  46. package/src/actions/clients/fetchOpenApi.ts +97 -0
  47. package/src/actions/clients/fetchOpenApi.unit.test.ts +245 -0
  48. package/src/actions/clients/fetchRailwayBackend.ts +34 -0
  49. package/src/actions/enso/getEnsoUserTokensWithBalances.ts +18 -0
  50. package/src/actions/exports.ts +2 -0
  51. package/src/actions/honey/getChartData.ts +53 -12
  52. package/src/actions/honey/getHoney24hVolume.ts +34 -6
  53. package/src/actions/honey/getHoneyTxns.ts +93 -0
  54. package/src/actions/honey/getPythLatestPrices.ts +7 -0
  55. package/src/actions/pol/__tests__/rewardVaults.integration.test.ts +1 -1
  56. package/src/actions/pol/getAutoclaimedIncentives.ts +21 -10
  57. package/src/actions/pol/getAutoclaimedIncentivesTxHash.ts +41 -0
  58. package/src/actions/pol/getBgtIncentiveDistributorPaused.ts +5 -12
  59. package/src/actions/pol/getEarnedStakedBeraVault.ts +20 -16
  60. package/src/actions/pol/getRewardVaults.ts +4 -4
  61. package/src/actions/pol/getStakingDailyAssets.ts +18 -14
  62. package/src/actions/validators/getValidatorIncentiveDistribution.ts +64 -12
  63. package/src/actions/validators/utils/getValidatorBoostApy.ts +1 -1
  64. package/src/contexts/SwrFallback.tsx +2 -1
  65. package/src/data/contracts.ts +4 -0
  66. package/src/errors/RequestError.ts +12 -3
  67. package/src/errors/RequestError.unit.test.ts +55 -0
  68. package/src/errors/errorMap.ts +8 -0
  69. package/src/errors/getRevertReason.integration.test.ts +5 -1
  70. package/src/hooks/bend/useGetConvertToAssets.ts +2 -3
  71. package/src/hooks/dex/useAggregatorsQuotes.ts +10 -10
  72. package/src/hooks/dex/useAggregatorsRouterFeeBps.ts +1 -1
  73. package/src/hooks/dex/useAllUserPools.ts +7 -5
  74. package/src/hooks/dex/useApiPool.ts +1 -1
  75. package/src/hooks/dex/useGlobalLiquidityAndSwapVolume.ts +1 -1
  76. package/src/hooks/dex/useOnChainPoolData.ts +1 -1
  77. package/src/hooks/dex/usePollPoolCreationRelayerApproval.ts +2 -2
  78. package/src/hooks/dex/usePoolEvents.ts +1 -2
  79. package/src/hooks/dex/usePoolHistoricalData.ts +2 -3
  80. package/src/hooks/dex/usePools.ts +4 -2
  81. package/src/hooks/dex/useSingleAggregatorQuote.ts +6 -18
  82. package/src/hooks/enso/useBendDemultiply.ts +3 -4
  83. package/src/hooks/enso/useBendMultiply.ts +3 -4
  84. package/src/hooks/enso/useBendZapSupply.ts +3 -4
  85. package/src/hooks/enso/useEnsoSwapBundle.ts +1 -1
  86. package/src/hooks/enso/useEnsoUserTokensWithBalances.ts +3 -5
  87. package/src/hooks/enso/useEnsoWalletV2Address.ts +1 -1
  88. package/src/hooks/enso/useIsBendAuthorized.ts +1 -1
  89. package/src/hooks/enso/useZapStakeBera.ts +2 -2
  90. package/src/hooks/exports.ts +2 -0
  91. package/src/hooks/governance/useGetPastVotes.ts +1 -1
  92. package/src/hooks/governance/useHasVoted.ts +1 -1
  93. package/src/hooks/governance/useIsCanceller.ts +1 -1
  94. package/src/hooks/governance/usePollAllProposals.ts +13 -12
  95. package/src/hooks/governance/usePollProposal.ts +3 -3
  96. package/src/hooks/governance/usePollProposalThreshold.ts +1 -1
  97. package/src/hooks/governance/usePollProposalVotes.ts +23 -5
  98. package/src/hooks/governance/usePollUserDelegates.ts +3 -3
  99. package/src/hooks/governance/useProposalFromTx.ts +2 -1
  100. package/src/hooks/governance/useProposalSnapshot.ts +2 -3
  101. package/src/hooks/governance/useProposalState.ts +2 -2
  102. package/src/hooks/governance/useProposalTimelockState.ts +2 -1
  103. package/src/hooks/governance/useQuorum.ts +1 -2
  104. package/src/hooks/honey/useCappedGlobally.ts +3 -6
  105. package/src/hooks/honey/useCappedRelatively.ts +2 -2
  106. package/src/hooks/honey/useCollateralWeights.ts +3 -3
  107. package/src/hooks/honey/useHoney24hVolume.ts +1 -1
  108. package/src/hooks/honey/useHoneyBalances.ts +1 -1
  109. package/src/hooks/honey/useHoneyChartData.ts +1 -1
  110. package/src/hooks/honey/useHoneyVaultsBalance.ts +2 -3
  111. package/src/hooks/honey/useIsBadCollateralAsset.ts +4 -7
  112. package/src/hooks/honey/useIsBasketModeEnabled.ts +4 -7
  113. package/src/hooks/honey/usePythLatestPrices.ts +13 -9
  114. package/src/hooks/perps/usePythUpdateFee.ts +13 -11
  115. package/src/hooks/pol/useAutoclaimedIncentives.ts +2 -12
  116. package/src/hooks/pol/useAutoclaimedIncentivesTxHash.ts +44 -0
  117. package/src/hooks/pol/useBgtIncentiveDistributorPaused.ts +39 -0
  118. package/src/hooks/pol/useBgtUnstakedBalance.ts +2 -2
  119. package/src/hooks/pol/useClaimableFees.ts +1 -1
  120. package/src/hooks/pol/useHighestVaultsAPR.ts +4 -6
  121. package/src/hooks/pol/useOnChainRewardVault.ts +77 -72
  122. package/src/hooks/pol/usePollGlobalData.ts +2 -3
  123. package/src/hooks/pol/usePollMarkets.ts +2 -2
  124. package/src/hooks/pol/useQueuedBeraUnlock.ts +2 -2
  125. package/src/hooks/pol/useRewardTokenToBeraRate.ts +2 -2
  126. package/src/hooks/pol/useRewardVault.ts +7 -6
  127. package/src/hooks/pol/useRewardVaultBalanceFromStakingToken.ts +4 -4
  128. package/src/hooks/pol/useRewardVaultFromToken.ts +1 -1
  129. package/src/hooks/pol/useRewardVaultIncentives.ts +1 -1
  130. package/src/hooks/pol/useRewardVaultRewards.ts +2 -2
  131. package/src/hooks/pol/useRewardVaults.ts +3 -6
  132. package/src/hooks/pol/useStakedAPR.ts +1 -2
  133. package/src/hooks/pol/useStakedData.ts +90 -41
  134. package/src/hooks/pol/useStakedSnapshots.ts +1 -1
  135. package/src/hooks/pol/useStakingVaultsMetadata.ts +1 -1
  136. package/src/hooks/pol/useTotalStakedAmount.ts +1 -2
  137. package/src/hooks/pol/useUserVaultInfo.ts +2 -2
  138. package/src/hooks/pol/useUserVaults.ts +2 -3
  139. package/src/hooks/pol/useVaultAddress.ts +1 -1
  140. package/src/hooks/pol/useVaultHistory.ts +1 -2
  141. package/src/hooks/pol/useVaultValidators.ts +2 -2
  142. package/src/hooks/tokens/useMultipleTokenInformation.ts +2 -2
  143. package/src/hooks/tokens/usePollAllowances.ts +3 -4
  144. package/src/hooks/tokens/usePollBalance.ts +2 -2
  145. package/src/hooks/tokens/usePollWalletBalances.ts +2 -2
  146. package/src/hooks/tokens/useStakingTokenInformation.ts +2 -2
  147. package/src/hooks/tokens/useTokenCurrentPrices.ts +11 -13
  148. package/src/hooks/tokens/useTokenInformation.ts +2 -2
  149. package/src/hooks/tokens/useTokenPrice.ts +2 -1
  150. package/src/hooks/tokens/useTokenPrices.ts +3 -4
  151. package/src/hooks/tokens/useTotalSupply.ts +1 -1
  152. package/src/hooks/tokens/useUnderlyingAsset.ts +1 -2
  153. package/src/hooks/useBlockToTimestamp.ts +1 -2
  154. package/src/hooks/useGetVerifiedAbi.ts +2 -1
  155. package/src/hooks/validators/useAllValidators.ts +2 -3
  156. package/src/hooks/validators/useApiEnrichedAllocation.ts +1 -1
  157. package/src/hooks/validators/useApiValidator.ts +3 -6
  158. package/src/hooks/validators/useBaselineRewardAllocation.ts +1 -2
  159. package/src/hooks/validators/useDailyValidatorBlockStats.ts +1 -1
  160. package/src/hooks/validators/useDefaultRewardAllocation.ts +2 -3
  161. package/src/hooks/validators/useManagedValidatorRole.ts +2 -2
  162. package/src/hooks/validators/useOnChainValidator.ts +3 -3
  163. package/src/hooks/validators/useStakingPoolBatch.ts +3 -4
  164. package/src/hooks/validators/useUserActiveValidators.ts +2 -3
  165. package/src/hooks/validators/useUserBoostsOnValidator.ts +1 -1
  166. package/src/hooks/validators/useUserClaimableIncentives.ts +1 -1
  167. package/src/hooks/validators/useUserStakingPositions.ts +2 -1
  168. package/src/hooks/validators/useValidator.ts +4 -8
  169. package/src/hooks/validators/useValidatorAnalytics.ts +1 -1
  170. package/src/hooks/validators/useValidatorCommission.ts +2 -2
  171. package/src/hooks/validators/useValidatorIncentiveDistribution.ts +3 -3
  172. package/src/hooks/validators/useValidatorQueuedCommission.ts +2 -2
  173. package/src/hooks/validators/useValidatorQueuedOperatorAddress.ts +2 -2
  174. package/src/hooks/validators/useValidatorQueuedRewardAllocation.ts +2 -2
  175. package/src/hooks/validators/useValidatorRewardAllocation.ts +2 -2
  176. package/src/types/bribe-boost.d.ts +14 -3
  177. package/src/types/global.d.ts +3 -4
  178. package/src/types/pol.d.ts +17 -3
  179. package/src/utils/polyfillAbortSignalAny.ts +53 -0
  180. package/src/utils/polyfillAbortSignalAny.unit.test.ts +81 -0
  181. package/dist/polling-BKnyavLI.d.ts +0 -8
  182. /package/dist/{exports-BcUTGFUb.d.ts → getApolloClient-BcUTGFUb.d.ts} +0 -0
@@ -0,0 +1,93 @@
1
+ import type { HoneyTransactionsLatestResponse } from "@berachain/graphql/beep";
2
+ import type { GetHoneyTxnQuery } from "@berachain/graphql/honey";
3
+
4
+ import { BeraError } from "../../errors/BeraError";
5
+ import { beraFetchJson } from "../../utils/beraFetch";
6
+ import { parseBaseArgs } from "../../utils/parseBaseArgs";
7
+ import { fetchBeep } from "../clients/fetchBeep";
8
+
9
+ type HoneyTxn = HoneyTransactionsLatestResponse[number];
10
+ /** beep's transaction type discriminator (`"MINT" | "REDEEM"`). */
11
+ type HoneyTxnType = HoneyTxn["type"];
12
+
13
+ interface GetHoneyTxnsArgs {
14
+ /** Zero-based page index (the page size is applied internally). */
15
+ index: number;
16
+ /** Page size. */
17
+ limit: number;
18
+ /** Optional MINT/REDEEM filter; omit for all transactions. */
19
+ txnType?: HoneyTxnType;
20
+ }
21
+
22
+ /**
23
+ * Browser-only. Returns a page of honey transactions in the `beep` response
24
+ * shape (`HoneyTransactionsLatestResponse`) the transactions table consumes.
25
+ *
26
+ * Reads from the `beep` backend (`fetchBeep`) when configured, falling back to
27
+ * the legacy honey subgraph proxied through `/api/honey/txns` (whose GraphQL
28
+ * result is adapted into the beep shape) otherwise.
29
+ */
30
+ export async function getHoneyTxns({
31
+ index,
32
+ limit,
33
+ txnType,
34
+ }: GetHoneyTxnsArgs): Promise<HoneyTransactionsLatestResponse> {
35
+ if (typeof window === "undefined") {
36
+ throw new BeraError({
37
+ message:
38
+ "getHoneyTxns is browser-only; call from a Client Component / SWR hook",
39
+ level: "error",
40
+ });
41
+ }
42
+
43
+ const { config } = parseBaseArgs({});
44
+
45
+ // TODO(beep): remove this entire block once `beep` is deployed on every
46
+ // chain. It is the only legacy honey-subgraph code left here; deleting it
47
+ // leaves the `beep` path below as the sole implementation.
48
+ if (!config.beep) {
49
+ const params = new URLSearchParams({
50
+ skip: String(index * limit),
51
+ limit: String(limit),
52
+ });
53
+ if (txnType) params.set("type", txnType);
54
+
55
+ const txns = await beraFetchJson<GetHoneyTxnQuery["honeyTxns"]>({
56
+ url: `/api/honey/txns?${params}`,
57
+ name: "honey-txns",
58
+ type: "rest",
59
+ });
60
+ return txns.map(fromHoneyTxn);
61
+ }
62
+
63
+ // beep backend (next-gen), typed against `@berachain/graphql/beep`. Queried
64
+ // directly from the browser — no Vercel proxy. beep's `page` is 1-indexed and
65
+ // filters server-side by `type`; `fetchOpenApi` omits `type` when `txnType`
66
+ // is undefined (the "all" tab), so each tab paginates its own filtered feed.
67
+ return fetchBeep("/v0/honey/transactions/latest", {
68
+ query: { page: String(index + 1), perPage: String(limit), type: txnType },
69
+ });
70
+ }
71
+
72
+ /**
73
+ * Adapt a legacy subgraph transaction into the beep `HoneyTransactionsLatest`
74
+ * shape: nested `chainTransaction.txHash` → flat `txHash`, `collateral` →
75
+ * `collaterals` (`collateral`/`collateralAmount` → `address`/`amount`).
76
+ *
77
+ * The subgraph reports `timestamp` in seconds (matching beep), so it passes
78
+ * through as a number. A subgraph txn always carries a `type` in practice.
79
+ */
80
+ function fromHoneyTxn(txn: GetHoneyTxnQuery["honeyTxns"][number]): HoneyTxn {
81
+ return {
82
+ txHash: txn.chainTransaction.txHash,
83
+ type: (txn.type ?? "MINT") as HoneyTxnType,
84
+ collaterals: txn.collateral.map((collateral) => ({
85
+ address: collateral.collateral,
86
+ amount: collateral.collateralAmount,
87
+ })),
88
+ to: txn.to,
89
+ from: txn.from,
90
+ honeyAmount: txn.honeyAmount,
91
+ timestamp: Number(txn.timestamp),
92
+ };
93
+ }
@@ -1,8 +1,15 @@
1
1
  import { HermesClient } from "@pythnetwork/hermes-client";
2
2
  import { formatUnits } from "viem";
3
3
 
4
+ import { polyfillAbortSignalAny } from "../../utils/polyfillAbortSignalAny";
5
+
4
6
  const pythEndpoint = "https://hermes.pyth.network";
5
7
 
8
+ // @pythnetwork/hermes-client uses AbortSignal.any, which is missing on older
9
+ // browsers/WebViews (e.g. Chrome Mobile WebView 114). Install the polyfill
10
+ // before the client runs so getLatestPriceUpdates doesn't throw. See HONEY-188.
11
+ polyfillAbortSignalAny();
12
+
6
13
  /**
7
14
  * Interface representing the latest Pyth price updates
8
15
  * @interface PythLatestUpdates
@@ -25,7 +25,7 @@ describe("rewardVaults", async () => {
25
25
  it("should have consistent data", () => {
26
26
  const totalBgtCatpure = gaugeList.reduce(
27
27
  (acc, vault) =>
28
- acc + Number(vault.dynamicData?.bgtCapturePercentage ?? 0),
28
+ acc + Number(vault.dynamicData?.rewardCapturePercentage ?? 0),
29
29
  0,
30
30
  );
31
31
 
@@ -1,5 +1,6 @@
1
1
  import type { Address } from "viem";
2
2
 
3
+ import { RequestError } from "../../errors/RequestError";
3
4
  import type { AutoclaimedIncentivesResponse } from "../../types/bribe-boost";
4
5
  import { beraFetchJson } from "../../utils/beraFetch";
5
6
  import { parseBaseArgs } from "../../utils/parseBaseArgs";
@@ -8,6 +9,9 @@ import { parseBaseArgs } from "../../utils/parseBaseArgs";
8
9
  * Server-side function to fetch the incentives the bot autoclaimed on behalf
9
10
  * of a wallet during the BGT → BERA cutover. Only valid to call once the
10
11
  * bgtIncentiveDistributor contract is paused.
12
+ *
13
+ * Returns `null` on 404 — the endpoint 404s when the bot has not yet processed
14
+ * the wallet, which is a normal "no data yet" state rather than an error.
11
15
  */
12
16
  export async function getAutoclaimedIncentives({
13
17
  account,
@@ -17,14 +21,21 @@ export async function getAutoclaimedIncentives({
17
21
  } & BeraJS.BaseFunctionArgs): Promise<AutoclaimedIncentivesResponse | null> {
18
22
  const { config } = parseBaseArgs(args);
19
23
 
20
- return beraFetchJson<AutoclaimedIncentivesResponse>(
21
- {
22
- url: `${
23
- config.pol.bribeBoostApi
24
- }/api/v1/wallets/${account.toLowerCase()}/autoclaimed`,
25
- name: "pol-autoclaimed-incentives",
26
- type: "rest",
27
- },
28
- { cache: "no-store" },
29
- );
24
+ try {
25
+ return await beraFetchJson<AutoclaimedIncentivesResponse>(
26
+ {
27
+ url: `${
28
+ config.pol.bribeBoostApi
29
+ }/api/v1/wallets/${account.toLowerCase()}/autoclaimed`,
30
+ name: "pol-autoclaimed-incentives",
31
+ type: "rest",
32
+ },
33
+ { cache: "no-store" },
34
+ );
35
+ } catch (error) {
36
+ if (error instanceof RequestError && error.statusCode === 404) {
37
+ return null;
38
+ }
39
+ throw error;
40
+ }
30
41
  }
@@ -0,0 +1,41 @@
1
+ import type { Address } from "viem";
2
+
3
+ import { RequestError } from "../../errors/RequestError";
4
+ import type { AutoclaimedIncentivesTxHashResponse } from "../../types/bribe-boost";
5
+ import { beraFetchJson } from "../../utils/beraFetch";
6
+ import { parseBaseArgs } from "../../utils/parseBaseArgs";
7
+
8
+ /**
9
+ * Companion to `getAutoclaimedIncentives` that fetches the on-chain tx hash
10
+ * for each autoclaimed token. Same nested shape as `/autoclaimed`, but each
11
+ * token leaf is `{ txhash }` where the hash may be absent or empty while the
12
+ * bot is still in flight.
13
+ *
14
+ * Returns `null` on 404 (bot has not run yet for this wallet).
15
+ */
16
+ export async function getAutoclaimedIncentivesTxHash({
17
+ account,
18
+ ...args
19
+ }: {
20
+ account: Address;
21
+ } & BeraJS.BaseFunctionArgs): Promise<AutoclaimedIncentivesTxHashResponse | null> {
22
+ const { config } = parseBaseArgs(args);
23
+
24
+ try {
25
+ return await beraFetchJson<AutoclaimedIncentivesTxHashResponse>(
26
+ {
27
+ url: `${
28
+ config.pol.bribeBoostApi
29
+ }/api/v1/wallets/${account.toLowerCase()}/autoclaimed/txhash`,
30
+ name: "pol-autoclaimed-incentives-txhash",
31
+ type: "rest",
32
+ },
33
+ { cache: "no-store" },
34
+ );
35
+ } catch (error) {
36
+ if (error instanceof RequestError && error.statusCode === 404) {
37
+ return null;
38
+ }
39
+ throw error;
40
+ }
41
+ }
@@ -9,8 +9,6 @@ import { parseBaseArgs } from "../../utils/parseBaseArgs";
9
9
  * Reads `paused()` on the BGT incentive distributor. Used to gate the
10
10
  * autoclaim banner — when `true`, users can no longer self-claim and the
11
11
  * bot is responsible for distributing incentives on their behalf.
12
- *
13
- * Fails closed: any read error returns `false` so the banner stays hidden.
14
12
  */
15
13
  export async function getBgtIncentiveDistributorPaused({
16
14
  publicClient,
@@ -22,14 +20,9 @@ export async function getBgtIncentiveDistributorPaused({
22
20
 
23
21
  const { config } = parseBaseArgs(args);
24
22
 
25
- try {
26
- const paused = await publicClient.readContract({
27
- address: config.pol.bgtIncentiveDistributor,
28
- abi: bgtIncentiveDistributorAbi,
29
- functionName: "paused",
30
- });
31
- return paused;
32
- } catch {
33
- return false;
34
- }
23
+ return publicClient.readContract({
24
+ address: config.pol.bgtIncentiveDistributor,
25
+ abi: bgtIncentiveDistributorAbi,
26
+ functionName: "paused",
27
+ });
35
28
  }
@@ -1,11 +1,8 @@
1
1
  import type { Address } from "viem";
2
2
 
3
- import { getUriFromLink } from "@berachain/config";
4
-
5
- import type { VaultEarningResponse } from "@berachain/graphql/api";
6
-
7
- import { beraFetchJson } from "../../utils/beraFetch";
8
3
  import { parseBaseArgs } from "../../utils/parseBaseArgs";
4
+ import { fetchBeep } from "../clients/fetchBeep";
5
+ import { fetchRailwayBackend } from "../clients/fetchRailwayBackend";
9
6
 
10
7
  type GetEarnedStakedBeraVaultArgs = {
11
8
  /**
@@ -21,17 +18,24 @@ export async function getEarnedStakedBeraVault({
21
18
  address,
22
19
  account,
23
20
  ...args
24
- }: BeraJS.BaseFunctionArgs &
25
- GetEarnedStakedBeraVaultArgs): Promise<VaultEarningResponse> {
21
+ }: BeraJS.BaseFunctionArgs & GetEarnedStakedBeraVaultArgs) {
26
22
  const { config } = parseBaseArgs(args);
27
23
 
28
- const url = `${getUriFromLink(config.backend)}/vaults/${address}/earnings/${account}`;
29
- return beraFetchJson<VaultEarningResponse>({
30
- url,
31
- name:
32
- typeof config.backend === "string"
33
- ? "backend-railway"
34
- : config.backend.name,
35
- type: "rest",
36
- });
24
+ // TODO(beep): remove this entire block once `beep` is deployed on every
25
+ // chain. It is the only legacy-Railway-specific code left here; deleting it
26
+ // leaves the `beep` path below as the sole implementation.
27
+ if (!config.beep) {
28
+ return fetchRailwayBackend(
29
+ "/vaults/{vault}/earnings/{owner}",
30
+ { path: { vault: address, owner: account } },
31
+ args,
32
+ );
33
+ }
34
+
35
+ // beep backend (next-gen), typed against `@berachain/graphql/beep`.
36
+ return fetchBeep(
37
+ "/v0/stake/{vault}/earnings/{owner}",
38
+ { path: { vault: address, owner: account } },
39
+ args,
40
+ );
37
41
  }
@@ -87,13 +87,13 @@ export async function getRewardVaults({
87
87
  ...vault,
88
88
  dynamicData: {
89
89
  ...vault.dynamicData,
90
- allTimeReceivedBGTAmount:
91
- vault.dynamicData?.allTimeReceivedBGTAmount ?? "0",
92
- bgtCapturePercentage: vault.dynamicData?.bgtCapturePercentage ?? "0",
90
+ allTimeRewards: vault.dynamicData?.allTimeRewards ?? "0",
91
+ rewardCapturePercentage:
92
+ vault.dynamicData?.rewardCapturePercentage ?? 0,
93
93
  activeIncentivesValueUsd: totalIncentiveInUsdc.toString(),
94
94
  activeIncentivesRateUsd:
95
95
  vault.dynamicData?.activeIncentivesRateUsd ?? "0",
96
- bgtCapturePerBlock: vault.dynamicData?.bgtCapturePerBlock ?? "0",
96
+ rewardCapturePerBlock: vault.dynamicData?.rewardCapturePerBlock ?? 0,
97
97
  },
98
98
  activeIncentives: incentivesArray,
99
99
  } satisfies typeof vault;
@@ -1,11 +1,8 @@
1
1
  import type { Address } from "viem";
2
2
 
3
- import { getUriFromLink } from "@berachain/config";
4
-
5
- import type { VaultStatsByDayResponse } from "@berachain/graphql/api";
6
-
7
- import { beraFetchJson } from "../../utils/beraFetch";
8
3
  import { parseBaseArgs } from "../../utils/parseBaseArgs";
4
+ import { fetchBeep } from "../clients/fetchBeep";
5
+ import { fetchRailwayBackend } from "../clients/fetchRailwayBackend";
9
6
 
10
7
  export async function getStakingDailyAssets({
11
8
  address,
@@ -13,15 +10,22 @@ export async function getStakingDailyAssets({
13
10
  }: {
14
11
  address: Address;
15
12
  range: 30 | 60 | 90;
16
- }): Promise<VaultStatsByDayResponse> {
13
+ }) {
17
14
  const { config } = parseBaseArgs({});
18
- const url = `${getUriFromLink(config.backend)}/vaults/${address}/stats-by-day?days=${range}`;
19
- return beraFetchJson<VaultStatsByDayResponse>({
20
- url,
21
- name:
22
- typeof config.backend === "string"
23
- ? "backend-railway"
24
- : config.backend.name,
25
- type: "rest",
15
+
16
+ // TODO(beep): remove this entire block once `beep` is deployed on every
17
+ // chain. It is the only legacy-Railway-specific code left here; deleting it
18
+ // leaves the `beep` path below as the sole implementation.
19
+ if (!config.beep) {
20
+ return fetchRailwayBackend("/vaults/{vault}/stats-by-day", {
21
+ path: { vault: address },
22
+ query: { days: `${range}` },
23
+ });
24
+ }
25
+
26
+ // beep backend (next-gen), typed against `@berachain/graphql/beep`.
27
+ return fetchBeep("/v0/stake/{vault}/stats-by-day", {
28
+ path: { vault: address },
29
+ query: { days: `${range}` },
26
30
  });
27
31
  }
@@ -1,18 +1,21 @@
1
1
  import type { Address } from "viem";
2
2
 
3
- import type { GetValidatorIncentiveDistributionQuery } from "@berachain/graphql/pol/subgraph";
3
+ import type { ValidatorIncentivesResponse } from "@berachain/graphql/beep";
4
4
 
5
5
  import { BeraError } from "../../errors/BeraError";
6
6
  import { beraFetchJson } from "../../utils/beraFetch";
7
+ import { calculateTimestampFromDays } from "../../utils/formatTimestamps";
8
+ import { parseBaseArgs } from "../../utils/parseBaseArgs";
9
+ import { fetchBeep } from "../clients/fetchBeep";
7
10
 
8
- /** Browser-only. Hits `/api/pol/validator-incentive-distribution`. */
11
+ /** Browser-only. Reads from beep when configured, else the subgraph proxy. */
9
12
  export async function getValidatorIncentiveDistribution({
10
13
  pubkey,
11
14
  dayRange,
12
15
  }: {
13
16
  pubkey: Address;
14
17
  dayRange: number;
15
- }): Promise<GetValidatorIncentiveDistributionQuery | undefined> {
18
+ }): Promise<ValidatorIncentivesResponse | undefined> {
16
19
  if (typeof window === "undefined") {
17
20
  throw new BeraError({
18
21
  message:
@@ -21,13 +24,62 @@ export async function getValidatorIncentiveDistribution({
21
24
  });
22
25
  }
23
26
 
24
- const params = new URLSearchParams({
25
- pubkey,
26
- dayRange: String(dayRange),
27
- });
28
- return beraFetchJson<GetValidatorIncentiveDistributionQuery>({
29
- url: `/api/pol/validator-incentive-distribution?${params}`,
30
- name: "pol-validator-incentive-distribution",
31
- type: "rest",
32
- });
27
+ const { config } = parseBaseArgs({});
28
+
29
+ // TODO(beep): remove this entire block (and the subgraph proxy route at
30
+ // `/api/pol/validator-incentive-distribution`) once `beep` is deployed on
31
+ // every chain. beep then becomes the sole implementation. The route already
32
+ // maps the subgraph response into beep's `ValidatorIncentivesResponse` shape,
33
+ // so the client consumes a single (beep) type regardless of source.
34
+ if (!config.beep) {
35
+ const params = new URLSearchParams({
36
+ pubkey,
37
+ dayRange: String(dayRange),
38
+ });
39
+ return beraFetchJson<ValidatorIncentivesResponse>({
40
+ url: `/api/pol/validator-incentive-distribution?${params}`,
41
+ name: "pol-validator-incentive-distribution",
42
+ type: "rest",
43
+ });
44
+ }
45
+
46
+ // beep backend (next-gen). It is a public (`NEXT_PUBLIC_*`) URL, so it can be
47
+ // called directly from the browser; the subgraph above stays behind the proxy
48
+ // because it needs server-side auth headers.
49
+ //
50
+ // beep's `after` cursor is in seconds; `calculateTimestampFromDays` returns
51
+ // microseconds, matching the subgraph's `timestamp_gte`. Pin it to the start
52
+ // of the target day (UTC) so the cursor is stable within a day instead of
53
+ // sliding every second — beep buckets by `interval: "day"` anyway, and a
54
+ // stable value keeps requests cacheable.
55
+ const SECONDS_PER_DAY = 86_400;
56
+ const after = String(
57
+ Math.floor(
58
+ calculateTimestampFromDays(dayRange) / 1_000_000 / SECONDS_PER_DAY,
59
+ ) * SECONDS_PER_DAY,
60
+ );
61
+
62
+ // beep defaults to 100 rows/page, so page until a short page to gather the
63
+ // full range (matches the subgraph's `first: 1000`). In practice this is a
64
+ // single request — a busy validator is ~325 rows over the UI's max 90-day
65
+ // window, well under one page.
66
+ const PER_PAGE = 1000;
67
+ const rows: ValidatorIncentivesResponse = [];
68
+ let page = 1;
69
+ while (true) {
70
+ const pageRows = await fetchBeep("/v0/validators/{pubkey}/incentives", {
71
+ path: { pubkey },
72
+ query: {
73
+ interval: "day",
74
+ after,
75
+ page: String(page),
76
+ perPage: String(PER_PAGE),
77
+ },
78
+ });
79
+ rows.push(...pageRows);
80
+ if (pageRows.length < PER_PAGE) break;
81
+ page++;
82
+ }
83
+
84
+ return rows;
33
85
  }
@@ -51,7 +51,7 @@ export function getValidatorBoostApy({
51
51
 
52
52
  const boostApy =
53
53
  (returnPerBgt *
54
- Number(validator.dynamicData?.lastDayDistributedBGTAmount ?? 0) *
54
+ Number(validator.dynamicData?.lastDayDistributedRewards ?? 0) *
55
55
  365) /
56
56
  (validatorActiveBoostAmount * bgtPrice);
57
57
 
@@ -1,6 +1,7 @@
1
1
  import type React from "react";
2
2
  import { useEffect } from "react";
3
- import { SWRConfig } from "swr";
3
+
4
+ import { SWRConfig } from "@berachain/utils/pkg/swr";
4
5
 
5
6
  import { BeraError } from "../errors/BeraError";
6
7
  import { BeraMonitoring } from "../errors/BeraMonitoring";
@@ -377,6 +377,10 @@ export const contracts = [
377
377
  "80094": "0x2880aB155794e7179c9eE2e38200202908C17B43",
378
378
  name: "external.pyth",
379
379
  },
380
+ {
381
+ "80094": "0xB5f473c4b7F402d8f7bED42b6D516f5ff3306B01",
382
+ name: "bend.production.supportedVaults.1",
383
+ },
380
384
  {
381
385
  "80069": null,
382
386
  "80094": "0xC5FabF3a7E98a2ed89f5d5057Ab010634Ca7e71f",
@@ -1,6 +1,7 @@
1
1
  import type { ErrorLike } from "@apollo/client";
2
2
 
3
3
  import { getUriFromLink } from "@berachain/config";
4
+ import { bepolia } from "@berachain/config/bepolia";
4
5
  import { mainnet } from "@berachain/config/mainnet";
5
6
 
6
7
  import { BeraError, type IBeraErrorArgs } from "./BeraError";
@@ -33,12 +34,16 @@ export class RequestError extends BeraError {
33
34
  */
34
35
  private queryRichfulDomains = [
35
36
  mainnet.bex.aggregatorsProxyUrl,
36
- "https://api.fly.trade/aggregator/quote",
37
+ // covers both /aggregator/quote and /aggregator/transaction?quoteId=...
38
+ // (the transaction endpoint's quoteId would otherwise fragment grouping)
39
+ "https://api.fly.trade/aggregator",
37
40
  "https://open-api.openocean.finance/v4/bera/swap",
38
41
  // vercel internal proxy
39
42
  "/api/aggregators?aggregator",
40
43
  // bonder endpoints have date-based query params (e.g. ?start=2025-11-28)
41
44
  mainnet.backend,
45
+ // beep (next-gen backend) on testnet — same date-based bonder query params
46
+ bepolia.beep,
42
47
  ];
43
48
 
44
49
  statusCode: number | undefined;
@@ -208,14 +213,18 @@ export class RequestError extends BeraError {
208
213
  // - have a network error
209
214
  // - have CORS errors
210
215
  // the list is empirically collected from sentry error logs.
216
+ // The trailing "(host)" suffix is optional: some browsers/transports omit
217
+ // it (e.g. bare "Failed to fetch" / "Load failed"). We normalize all of
218
+ // them to a single NETWORK_ERROR reason so the variants group together,
219
+ // falling back to the endpoint url when no host is present in the message.
211
220
  const failedToFetchMatch = message.match(
212
- /^(?:NetworkError when attempting to fetch resource\.|Failed to fetch|Load failed) \(([a-z0-9-.]+)\)$/,
221
+ /^(?:NetworkError when attempting to fetch resource\.|Failed to fetch|Load failed)(?: \(([a-z0-9-.]+)\))?$/,
213
222
  );
214
223
  if (failedToFetchMatch) {
215
224
  return {
216
225
  reason: RequestError.REASON_MAP.NETWORK_ERROR,
217
226
  message: message,
218
- url: failedToFetchMatch[1],
227
+ url: failedToFetchMatch[1] ?? this.endpoint.url,
219
228
  };
220
229
  }
221
230
  }
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { RequestError } from "./RequestError.js";
4
+
5
+ describe("RequestError endpoint normalization (grouping)", () => {
6
+ it("strips query params from the fly.trade transaction endpoint so quoteId no longer fragments groups", () => {
7
+ const base = "https://api.fly.trade/aggregator/transaction";
8
+ const a = new RequestError({
9
+ response: undefined,
10
+ endpoint: {
11
+ url: `${base}?quoteId=aaaa-1111&estimateGas=false`,
12
+ type: "rest",
13
+ },
14
+ });
15
+ const b = new RequestError({
16
+ response: undefined,
17
+ endpoint: {
18
+ url: `${base}?quoteId=bbbb-2222&estimateGas=false`,
19
+ type: "rest",
20
+ },
21
+ });
22
+
23
+ expect(a.endpoint.url).toBe(base);
24
+ expect(b.endpoint.url).toBe(base);
25
+ expect(a.endpoint.url).toBe(b.endpoint.url);
26
+ });
27
+ });
28
+
29
+ describe("RequestError network-error normalization (grouping)", () => {
30
+ it.each([
31
+ "Failed to fetch",
32
+ "Load failed",
33
+ "NetworkError when attempting to fetch resource.",
34
+ "Failed to fetch (api.berachain.com)",
35
+ ])("normalizes %s to NETWORK_ERROR reason", (message) => {
36
+ const err = new RequestError({
37
+ response: undefined,
38
+ cause: new TypeError(message),
39
+ endpoint: { url: "https://api.berachain.com", type: "graphql" },
40
+ });
41
+
42
+ expect(err.reason).toBe(RequestError.REASON_MAP.NETWORK_ERROR);
43
+ expect(err.level).toBe("warning");
44
+ });
45
+
46
+ it("does not treat unrelated messages as network errors", () => {
47
+ const err = new RequestError({
48
+ response: undefined,
49
+ cause: new TypeError("Cannot read properties of undefined"),
50
+ endpoint: { url: "https://api.berachain.com", type: "graphql" },
51
+ });
52
+
53
+ expect(err.reason).not.toBe(RequestError.REASON_MAP.NETWORK_ERROR);
54
+ });
55
+ });
@@ -89,6 +89,14 @@ export const errorMsgMap = {
89
89
  errorMSG:
90
90
  "Nonce is too low. Your wallet might have unconfirmed transactions.",
91
91
  },
92
+ REPLACEMENT_UNDERPRICED: {
93
+ // Transient resubmission issue (gas bump too low). Not function-specific —
94
+ // normalizing the raw RPC string to this key collapses the per-function
95
+ // Sentry groups (functionName is still kept as a tag).
96
+ keywords: ["replacement transaction underpriced"],
97
+ errorMSG:
98
+ "Your wallet tried to replace a pending transaction without raising the gas enough. Please wait for the previous transaction to finish, or try again.",
99
+ },
92
100
  GAS_PRICE: {
93
101
  keywords: ["gasLimit"],
94
102
  errorMSG:
@@ -78,8 +78,12 @@ const expectedRevertReasons = [
78
78
  },
79
79
  {
80
80
  functionName: "revertNoReasonAssembly",
81
+ // A revert with no data has nothing to decode. The two replay paths surface it
82
+ // differently: simulateContract (getRevertReason) yields the RPC "execution
83
+ // reverted", while sendCalls/simulateCalls (eip5972) yields viem's zero-data
84
+ // error chain whose innermost name is "AbiDecodingZeroDataError".
81
85
  onChainReason: "execution reverted",
82
- revertReason: "execution failed",
86
+ revertReason: "AbiDecodingZeroDataError",
83
87
  txHashWith5972:
84
88
  "0xcd9af1bca5ac53d1fd6bd33796a087f15895943047ae0d20f51331d78945a7a8",
85
89
  },
@@ -1,6 +1,5 @@
1
- import useSWR from "swr";
2
-
3
1
  import { usePublicClient } from "@berachain/wagmi/hooks";
2
+ import { useSWR } from "@berachain/utils/pkg/swr";
4
3
 
5
4
  import type { GetConvertToAssetsProps } from "../../actions/bend/getConvertToAssets";
6
5
  import { getConvertToAssets } from "../../actions/bend/getConvertToAssets";
@@ -30,7 +29,7 @@ export const useGetConvertToAssets = (
30
29
  });
31
30
  },
32
31
  {
33
- ...options?.opts,
32
+ ...options,
34
33
  },
35
34
  );
36
35