From ff5ac3602b840af2b04b393aed8a64f0f58257c5 Mon Sep 17 00:00:00 2001
From: 0age <37939117+0age@users.noreply.github.com>
Date: Mon, 9 Dec 2024 23:30:56 -0800
Subject: [PATCH] show finalization thresholds on FE
---
frontend/src/components/BalanceDisplay.tsx | 25 ++++-----
.../src/components/FinalizationThreshold.tsx | 18 +++++++
frontend/src/hooks/useAllocatorAPI.ts | 7 +++
.../src/hooks/useFinalizationThreshold.ts | 52 +++++++++++++++++++
4 files changed, 87 insertions(+), 15 deletions(-)
create mode 100644 frontend/src/components/FinalizationThreshold.tsx
create mode 100644 frontend/src/hooks/useFinalizationThreshold.ts
diff --git a/frontend/src/components/BalanceDisplay.tsx b/frontend/src/components/BalanceDisplay.tsx
index 4de9fc4..33b782f 100644
--- a/frontend/src/components/BalanceDisplay.tsx
+++ b/frontend/src/components/BalanceDisplay.tsx
@@ -2,12 +2,14 @@ import { useState, useEffect, useCallback, useMemo } from 'react';
import { useAccount, useChainId } from 'wagmi';
import { useBalances } from '../hooks/useBalances';
import { useResourceLocks } from '../hooks/useResourceLocks';
+import { useFinalizationThreshold } from '../hooks/useFinalizationThreshold';
import { formatUnits } from 'viem';
import { Transfer } from './Transfer';
import { InitiateForcedWithdrawalDialog } from './InitiateForcedWithdrawalDialog';
import { ForcedWithdrawalDialog } from './ForcedWithdrawalDialog';
import { useCompact } from '../hooks/useCompact';
import { useNotification } from '../hooks/useNotification';
+import { FinalizationThreshold } from './FinalizationThreshold';
interface BalanceDisplayProps {
sessionToken: string | null;
@@ -49,7 +51,7 @@ function formatTimeRemaining(
return `${seconds}s`;
}
-const formatResetPeriod = (seconds: number): string => {
+export const formatResetPeriod = (seconds: number): string => {
if (seconds < 60) return `${seconds} seconds`;
if (seconds < 3600) return `${Math.floor(seconds / 60)} minutes`;
if (seconds < 86400) return `${Math.floor(seconds / 3600)} hours`;
@@ -444,27 +446,20 @@ export function BalanceDisplay({
{balance.resourceLock?.resetPeriod &&
balance.resourceLock.resetPeriod > 0 && (
- Reset Period: {balance.resetPeriodFormatted}
+ Reset Period: {formatResetPeriod(balance.resourceLock.resetPeriod)}
)}
+
{balance.resourceLock?.isMultichain && (
Multichain
)}
-
- {balance.withdrawalStatus === 0
- ? 'Active'
- : withdrawableAt <= currentTime
- ? 'Forced Withdrawals Enabled'
- : `Forced Withdrawals Enabled in ${formatTimeRemaining(withdrawableAt, currentTime)}`}
-
+ {balance.withdrawalStatus === 0 && (
+
+ Active
+
+ )}
{/* Balances Grid */}
diff --git a/frontend/src/components/FinalizationThreshold.tsx b/frontend/src/components/FinalizationThreshold.tsx
new file mode 100644
index 0000000..34d52d5
--- /dev/null
+++ b/frontend/src/components/FinalizationThreshold.tsx
@@ -0,0 +1,18 @@
+import { useFinalizationThreshold } from '../hooks/useFinalizationThreshold';
+import { formatResetPeriod } from './BalanceDisplay';
+
+interface FinalizationThresholdProps {
+ chainId: number;
+}
+
+export function FinalizationThreshold({ chainId }: FinalizationThresholdProps) {
+ const { finalizationThreshold } = useFinalizationThreshold(chainId);
+
+ if (finalizationThreshold === null) return null;
+
+ return (
+
+ Finalization: {formatResetPeriod(finalizationThreshold)}
+
+ );
+}
diff --git a/frontend/src/hooks/useAllocatorAPI.ts b/frontend/src/hooks/useAllocatorAPI.ts
index c3df9fa..a75f94f 100644
--- a/frontend/src/hooks/useAllocatorAPI.ts
+++ b/frontend/src/hooks/useAllocatorAPI.ts
@@ -5,6 +5,13 @@ interface HealthCheckResponse {
allocatorAddress: string;
signingAddress: string;
timestamp: string;
+ chainConfig: {
+ defaultFinalizationThresholdSeconds: number;
+ supportedChains: Array<{
+ chainId: string;
+ finalizationThresholdSeconds: number;
+ }>;
+ };
}
interface CompactRequest {
diff --git a/frontend/src/hooks/useFinalizationThreshold.ts b/frontend/src/hooks/useFinalizationThreshold.ts
new file mode 100644
index 0000000..16ac060
--- /dev/null
+++ b/frontend/src/hooks/useFinalizationThreshold.ts
@@ -0,0 +1,52 @@
+import { useState, useEffect } from 'react';
+
+interface ChainConfig {
+ defaultFinalizationThresholdSeconds: number;
+ supportedChains: Array<{
+ chainId: string;
+ finalizationThresholdSeconds: number;
+ }>;
+}
+
+export function useFinalizationThreshold(chainId: number) {
+ const [finalizationThreshold, setFinalizationThreshold] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ const fetchFinalizationThreshold = async () => {
+ try {
+ const response = await fetch('/health');
+ if (!response.ok) {
+ throw new Error('Failed to fetch chain configuration');
+ }
+ const data = await response.json();
+ const chainConfig: ChainConfig = data.chainConfig;
+
+ // Find the chain-specific threshold or use default
+ const chainSpecific = chainConfig.supportedChains.find(
+ chain => chain.chainId === chainId.toString()
+ );
+
+ setFinalizationThreshold(
+ chainSpecific?.finalizationThresholdSeconds ??
+ chainConfig.defaultFinalizationThresholdSeconds
+ );
+ setError(null);
+ } catch (err) {
+ setError(
+ err instanceof Error
+ ? err.message
+ : 'Failed to fetch finalization threshold'
+ );
+ setFinalizationThreshold(null);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ fetchFinalizationThreshold();
+ }, [chainId]);
+
+ return { finalizationThreshold, isLoading, error };
+}