From 4145d4811138f0987beeb9df0bfd6dcee2d613b1 Mon Sep 17 00:00:00 2001 From: Fabio Rigamonti <73019897+fabiorigam@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:19:46 +0100 Subject: [PATCH] feat: add new hooks --- .../src/app/pages/homepage.tsx | 11 ++- packages/dapp-kit-react-privy/package.json | 6 +- .../DAppKitPrivyProvider.tsx | 70 ++++++++++++------- .../src/DAppKitPrivyProvider/hooks/index.ts | 2 + .../hooks/useB3TRBalance.tsx | 33 +++++++++ .../hooks/useVOT3Balance.tsx | 33 +++++++++ .../src/DAppKitPrivyProvider/utils/consts.ts | 23 ++++++ yarn.lock | 19 +++++ 8 files changed, 168 insertions(+), 29 deletions(-) create mode 100644 packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useB3TRBalance.tsx create mode 100644 packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useVOT3Balance.tsx create mode 100644 packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/utils/consts.ts diff --git a/examples/sample-privy-next-app/src/app/pages/homepage.tsx b/examples/sample-privy-next-app/src/app/pages/homepage.tsx index e3985a24..bc95e3de 100644 --- a/examples/sample-privy-next-app/src/app/pages/homepage.tsx +++ b/examples/sample-privy-next-app/src/app/pages/homepage.tsx @@ -4,6 +4,8 @@ import { type ReactElement } from 'react'; import { useDisclosure, Button } from "@chakra-ui/react"; import { useWalletAdapter, + useVOT3Balance, + useB3TRBalance, // dappKitModal, ConnectModal, } from "@vechain/dapp-kit-react-privy"; @@ -11,7 +13,8 @@ import { const HomePage = (): ReactElement => { const { isConnected, isConnectedWithPrivy, isConnectedWithDappKit, connectedAddress, abstractedAccount, logout } = useWalletAdapter(); - + const b3trBalanceQuery = isConnected ? useB3TRBalance({ address: connectedAddress ?? '' }) : useB3TRBalance({ address: abstractedAccount.embeddedWallet?.address ?? '' }); + const vot3BalanceQuery = isConnected ? useVOT3Balance({ address: connectedAddress ?? '' }) : useVOT3Balance({ address: abstractedAccount.embeddedWallet?.address ?? '' }); const { isOpen: isLoginOpen, onOpen: onLoginOpen, @@ -33,6 +36,12 @@ const HomePage = (): ReactElement => {

Connected with DappKit: {isConnectedWithDappKit.toString()}

Abstracted Account: {abstractedAccount.embeddedWallet?.address}

Connected Address: {connectedAddress}

+

+ B3TR Balance: {b3trBalanceQuery.isLoading ? 'Loading...' : b3trBalanceQuery.data ?? 'N/A'} +

+

+ VOT3 Balance: {vot3BalanceQuery.isLoading ? 'Loading...' : vot3BalanceQuery.data ?? 'N/A'} +

)} diff --git a/packages/dapp-kit-react-privy/package.json b/packages/dapp-kit-react-privy/package.json index 84d285ff..60b70c76 100644 --- a/packages/dapp-kit-react-privy/package.json +++ b/packages/dapp-kit-react-privy/package.json @@ -26,7 +26,8 @@ "@tanstack/react-query": "^5.61.0", "@vechain/dapp-kit-react": "*", "@vechain/sdk-core": "^1.0.0-rc.3", - "@vechain/sdk-network": "^1.0.0-rc.3" + "@vechain/sdk-network": "^1.0.0-rc.3", + "@vechain/vebetterdao-contracts": "^4.1.0" }, "devDependencies": { "@types/react": "^18.2.28", @@ -35,6 +36,7 @@ "react": "^18.2.0", "tsup": "*", "typescript": "*", - "vite": "^4.5.5" + "vite": "^4.5.5", + "vitest": "^0.34.6" } } diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/DAppKitPrivyProvider.tsx b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/DAppKitPrivyProvider.tsx index b32a25be..af8f1326 100644 --- a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/DAppKitPrivyProvider.tsx +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/DAppKitPrivyProvider.tsx @@ -2,6 +2,7 @@ import { ReactNode } from "react"; import { PrivyProvider as BasePrivyProvider } from "@privy-io/react-auth"; import { DAppKitProvider } from "@vechain/dapp-kit-react"; import { SmartAccountProvider } from "./hooks"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; type Props = { children: ReactNode; @@ -54,6 +55,21 @@ type Props = { }; }; +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 0, + staleTime: 30000, + refetchOnWindowFocus: true, + refetchOnMount: true, + refetchOnReconnect: true, + refetchInterval: false, + refetchIntervalInBackground: false, + gcTime: 1000 * 60 * 60 * 24 // 24 hours + } + } +}); + export const DAppKitPrivyProvider = ({ children, appId, @@ -65,32 +81,34 @@ export const DAppKitPrivyProvider = ({ dappKitConfig }: Props) => { return ( - - + - - {children} - - - + + + {children} + + + + ); }; \ No newline at end of file diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/index.ts b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/index.ts index efdcfb24..6a37515f 100644 --- a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/index.ts +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/index.ts @@ -1,4 +1,6 @@ +export * from "./useB3TRBalance"; export * from "./useWalletAdapter"; export * from "./useTxReceipt"; +export * from "./useVOT3Balance"; export * from "./useSendAccountAbstractedTransaction"; export * from "./useSmartAccount"; diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useB3TRBalance.tsx b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useB3TRBalance.tsx new file mode 100644 index 00000000..d09dac65 --- /dev/null +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useB3TRBalance.tsx @@ -0,0 +1,33 @@ +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import { B3TR_CONTRACT } from "../utils/consts"; +import { FixedPointNumber, Units } from "@vechain/sdk-core"; + +export const useB3TRBalance = ({ + address +}: { + address: string; +}): UseQueryResult => { + return useQuery({ + queryKey: ["useB3TRBalance", address], + queryFn: async () => { + if (address !== null && address !== undefined && address === '') { + return '0'; + } + try { + const balanceB3TR = ( + await B3TR_CONTRACT.read.balanceOf(address) + )[0] as bigint; + + return Units.formatEther( + FixedPointNumber.of(balanceB3TR) + ); + } catch (error) { + console.error('Failed to fetch B3TR balance:', error); + return 'error'; + } + }, + staleTime: 3000, + refetchInterval: 10000, + enabled: address !== null && address !== undefined && address !== '' + }); +}; diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useVOT3Balance.tsx b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useVOT3Balance.tsx new file mode 100644 index 00000000..bdffc7c2 --- /dev/null +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useVOT3Balance.tsx @@ -0,0 +1,33 @@ +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import { VOT3_CONTRACT } from "../utils/consts"; +import { FixedPointNumber, Units } from "@vechain/sdk-core"; + +export const useVOT3Balance = ({ + address +}: { + address: string; +}): UseQueryResult => { + return useQuery({ + queryKey: ["useVOT3Balance", address], + queryFn: async () => { + if (address !== null && address !== undefined && address === '') { + return '0'; + } + try { + const balanceVOT3 = ( + await VOT3_CONTRACT.read.balanceOf(address) + )[0] as bigint; + + return Units.formatEther( + FixedPointNumber.of(balanceVOT3) + ); + } catch (error) { + console.error('Failed to fetch VOT3 balance:', error); + return 'error'; + } + }, + staleTime: 3000, + refetchInterval: 10000, + enabled: address !== null && address !== undefined && address !== '' + }); +}; diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/utils/consts.ts b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/utils/consts.ts new file mode 100644 index 00000000..c1098bc2 --- /dev/null +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/utils/consts.ts @@ -0,0 +1,23 @@ +import { B3TR, VOT3 } from '@vechain/vebetterdao-contracts'; +import { ThorClient } from '@vechain/sdk-network'; + +/** + * Thor client instance + */ +export const THOR_CLIENT = ThorClient.at('https://mainnet.vechain.org'); + +/** + * B3TR contract instance + */ +export const B3TR_CONTRACT = THOR_CLIENT.contracts.load( + B3TR.address.mainnet, + B3TR.abi +); + +/** + * VOT3 contract instance + */ +export const VOT3_CONTRACT = THOR_CLIENT.contracts.load( + VOT3.address.mainnet, + VOT3.abi +); diff --git a/yarn.lock b/yarn.lock index 8519910a..e5e4c351 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4837,11 +4837,21 @@ read-package-json-fast "^3.0.0" which "^3.0.0" +"@openzeppelin/contracts-upgradeable@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz#3e5321a2ecdd0b206064356798c21225b6ec7105" + integrity sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ== + "@openzeppelin/contracts-upgradeable@^5.0.2": version "5.1.0" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.1.0.tgz#4d37648b7402929c53e2ff6e45749ecff91eb2b6" integrity sha512-AIElwP5Ck+cslNE+Hkemf5SxjJoF4wBvvjxc27Rp+9jaPs/CLIaUBMYe1FNzhdiN0cYuwGRmYaRHmmntuiju4Q== +"@openzeppelin/contracts@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210" + integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA== + "@openzeppelin/contracts@^5.0.2": version "5.1.0" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.1.0.tgz#4e61162f2a2bf414c4e10c45eca98ce5f1aadbd4" @@ -7525,6 +7535,15 @@ "@openzeppelin/contracts-upgradeable" "^5.0.2" ethers "^6.9.0" +"@vechain/vebetterdao-contracts@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@vechain/vebetterdao-contracts/-/vebetterdao-contracts-4.1.0.tgz#5a081bf9c548ea777fe16dcab40536d6d2cc1a62" + integrity sha512-vLxxErpvHuVisrkgvrrqgz8hkhbhreEmOyjolcRGpYF9ozzhEm1wTZKelO9qmKoNi/mviMG6ZYZU3Ykwg9LfIw== + dependencies: + "@openzeppelin/contracts" "5.0.2" + "@openzeppelin/contracts-upgradeable" "5.0.2" + ethers "^6.9.0" + "@vitejs/plugin-basic-ssl@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz#48c46eab21e0730921986ce742563ae83fe7fe34"