diff --git a/web/src/pages/WalletDashboard.tsx b/web/src/pages/WalletDashboard.tsx index 6188ba0f..c45fa270 100644 --- a/web/src/pages/WalletDashboard.tsx +++ b/web/src/pages/WalletDashboard.tsx @@ -12,6 +12,8 @@ import { ArrowUpRight, ArrowDownRight, History, ArrowLeft, RefreshCw, Coins, Loa import { toast } from 'sonner'; import { getSigner } from '@/lib/get-signer'; import { getPezRewards, recordTrustScore, claimPezReward, type PezRewardInfo } from '@pezkuwi/lib/scores'; +import { isMultisigMember, BRIDGE_MULTISIG_SPECIFIC_ADDRESSES } from '@pezkuwi/lib/multisig'; +import { ShieldCheck } from 'lucide-react'; interface Transaction { blockNumber: number; @@ -38,6 +40,27 @@ const WalletDashboard: React.FC = () => { const [pezRewards, setPezRewards] = useState(null); const [isRecordingScore, setIsRecordingScore] = useState(false); const [isClaimingReward, setIsClaimingReward] = useState(false); + const [isMultisigSigner, setIsMultisigSigner] = useState(false); + + // Only show the multisig operations shortcut to the 5 real USDT bridge signatories - a + // decorative check here (the route itself is the real gate via ProtectedRoute). + useEffect(() => { + if (!api || !isApiReady || !selectedAccount) { + setIsMultisigSigner(false); + return; + } + let cancelled = false; + isMultisigMember(api, selectedAccount.address, BRIDGE_MULTISIG_SPECIFIC_ADDRESSES) + .then((result) => { + if (!cancelled) setIsMultisigSigner(result); + }) + .catch(() => { + if (!cancelled) setIsMultisigSigner(false); + }); + return () => { + cancelled = true; + }; + }, [api, isApiReady, selectedAccount]); // Fetch recent transactions (limited to last 10 blocks for performance) const fetchRecentTransactions = async () => { @@ -423,6 +446,19 @@ const WalletDashboard: React.FC = () => { + {/* Multisig Operations shortcut - only visible to the 5 real USDT bridge + signatories (route itself is the real gate; this is just discoverability) */} + {isMultisigSigner && ( + + )} + {/* PEZ Rewards Card */} {pezRewards && (