@berachain/berajs 0.2.3 → 0.2.4
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.
- package/.claude/skills/berajs/SKILL.md +222 -0
- package/.claude/skills/berajs/references/dex.md +235 -0
- package/.claude/skills/berajs/references/pol.md +194 -0
- package/.claude/skills/berajs/references/staking.md +198 -0
- package/.claude/skills/berajs/references/tokens.md +170 -0
- package/dist/{BexStatusProvider-nS3NcdxI.d.cts → BexStatusProvider-DRymVlQf.d.cts} +1 -1
- package/dist/{BexStatusProvider-nS3NcdxI.d.ts → BexStatusProvider-DRymVlQf.d.ts} +1 -1
- package/dist/{HoneyConfigProvider-CK6mOKFH.d.ts → HoneyConfigProvider-DVP_9KZn.d.ts} +1 -1
- package/dist/{HoneyConfigProvider-Ca3ouozs.d.cts → HoneyConfigProvider-DfkjmzEf.d.cts} +1 -1
- package/dist/abi/exports.cjs +1 -1
- package/dist/abi/exports.cjs.map +1 -1
- package/dist/abi/exports.d.cts +1893 -25347
- package/dist/abi/exports.d.ts +1893 -25347
- package/dist/abi/exports.mjs +1 -1
- package/dist/abi/exports.mjs.map +1 -1
- package/dist/actions/exports.cjs +1 -1
- package/dist/actions/exports.cjs.map +1 -1
- package/dist/actions/exports.d.cts +10 -9
- package/dist/actions/exports.d.ts +10 -9
- package/dist/actions/exports.mjs +1 -1
- package/dist/actions/exports.mjs.map +1 -1
- package/dist/chunk-4GU2O2OW.cjs +4 -0
- package/dist/chunk-4GU2O2OW.cjs.map +1 -0
- package/dist/chunk-5XWELBWR.mjs +2 -0
- package/dist/chunk-5XWELBWR.mjs.map +1 -0
- package/dist/chunk-BS6K7HGH.cjs +2 -0
- package/dist/chunk-BS6K7HGH.cjs.map +1 -0
- package/dist/chunk-NLVWRMGD.mjs +2 -0
- package/dist/chunk-NLVWRMGD.mjs.map +1 -0
- package/dist/chunk-OUD27MU7.cjs +2 -0
- package/dist/chunk-OUD27MU7.cjs.map +1 -0
- package/dist/chunk-RW3JFPED.mjs +4 -0
- package/dist/chunk-RW3JFPED.mjs.map +1 -0
- package/dist/chunk-S3EAKCVM.cjs +2 -0
- package/dist/{chunk-PKXAW6MO.cjs.map → chunk-S3EAKCVM.cjs.map} +1 -1
- package/dist/chunk-YNO7BCCM.mjs +2 -0
- package/dist/{chunk-3YXSUBA5.mjs.map → chunk-YNO7BCCM.mjs.map} +1 -1
- package/dist/contexts/exports.d.cts +3 -3
- package/dist/contexts/exports.d.ts +3 -3
- package/dist/enum/exports.d.cts +1 -1
- package/dist/enum/exports.d.ts +1 -1
- package/dist/errors/exports.d.cts +1 -1
- package/dist/errors/exports.d.ts +1 -1
- package/dist/{getValidatorQueuedOperatorAddress-NrjpnEn8.d.ts → getValidatorQueuedOperatorAddress-CqR6cyqC.d.ts} +3 -3
- package/dist/{getValidatorQueuedOperatorAddress-D_LEt3vv.d.cts → getValidatorQueuedOperatorAddress-DZgrPmZ2.d.cts} +3 -3
- package/dist/{global.d-X3cqpCEB.d.ts → global.d-BeYWDreg.d.ts} +4 -4
- package/dist/{global.d-DLRtrPG5.d.cts → global.d-DghRxpHd.d.cts} +4 -4
- package/dist/hooks/exports.cjs +3 -3
- package/dist/hooks/exports.cjs.map +1 -1
- package/dist/hooks/exports.d.cts +40 -38
- package/dist/hooks/exports.d.ts +40 -38
- package/dist/hooks/exports.mjs +3 -3
- package/dist/hooks/exports.mjs.map +1 -1
- package/dist/{txnEnum-BlBYhNRl.d.cts → txnEnum-DxPRHSJt.d.cts} +1 -1
- package/dist/{txnEnum-BlBYhNRl.d.ts → txnEnum-DxPRHSJt.d.ts} +1 -1
- package/dist/types/exports.d.cts +3 -3
- package/dist/types/exports.d.ts +3 -3
- package/dist/{useHoneySwapState-D1DKG_Of.d.ts → useHoneySwapState-B494PQDl.d.ts} +1 -1
- package/dist/{useHoneySwapState-B-vmIP1b.d.cts → useHoneySwapState-D6vpv19r.d.cts} +1 -1
- package/dist/utils/exports.cjs +1 -1
- package/dist/utils/exports.cjs.map +1 -1
- package/dist/utils/exports.d.cts +2 -2
- package/dist/utils/exports.d.ts +2 -2
- package/dist/utils/exports.mjs +1 -1
- package/dist/utils/exports.mjs.map +1 -1
- package/package.json +8 -9
- package/src/abi/exports.ts +0 -27
- package/src/actions/bend/getConvertToAssets.ts +1 -1
- package/src/actions/bend/getMaxDeposit.ts +1 -1
- package/src/actions/dex/aggregators/bex.ts +2 -1
- package/src/actions/dex/aggregators/enso/enso.ts +3 -2
- package/src/actions/dex/aggregators/enso/ensoErc4626.debug.test.ts +2 -3
- package/src/actions/dex/aggregators/erc4626.ts +2 -1
- package/src/actions/dex/aggregators/fly.ts +2 -1
- package/src/actions/dex/aggregators/haiku.ts +2 -1
- package/src/actions/dex/aggregators/kyberswap.ts +2 -2
- package/src/actions/dex/aggregators/oogabooga.ts +2 -1
- package/src/actions/dex/aggregators/openOcean.ts +2 -1
- package/src/actions/dex/aggregators/wbera.ts +2 -1
- package/src/actions/dex/getVaultPausedState.ts +2 -1
- package/src/actions/enso/getEnsoUserTokensWithBalances.debug.test.ts +1 -1
- package/src/actions/governance/__tests__/checkProposalField.unit.test.ts +2 -1
- package/src/actions/governance/__tests__/getDecodedFunctionData.integration.test.ts +66 -78
- package/src/actions/governance/__tests__/getQuorum.integration.test.ts +6 -7
- package/src/actions/governance/getDecodedFunctionData.ts +2 -2
- package/src/actions/governance/getProposalFromTx.ts +2 -1
- package/src/actions/governance/getProposalParams.ts +3 -2
- package/src/actions/governance/getQuorum.ts +2 -1
- package/src/actions/honey/getCollateralWeights.ts +2 -1
- package/src/actions/honey/getGlobalCapLimit.ts +2 -1
- package/src/actions/honey/getHoneyCollaterals.ts +2 -1
- package/src/actions/honey/getHoneyFees.ts +2 -1
- package/src/actions/honey/getHoneyPausedState.ts +2 -1
- package/src/actions/honey/getHoneyPreview.ts +2 -1
- package/src/actions/honey/getHoneyPythPriceOracle.ts +1 -1
- package/src/actions/honey/getHoneyRootPriceOracle.ts +2 -1
- package/src/actions/honey/getHoneyVaultsBalance.ts +3 -2
- package/src/actions/honey/getRelativeCapLimit.ts +2 -1
- package/src/actions/honey/getSharesWithoutFees.ts +3 -2
- package/src/actions/honey/getSwapPayload.ts +3 -2
- package/src/actions/honey/isBadCollateralAsset.ts +3 -2
- package/src/actions/honey/isBasketModeEnabled.ts +3 -2
- package/src/actions/pol/getBgtTokenTotalBoosts.ts +2 -1
- package/src/actions/pol/getLSTStakeConfig.ts +2 -1
- package/src/actions/pol/getRewardTokenToBeraRate.ts +2 -1
- package/src/actions/pol/getRewardVaultBeaconImplementation.ts +2 -1
- package/src/actions/pol/getRewardVaultDurationConstants.ts +2 -1
- package/src/actions/pol/getRewardVaultFromToken.ts +2 -1
- package/src/actions/pol/getRewardVaultIncentives.ts +2 -1
- package/src/actions/pol/getRewardVaultRewards.ts +2 -1
- package/src/actions/pol/getRewardVaultStakingToken.ts +1 -1
- package/src/actions/pol/getRewardVaults.ts +2 -1
- package/src/actions/pol/getSWBeraVaultMetadata.ts +2 -1
- package/src/actions/pol/getSWBeraWithdrawal.ts +2 -1
- package/src/actions/pol/getStakeWithdrawalCooldown.ts +1 -1
- package/src/actions/pol/getTotalStakedAmount.ts +2 -1
- package/src/actions/pol/getUserVaults.ts +2 -1
- package/src/actions/pol/getUserVaultsBalance.ts +2 -1
- package/src/actions/pol/getUserVaultsReward.ts +1 -1
- package/src/actions/pol/getVaultsSupply.ts +1 -1
- package/src/actions/pyth/getHoneyPythFeeds.ts +2 -1
- package/src/actions/transactions/beraWriteContract.integration.test.ts +48 -51
- package/src/actions/validators/getActiveBoostAndCommissionChangeDelay.ts +3 -2
- package/src/actions/validators/getBaselineRewardAllocation.ts +2 -1
- package/src/actions/validators/getDefaultRewardAllocation.ts +2 -1
- package/src/actions/validators/getUserBoostsOnValidator.ts +2 -1
- package/src/actions/validators/getValidatorCommission.ts +2 -1
- package/src/actions/validators/getValidatorOperatorAddress.ts +2 -1
- package/src/actions/validators/getValidatorQueuedCommission.ts +2 -1
- package/src/actions/validators/getValidatorQueuedOperatorAddress.ts +2 -1
- package/src/actions/validators/getValidatorQueuedRewardAllocation.ts +2 -1
- package/src/actions/validators/getValidatorRewardAllocation.ts +2 -1
- package/src/actions/validators/getValidatorRewardAllocatorAddress.ts +2 -1
- package/src/actions/validators/utils/__tests__/validatorUtils.integration.test.ts +10 -11
- package/src/errors/getRevertReason.integration.test.ts +115 -107
- package/src/hooks/dex/useAggregatorsRouterFeeBps.ts +2 -1
- package/src/hooks/dex/useCreatePool.ts +2 -1
- package/src/hooks/dex/usePollPoolCreationRelayerApproval.ts +2 -1
- package/src/hooks/governance/useGetPastVotes.ts +2 -1
- package/src/hooks/governance/useHasVoted.ts +2 -1
- package/src/hooks/governance/useIsCanceller.ts +2 -1
- package/src/hooks/governance/usePollProposalThreshold.ts +2 -1
- package/src/hooks/governance/usePollUserDelegates.ts +2 -1
- package/src/hooks/governance/useProposalSnapshot.ts +2 -1
- package/src/hooks/governance/useProposalState.ts +2 -1
- package/src/hooks/governance/useProposalTimelockState.ts +5 -4
- package/src/hooks/pol/useBgtUnstakedBalance.ts +2 -1
- package/src/hooks/pol/useOnChainRewardVault.ts +2 -1
- package/src/hooks/pol/useRewardVaultBalanceFromStakingToken.ts +2 -1
- package/src/hooks/pol/useRewardVaultFromToken.ts +2 -1
- package/src/hooks/validators/useOnChainValidator.ts +4 -3
- package/dist/chunk-3YXSUBA5.mjs +0 -2
- package/dist/chunk-A4UDYSB6.mjs +0 -4
- package/dist/chunk-A4UDYSB6.mjs.map +0 -1
- package/dist/chunk-CYKCYPFR.cjs +0 -2
- package/dist/chunk-CYKCYPFR.cjs.map +0 -1
- package/dist/chunk-ECRMUMTA.mjs +0 -2
- package/dist/chunk-ECRMUMTA.mjs.map +0 -1
- package/dist/chunk-F4BKSBEM.mjs +0 -2
- package/dist/chunk-F4BKSBEM.mjs.map +0 -1
- package/dist/chunk-FL2N3XHK.cjs +0 -2
- package/dist/chunk-FL2N3XHK.cjs.map +0 -1
- package/dist/chunk-MUCEYO3E.cjs +0 -4
- package/dist/chunk-MUCEYO3E.cjs.map +0 -1
- package/dist/chunk-P2Q7CMUD.cjs +0 -2
- package/dist/chunk-P2Q7CMUD.cjs.map +0 -1
- package/dist/chunk-PKXAW6MO.cjs +0 -2
- package/dist/chunk-Q3SCM6WL.mjs +0 -2
- package/dist/chunk-Q3SCM6WL.mjs.map +0 -1
- package/dist/chunk-TEBJWAVU.mjs +0 -2
- package/dist/chunk-TEBJWAVU.mjs.map +0 -1
- package/dist/chunk-VP7XUOSI.cjs +0 -2
- package/dist/chunk-VP7XUOSI.cjs.map +0 -1
- package/dist/pythWrapper-CBjsmmsK.d.cts +0 -1958
- package/dist/pythWrapper-CBjsmmsK.d.ts +0 -1958
- package/src/abi/bend/metaMorpho.ts +0 -2584
- package/src/abi/bend/morpho.ts +0 -444
- package/src/abi/bex/aggregatorsRouter.ts +0 -492
- package/src/abi/bex/balancerComposableStablePoolFactoryV6.ts +0 -283
- package/src/abi/bex/balancerPoolCreationHelper.ts +0 -267
- package/src/abi/bex/balancerVault.ts +0 -757
- package/src/abi/governance/governance.ts +0 -1016
- package/src/abi/governance/governanceTimelock.ts +0 -589
- package/src/abi/honey/collateralVault.ts +0 -1144
- package/src/abi/honey/honey.ts +0 -563
- package/src/abi/honey/honeyFactory.ts +0 -1270
- package/src/abi/honey/honeyFactoryReader.ts +0 -894
- package/src/abi/honey/honeyRootOracle.ts +0 -492
- package/src/abi/honey/pythPriceOracle.ts +0 -619
- package/src/abi/honey/pythWrapper.ts +0 -446
- package/src/abi/pol/LSTStakerVault.ts +0 -2032
- package/src/abi/pol/beaconDeposit.ts +0 -595
- package/src/abi/pol/beraChef.ts +0 -1019
- package/src/abi/pol/bgt.ts +0 -1008
- package/src/abi/pol/bgtIncentiveDistributor.ts +0 -640
- package/src/abi/pol/bgtStaker.ts +0 -1034
- package/src/abi/pol/rewardAllocationFactory.ts +0 -408
- package/src/abi/pol/rewardVault.ts +0 -1928
- package/src/abi/pol/rewardVaultFactory.ts +0 -586
- package/src/abi/pol/rewardVaultHelper.ts +0 -882
- package/src/abi/pol/stakeBeraVault.ts +0 -1116
- package/src/abi/pol/stakeBeraVaultWithdrawalRequest.ts +0 -618
- package/src/abi/pol/wbera.ts +0 -366
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: berajs
|
|
3
|
+
description: Use when the user asks about "@berachain/berajs", "berajs SDK", "useRewardVaults", "useBeraContractWrite", "beraWriteContract", "BeraFlagsProvider", "BGT", "reward vault", "BEX pools", "Berachain DEX", "berachain token balances", "usePollWalletBalances", "getAllPools", or any question about integrating the berajs SDK into a React or Next.js application.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# BeraJS SDK — Developer Reference
|
|
8
|
+
|
|
9
|
+
`@berachain/berajs` is a TypeScript SDK for Berachain's DeFi ecosystem. Built on wagmi v2, viem, and SWR.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @berachain/berajs
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies:
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add viem react react-dom @berachain/wagmi
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Import Paths
|
|
23
|
+
|
|
24
|
+
The package uses **sub-path exports** — never import from the root:
|
|
25
|
+
|
|
26
|
+
| What you need | Import from |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Actions (async functions) | `@berachain/berajs/actions` |
|
|
29
|
+
| React hooks | `@berachain/berajs/hooks` |
|
|
30
|
+
| Context providers | `@berachain/berajs/contexts` |
|
|
31
|
+
| Utility functions | `@berachain/berajs/utils` |
|
|
32
|
+
| TypeScript types | `@berachain/berajs/types` |
|
|
33
|
+
| Enums | `@berachain/berajs/enum` |
|
|
34
|
+
| ABIs | `@berachain/berajs/abi` |
|
|
35
|
+
|
|
36
|
+
## Required Provider Setup
|
|
37
|
+
|
|
38
|
+
Wrap your app with providers **in this order**. Only include providers for features you use:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
"use client";
|
|
42
|
+
import {
|
|
43
|
+
BeraFlagsProvider,
|
|
44
|
+
TokensProvider,
|
|
45
|
+
BexStatusProvider,
|
|
46
|
+
} from "@berachain/berajs/contexts";
|
|
47
|
+
import { defaultBeraFlags } from "@berachain/berajs/utils";
|
|
48
|
+
|
|
49
|
+
function Providers({ children }: { children: React.ReactNode }) {
|
|
50
|
+
return (
|
|
51
|
+
<BeraFlagsProvider flags={defaultBeraFlags}>
|
|
52
|
+
<TokensProvider
|
|
53
|
+
defaultTokens={[]}
|
|
54
|
+
edgeConfigTokenList={[]}
|
|
55
|
+
userTokens={[]}
|
|
56
|
+
onAddToken={() => {}}
|
|
57
|
+
onRemoveToken={() => {}}
|
|
58
|
+
>
|
|
59
|
+
<BexStatusProvider
|
|
60
|
+
isVaultPaused={false}
|
|
61
|
+
factories={{ composableStable: "enabled", weighted: "enabled" }}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
</BexStatusProvider>
|
|
65
|
+
</TokensProvider>
|
|
66
|
+
</BeraFlagsProvider>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Provider responsibilities:**
|
|
72
|
+
- `BeraFlagsProvider` — feature flags used throughout the SDK (required for all berajs hooks)
|
|
73
|
+
- `TokensProvider` — token list management; required for token hooks
|
|
74
|
+
- `BexStatusProvider` — vault/pool pause state; required for `useBexStatus`
|
|
75
|
+
- `HoneyConfigProvider` — only needed for Honey mint/redeem features (not covered here)
|
|
76
|
+
|
|
77
|
+
### SSR prefetching (Next.js)
|
|
78
|
+
|
|
79
|
+
Use `SWRFallback` to pass server-fetched data to SWR hooks:
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { SWRFallback } from "@berachain/berajs/contexts";
|
|
83
|
+
import { useRewardVaultsQueryKey } from "@berachain/berajs/hooks";
|
|
84
|
+
import { getRewardVaults } from "@berachain/berajs/actions";
|
|
85
|
+
|
|
86
|
+
// server component
|
|
87
|
+
const queryKey = useRewardVaultsQueryKey();
|
|
88
|
+
const vaults = await getRewardVaults({ filter: {} });
|
|
89
|
+
|
|
90
|
+
<SWRFallback fallback={{ [JSON.stringify(queryKey)]: vaults }}>
|
|
91
|
+
{children}
|
|
92
|
+
</SWRFallback>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Core Patterns
|
|
96
|
+
|
|
97
|
+
### Actions vs Hooks
|
|
98
|
+
|
|
99
|
+
**Actions** — plain async functions. Use server-side or imperatively:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { getRewardVaults } from "@berachain/berajs/actions";
|
|
103
|
+
const vaults = await getRewardVaults({ filter: {} });
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Hooks** — SWR-powered React hooks. Use in client components:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { useRewardVaults } from "@berachain/berajs/hooks";
|
|
110
|
+
const { data: vaults, isLoading, refresh } = useRewardVaults({ filter: {} });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Rule:** In a React component → use the hook. On the server or imperatively → use the action.
|
|
114
|
+
|
|
115
|
+
### BaseFunctionArgs
|
|
116
|
+
|
|
117
|
+
Every action accepts `BeraJS.BaseFunctionArgs` as a spread:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
// Defaults to mainnet (chainId 80094)
|
|
121
|
+
await getRewardVaults({ filter: {} });
|
|
122
|
+
|
|
123
|
+
// Override for testnet:
|
|
124
|
+
import { ChainId } from "@berachain/config";
|
|
125
|
+
await getRewardVaults({ filter: {}, chainId: ChainId.BEPOLIA });
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### DefaultHookOptions
|
|
129
|
+
|
|
130
|
+
Every hook accepts an optional second argument:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
// Conditionally fetch (wait for wallet connection):
|
|
134
|
+
const { data } = useRewardVaults(
|
|
135
|
+
{ filter: {} },
|
|
136
|
+
{ opts: { isEnabled: !!account } }
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Custom refresh interval (ms):
|
|
140
|
+
const { data } = usePollWalletBalances(
|
|
141
|
+
{ account },
|
|
142
|
+
{ opts: { refreshInterval: 5000 } }
|
|
143
|
+
);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### DefaultHookReturnType
|
|
147
|
+
|
|
148
|
+
All hooks return:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
{
|
|
152
|
+
data: T | undefined;
|
|
153
|
+
isLoading: boolean; // true on first fetch
|
|
154
|
+
isValidating: boolean; // true on any fetch including refetch
|
|
155
|
+
error: any;
|
|
156
|
+
refresh: () => void; // triggers revalidation (replaces SWR mutate)
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Sending Transactions
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { useBeraContractWrite } from "@berachain/berajs/hooks";
|
|
164
|
+
import { TransactionActionType } from "@berachain/berajs/enum";
|
|
165
|
+
|
|
166
|
+
const { write, isLoading, isSuccess, isError, reset } = useBeraContractWrite({
|
|
167
|
+
onSuccess: (receipt) => console.log("Done", receipt.transactionHash),
|
|
168
|
+
onError: (error) => console.error(error.displayMessage),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
write({
|
|
172
|
+
address: "0xContract",
|
|
173
|
+
abi: myAbi,
|
|
174
|
+
functionName: "myFunction",
|
|
175
|
+
params: [arg1, arg2],
|
|
176
|
+
message: "Doing the thing...",
|
|
177
|
+
actionType: TransactionActionType.STAKE,
|
|
178
|
+
contractName: "pol.rewardVault", // required in dev; see ContractName enum
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Batch calls (EIP-5792):**
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
write({
|
|
186
|
+
message: "Approve and stake",
|
|
187
|
+
actionType: TransactionActionType.STAKE,
|
|
188
|
+
calls: [
|
|
189
|
+
{ address: tokenAddress, abi: erc20Abi, functionName: "approve", params: [spender, amount] },
|
|
190
|
+
{ address: vaultAddress, abi: vaultAbi, functionName: "stake", params: [amount] },
|
|
191
|
+
],
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Key `IContractWrite` fields:**
|
|
196
|
+
- `message` — shown to user while pending
|
|
197
|
+
- `actionType` — from `TransactionActionType` enum
|
|
198
|
+
- `contractName` — required in dev mode; values from `ContractName` enum
|
|
199
|
+
- `permissionless: true` — set if `msg.sender` does not matter
|
|
200
|
+
- `onSuccess(receipt, writeArgs)` — after confirmation
|
|
201
|
+
- `onError(error, writeArgs)` — `error.displayMessage` is user-safe
|
|
202
|
+
- `onSubmission({ txHash }, writeArgs)` — when tx hash is available
|
|
203
|
+
- `onWarning(error, writeArgs)` — non-fatal warning (tx still submitted)
|
|
204
|
+
|
|
205
|
+
### Error Types
|
|
206
|
+
|
|
207
|
+
Import from `@berachain/berajs/errors`:
|
|
208
|
+
|
|
209
|
+
| Type | When it appears |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `BeraError` | Base class for all berajs errors |
|
|
212
|
+
| `TransactionFailedError` | Tx reverted or simulation failed |
|
|
213
|
+
| `NotFoundError` | Resource does not exist (e.g. unknown vault address) |
|
|
214
|
+
| `InvalidArgumentError` | Wrong or missing argument |
|
|
215
|
+
| `RequestError` | Network/RPC request failed |
|
|
216
|
+
|
|
217
|
+
## Domain References
|
|
218
|
+
|
|
219
|
+
- **Tokens** — `./references/tokens.md`
|
|
220
|
+
- **POL (Reward Vaults, BGT)** — `./references/pol.md`
|
|
221
|
+
- **DEX (Pools, Swaps)** — `./references/dex.md`
|
|
222
|
+
- **Liquid Staking (swBERA)** — `./references/staking.md`
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# BeraJS — DEX (BEX) Reference
|
|
2
|
+
|
|
3
|
+
BEX is Berachain's native DEX. `@berachain/berajs` provides pool data, swap quotes via multiple aggregators, and protocol pause status.
|
|
4
|
+
|
|
5
|
+
## Pool List
|
|
6
|
+
|
|
7
|
+
### `usePools` / `getAllPools`
|
|
8
|
+
|
|
9
|
+
Paginated pool list with search and sorting.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { usePools } from "@berachain/berajs/hooks";
|
|
13
|
+
import { GqlPoolOrderBy, GqlPoolOrderDirection } from "@berachain/graphql/pol/api";
|
|
14
|
+
|
|
15
|
+
const { data, isLoading } = usePools({
|
|
16
|
+
first: 20,
|
|
17
|
+
skip: 0,
|
|
18
|
+
orderBy: GqlPoolOrderBy.TotalLiquidity,
|
|
19
|
+
orderDirection: GqlPoolOrderDirection.Desc,
|
|
20
|
+
textSearch: "HONEY", // optional
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// data: { pools: GqlPoolFragment[], count: number }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Single Pool
|
|
27
|
+
|
|
28
|
+
### `usePool` / `getApiPool`
|
|
29
|
+
|
|
30
|
+
Fetch one pool by its contract address.
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { usePool } from "@berachain/berajs/hooks";
|
|
34
|
+
|
|
35
|
+
const { data: pool } = usePool({ id: "0xPoolAddress" });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Swap Quotes
|
|
39
|
+
|
|
40
|
+
### `useAggregatorsQuotes`
|
|
41
|
+
|
|
42
|
+
Get quotes from **all enabled aggregators** simultaneously, ranked best to worst.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { useAggregatorsQuotes } from "@berachain/berajs/hooks";
|
|
46
|
+
import { SwapKind } from "@berachain-foundation/berancer-sdk";
|
|
47
|
+
import type { IAggregatorArgs } from "@berachain/berajs/types";
|
|
48
|
+
|
|
49
|
+
const swapArgs: IAggregatorArgs = {
|
|
50
|
+
tokenIn: {
|
|
51
|
+
address: "0xWBERA",
|
|
52
|
+
decimals: 18,
|
|
53
|
+
symbol: "WBERA",
|
|
54
|
+
name: "Wrapped BERA",
|
|
55
|
+
chainId: 80094,
|
|
56
|
+
},
|
|
57
|
+
tokenOut: {
|
|
58
|
+
address: "0xHONEY",
|
|
59
|
+
decimals: 18,
|
|
60
|
+
symbol: "HONEY",
|
|
61
|
+
name: "Honey",
|
|
62
|
+
chainId: 80094,
|
|
63
|
+
},
|
|
64
|
+
amount: "1000000000000000000", // 1 WBERA in wei
|
|
65
|
+
slippage: 0.5, // 0.5%
|
|
66
|
+
account: "0x...",
|
|
67
|
+
swapKind: SwapKind.GivenIn,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const { data: quotes, isLoading } = useAggregatorsQuotes(swapArgs);
|
|
71
|
+
|
|
72
|
+
// quotes: IAggregatorQuote[] | undefined — sorted best to worst
|
|
73
|
+
// quotes[0].isBest === true
|
|
74
|
+
// quotes[0].amountOut — output amount as string
|
|
75
|
+
// quotes[0].amountOutUsd — USD value as string
|
|
76
|
+
// quotes[0].priceImpactPercentage
|
|
77
|
+
// quotes[0].getCalldata?.({ account }) → { address, data, value, abi?, functionName? }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `useSingleAggregatorQuote`
|
|
81
|
+
|
|
82
|
+
Quote from one specific aggregator. Useful for dedicated aggregator UIs.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { useSingleAggregatorQuote } from "@berachain/berajs/hooks";
|
|
86
|
+
// Same args as useAggregatorsQuotes, plus aggregator name
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Protocol/Pool Pause Status
|
|
90
|
+
|
|
91
|
+
### `useBexStatus`
|
|
92
|
+
|
|
93
|
+
**Always check before allowing swaps or deposits.**
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { useBexStatus } from "@berachain/berajs/hooks";
|
|
97
|
+
|
|
98
|
+
const { protocol, pool } = useBexStatus();
|
|
99
|
+
|
|
100
|
+
// Disable all swaps when protocol is paused:
|
|
101
|
+
if (protocol.isPaused) return <div>Protocol paused</div>;
|
|
102
|
+
|
|
103
|
+
// Pool-level flags (set BexStatusProvider's onPoolChange first):
|
|
104
|
+
pool?.isPaused // pool is paused
|
|
105
|
+
pool?.isInRecoveryMode // proportional exit only
|
|
106
|
+
pool?.disablePoolDeposits
|
|
107
|
+
pool?.disablePoolWithdrawals
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
To track a specific pool, call `onPoolChange` from the context:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { useContext } from "react";
|
|
114
|
+
import { BexStateContext } from "@berachain/berajs/contexts";
|
|
115
|
+
|
|
116
|
+
const { onPoolChange } = useContext(BexStateContext);
|
|
117
|
+
|
|
118
|
+
// When user navigates to a pool page:
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
onPoolChange({ id: poolId, isInRecoveryMode, isPaused });
|
|
121
|
+
}, [poolId]);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Key Types
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
type IAggregatorArgs = {
|
|
128
|
+
tokenIn: MinimalERC20;
|
|
129
|
+
tokenOut: MinimalERC20;
|
|
130
|
+
amount: string; // wei string
|
|
131
|
+
slippage: number; // e.g. 0.5 for 0.5%
|
|
132
|
+
account?: Address;
|
|
133
|
+
swapKind: SwapKind; // from @berachain-foundation/berancer-sdk
|
|
134
|
+
publicClient?: PublicClient;
|
|
135
|
+
aggregatorsFeeBps?: number;
|
|
136
|
+
rewardVault?: Address; // stake output into this vault after swap
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
type IAggregatorQuote = {
|
|
140
|
+
name: string;
|
|
141
|
+
amountOut: string;
|
|
142
|
+
amountOutUsd: string;
|
|
143
|
+
amountIn: string;
|
|
144
|
+
amountInUsd: string;
|
|
145
|
+
priceImpactPercentage: number;
|
|
146
|
+
exchangeRate: number;
|
|
147
|
+
relativeLossPercentage: number;
|
|
148
|
+
isBest?: boolean;
|
|
149
|
+
allowanceRequirements: AllowanceQueryItem[];
|
|
150
|
+
swapFeeBps: number;
|
|
151
|
+
getCalldata?: ({ account }: { account: Address }) => Calldata;
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Complete Example: Swap UI
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
"use client";
|
|
159
|
+
import { useAggregatorsQuotes, useBeraContractWrite } from "@berachain/berajs/hooks";
|
|
160
|
+
import { useBexStatus } from "@berachain/berajs/hooks";
|
|
161
|
+
import { TransactionActionType } from "@berachain/berajs/enum";
|
|
162
|
+
import { SwapKind } from "@berachain-foundation/berancer-sdk";
|
|
163
|
+
import { useAccount } from "wagmi";
|
|
164
|
+
import type { Address } from "viem";
|
|
165
|
+
|
|
166
|
+
const WBERA = {
|
|
167
|
+
address: "0x6969696969696969696969696969696969696969" as Address,
|
|
168
|
+
decimals: 18,
|
|
169
|
+
symbol: "WBERA",
|
|
170
|
+
name: "Wrapped BERA",
|
|
171
|
+
chainId: 80094,
|
|
172
|
+
};
|
|
173
|
+
const HONEY = {
|
|
174
|
+
address: "0xFCBD14DC51f0A4d49d5E53C2E0950e0bC26d0Dce" as Address,
|
|
175
|
+
decimals: 18,
|
|
176
|
+
symbol: "HONEY",
|
|
177
|
+
name: "Honey",
|
|
178
|
+
chainId: 80094,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export function SwapUI({ amountIn }: { amountIn: string }) {
|
|
182
|
+
const { address } = useAccount();
|
|
183
|
+
const { protocol } = useBexStatus();
|
|
184
|
+
|
|
185
|
+
const { data: quotes, isLoading: isQuoting } = useAggregatorsQuotes(
|
|
186
|
+
{
|
|
187
|
+
tokenIn: WBERA,
|
|
188
|
+
tokenOut: HONEY,
|
|
189
|
+
amount: amountIn,
|
|
190
|
+
slippage: 0.5,
|
|
191
|
+
account: address,
|
|
192
|
+
swapKind: SwapKind.GivenIn,
|
|
193
|
+
},
|
|
194
|
+
{ opts: { isEnabled: !!amountIn && amountIn !== "0" && !protocol.isPaused } }
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
const { write, isLoading: isSwapping } = useBeraContractWrite();
|
|
198
|
+
|
|
199
|
+
const bestQuote = quotes?.[0];
|
|
200
|
+
|
|
201
|
+
const handleSwap = () => {
|
|
202
|
+
if (!bestQuote?.getCalldata || !address) return;
|
|
203
|
+
const calldata = bestQuote.getCalldata({ account: address });
|
|
204
|
+
|
|
205
|
+
write({
|
|
206
|
+
address: calldata.address,
|
|
207
|
+
data: calldata.data,
|
|
208
|
+
value: calldata.value,
|
|
209
|
+
message: "Swapping WBERA for HONEY...",
|
|
210
|
+
actionType: TransactionActionType.SWAP,
|
|
211
|
+
contractName: "bex.router",
|
|
212
|
+
onSuccess: (receipt) => console.log("Swapped!", receipt.transactionHash),
|
|
213
|
+
onError: (err) => console.error(err.displayMessage),
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
if (protocol.isPaused) return <div>Protocol is paused</div>;
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<div>
|
|
221
|
+
{isQuoting && <p>Getting quotes...</p>}
|
|
222
|
+
{bestQuote && !isQuoting && (
|
|
223
|
+
<div>
|
|
224
|
+
<p>Best route: {bestQuote.name}</p>
|
|
225
|
+
<p>You receive: {bestQuote.amountOut} HONEY (${bestQuote.amountOutUsd})</p>
|
|
226
|
+
<p>Price impact: {bestQuote.priceImpactPercentage.toFixed(2)}%</p>
|
|
227
|
+
<button onClick={handleSwap} disabled={isSwapping || !address}>
|
|
228
|
+
{isSwapping ? "Swapping..." : "Swap"}
|
|
229
|
+
</button>
|
|
230
|
+
</div>
|
|
231
|
+
)}
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# BeraJS — POL Reference
|
|
2
|
+
|
|
3
|
+
POL (Proof of Liquidity) is Berachain's validator incentive system. Protocols deploy **reward vaults** that emit **BGT** (non-transferable governance token) to stakers. Validators direct BGT emissions to vaults via their cutting board weights.
|
|
4
|
+
|
|
5
|
+
## Reward Vault List
|
|
6
|
+
|
|
7
|
+
### `useRewardVaults` / `getRewardVaults`
|
|
8
|
+
|
|
9
|
+
Paginated list of reward vaults with optional filtering.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { useRewardVaults } from "@berachain/berajs/hooks";
|
|
13
|
+
|
|
14
|
+
const { data, isLoading, refresh } = useRewardVaults({
|
|
15
|
+
filter: {
|
|
16
|
+
first: 20,
|
|
17
|
+
// where: { search: "kodiak" }
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// data: ApiVaultFragment[] | undefined
|
|
22
|
+
// Each vault has: address, name, stakingToken, apr, tvl, etc.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// Server-side:
|
|
27
|
+
import { getRewardVaults } from "@berachain/berajs/actions";
|
|
28
|
+
const vaults = await getRewardVaults({ filter: { first: 20 } });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### `useRewardVaultsQueryKey`
|
|
32
|
+
|
|
33
|
+
Get the SWR cache key for SSR prefetching:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { useRewardVaultsQueryKey } from "@berachain/berajs/hooks";
|
|
37
|
+
const key = useRewardVaultsQueryKey(filter, onChainIncentives);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Single Vault
|
|
41
|
+
|
|
42
|
+
### `useRewardVault` / `getRewardVault`
|
|
43
|
+
|
|
44
|
+
Fetch a single vault by its contract address.
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { useRewardVault } from "@berachain/berajs/hooks";
|
|
48
|
+
|
|
49
|
+
const { data: vault } = useRewardVault({ address: "0xVaultAddress" });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Throws `NotFoundError` if the vault does not exist.
|
|
53
|
+
|
|
54
|
+
## User Vault Position
|
|
55
|
+
|
|
56
|
+
### `useUserVaultInfo` / `getUserVaultInfo`
|
|
57
|
+
|
|
58
|
+
Connected user's staked balance and earned BGT for a vault.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { useUserVaultInfo } from "@berachain/berajs/hooks";
|
|
62
|
+
import { useAccount } from "wagmi";
|
|
63
|
+
|
|
64
|
+
const { address } = useAccount();
|
|
65
|
+
const { data: vaultInfo } = useUserVaultInfo(
|
|
66
|
+
{ vaultAddress: "0xVault", account: address },
|
|
67
|
+
{ opts: { isEnabled: !!address } }
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// vaultInfo: UserVaultInfo | undefined
|
|
71
|
+
// {
|
|
72
|
+
// balance: bigint, // staked amount in wei
|
|
73
|
+
// delegatedBalance: bigint,
|
|
74
|
+
// withdrawableBalance: bigint,
|
|
75
|
+
// rewards: string, // earned BGT (formatted string)
|
|
76
|
+
// percentage: string // user's % share of vault
|
|
77
|
+
// }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `useUserVaults` / `getUserVaults`
|
|
81
|
+
|
|
82
|
+
All vaults where the user has an active staked position.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { useUserVaults } from "@berachain/berajs/hooks";
|
|
86
|
+
|
|
87
|
+
const { data: userVaults } = useUserVaults({ account: "0x..." });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Vault Incentives
|
|
91
|
+
|
|
92
|
+
### `useRewardVaultIncentives` / `getRewardVaultIncentives`
|
|
93
|
+
|
|
94
|
+
Incentive tokens offered by protocols to attract BGT emissions to their vault.
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { useRewardVaultIncentives } from "@berachain/berajs/hooks";
|
|
98
|
+
|
|
99
|
+
const { data: incentives } = useRewardVaultIncentives({
|
|
100
|
+
vaultAddress: "0xVault",
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## BGT APR
|
|
105
|
+
|
|
106
|
+
### `useBgtAprSimulation` / `getBgtAprSimulation`
|
|
107
|
+
|
|
108
|
+
Estimate APR for a vault given a hypothetical BGT emission weight.
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { useBgtAprSimulation } from "@berachain/berajs/hooks";
|
|
112
|
+
|
|
113
|
+
const { data: simulation } = useBgtAprSimulation({
|
|
114
|
+
vaultAddress: "0xVault",
|
|
115
|
+
proposedWeight: 0.1, // 10% of total BGT emissions
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Transaction Action Types (POL)
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { TransactionActionType } from "@berachain/berajs/enum";
|
|
123
|
+
|
|
124
|
+
TransactionActionType.STAKE // "Stake"
|
|
125
|
+
TransactionActionType.UNSTAKE // "Unstake"
|
|
126
|
+
TransactionActionType.CLAIMING_REWARDS // "Claiming BGT"
|
|
127
|
+
TransactionActionType.CREATE_BRIBE // "Add Incentives"
|
|
128
|
+
TransactionActionType.CLAIMING_BRIBES // "Claiming Incentives"
|
|
129
|
+
TransactionActionType.BONDING_BERA // "Stake BERA"
|
|
130
|
+
TransactionActionType.UNBONDING_BERA // "Unstake BERA"
|
|
131
|
+
TransactionActionType.QUEUE_UNBONDING_BERA // "Queue Unstake BERA"
|
|
132
|
+
TransactionActionType.REDEEM_BGT // "Redeem BGT"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Complete Example: Vault Card with Claim Button
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
"use client";
|
|
139
|
+
import { useUserVaultInfo, useRewardVault } from "@berachain/berajs/hooks";
|
|
140
|
+
import { useBeraContractWrite } from "@berachain/berajs/hooks";
|
|
141
|
+
import { TransactionActionType } from "@berachain/berajs/enum";
|
|
142
|
+
import { useAccount } from "wagmi";
|
|
143
|
+
import type { Address } from "viem";
|
|
144
|
+
|
|
145
|
+
// Minimal ABI for the getReward function on reward vaults
|
|
146
|
+
const REWARD_VAULT_ABI = [{
|
|
147
|
+
name: "getReward",
|
|
148
|
+
type: "function",
|
|
149
|
+
stateMutability: "nonpayable",
|
|
150
|
+
inputs: [{ name: "account", type: "address" }],
|
|
151
|
+
outputs: [{ name: "reward", type: "uint256" }],
|
|
152
|
+
}] as const;
|
|
153
|
+
|
|
154
|
+
export function VaultCard({ vaultAddress }: { vaultAddress: Address }) {
|
|
155
|
+
const { address } = useAccount();
|
|
156
|
+
const { data: vault } = useRewardVault({ address: vaultAddress });
|
|
157
|
+
const { data: userInfo, refresh } = useUserVaultInfo(
|
|
158
|
+
{ vaultAddress, account: address },
|
|
159
|
+
{ opts: { isEnabled: !!address } }
|
|
160
|
+
);
|
|
161
|
+
const { write, isLoading } = useBeraContractWrite();
|
|
162
|
+
|
|
163
|
+
const handleClaim = () => {
|
|
164
|
+
if (!address) return;
|
|
165
|
+
write({
|
|
166
|
+
address: vaultAddress,
|
|
167
|
+
abi: REWARD_VAULT_ABI,
|
|
168
|
+
functionName: "getReward",
|
|
169
|
+
params: [address],
|
|
170
|
+
message: "Claiming BGT rewards...",
|
|
171
|
+
actionType: TransactionActionType.CLAIMING_REWARDS,
|
|
172
|
+
contractName: "pol.rewardVault",
|
|
173
|
+
onSuccess: () => refresh(),
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
if (!vault) return null;
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div>
|
|
181
|
+
<h3>{vault.name}</h3>
|
|
182
|
+
{userInfo && (
|
|
183
|
+
<>
|
|
184
|
+
<p>Earned BGT: {userInfo.rewards}</p>
|
|
185
|
+
<p>Your share: {userInfo.percentage}%</p>
|
|
186
|
+
</>
|
|
187
|
+
)}
|
|
188
|
+
<button onClick={handleClaim} disabled={isLoading || !address}>
|
|
189
|
+
{isLoading ? "Claiming..." : "Claim BGT"}
|
|
190
|
+
</button>
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
```
|