diff --git a/src/app/components/mint-unmint/components/landing-page/landing-page.tsx b/src/app/components/mint-unmint/components/landing-page/landing-page.tsx index 395393cd..3d41d6ff 100644 --- a/src/app/components/mint-unmint/components/landing-page/landing-page.tsx +++ b/src/app/components/mint-unmint/components/landing-page/landing-page.tsx @@ -1,13 +1,17 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { Divider, HStack } from '@chakra-ui/react'; +import { TokenStatsBoardTVL } from '@components/proof-of-reserve/components/token-stats-board/components/token-stats-board-tvl'; +import { useBitcoinPrice } from '@hooks/use-bitcoin-price'; +import { ProofOfReserveContext } from '@providers/proof-of-reserve-context-provider'; -import { ProtocolSummaryStack } from '../protocol-summary-stack/protocol-summary-stack'; import { LandingPageLayout } from './components/landing-page.layout'; import { SetupInformation } from './components/setup-information/setup-informatio'; import { WelcomeStack } from './components/welcome-stack'; export function LandingPage(): React.JSX.Element { + const { bitcoinPrice } = useBitcoinPrice(); + const { totalSupply } = useContext(ProofOfReserveContext); return ( @@ -15,7 +19,7 @@ export function LandingPage(): React.JSX.Element { - + ); diff --git a/src/app/components/mint-unmint/components/protocol-summary-stack/components/protocol-summary-stack.layout.tsx b/src/app/components/mint-unmint/components/protocol-summary-stack/components/protocol-summary-stack.layout.tsx deleted file mode 100644 index 7f40bd8e..00000000 --- a/src/app/components/mint-unmint/components/protocol-summary-stack/components/protocol-summary-stack.layout.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { HStack } from '@chakra-ui/react'; -import { HasChildren } from '@models/has-children'; - -export function ProtocolSummaryStackLayout({ children }: HasChildren): React.JSX.Element { - return ( - - {children} - - ); -} diff --git a/src/app/components/mint-unmint/components/protocol-summary-stack/protocol-summary-stack.tsx b/src/app/components/mint-unmint/components/protocol-summary-stack/protocol-summary-stack.tsx deleted file mode 100644 index a67e69c3..00000000 --- a/src/app/components/mint-unmint/components/protocol-summary-stack/protocol-summary-stack.tsx +++ /dev/null @@ -1,33 +0,0 @@ -// import { ProtocolHistory } from "@components/protocol-history/protocol-history"; -import { Skeleton, Text, VStack } from '@chakra-ui/react'; -import { useBitcoinPrice } from '@hooks/use-bitcoin-price'; -import { useEthereum } from '@hooks/use-ethereum'; - -import { ProtocolSummaryStackLayout } from './components/protocol-summary-stack.layout'; - -export function ProtocolSummaryStack(): React.JSX.Element { - const { totalSupply } = useEthereum(); - const { bitcoinPrice } = useBitcoinPrice(); - - return ( - - - - TVL - - - - - {totalSupply} dlcBTC - - - - - ${totalSupply && bitcoinPrice ? (totalSupply * bitcoinPrice).toLocaleString() : 0} - - - - - - ); -} diff --git a/src/app/components/proof-of-reserve/proof-of-reserve.tsx b/src/app/components/proof-of-reserve/proof-of-reserve.tsx index be1daeaf..d3e5395e 100644 --- a/src/app/components/proof-of-reserve/proof-of-reserve.tsx +++ b/src/app/components/proof-of-reserve/proof-of-reserve.tsx @@ -2,7 +2,6 @@ import { useContext } from 'react'; import { Divider, HStack, Text } from '@chakra-ui/react'; import { useBitcoinPrice } from '@hooks/use-bitcoin-price'; -import { useEthereum } from '@hooks/use-ethereum'; import { bitcoin, dlcBTC } from '@models/token'; import { ProofOfReserveContext } from '@providers/proof-of-reserve-context-provider'; @@ -12,9 +11,9 @@ import { TokenStatsBoardTVL } from './components/token-stats-board/components/to import { TokenStatsBoardLayout } from './components/token-stats-board/token-stats-board.layout'; export function ProofOfReserve(): React.JSX.Element { - const { totalSupply } = useEthereum(); const { bitcoinPrice } = useBitcoinPrice(); - const { proofOfReserve } = useContext(ProofOfReserveContext); + + const { proofOfReserve, totalSupply } = useContext(ProofOfReserveContext); return ( diff --git a/src/app/hooks/use-ethereum.ts b/src/app/hooks/use-ethereum.ts index 2978e5f6..930c55ce 100644 --- a/src/app/hooks/use-ethereum.ts +++ b/src/app/hooks/use-ethereum.ts @@ -4,6 +4,12 @@ import { useSelector } from 'react-redux'; import { customShiftValue } from '@common/utilities'; import { EthereumError } from '@models/error-types'; +import { + EthereumNetwork, + EthereumNetworkID, + ethereumArbSepolia, + ethereumSepolia, +} from '@models/ethereum-network'; import { RawVault, Vault, VaultState } from '@models/vault'; import { VaultContext } from '@providers/vault-context-provider'; import { RootState, store } from '@store/index'; @@ -17,10 +23,10 @@ interface UseEthereumReturnType { getDLCBTCBalance: () => Promise; getLockedBTCBalance: () => Promise; totalSupply: number | undefined; - getAttestorGroupPublicKey: () => Promise; + getAttestorGroupPublicKey: (ethereumNetwork: EthereumNetwork) => Promise; getAllVaults: () => Promise; getVault: (vaultUUID: string, vaultState: VaultState) => Promise; - getAllFundedVaults: () => Promise; + getAllFundedVaults: (thereumNetwork: EthereumNetwork) => Promise; setupVault: (btcDepositAmount: number) => Promise; closeVault: (vaultUUID: string) => Promise; } @@ -38,14 +44,18 @@ export function throwEthereumError(message: string, error: any): void { export function useEthereum(): UseEthereumReturnType { const { vaults } = useContext(VaultContext); - const { protocolContract, dlcBTCContract, dlcManagerContract } = useEthereumContext(); + const { protocolContract, dlcBTCContract } = useEthereumContext(); const { address, network } = useSelector((state: RootState) => state.account); const [totalSupply, setTotalSupply] = useState(undefined); const fetchTotalSupply = async () => { - await getTotalSupply(); + const sepoliaTotalSupply = await getTotalSupply(ethereumSepolia); + console.log('sepoliaTotalSupply', sepoliaTotalSupply); + const arbSepoliaTotalSupply = await getTotalSupply(ethereumArbSepolia); + console.log('arbSepoliaTotalSupply', arbSepoliaTotalSupply); + setTotalSupply(customShiftValue(sepoliaTotalSupply + arbSepoliaTotalSupply, 8, true)); }; useEffect(() => { @@ -69,15 +79,27 @@ export function useEthereum(): UseEthereumReturnType { }; } - async function getTotalSupply() { - const provider = ethers.providers.getDefaultProvider( - 'https://ethereum-sepolia.publicnode.com/' - ); - const branchName = import.meta.env.VITE_ETHEREUM_DEPLOYMENT_BRANCH; - const contractVersion = import.meta.env.VITE_ETHEREUM_DEPLOYMENT_VERSION; - const deploymentPlanURL = `https://raw.githubusercontent.com/DLC-link/dlc-solidity/${branchName}/deploymentFiles/sepolia/v${contractVersion}/DLCBTC.json`; + async function getDefaultProvider( + ethereumNetwork: EthereumNetwork, + contractName: string + ): Promise { + let nodeURL: string; + switch (ethereumNetwork.id) { + case EthereumNetworkID.Sepolia: + nodeURL = 'https://ethereum-sepolia.publicnode.com/'; + break; + case EthereumNetworkID.ArbSepolia: + nodeURL = 'https://sepolia-rollup.arbitrum.io/rpc'; + break; + default: + throw new EthereumError(`Invalid Ethereum Network ID: ${ethereumNetwork.id}`); + } try { + const provider = ethers.providers.getDefaultProvider(nodeURL); + const branchName = import.meta.env.VITE_ETHEREUM_DEPLOYMENT_BRANCH; + const contractVersion = import.meta.env.VITE_ETHEREUM_DEPLOYMENT_VERSION; + const deploymentPlanURL = `https://raw.githubusercontent.com/DLC-link/dlc-solidity/${branchName}/deploymentFiles/${ethereumNetwork.name.toLowerCase()}/v${contractVersion}/${contractName}.json`; const response = await fetch(deploymentPlanURL); const contractData = await response.json(); const protocolContract = new ethers.Contract( @@ -85,8 +107,17 @@ export function useEthereum(): UseEthereumReturnType { contractData.contract.abi, provider ); + return protocolContract; + } catch (error) { + throw new EthereumError(`Could not get Default Provider: ${error}}`); + } + } + + async function getTotalSupply(ethereumNetwork: EthereumNetwork): Promise { + try { + const protocolContract = await getDefaultProvider(ethereumNetwork, 'DLCBTC'); const totalSupply = await protocolContract.totalSupply(); - setTotalSupply(customShiftValue(totalSupply, 8, true)); + return totalSupply.toNumber(); } catch (error) { throw new EthereumError(`Could not fetch Total Supply Info: ${error}}`); } @@ -115,10 +146,11 @@ export function useEthereum(): UseEthereumReturnType { } } - async function getAttestorGroupPublicKey(): Promise { + async function getAttestorGroupPublicKey(ethereumNetwork: EthereumNetwork): Promise { try { - if (!dlcManagerContract) throw new Error('Protocol contract not initialized'); - return await dlcManagerContract.attestorGroupPubKey(); + const dlcManagerContract = await getDefaultProvider(ethereumNetwork, 'DLCManager'); + const attestorGroupPubKey = await dlcManagerContract.attestorGroupPubKey(); + return attestorGroupPubKey; } catch (error) { throw new EthereumError(`Could not fetch Attestor Public Key: ${error}`); } @@ -173,9 +205,9 @@ export function useEthereum(): UseEthereumReturnType { throw new EthereumError(`Failed to fetch Vault ${vaultUUID} after ${maxRetries} retries`); } - async function getAllFundedVaults(): Promise { + async function getAllFundedVaults(ethereumNetwork: EthereumNetwork): Promise { try { - if (!dlcManagerContract) throw new Error('DLC Manager contract not initialized'); + const dlcManagerContract = await getDefaultProvider(ethereumNetwork, 'DLCManager'); const vaults: RawVault[] = await dlcManagerContract.getFundedDLCs(0, 1000000); return vaults; } catch (error) { diff --git a/src/app/hooks/use-proof-of-reserve.ts b/src/app/hooks/use-proof-of-reserve.ts index 370bcbf6..200ff636 100644 --- a/src/app/hooks/use-proof-of-reserve.ts +++ b/src/app/hooks/use-proof-of-reserve.ts @@ -4,6 +4,7 @@ import { useQuery } from 'react-query'; import { customShiftValue } from '@common/utilities'; import { BitcoinNetwork } from '@models/bitcoin-network'; import { BitcoinTransaction, BitcoinTransactionVectorOutput } from '@models/bitcoin-transaction'; +import { ethereumArbSepolia, ethereumSepolia } from '@models/ethereum-network'; import { RawVault } from '@models/vault'; import { hex } from '@scure/base'; import { p2tr, p2tr_ns, taprootTweakPubkey } from '@scure/btc-signer'; @@ -141,7 +142,7 @@ export function useProofOfReserve(): UseProofOfReserveReturnType { ); // Get the Attestor Public Key from the Attestor Group - const attestorPublicKey = await getAttestorGroupPublicKey(); + const attestorPublicKey = await getAttestorGroupPublicKey(ethereumSepolia); // Create two MultiSig Transactions, because the User and Attestor can sign in any order // Create the MultiSig Transaction A @@ -177,10 +178,13 @@ export function useProofOfReserve(): UseProofOfReserveReturnType { } async function calculateProofOfReserve() { - const fundedVaults = await getAllFundedVaults(); + const sepoliaFundedVaults = await getAllFundedVaults(ethereumSepolia); + const arbSepoliaFundedVaults = await getAllFundedVaults(ethereumArbSepolia); + + const allVaults = [...sepoliaFundedVaults, ...arbSepoliaFundedVaults]; const results = await Promise.all( - fundedVaults.map(async vault => { + allVaults.map(async vault => { try { if (await verifyVaultDeposit(vault)) { return vault.valueLocked.toNumber(); diff --git a/src/app/providers/proof-of-reserve-context-provider.tsx b/src/app/providers/proof-of-reserve-context-provider.tsx index 1aba42a0..d8a9c9df 100644 --- a/src/app/providers/proof-of-reserve-context-provider.tsx +++ b/src/app/providers/proof-of-reserve-context-provider.tsx @@ -1,21 +1,25 @@ import { createContext } from 'react'; +import { useEthereum } from '@hooks/use-ethereum'; import { useProofOfReserve } from '@hooks/use-proof-of-reserve'; import { HasChildren } from '@models/has-children'; interface ProofOfReserveContextProviderType { proofOfReserve: number | undefined; + totalSupply: number | undefined; } export const ProofOfReserveContext = createContext({ proofOfReserve: undefined, + totalSupply: undefined, }); export function ProofOfReserveContextProvider({ children }: HasChildren): React.JSX.Element { const { proofOfReserve } = useProofOfReserve(); + const { totalSupply } = useEthereum(); return ( - + {children} ); diff --git a/src/shared/models/ethereum-network.ts b/src/shared/models/ethereum-network.ts index 09e3dc4b..43b43cec 100644 --- a/src/shared/models/ethereum-network.ts +++ b/src/shared/models/ethereum-network.ts @@ -30,13 +30,13 @@ const ethereumGoerli: EthereumNetwork = { id: EthereumNetworkID.Goerli, }; -const ethereumSepolia: EthereumNetwork = { +export const ethereumSepolia: EthereumNetwork = { name: 'Sepolia', displayName: 'Sepolia', id: EthereumNetworkID.Sepolia, }; -const ethereumArbSepolia: EthereumNetwork = { +export const ethereumArbSepolia: EthereumNetwork = { name: 'ArbSepolia', displayName: 'Arbitrum Sepolia', id: EthereumNetworkID.ArbSepolia,