Skip to content

Commit

Permalink
feat: get balance and rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
jrwbabylonlab committed Nov 30, 2024
1 parent 30ed0cc commit 7501af3
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 6 deletions.
68 changes: 63 additions & 5 deletions src/app/components/PersonalBalance/PersonalBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,91 @@
import { Heading } from "@babylonlabs-io/bbn-core-ui";
import { useEffect, useState } from "react";

import { useBTCWallet } from "@/app/context/wallet/BTCWalletProvider";
import { useCosmosWallet } from "@/app/context/wallet/CosmosWalletProvider";
import { useRewardsService } from "@/app/hooks/services/useRewardsService";
import { ubbnToBbn } from "@/utils/bbn";
import { satoshiToBtc } from "@/utils/btc";

import { StatItem } from "../Stats/StatItem";

export function PersonalBalance() {
const { getBalance: getBTCBalance, connected: btcConnected } = useBTCWallet();
const {
signingStargateClient,
connected: cosmosConnected,
bech32Address,
} = useCosmosWallet();

const { getRewards } = useRewardsService();
const [rewards, setRewards] = useState<number>();
const [btcBalance, setBTCBalance] = useState<number>();
const [cosmosBalance, setCosmosBalance] = useState<number>();

useEffect(() => {
const fetchRewards = async () => {
const result = await getRewards();
setRewards(result);
};
const fetchBTCBalance = async () => {
const balance = await getBTCBalance();
setBTCBalance(balance);
};
const fetchCosmosBalance = async () => {
const balance = await signingStargateClient?.getBalance(
bech32Address,
"ubbn",
);
const bbnAmount = Number(balance?.amount ?? 0);
setCosmosBalance(bbnAmount);
};
fetchRewards();
fetchBTCBalance();
fetchCosmosBalance();
}, [getRewards, getBTCBalance, signingStargateClient, bech32Address]);

if (!btcConnected || !cosmosConnected) {
return null;
}

return (
<div className="flex flex-col gap-4 p-1 xl:justify-between mb-12">
<Heading variant="h5" className="text-primary-dark md:text-4xl">
Wallet Balance
</Heading>
<div className="flex flex-col justify-between bg-secondary-contrast rounded p-6 text-base md:flex-row">
<StatItem loading={false} title="Bitcoin Balance" value="100.134 BTC" />
{/* TODO: Need to add the staker tvl value for the bitcoin balance */}
<StatItem
loading={false}
title="Bitcoin Balance"
value={`${satoshiToBtc(btcBalance ?? 0)} BTC`}
/>

<div className="divider mx-0 my-2 md:divider-horizontal" />

<StatItem loading={false} title="Stakable Bitcoin" value="0.134 BTC" />
<StatItem
loading={false}
title="Stakable Bitcoin"
value={`${satoshiToBtc(btcBalance ?? 0)} BTC`}
/>

<div className="divider mx-0 my-2 md:divider-horizontal" />

<StatItem loading={false} title="Babylon Balance" value="100.134 BBN" />
<StatItem
loading={false}
title="Babylon Balance"
value={`${ubbnToBbn(cosmosBalance ?? 0)} BBN`}
/>

<div className="divider mx-0 my-2 md:divider-horizontal" />

<StatItem
loading={false}
title="BBN Rewards"
value="0.134 BBN"
value={`${ubbnToBbn(rewards ?? 0)} BBN`}
actionComponent={{
title: "Claim",
onAction: () => {},
onAction: () => { },
}}
/>
</div>
Expand Down
27 changes: 26 additions & 1 deletion src/app/context/wallet/CosmosWalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { SigningStargateClient } from "@cosmjs/stargate";
import {
DistributionExtension,
QueryClient,
setupDistributionExtension,
SigningStargateClient,
} from "@cosmjs/stargate";
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
import { CosmosProvider } from "@tomo-inc/wallet-connect-sdk";
import {
createContext,
Expand All @@ -22,6 +28,7 @@ interface CosmosWalletContextProps {
disconnect: () => void;
open: () => void;
signingStargateClient: SigningStargateClient | undefined;
distributionQueryClient: DistributionExtension | undefined;
}

const CosmosWalletContext = createContext<CosmosWalletContextProps>({
Expand All @@ -30,6 +37,7 @@ const CosmosWalletContext = createContext<CosmosWalletContextProps>({
disconnect: () => {},
open: () => {},
signingStargateClient: undefined,
distributionQueryClient: undefined,
});

export const CosmosWalletProvider = ({ children }: PropsWithChildren) => {
Expand All @@ -40,6 +48,10 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => {
const [signingStargateClient, setSigningStargateClient] = useState<
SigningStargateClient | undefined
>();
const [distributionQueryClient, setDistributionQueryClient] = useState<
DistributionExtension | undefined
>();

const { showError, captureError } = useError();
const { open, isConnected, providers } = useWalletConnection();

Expand All @@ -58,6 +70,17 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => {
const client = await providers.cosmosProvider.getSigningStargateClient({
registry: getBbnRegistry(),
});

// TODO: Temporary solution until #409 is merged
// Create QueryClient directly
const tmClient = await Tendermint34Client.connect(
"https://rpc.devnet.babylonlabs.io",
);
const baseQuery = QueryClient.withExtensions(tmClient);
const distributionQuery = setupDistributionExtension(baseQuery);

setDistributionQueryClient(distributionQuery);

setSigningStargateClient(client);
setCosmosWalletProvider(providers.cosmosProvider);
setCosmosBech32Address(address);
Expand All @@ -81,13 +104,15 @@ export const CosmosWalletProvider = ({ children }: PropsWithChildren) => {
disconnect: cosmosDisconnect,
open,
signingStargateClient,
distributionQueryClient,
}),
[
cosmosBech32Address,
cosmosWalletProvider,
cosmosDisconnect,
open,
signingStargateClient,
distributionQueryClient,
],
);

Expand Down
52 changes: 52 additions & 0 deletions src/app/hooks/services/useRewardsService.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useCallback } from "react";

import { useCosmosWallet } from "@/app/context/wallet/CosmosWalletProvider";

export const useRewardsService = () => {
const {
connected: cosmosConnected,
bech32Address,
signingStargateClient,
distributionQueryClient,
} = useCosmosWallet();

const getRewards = useCallback(async (): Promise<number> => {
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,
]);

const claimRewards = useCallback(async () => {
throw new Error("Not implemented");
}, []);

return {
getRewards,
claimRewards,
};
};
19 changes: 19 additions & 0 deletions src/utils/bbn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Converts BBN to uBBN (micro BBN).
* should be used internally in the app
* @param bbn The amount in BBN.
* @returns The equivalent amount in uBBN.
*/
export function bbnToUbbn(bbn: number): number {
return Math.round(bbn * 1e6);
}

/**
* Converts uBBN (micro BBN) to BBN.
* should be used only in the UI
* @param ubbn The amount in uBBN.
* @returns The equivalent amount in BBN.
*/
export function ubbnToBbn(ubbn: number): number {
return ubbn / 1e6;
}

0 comments on commit 7501af3

Please sign in to comment.