Skip to content

Commit

Permalink
feat: replace fetching with reactqueries for block height fetching (#56)
Browse files Browse the repository at this point in the history
* feat: replace fetching with reactqueries for block height fetching
  • Loading branch information
Polybius93 authored Mar 21, 2024
1 parent 288f36e commit d8b4f97
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 60 deletions.
100 changes: 98 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"prettier": "^3.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.3",
"react-redux": "^8.1.3",
"react-youtube": "^10.1.0",
"redux": "^4.2.1",
Expand Down
28 changes: 18 additions & 10 deletions src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
import { QueryClient, QueryClientProvider } from 'react-query';
import { Route } from 'react-router-dom';

import { AppLayout } from '@components/app.layout';
import { MyVaults } from '@pages/my-vaults/my-vaults';
import { ProofOfReservePage } from '@pages/proof-of-reserve/proof-of-reserve-page';
import { BalanceContextProvider } from '@providers/balance-context-provider';
import { BlockchainHeightContextProvider } from '@providers/bitcoin-query-provider';
import { EthereumObserverProvider } from '@providers/ethereum-observer-provider';

import { About } from './pages/about/about';
import { Dashboard } from './pages/dashboard/dashboard';
import { EthereumContextProvider } from './providers/ethereum-context-provider';
import { VaultContextProvider } from './providers/vault-context-provider';

const queryClient = new QueryClient();

export function App(): React.JSX.Element {
return (
<EthereumContextProvider>
<EthereumObserverProvider>
<VaultContextProvider>
<BalanceContextProvider>
<AppLayout>
<Route path="/" element={<Dashboard />} />
<Route path="/my-vaults" element={<MyVaults />} />
<Route path="/how-it-works" element={<About />} />
<Route path="/proof-of-reserve" element={<ProofOfReservePage />} />
</AppLayout>
</BalanceContextProvider>
</VaultContextProvider>
<QueryClientProvider client={queryClient}>
<VaultContextProvider>
<BlockchainHeightContextProvider>
<BalanceContextProvider>
<AppLayout>
<Route path="/" element={<Dashboard />} />
<Route path="/my-vaults" element={<MyVaults />} />
<Route path="/how-it-works" element={<About />} />
<Route path="/proof-of-reserve" element={<ProofOfReservePage />} />
</AppLayout>
</BalanceContextProvider>
</BlockchainHeightContextProvider>
</VaultContextProvider>
</QueryClientProvider>
</EthereumObserverProvider>
</EthereumContextProvider>
);
Expand Down
1 change: 1 addition & 0 deletions src/app/components/mint-unmint/mint-unmint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function MintUnmint({ address }: MintUnmintContainerProps): React.JSX.Ele
setTimeout(() => {
setAnimate(false);
}, 1000);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [mintStep, unmintStep]);

function handleTabsChange(index: number) {
Expand Down
1 change: 1 addition & 0 deletions src/app/components/proof-of-reserve/proof-of-reserve.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function ProofOfReserve(): React.JSX.Element {
setContent(data);
})
.catch(error => {
// eslint-disable-next-line no-console
console.error('Error fetching data:', error);
});
}, []);
Expand Down
18 changes: 18 additions & 0 deletions src/app/hooks/use-blockchain-height-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from 'react-query';

export function useBlockchainHeightQuery(): number | undefined {
const bitcoinBlockchainAPIURL = import.meta.env.VITE_BITCOIN_BLOCKCHAIN_API_URL;
const bitcoinExplorerHeightURL = `${bitcoinBlockchainAPIURL}/blocks/tip/height`;

async function getBlockchainHeight() {
const response = await fetch(bitcoinExplorerHeightURL);
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
}

const { data: blockHeight } = useQuery('blockHeight', () => getBlockchainHeight(), {
refetchInterval: 10000,
});

return blockHeight;
}
100 changes: 53 additions & 47 deletions src/app/hooks/use-confirmation-checker.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
import { useEffect, useMemo, useRef, useState } from 'react';
import { useContext, useEffect, useState } from 'react';
import { useQuery } from 'react-query';

import { Vault, VaultState } from '@models/vault';
import { BlockchainHeightContext } from '@providers/bitcoin-query-provider';

export function useConfirmationChecker(vault?: Vault): number {
const txID = vault?.state === VaultState.FUNDING ? vault?.fundingTX : vault?.closingTX;
const { blockHeight } = useContext(BlockchainHeightContext);

let txID;
switch (vault?.state) {
case VaultState.FUNDING:
txID = vault?.fundingTX;
break;
case VaultState.CLOSED:
txID = vault?.closingTX;
break;
default:
txID = undefined;
}

const [blockHeightAtBroadcast, setBlockHeightAtBroadcast] = useState<number | undefined>(
undefined
);
const [transactionProgress, setTransactionProgress] = useState<number>(0);

const bitcoinBlockchainAPIURL = import.meta.env.VITE_BITCOIN_BLOCKCHAIN_API_URL;

const bitcoinExplorerTXURL = `${bitcoinBlockchainAPIURL}/tx/${txID}`;
const bitcoinExplorerHeightURL = `${bitcoinBlockchainAPIURL}/blocks/tip/height`;
const fetchInterval = useRef<number | undefined>(undefined);

const [transactionProgress, setTransactionProgress] = useState(0);

const memoizedTransactionProgress = useMemo(() => transactionProgress, [transactionProgress]);

const fetchTransactionDetails = async () => {
if (!txID || (vault?.state && ![VaultState.FUNDING, VaultState.CLOSED].includes(vault.state))) {
clearInterval(fetchInterval.current);
return;
async function fetchTransactionDetails() {
const response = await fetch(bitcoinExplorerTXURL);
if (!response.ok) throw new Error('Network response was not ok');
const transactionDetails = await response.json();
return transactionDetails.status.block_height;
}

const { data: txBlockHeightAtBroadcast } = useQuery(
['transactionDetails', txID],
() => fetchTransactionDetails(),
{
enabled:
!!txID &&
(vault?.state === VaultState.FUNDING || vault?.state === VaultState.CLOSED) &&
!blockHeightAtBroadcast,
refetchInterval: 10000,
}
);

let bitcoinCurrentBlockHeight;
try {
const response = await fetch(bitcoinExplorerHeightURL, {
headers: { Accept: 'application/json' },
});
bitcoinCurrentBlockHeight = await response.json();
} catch (error) {
console.error(error);
}

let bitcoinTransactionBlockHeight;

try {
const response = await fetch(bitcoinExplorerTXURL, {
headers: { Accept: 'application/json' },
});
const bitcoinTransactionDetails = await response.json();
bitcoinTransactionBlockHeight = bitcoinTransactionDetails.status.block_height;
} catch (error) {
console.error(error);
useEffect(() => {
if (txBlockHeightAtBroadcast && typeof txBlockHeightAtBroadcast === 'number') {
setBlockHeightAtBroadcast(txBlockHeightAtBroadcast);
}
}, [txBlockHeightAtBroadcast]);

const difference = bitcoinCurrentBlockHeight - bitcoinTransactionBlockHeight;

setTransactionProgress(difference > 0 ? difference : 0);
useEffect(() => {
if (
(vault?.state != VaultState.FUNDING && vault?.state != VaultState.CLOSED) ||
transactionProgress > 6
)
return;

if (difference > 6) {
clearInterval(fetchInterval.current);
const blockHeightDifference = (blockHeight as number) - (blockHeightAtBroadcast as number);
if (typeof blockHeightDifference === 'number') {
setTransactionProgress(blockHeightDifference);
}
};

fetchTransactionDetails();

useEffect(() => {
fetchInterval.current = setInterval(fetchTransactionDetails, 10000) as unknown as number; // Cleanup the interval when the component unmounts
return () => clearInterval(fetchInterval.current);
}, [vault?.state, txID]);
}, [blockHeightAtBroadcast, blockHeight, vault?.state, transactionProgress]);

return memoizedTransactionProgress;
return transactionProgress;
}
Loading

0 comments on commit d8b4f97

Please sign in to comment.