diff --git a/src/app/components/Delegations/Delegations.tsx b/src/app/components/Delegations/Delegations.tsx index 2bb6e4b1..a0528ecf 100644 --- a/src/app/components/Delegations/Delegations.tsx +++ b/src/app/components/Delegations/Delegations.tsx @@ -13,7 +13,7 @@ import { import { DelegationsPointsProvider } from "@/app/context/api/DelegationsPointsProvider"; import { useError } from "@/app/context/Error/ErrorContext"; import { useBTCWallet } from "@/app/context/wallet/BTCWalletProvider"; -import { useDelegations } from "@/app/hooks/api/useDelegations"; +import { useDelegations } from "@/app/hooks/client/api/useDelegations"; import { useHealthCheck } from "@/app/hooks/useHealthCheck"; import { useDelegationState } from "@/app/state/DelegationState"; import { diff --git a/src/app/components/FAQ/FAQ.tsx b/src/app/components/FAQ/FAQ.tsx index 7c4a820d..9e12c390 100644 --- a/src/app/components/FAQ/FAQ.tsx +++ b/src/app/components/FAQ/FAQ.tsx @@ -1,6 +1,6 @@ import { Heading } from "@babylonlabs-io/bbn-core-ui"; -import { useNetworkInfo } from "@/app/hooks/api/useNetworkInfo"; +import { useNetworkInfo } from "@/app/hooks/client/api/useNetworkInfo"; import { getNetworkConfig } from "@/config/network.config"; import { questions } from "./data/questions"; diff --git a/src/app/components/Modals/PendingVerificationModal.tsx b/src/app/components/Modals/PendingVerificationModal.tsx index 08f268ed..06f03ccd 100644 --- a/src/app/components/Modals/PendingVerificationModal.tsx +++ b/src/app/components/Modals/PendingVerificationModal.tsx @@ -2,7 +2,7 @@ import { Button, Heading, Loader } from "@babylonlabs-io/bbn-core-ui"; import { useCallback } from "react"; import { BiSolidBadgeCheck } from "react-icons/bi"; -import { useDelegationV2 } from "@/app/hooks/api/useDelegationV2"; +import { useDelegationV2 } from "@/app/hooks/client/api/useDelegationV2"; import { useTransactionService } from "@/app/hooks/services/useTransactionService"; import { DelegationV2StakingState as state } from "@/app/types/delegationsV2"; import { getNetworkConfig } from "@/config/network.config"; diff --git a/src/app/components/Modals/PreviewModal.tsx b/src/app/components/Modals/PreviewModal.tsx index 8146b778..a7069c7c 100644 --- a/src/app/components/Modals/PreviewModal.tsx +++ b/src/app/components/Modals/PreviewModal.tsx @@ -11,7 +11,7 @@ import { Text, } from "@babylonlabs-io/bbn-core-ui"; -import { useNetworkInfo } from "@/app/hooks/api/useNetworkInfo"; +import { useNetworkInfo } from "@/app/hooks/client/api/useNetworkInfo"; import { useIsMobileView } from "@/app/hooks/useBreakpoint"; import { getNetworkConfig } from "@/config/network.config"; import { satoshiToBtc } from "@/utils/btc"; diff --git a/src/app/components/Stats/Stats.tsx b/src/app/components/Stats/Stats.tsx index fa77d464..41d37bd1 100644 --- a/src/app/components/Stats/Stats.tsx +++ b/src/app/components/Stats/Stats.tsx @@ -1,7 +1,7 @@ import { Heading } from "@babylonlabs-io/bbn-core-ui"; import { memo } from "react"; -import { useSystemStats } from "@/app/hooks/api/useSystemStats"; +import { useSystemStats } from "@/app/hooks/client/api/useSystemStats"; import { getNetworkConfig } from "@/config/network.config"; import { satoshiToBtc } from "@/utils/btc"; import { maxDecimals } from "@/utils/maxDecimals"; diff --git a/src/app/components/Summary/Summary.tsx b/src/app/components/Summary/Summary.tsx index abf96098..1e8d2589 100644 --- a/src/app/components/Summary/Summary.tsx +++ b/src/app/components/Summary/Summary.tsx @@ -3,7 +3,7 @@ import { FaBitcoin } from "react-icons/fa"; import { Tooltip } from "react-tooltip"; import { useBTCWallet } from "@/app/context/wallet/BTCWalletProvider"; -import { useNetworkInfo } from "@/app/hooks/api/useNetworkInfo"; +import { useNetworkInfo } from "@/app/hooks/client/api/useNetworkInfo"; import { useHealthCheck } from "@/app/hooks/useHealthCheck"; import { useAppState } from "@/app/state"; import { useDelegationState } from "@/app/state/DelegationState"; diff --git a/src/app/context/wallet/CosmosWalletProvider.tsx b/src/app/context/wallet/CosmosWalletProvider.tsx index 02461c78..be000abb 100644 --- a/src/app/context/wallet/CosmosWalletProvider.tsx +++ b/src/app/context/wallet/CosmosWalletProvider.tsx @@ -1,9 +1,4 @@ -import { - DistributionExtension, - QueryClient, - setupDistributionExtension, - SigningStargateClient, -} from "@cosmjs/stargate"; +import { QueryClient, SigningStargateClient } from "@cosmjs/stargate"; import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; import { CosmosProvider } from "@tomo-inc/wallet-connect-sdk"; import { @@ -28,7 +23,7 @@ interface CosmosWalletContextProps { disconnect: () => void; open: () => void; signingStargateClient: SigningStargateClient | undefined; - distributionQueryClient: DistributionExtension | undefined; + queryClient: QueryClient | undefined; } const CosmosWalletContext = createContext({ @@ -37,7 +32,7 @@ const CosmosWalletContext = createContext({ disconnect: () => {}, open: () => {}, signingStargateClient: undefined, - distributionQueryClient: undefined, + queryClient: undefined, }); export const CosmosWalletProvider = ({ children }: PropsWithChildren) => { @@ -48,9 +43,7 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => { const [signingStargateClient, setSigningStargateClient] = useState< SigningStargateClient | undefined >(); - const [distributionQueryClient, setDistributionQueryClient] = useState< - DistributionExtension | undefined - >(); + const [queryClient, setQueryClient] = useState(); const { showError, captureError } = useError(); const { open, isConnected, providers } = useWalletConnection(); @@ -76,10 +69,8 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => { const tmClient = await Tendermint34Client.connect( "https://rpc.devnet.babylonlabs.io", ); - const baseQuery = QueryClient.withExtensions(tmClient); - const distributionQuery = setupDistributionExtension(baseQuery); - - setDistributionQueryClient(distributionQuery); + const queryClient = QueryClient.withExtensions(tmClient); + setQueryClient(queryClient); setSigningStargateClient(client); setCosmosWalletProvider(providers.cosmosProvider); @@ -104,7 +95,7 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => { disconnect: cosmosDisconnect, open, signingStargateClient, - distributionQueryClient, + queryClient, }), [ cosmosBech32Address, @@ -112,7 +103,7 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => { cosmosDisconnect, open, signingStargateClient, - distributionQueryClient, + queryClient, ], ); diff --git a/src/app/hooks/api/useApi.ts b/src/app/hooks/client/api/useApi.ts similarity index 100% rename from src/app/hooks/api/useApi.ts rename to src/app/hooks/client/api/useApi.ts diff --git a/src/app/hooks/api/useBTCTipHeight.ts b/src/app/hooks/client/api/useBTCTipHeight.ts similarity index 79% rename from src/app/hooks/api/useBTCTipHeight.ts rename to src/app/hooks/client/api/useBTCTipHeight.ts index 7c5e30e1..86236831 100644 --- a/src/app/hooks/api/useBTCTipHeight.ts +++ b/src/app/hooks/client/api/useBTCTipHeight.ts @@ -1,4 +1,4 @@ -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; import { getTipHeight } from "@/utils/mempool_api"; export const BTC_TIP_HEIGHT_KEY = "BTC_TIP_HEIGHT"; diff --git a/src/app/hooks/api/useDelegationV2.ts b/src/app/hooks/client/api/useDelegationV2.ts similarity index 100% rename from src/app/hooks/api/useDelegationV2.ts rename to src/app/hooks/client/api/useDelegationV2.ts diff --git a/src/app/hooks/api/useDelegations.ts b/src/app/hooks/client/api/useDelegations.ts similarity index 100% rename from src/app/hooks/api/useDelegations.ts rename to src/app/hooks/client/api/useDelegations.ts diff --git a/src/app/hooks/api/useDelegationsV2.ts b/src/app/hooks/client/api/useDelegationsV2.ts similarity index 100% rename from src/app/hooks/api/useDelegationsV2.ts rename to src/app/hooks/client/api/useDelegationsV2.ts diff --git a/src/app/hooks/api/useFinalityProvidersV2.ts b/src/app/hooks/client/api/useFinalityProvidersV2.ts similarity index 100% rename from src/app/hooks/api/useFinalityProvidersV2.ts rename to src/app/hooks/client/api/useFinalityProvidersV2.ts diff --git a/src/app/hooks/api/useNetworkFees.ts b/src/app/hooks/client/api/useNetworkFees.ts similarity index 83% rename from src/app/hooks/api/useNetworkFees.ts rename to src/app/hooks/client/api/useNetworkFees.ts index 8632af1a..2fe5fc86 100644 --- a/src/app/hooks/api/useNetworkFees.ts +++ b/src/app/hooks/client/api/useNetworkFees.ts @@ -1,4 +1,4 @@ -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; import { getNetworkFees } from "@/utils/mempool_api"; export const NETWORK_FEES_KEY = "NETWORK_FEES"; diff --git a/src/app/hooks/api/useNetworkInfo.ts b/src/app/hooks/client/api/useNetworkInfo.ts similarity index 85% rename from src/app/hooks/api/useNetworkInfo.ts rename to src/app/hooks/client/api/useNetworkInfo.ts index 44e319cd..b6091257 100644 --- a/src/app/hooks/api/useNetworkInfo.ts +++ b/src/app/hooks/client/api/useNetworkInfo.ts @@ -1,5 +1,5 @@ import { getNetworkInfo } from "@/app/api/getNetworkInfo"; -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; import { NetworkInfo } from "@/app/types/networkInfo"; export const NETWORK_INFO_KEY = "NETWORK_INFO"; diff --git a/src/app/hooks/api/useOrdinals.ts b/src/app/hooks/client/api/useOrdinals.ts similarity index 95% rename from src/app/hooks/api/useOrdinals.ts rename to src/app/hooks/client/api/useOrdinals.ts index b8712fbb..4fde0984 100644 --- a/src/app/hooks/api/useOrdinals.ts +++ b/src/app/hooks/client/api/useOrdinals.ts @@ -1,7 +1,7 @@ import { postVerifyUtxoOrdinals } from "@/app/api/postFilterOrdinals"; import { ONE_MINUTE } from "@/app/constants"; import { useBTCWallet } from "@/app/context/wallet/BTCWalletProvider"; -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; import { wait } from "@/utils"; import { filterDust } from "@/utils/wallet"; import { diff --git a/src/app/hooks/api/useSystemStats.ts b/src/app/hooks/client/api/useSystemStats.ts similarity index 86% rename from src/app/hooks/api/useSystemStats.ts rename to src/app/hooks/client/api/useSystemStats.ts index 1cbacb92..070caf3e 100644 --- a/src/app/hooks/api/useSystemStats.ts +++ b/src/app/hooks/client/api/useSystemStats.ts @@ -1,6 +1,6 @@ import { getSystemStats } from "@/app/api/getSystemStats"; import { ONE_MINUTE } from "@/app/constants"; -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; export const BTC_TIP_HEIGHT_KEY = "API_STATS"; diff --git a/src/app/hooks/api/useUTXOs.ts b/src/app/hooks/client/api/useUTXOs.ts similarity index 89% rename from src/app/hooks/api/useUTXOs.ts rename to src/app/hooks/client/api/useUTXOs.ts index 687d8f52..5918a6c6 100644 --- a/src/app/hooks/api/useUTXOs.ts +++ b/src/app/hooks/client/api/useUTXOs.ts @@ -1,6 +1,6 @@ import { ONE_MINUTE } from "@/app/constants"; import { useBTCWallet } from "@/app/context/wallet/BTCWalletProvider"; -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; export const UTXO_KEY = "UTXO"; diff --git a/src/app/hooks/api/useVersions.ts b/src/app/hooks/client/api/useVersions.ts similarity index 83% rename from src/app/hooks/api/useVersions.ts rename to src/app/hooks/client/api/useVersions.ts index 3ea629a6..e5a35ad2 100644 --- a/src/app/hooks/api/useVersions.ts +++ b/src/app/hooks/client/api/useVersions.ts @@ -1,5 +1,5 @@ import { getGlobalParams } from "@/app/api/getGlobalParams"; -import { useAPIQuery } from "@/app/hooks/api/useApi"; +import { useAPIQuery } from "@/app/hooks/client/api/useApi"; export const VERSIONS_KEY = "VERSIONS"; diff --git a/src/app/hooks/client/query/useBbnQuery.ts b/src/app/hooks/client/query/useBbnQuery.ts new file mode 100644 index 00000000..cbaa6aef --- /dev/null +++ b/src/app/hooks/client/query/useBbnQuery.ts @@ -0,0 +1,54 @@ +import { incentivequery } from "@babylonlabs-io/babylon-proto-ts"; +import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate"; +import { useCallback } from "react"; + +import { useCosmosWallet } from "@/app/context/wallet/CosmosWalletProvider"; + +const REWARD_GAUGE_KEY_BTC_DELEGATION = "btc_delegation"; + +/** + * Query service for Babylon which contains all the queries for + * interacting with Babylon RPC nodes + */ +export const useBbnQuery = () => { + const { queryClient, bech32Address } = useCosmosWallet(); + + const getRewards = useCallback(async (): Promise => { + if (!queryClient || !bech32Address) { + return 0; + } + const { incentive } = setupIncentiveExtension(queryClient); + + const req: incentivequery.QueryRewardGaugesRequest = + incentivequery.QueryRewardGaugesRequest.fromPartial({ + address: bech32Address, + }); + + const { rewardGauges } = await incentive.RewardGauges(req); + const btcDelegationRewards = + rewardGauges[REWARD_GAUGE_KEY_BTC_DELEGATION]?.coins; + if (!btcDelegationRewards) { + return 0; + } + + return btcDelegationRewards.reduce( + (acc, coin) => acc + Number(coin.amount), + 0, + ); + }, [queryClient, bech32Address]); + + return { + getRewards, + }; +}; + +// Extend the QueryClient with the Incentive module +const setupIncentiveExtension = ( + base: QueryClient, +): { + incentive: incentivequery.QueryClientImpl; +} => { + const rpc = createProtobufRpcClient(base); + const incentiveQueryClient = new incentivequery.QueryClientImpl(rpc); + return { incentive: incentiveQueryClient }; +}; diff --git a/src/app/hooks/services/useFinalityProviderService.ts b/src/app/hooks/services/useFinalityProviderService.ts index 27d0dd17..5c30021a 100644 --- a/src/app/hooks/services/useFinalityProviderService.ts +++ b/src/app/hooks/services/useFinalityProviderService.ts @@ -1,7 +1,7 @@ import { useDebounce } from "@uidotdev/usehooks"; import { useCallback, useState } from "react"; -import { useFinalityProviders } from "@/app/hooks/api/useFinalityProvidersV2"; +import { useFinalityProviders } from "@/app/hooks/client/api/useFinalityProvidersV2"; interface SortState { field?: string; diff --git a/src/app/hooks/services/useRewardsService.tsx b/src/app/hooks/services/useRewardsService.tsx index 4a0da983..a846a495 100644 --- a/src/app/hooks/services/useRewardsService.tsx +++ b/src/app/hooks/services/useRewardsService.tsx @@ -2,44 +2,23 @@ import { useCallback } from "react"; import { useCosmosWallet } from "@/app/context/wallet/CosmosWalletProvider"; +import { useBbnQuery } from "../client/query/useBbnQuery"; + export const useRewardsService = () => { const { connected: cosmosConnected, bech32Address, signingStargateClient, - distributionQueryClient, } = useCosmosWallet(); + const { getRewards: getBbnRewards } = useBbnQuery(); + const getRewards = useCallback(async (): Promise => { if (!cosmosConnected || !bech32Address || !signingStargateClient) { return 0; } - // get public key - const account = await signingStargateClient.getAccount(bech32Address); - const publicKeyHex = Buffer.from(account?.pubkey?.value ?? "").toString( - "hex", - ); - console.log("publicKey", publicKeyHex); - - const result = - await distributionQueryClient?.distribution.delegationTotalRewards( - bech32Address, - ); - if (!result) { - throw new Error("Unable to fetch rewards"); - } - console.log("result", result); - // Sum up all the rewards into a single number - const total = result.total.reduce((sum, coin) => { - return sum + Number(coin.amount); - }, 0); - return total; - }, [ - cosmosConnected, - bech32Address, - signingStargateClient, - distributionQueryClient, - ]); + return getBbnRewards(); + }, [cosmosConnected, bech32Address, signingStargateClient, getBbnRewards]); const claimRewards = useCallback(async () => { throw new Error("Not implemented"); diff --git a/src/app/hooks/services/useTransactionService.tsx b/src/app/hooks/services/useTransactionService.tsx index 91955e31..5389c9aa 100644 --- a/src/app/hooks/services/useTransactionService.tsx +++ b/src/app/hooks/services/useTransactionService.tsx @@ -28,7 +28,7 @@ import { import { getFeeRateFromMempool } from "@/utils/getFeeRateFromMempool"; import { getTxInfo, getTxMerkleProof } from "@/utils/mempool_api"; -import { useNetworkFees } from "../api/useNetworkFees"; +import { useNetworkFees } from "../client/api/useNetworkFees"; export interface BtcStakingInputs { finalityProviderPkNoCoordHex: string; diff --git a/src/app/state/DelegationState.tsx b/src/app/state/DelegationState.tsx index b5e61d8a..ee55c4f9 100644 --- a/src/app/state/DelegationState.tsx +++ b/src/app/state/DelegationState.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, type PropsWithChildren } from "react"; import { useLocalStorage } from "usehooks-ts"; import { useBTCWallet } from "@/app/context/wallet/BTCWalletProvider"; -import { useDelegations } from "@/app/hooks/api/useDelegations"; +import { useDelegations } from "@/app/hooks/client/api/useDelegations"; import type { Delegation } from "@/app/types/delegations"; import { DelegationState as DelegationEnum } from "@/app/types/delegations"; import { createStateUtils } from "@/utils/createStateUtils"; diff --git a/src/app/state/DelegationV2State.tsx b/src/app/state/DelegationV2State.tsx index d1078b7a..85a37ca9 100644 --- a/src/app/state/DelegationV2State.tsx +++ b/src/app/state/DelegationV2State.tsx @@ -6,7 +6,7 @@ import type { DelegationV2 } from "@/app/types/delegationsV2"; import { createStateUtils } from "@/utils/createStateUtils"; import { getDelegationsV2LocalStorageKey } from "@/utils/local_storage/getDelegationsLocalStorageKey"; -import { useDelegationsV2 } from "../hooks/api/useDelegationsV2"; +import { useDelegationsV2 } from "../hooks/client/api/useDelegationsV2"; interface DelegationV2State { isLoading: boolean; diff --git a/src/app/state/index.tsx b/src/app/state/index.tsx index fcb59f9c..7c11d3ac 100644 --- a/src/app/state/index.tsx +++ b/src/app/state/index.tsx @@ -1,8 +1,8 @@ import { useCallback, useMemo, useState, type PropsWithChildren } from "react"; -import { useBTCTipHeight } from "@/app/hooks/api/useBTCTipHeight"; -import { useOrdinals } from "@/app/hooks/api/useOrdinals"; -import { useUTXOs } from "@/app/hooks/api/useUTXOs"; +import { useBTCTipHeight } from "@/app/hooks/client/api/useBTCTipHeight"; +import { useOrdinals } from "@/app/hooks/client/api/useOrdinals"; +import { useUTXOs } from "@/app/hooks/client/api/useUTXOs"; import { createStateUtils } from "@/utils/createStateUtils"; import { filterDust } from "@/utils/wallet"; import type { @@ -10,7 +10,7 @@ import type { UTXO, } from "@/utils/wallet/btc_wallet_provider"; -import { useNetworkInfo } from "../hooks/api/useNetworkInfo"; +import { useNetworkInfo } from "../hooks/client/api/useNetworkInfo"; import { NetworkInfo } from "../types/networkInfo"; import { DelegationState } from "./DelegationState"; diff --git a/src/utils/wallet/bbnRegistry.ts b/src/utils/wallet/bbnRegistry.ts index 207a5a0a..c881076c 100644 --- a/src/utils/wallet/bbnRegistry.ts +++ b/src/utils/wallet/bbnRegistry.ts @@ -1,4 +1,4 @@ -import { btcstakingtx } from "@babylonlabs-io/babylon-proto-ts"; +import { btcstakingtx, incentivetx } from "@babylonlabs-io/babylon-proto-ts"; import { MessageFns } from "@babylonlabs-io/babylon-proto-ts/dist/generated/google/protobuf/any"; import { GeneratedType, Registry } from "@cosmjs/proto-signing"; @@ -10,10 +10,16 @@ type ProtoToRegister = { // List of protos to register in the registry const protosToRegister: ProtoToRegister[] = [ + // BTC Staking { typeUrl: "/babylon.btcstaking.v1.MsgCreateBTCDelegation", messageType: btcstakingtx.MsgCreateBTCDelegation, }, + // Incentives + { + typeUrl: "/babylon.incentive.Msg/WithdrawReward", + messageType: incentivetx.MsgWithdrawReward, + }, ]; // Utility function to create a `GeneratedType` from `MessageFns`