diff --git a/src/features/store.ts b/src/features/store.ts index dce9c5b8..86d1808f 100644 --- a/src/features/store.ts +++ b/src/features/store.ts @@ -1,7 +1,12 @@ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; -import { FinalTransferStatuses, TransferContext, TransferStatus } from './transfer/types'; +import { + FinalTransferStatuses, + TransferContext, + TransferStatus, + TransferStatusParams, +} from './transfer/types'; // Increment this when persist state has breaking changes const PERSIST_STATE_VERSION = 1; @@ -28,6 +33,7 @@ export interface AppState { setIsSenderNftOwner: (isOwner: boolean | null) => void; transferLoading: boolean; setTransferLoading: (isLoading: boolean) => void; + updateTransferStatusParams: (i: number, params: TransferStatusParams) => void; } export const useStore = create()( @@ -52,6 +58,16 @@ export const useStore = create()( }; }); }, + updateTransferStatusParams: (i, params) => { + set((state) => { + if (i >= state.transfers.length) return state; + const txs = [...state.transfers]; + txs[i].statusParams ||= params; + return { + transfers: txs, + }; + }); + }, failUnconfirmedTransfers: () => { set((state) => ({ transfers: state.transfers.map((t) => diff --git a/src/features/transfer/TransfersDetailsModal.tsx b/src/features/transfer/TransfersDetailsModal.tsx index c5886e74..e77439eb 100644 --- a/src/features/transfer/TransfersDetailsModal.tsx +++ b/src/features/transfer/TransfersDetailsModal.tsx @@ -16,6 +16,7 @@ import { getChainReference } from '../caip/chains'; import { AssetNamespace, parseCaip19Id } from '../caip/tokens'; import { getChainDisplayName, hasPermissionlessChain } from '../chains/utils'; import { getMultiProvider } from '../multiProvider'; +import { useStore } from '../store'; import { getToken } from '../tokens/metadata'; import { useAccountForChain } from '../wallet/hooks'; @@ -26,10 +27,12 @@ export function TransfersDetailsModal({ isOpen, onClose, transfer, + transferIndex, }: { isOpen: boolean; onClose: () => void; transfer: TransferContext; + transferIndex: number; }) { const [fromUrl, setFromUrl] = useState(''); const [toUrl, setToUrl] = useState(''); @@ -138,7 +141,12 @@ export function TransfersDetailsModal({ {isPermissionlessRoute ? ( ) : ( - + )} {status !== TransferStatus.ConfirmedTransfer && status !== TransferStatus.Delivered ? (
({ + updateTransferStatus: s.updateTransferStatus, + updateTransferStatusParams: s.updateTransferStatusParams, + })); + + useEffect(() => { + if (messageStatus === MessageStatus.Delivered) { + updateTransferStatus(transferIndex, TransferStatus.Delivered); + if (!transfer.statusParams) { + updateTransferStatusParams(transferIndex, { stage, timings, message }); + } + } + }, [transferIndex, messageStatus, updateTransferStatus]); return (
diff --git a/src/features/transfer/types.ts b/src/features/transfer/types.ts index 78a9ce5a..ed7c64d9 100644 --- a/src/features/transfer/types.ts +++ b/src/features/transfer/types.ts @@ -1,3 +1,5 @@ +import { ApiMessage, MessageStage, StageTimings } from '@hyperlane-xyz/widgets'; + import type { Route } from '../tokens/routes/types'; export interface TransferFormValues { @@ -30,6 +32,7 @@ export const FinalTransferStatuses = [ export interface TransferContext { status: TransferStatus; + statusParams?: TransferStatusParams; route: Route; params: TransferFormValues; originTxHash?: string; @@ -37,3 +40,9 @@ export interface TransferContext { timestamp: number; activeAccountAddress: Address; } + +export interface TransferStatusParams { + stage: MessageStage; + timings: StageTimings; + message: ApiMessage | null; +} diff --git a/src/features/wallet/SideBarMenu.tsx b/src/features/wallet/SideBarMenu.tsx index cf0192d2..f5d4c8b9 100644 --- a/src/features/wallet/SideBarMenu.tsx +++ b/src/features/wallet/SideBarMenu.tsx @@ -55,6 +55,8 @@ export function SideBarMenu({ const [isMenuOpen, setIsMenuOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedTransfer, setSelectedTransfer] = useState(null); + const [selectedTransferIndex, setSelectedTransferIndex] = useState(null); + const disconnects = useDisconnectFns(); const { readyAccounts } = useAccounts(); const didMountRef = useRef(false); @@ -70,6 +72,7 @@ export function SideBarMenu({ didMountRef.current = true; } else if (transferLoading) { setSelectedTransfer(transfers[transfers.length - 1]); + setSelectedTransferIndex(transfers.length - 1); setIsModalOpen(true); } }, [transfers, transferLoading]); @@ -147,11 +150,15 @@ export function SideBarMenu({
{sortedTransfers?.length > 0 && - sortedTransfers.map((t) => ( + sortedTransfers.map((t, i) => (
- {selectedTransfer && ( + {selectedTransferIndex !== null && selectedTransfer && ( { setIsModalOpen(false); - setSelectedTransfer(null); }} transfer={selectedTransfer} + transferIndex={selectedTransferIndex} /> )}