Skip to content

Commit

Permalink
fix: mempool endpoints errors should provide better UX (#165)
Browse files Browse the repository at this point in the history
* fix: mempool endpoints errors should provide better UX

* fix: remove delegation from local storage only when error status is 404
  • Loading branch information
totraev authored Sep 23, 2024
1 parent 6833efa commit 7ba30bc
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 30 deletions.
30 changes: 17 additions & 13 deletions src/app/components/Connect/ConnectSmall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import { Hash } from "../Hash/Hash";
import { LoadingSmall } from "../Loading/Loading";

interface ConnectSmallProps {
loading?: boolean;
onConnect: () => void;
address: string;
btcWalletBalanceSat?: number;
onDisconnect: () => void;
}

export const ConnectSmall: React.FC<ConnectSmallProps> = ({
loading = false,
onConnect,
address,
btcWalletBalanceSat,
Expand Down Expand Up @@ -65,20 +67,22 @@ export const ConnectSmall: React.FC<ConnectSmallProps> = ({
className="flex cursor-pointer outline-none items-stretch"
onClick={() => setShowMenu(!showMenu)}
>
<div className="flex items-center rounded-lg border border-base-200/75 p-2 pr-4">
<div className="flex items-center gap-1">
<FaBitcoin className="text-primary" />
{typeof btcWalletBalanceSat === "number" ? (
<p>
<strong>
{maxDecimals(satoshiToBtc(btcWalletBalanceSat), 8)} {coinName}
</strong>
</p>
) : (
<LoadingSmall text="Loading..." />
)}
{(typeof btcWalletBalanceSat === "number" || loading) && (
<div className="flex items-center rounded-lg border border-base-200/75 p-2 pr-4">
<div className="flex items-center gap-1">
<FaBitcoin className="text-primary" />
{typeof btcWalletBalanceSat === "number" && (
<p>
<strong>
{maxDecimals(satoshiToBtc(btcWalletBalanceSat), 8)}{" "}
{coinName}
</strong>
</p>
)}
{loading && <LoadingSmall text="Loading..." />}
</div>
</div>
</div>
)}
<div
className="relative right-[10px] flex items-center rounded-lg border border-primary bg-[#fdf2ec] p-2 dark:border-white dark:bg-base-200"
data-testid="address"
Expand Down
7 changes: 4 additions & 3 deletions src/app/components/Connect/ConnectedSmall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import { Hash } from "../Hash/Hash";
import { LoadingSmall } from "../Loading/Loading";

interface ConnectedSmallProps {
loading?: boolean;
address: string;
onDisconnect: () => void;
btcWalletBalanceSat?: number;
}

export const ConnectedSmall: React.FC<ConnectedSmallProps> = ({
loading = false,
address,
btcWalletBalanceSat,
onDisconnect,
Expand All @@ -42,16 +44,15 @@ export const ConnectedSmall: React.FC<ConnectedSmallProps> = ({
<div className="flex items-center rounded-lg border border-base-200/75 p-2 pr-4 w-full">
<div className="flex items-center gap-1 w-full justify-center">
<FaBitcoin className="text-primary" />
{typeof btcWalletBalanceSat === "number" ? (
{typeof btcWalletBalanceSat === "number" && (
<p>
<strong>
{maxDecimals(satoshiToBtc(btcWalletBalanceSat), 8)}{" "}
{coinName}
</strong>
</p>
) : (
<LoadingSmall text="Loading..." />
)}
{loading && <LoadingSmall text="Loading..." />}
</div>
</div>
<div className="relative flex items-center rounded-lg border border-primary bg-[#fdf2ec] p-2 dark:border-white dark:bg-base-200">
Expand Down
4 changes: 4 additions & 0 deletions src/app/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { TestingInfo } from "../TestingInfo/TestingInfo";
import { ThemeToggle } from "../ThemeToggle/ThemeToggle";

interface HeaderProps {
loading?: boolean;
onConnect: () => void;
address: string;
btcWalletBalanceSat?: number;
onDisconnect: () => void;
}

export const Header: React.FC<HeaderProps> = ({
loading,
onConnect,
address,
btcWalletBalanceSat,
Expand All @@ -32,6 +34,7 @@ export const Header: React.FC<HeaderProps> = ({
)}
</div>
<ConnectSmall
loading={loading}
onConnect={onConnect}
address={address}
btcWalletBalanceSat={btcWalletBalanceSat}
Expand All @@ -43,6 +46,7 @@ export const Header: React.FC<HeaderProps> = ({
className={`${address && "justify-end p-6 pt-0"}container mx-auto flex w-full items-center gap-4 md:hidden md:p-0`}
>
<ConnectedSmall
loading={loading}
address={address}
btcWalletBalanceSat={btcWalletBalanceSat}
onDisconnect={onDisconnect}
Expand Down
15 changes: 10 additions & 5 deletions src/app/components/Staking/Staking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ interface OverflowProperties {

interface StakingProps {
btcHeight: number | undefined;
disabled?: boolean;
isWalletConnected: boolean;
isLoading: boolean;
onConnect: () => void;
Expand All @@ -71,6 +72,7 @@ interface StakingProps {

export const Staking: React.FC<StakingProps> = ({
btcHeight,
disabled = false,
isWalletConnected,
onConnect,
isLoading,
Expand Down Expand Up @@ -115,6 +117,7 @@ export const Staking: React.FC<StakingProps> = ({
// Fetch fee rates, sat/vB
const {
data: mempoolFeeRates,
isLoading: areMempoolFeeRatesLoading,
error: mempoolFeeRatesError,
isError: hasMempoolFeeRatesError,
refetch: refetchMempoolFeeRates,
Expand All @@ -136,7 +139,7 @@ export const Staking: React.FC<StakingProps> = ({

// load global params and calculate the current staking params
const globalParams = useGlobalParams();
useMemo(() => {
useEffect(() => {
if (!btcHeight || !globalParams.data) {
return;
}
Expand All @@ -148,7 +151,7 @@ export const Staking: React.FC<StakingProps> = ({
}, [btcHeight, globalParams]);

// Calculate the overflow properties
useMemo(() => {
useEffect(() => {
if (!paramWithCtx || !paramWithCtx.currentVersion || !btcHeight) {
return;
}
Expand Down Expand Up @@ -519,14 +522,16 @@ export const Staking: React.FC<StakingProps> = ({
);
};

const hasError = disabled || hasMempoolFeeRatesError;

const renderStakingForm = () => {
// States of the staking form:
// Health check failed
if (!isApiNormal || isGeoBlocked) {
if (!isApiNormal || isGeoBlocked || hasError) {
return (
<Message
title="Staking is not available"
messages={[apiMessage || ""]}
messages={!hasError ? [apiMessage || ""] : [""]}
icon={isGeoBlocked ? geoRestricted : apiNotAvailable}
/>
);
Expand All @@ -536,7 +541,7 @@ export const Staking: React.FC<StakingProps> = ({
return <WalletNotConnected onConnect={onConnect} />;
}
// Wallet is connected but we are still loading the staking params
else if (isLoading) {
else if (isLoading || areMempoolFeeRatesLoading) {
return <LoadingView />;
}
// Staking has not started yet
Expand Down
10 changes: 7 additions & 3 deletions src/app/components/Summary/Summary.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, useState } from "react";
import { useEffect, useState } from "react";
import { AiOutlineInfoCircle } from "react-icons/ai";
import { FaBitcoin } from "react-icons/fa";
import { Tooltip } from "react-tooltip";
Expand All @@ -19,12 +19,14 @@ import { LoadingSmall } from "../Loading/Loading";
import { StakerPoints } from "../Points/StakerPoints";

interface SummaryProps {
loading?: boolean;
totalStakedSat: number;
btcWalletBalanceSat?: number;
publicKeyNoCoord: string;
}

export const Summary: React.FC<SummaryProps> = ({
loading = false,
totalStakedSat,
btcWalletBalanceSat,
publicKeyNoCoord,
Expand All @@ -39,7 +41,7 @@ export const Summary: React.FC<SummaryProps> = ({
const globalParams = useGlobalParams();
const { isApiNormal, isGeoBlocked } = useHealthCheck();

useMemo(() => {
useEffect(() => {
if (!btcHeight || !globalParams.data) {
return;
}
Expand Down Expand Up @@ -130,8 +132,10 @@ export const Summary: React.FC<SummaryProps> = ({
{maxDecimals(satoshiToBtc(btcWalletBalanceSat), 8)}{" "}
{coinName}
</p>
) : (
) : loading ? (
<LoadingSmall text="Loading..." />
) : (
"n.a."
)}
</div>
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ const Home: React.FC<HomeProps> = () => {
const {
data: availableUTXOs,
error: availableUTXOsError,
isLoading: isLoadingAvailableUTXOs,
isError: hasAvailableUTXOsError,
refetch: refetchAvailableUTXOs,
} = useQuery({
Expand Down Expand Up @@ -320,6 +321,7 @@ const Home: React.FC<HomeProps> = () => {
>
<NetworkBadge isWalletConnected={!!btcWallet} />
<Header
loading={isLoadingAvailableUTXOs}
onConnect={handleConnectModal}
onDisconnect={handleDisconnectBTC}
address={address}
Expand All @@ -330,16 +332,18 @@ const Home: React.FC<HomeProps> = () => {
<Stats />
{address && (
<Summary
loading={isLoadingAvailableUTXOs}
totalStakedSat={totalStakedSat}
btcWalletBalanceSat={btcWalletBalanceSat}
publicKeyNoCoord={publicKeyNoCoord}
/>
)}
<Staking
disabled={hasGlobalParamsVersionError || hasAvailableUTXOsError}
btcHeight={paramWithContext?.currentHeight}
isWalletConnected={!!btcWallet}
onConnect={handleConnectModal}
isLoading={isLoadingCurrentParams}
isLoading={isLoadingCurrentParams || isLoadingAvailableUTXOs}
btcWallet={btcWallet}
btcWalletBalanceSat={btcWalletBalanceSat}
btcWalletNetwork={btcWalletNetwork}
Expand Down
1 change: 1 addition & 0 deletions src/utils/delegations/signWithdrawalTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export const signWithdrawalTx = async (

// Sign the withdrawal transaction
let withdrawalTx: Transaction;

try {
const { psbt } = withdrawPsbtTxResult;
withdrawalTx = await signPsbtTx(psbt.toHex());
Expand Down
10 changes: 6 additions & 4 deletions src/utils/local_storage/filterDelegationsLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Delegation } from "@/app/types/delegations";

import { getTxInfo } from "../mempool_api";
import { getTxInfo, ServerError } from "../mempool_api";

// Duration after which a delegation should be removed from the local storage
// if not identified by the API or mempool.
Expand Down Expand Up @@ -44,10 +44,12 @@ export const filterDelegationsLocalStorage = async (
try {
const fetchedTx = await getTxInfo(localDelegation.stakingTxHashHex);
if (!fetchedTx) {
throw new Error("Transaction not found in the mempool");
throw new ServerError("Transaction not found in the mempool", 404);
}
} catch (err) {
if ((err as ServerError).code === 404) {
isInMempool = false;
}
} catch (_error) {
isInMempool = false;
}

if (!isInMempool) {
Expand Down
11 changes: 10 additions & 1 deletion src/utils/mempool_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import { Fees, UTXO } from "./wallet/wallet_provider";

const { mempoolApiUrl } = getNetworkConfig();

export class ServerError extends Error {
constructor(
message: string,
public code: number,
) {
super(message);
}
}

/*
URL Construction methods
*/
Expand Down Expand Up @@ -199,7 +208,7 @@ export async function getTxInfo(txId: string): Promise<any> {
const response = await fetch(txInfoUrl(txId));
if (!response.ok) {
const err = await response.text();
throw new Error(err);
throw new ServerError(err, response.status);
}
return await response.json();
}

0 comments on commit 7ba30bc

Please sign in to comment.