From dffe5fb64526a1e3e13cb6e7f03e935d29dfd104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Papie=C5=BC?= Date: Mon, 16 Dec 2024 17:26:58 +0100 Subject: [PATCH] chore: emit wallet events --- src-tauri/src/commands.rs | 35 +------- src-tauri/src/main.rs | 5 ++ src-tauri/src/node_adapter.rs | 44 ++++++---- src-tauri/src/wallet_adapter.rs | 83 ++++++++++++++++++- src-tauri/src/wallet_manager.rs | 36 +++++--- .../SideBar/components/Wallet/History.tsx | 8 +- .../main/SideBar/components/Wallet/Wallet.tsx | 11 +-- src/hooks/app/useSetUp.ts | 49 ++++++++++- src/hooks/mining/useMiningMetricsUpdater.ts | 12 +-- src/hooks/mining/useMiningStatesSync.ts | 22 +---- src/hooks/mining/useTransactions.ts | 58 ------------- src/store/useWalletStore.ts | 30 +++---- src/types/app-status.ts | 1 - src/types/invoke.ts | 2 - 14 files changed, 203 insertions(+), 193 deletions(-) delete mode 100644 src/hooks/mining/useTransactions.ts diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index fc3f05ed3..3af0b8995 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -102,7 +102,6 @@ pub struct MinerMetrics { #[derive(Debug, Serialize, Clone)] pub struct TariWalletDetails { - wallet_balance: Option, tari_address_base58: String, tari_address_emoji: String, } @@ -641,45 +640,15 @@ pub async fn get_tari_wallet_details( state: tauri::State<'_, UniverseAppState>, ) -> Result { let timer = Instant::now(); - if state.is_getting_wallet_balance.load(Ordering::SeqCst) { - let read = state.cached_wallet_details.read().await; - if let Some(details) = &*read { - warn!(target: LOG_TARGET, "Already getting wallet balance, returning cached value"); - return Ok(details.clone()); - } - warn!(target: LOG_TARGET, "Already getting wallet balance"); - return Err("Already getting wallet balance".to_string()); - } - state - .is_getting_wallet_balance - .store(true, Ordering::SeqCst); - let wallet_balance = match state.wallet_manager.get_balance().await { - Ok(w) => Some(w), - Err(e) => { - if !matches!(e, WalletManagerError::WalletNotStarted) { - warn!(target: LOG_TARGET, "Error getting wallet balance: {}", e); - } - - None - } - }; let tari_address = state.tari_address.read().await; if timer.elapsed() > MAX_ACCEPTABLE_COMMAND_TIME { warn!(target: LOG_TARGET, "get_tari_wallet_details took too long: {:?}", timer.elapsed()); } - let result = TariWalletDetails { - wallet_balance, + Ok(TariWalletDetails { tari_address_base58: tari_address.to_base58(), tari_address_emoji: tari_address.to_emoji_string(), - }; - let mut lock = state.cached_wallet_details.write().await; - *lock = Some(result.clone()); - state - .is_getting_wallet_balance - .store(false, Ordering::SeqCst); - - Ok(result) + }) } #[tauri::command] diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index ba5596c56..669880e1b 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -506,6 +506,11 @@ async fn setup_inner( .inspect_err(|e| error!(target: LOG_TARGET, "Could not emit event 'message': {:?}", e)), ); + state + .wallet_manager + .initialize_wallet_relay(app.clone()) + .await; + let move_handle = app.clone(); tauri::async_runtime::spawn(async move { let mut interval: time::Interval = time::interval(Duration::from_secs(1)); diff --git a/src-tauri/src/node_adapter.rs b/src-tauri/src/node_adapter.rs index 24169aafc..e908b5c0d 100644 --- a/src-tauri/src/node_adapter.rs +++ b/src-tauri/src/node_adapter.rs @@ -212,6 +212,7 @@ impl ProcessAdapter for MinotariNodeAdapter { last_block_height: 0, last_sha3_estimated_hashrate: 0, last_randomx_estimated_hashrate: 0, + last_block_reward: 0, }, )) } @@ -241,6 +242,7 @@ pub struct MinotariNodeStatusMonitor { last_block_height: u64, last_sha3_estimated_hashrate: u64, last_randomx_estimated_hashrate: u64, + last_block_reward: u64, } #[async_trait] @@ -264,22 +266,6 @@ impl MinotariNodeStatusMonitor { .await .map_err(|_| MinotariNodeStatusMonitorError::NodeNotStarted)?; - let res = client - .get_new_block_template(NewBlockTemplateRequest { - algo: Some(PowAlgo { pow_algo: 1 }), - max_weight: 0, - }) - .await - .map_err(|e| MinotariNodeStatusMonitorError::UnknownError(e.into()))?; - let res = res.into_inner(); - - let reward = res - .miner_data - .ok_or_else(|| { - MinotariNodeStatusMonitorError::UnknownError(anyhow!("No miner data found")) - })? - .reward; - let res = client .get_tip_info(Empty {}) .await @@ -300,17 +286,38 @@ impl MinotariNodeStatusMonitor { metadata.timestamp, ); - if sync_achieved && (block_height <= self.last_block_height) { + if sync_achieved + && (block_height <= self.last_block_height) + && self.last_sha3_estimated_hashrate > 0 + && self.last_randomx_estimated_hashrate > 0 + && self.last_block_reward > 0 + { return Ok(( self.last_sha3_estimated_hashrate, self.last_randomx_estimated_hashrate, - MicroMinotari(reward), + MicroMinotari(self.last_block_reward), block_height, block_time, sync_achieved, )); } + let res = client + .get_new_block_template(NewBlockTemplateRequest { + algo: Some(PowAlgo { pow_algo: 1 }), + max_weight: 0, + }) + .await + .map_err(|e| MinotariNodeStatusMonitorError::UnknownError(e.into()))?; + let res = res.into_inner(); + + let reward = res + .miner_data + .ok_or_else(|| { + MinotariNodeStatusMonitorError::UnknownError(anyhow!("No miner data found")) + })? + .reward; + // First try with 10 blocks let blocks = [10, 100]; let mut result = Err(anyhow::anyhow!("No difficulty found")); @@ -359,6 +366,7 @@ impl MinotariNodeStatusMonitor { } self.last_block_height = block_height; + self.last_block_reward = reward; Ok(result?) } diff --git a/src-tauri/src/wallet_adapter.rs b/src-tauri/src/wallet_adapter.rs index 40e0f6d99..7c57759a8 100644 --- a/src-tauri/src/wallet_adapter.rs +++ b/src-tauri/src/wallet_adapter.rs @@ -30,15 +30,20 @@ use anyhow::Error; use async_trait::async_trait; use log::{info, warn}; use minotari_node_grpc_client::grpc::wallet_client::WalletClient; -use minotari_node_grpc_client::grpc::{GetBalanceRequest, GetCompletedTransactionsRequest}; +use minotari_node_grpc_client::grpc::{ + GetBalanceRequest, GetCompletedTransactionsRequest, TransactionEventRequest, +}; use serde::Serialize; use std::path::PathBuf; +use std::sync::Arc; use tari_common::configuration::Network; use tari_common_types::tari_address::{TariAddress, TariAddressError}; use tari_core::transactions::tari_amount::MicroMinotari; use tari_crypto::ristretto::RistrettoPublicKey; use tari_shutdown::Shutdown; use tari_utilities::hex::Hex; +use tauri::Emitter; +use tokio::sync::RwLock; #[cfg(target_os = "windows")] use crate::utils::setup_utils::setup_utils::add_firewall_rule; @@ -196,6 +201,8 @@ impl ProcessAdapter for WalletAdapter { }, WalletStatusMonitor { grpc_port: self.grpc_port, + confirmed_transactions: Arc::new(RwLock::new(Vec::new())), + wallet_balance: Arc::new(RwLock::new(WalletBalance::default())), }, )) } @@ -222,6 +229,8 @@ pub enum WalletStatusMonitorError { #[derive(Clone)] pub struct WalletStatusMonitor { grpc_port: u16, + pub confirmed_transactions: Arc>>, + pub wallet_balance: Arc>, } #[async_trait] @@ -243,7 +252,18 @@ pub struct WalletBalance { pub pending_outgoing_balance: MicroMinotari, } -#[derive(Debug, Serialize)] +impl Default for WalletBalance { + fn default() -> Self { + WalletBalance { + available_balance: MicroMinotari(0), + timelocked_balance: MicroMinotari(0), + pending_incoming_balance: MicroMinotari(0), + pending_outgoing_balance: MicroMinotari(0), + } + } +} + +#[derive(Debug, Serialize, Clone)] pub struct TransactionInfo { pub tx_id: u64, pub source_address: String, @@ -264,7 +284,62 @@ impl WalletStatusMonitor { format!("http://127.0.0.1:{}", self.grpc_port) } - pub async fn get_balance(&self) -> Result { + pub async fn initialize_wallet_relay(&self, app_handle: tauri::AppHandle) { + let app_handle_clone = app_handle.clone(); + self.clone().update_wallet_data(app_handle_clone).await; + let monitor = self.clone(); + let app_handle_clone = app_handle.clone(); + + tokio::spawn(async move { + let mut client = WalletClient::connect(monitor.wallet_grpc_address()) + .await + .map_err(|_e| WalletStatusMonitorError::WalletNotStarted)?; + let res = client + .stream_transaction_events(TransactionEventRequest {}) + .await + .map_err(|e| WalletStatusMonitorError::UnknownError(e.into()))?; + + let mut stream = res.into_inner(); + while let Some(message) = stream + .message() + .await + .map_err(|e| WalletStatusMonitorError::UnknownError(e.into()))? + { + let tx = message.transaction.expect("Transaction not found"); + + monitor + .clone() + .update_wallet_data(app_handle_clone.clone()) + .await; + } + + Ok::<(), WalletStatusMonitorError>(()) + }); + } + + async fn update_wallet_data(self, app_handle: tauri::AppHandle) { + match self.fetch_transaction_history().await { + Ok(transactions) => { + *self.confirmed_transactions.write().await = transactions.clone(); + let _ = app_handle.emit("transaction_history_updated", transactions); + } + Err(e) => { + warn!(target: LOG_TARGET, "Failed to fetch transaction history: {:?}", e); + } + } + + match self.get_balance().await { + Ok(balance) => { + *self.wallet_balance.write().await = balance.clone(); + let _ = app_handle.emit("wallet_balance_updated", balance); + } + Err(e) => { + warn!(target: LOG_TARGET, "Failed to fetch balance: {:?}", e); + } + } + } + + async fn get_balance(&self) -> Result { let mut client = WalletClient::connect(self.wallet_grpc_address()) .await .map_err(|_e| WalletStatusMonitorError::WalletNotStarted)?; @@ -282,7 +357,7 @@ impl WalletStatusMonitor { }) } - pub async fn get_transaction_history( + async fn fetch_transaction_history( &self, ) -> Result, WalletStatusMonitorError> { let mut client = WalletClient::connect(self.wallet_grpc_address()) diff --git a/src-tauri/src/wallet_manager.rs b/src-tauri/src/wallet_manager.rs index 564d8892f..0e44cb5b7 100644 --- a/src-tauri/src/wallet_manager.rs +++ b/src-tauri/src/wallet_manager.rs @@ -103,9 +103,21 @@ impl WalletManager { ) .await?; process_watcher.wait_ready().await?; + Ok(()) } + pub async fn initialize_wallet_relay(&self, app_handle: tauri::AppHandle) { + let process_watcher = self.watcher.read().await; + process_watcher + .status_monitor + .as_ref() + .ok_or_else(|| WalletManagerError::WalletNotStarted) + .unwrap() + .initialize_wallet_relay(app_handle) + .await; + } + pub async fn set_view_private_key_and_spend_key( &self, view_private_key: String, @@ -118,32 +130,32 @@ impl WalletManager { pub async fn get_balance(&self) -> Result { let process_watcher = self.watcher.read().await; - process_watcher + let wallet_balance = process_watcher .status_monitor .as_ref() .ok_or_else(|| WalletManagerError::WalletNotStarted)? - .get_balance() + .wallet_balance + .read() .await - .map_err(|e| match e { - WalletStatusMonitorError::WalletNotStarted => WalletManagerError::WalletNotStarted, - _ => WalletManagerError::UnknownError(e.into()), - }) + .clone(); + + Ok(wallet_balance) } pub async fn get_transaction_history( &self, ) -> Result, WalletManagerError> { let process_watcher = self.watcher.read().await; - process_watcher + let tx_history = process_watcher .status_monitor .as_ref() .ok_or_else(|| WalletManagerError::WalletNotStarted)? - .get_transaction_history() + .confirmed_transactions + .read() .await - .map_err(|e| match e { - WalletStatusMonitorError::WalletNotStarted => WalletManagerError::WalletNotStarted, - _ => WalletManagerError::UnknownError(e.into()), - }) + .clone(); + + Ok(tx_history) } pub async fn stop(&self) -> Result { diff --git a/src/containers/main/SideBar/components/Wallet/History.tsx b/src/containers/main/SideBar/components/Wallet/History.tsx index c5c741733..a85bd0c55 100644 --- a/src/containers/main/SideBar/components/Wallet/History.tsx +++ b/src/containers/main/SideBar/components/Wallet/History.tsx @@ -1,7 +1,5 @@ -import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useWalletStore } from '@app/store/useWalletStore'; -import { CircularProgress } from '@app/components/elements/CircularProgress'; import HistoryItem from './HistoryItem'; import { ListLabel } from './HistoryItem.styles'; @@ -17,15 +15,15 @@ const container = { export default function History() { const { t } = useTranslation('sidebar', { useSuspense: false }); - const isTransactionLoading = useWalletStore((s) => s.isTransactionLoading); const transactions = useWalletStore((s) => s.transactions); - const txMarkup = useMemo(() => transactions.map((tx) => ), [transactions]); return ( {t('recent-wins')} - {isTransactionLoading && !transactions?.length ? : txMarkup} + {transactions.map((tx) => ( + + ))} ); diff --git a/src/containers/main/SideBar/components/Wallet/Wallet.tsx b/src/containers/main/SideBar/components/Wallet/Wallet.tsx index f1abb2617..820e824d8 100644 --- a/src/containers/main/SideBar/components/Wallet/Wallet.tsx +++ b/src/containers/main/SideBar/components/Wallet/Wallet.tsx @@ -12,7 +12,6 @@ import { useWalletStore } from '@app/store/useWalletStore.ts'; import { usePaperWalletStore } from '@app/store/usePaperWalletStore.ts'; import { useAppConfigStore } from '@app/store/useAppConfigStore.ts'; -import useFetchTx from '@app/hooks/mining/useTransactions.ts'; import SyncTooltip from './SyncTooltip/SyncTooltip.tsx'; import History from './History.tsx'; @@ -33,8 +32,6 @@ export default function Wallet() { const { t } = useTranslation('sidebar', { useSuspense: false }); const balance = useWalletStore((s) => s.balance); - const transactions = useWalletStore((s) => s.transactions); - const isTransactionLoading = useWalletStore((s) => s.isTransactionLoading); const setShowPaperWalletModal = usePaperWalletStore((s) => s.setShowModal); const paperWalletEnabled = useAppConfigStore((s) => s.paper_wallet_enabled); @@ -46,7 +43,6 @@ export default function Wallet() { const [showLongBalance, setShowLongBalance] = useState(false); const [animateNumbers, setShowAnimateNumbers] = useState(true); - const fetchTx = useFetchTx(); const formatted = formatNumber(balance || 0, FormatPreset.TXTM_COMPACT); const formattedLong = formatNumber(balance || 0, FormatPreset.TXTM_LONG); @@ -63,15 +59,10 @@ export default function Wallet() { const displayValue = balance === null ? '-' : showBalance ? formatted : '*****'; const handleShowClick = useCallback(() => { - if (balance && !transactions.length && !isTransactionLoading) { - fetchTx().then(() => setShowHistory((c) => !c)); - return; - } - setRecapCount(undefined); setShowHistory((c) => !c); - }, [balance, fetchTx, isTransactionLoading, setRecapCount, transactions?.length]); + }, [setRecapCount]); const handleSyncButtonClick = () => { setShowPaperWalletModal(true); diff --git a/src/hooks/app/useSetUp.ts b/src/hooks/app/useSetUp.ts index cbda61289..05e41fe1d 100644 --- a/src/hooks/app/useSetUp.ts +++ b/src/hooks/app/useSetUp.ts @@ -9,6 +9,9 @@ import { useAppStateStore } from '../../store/appStateStore.ts'; import { useAirdropStore } from '@app/store/useAirdropStore.ts'; import { useHandleAirdropTokensRefresh } from '../airdrop/stateHelpers/useAirdropTokensRefresh.ts'; +import { TransactionInfo, WalletBalance } from '@app/types/app-status.ts'; +import { Transaction } from '@app/types/wallet.ts'; +import { useWalletStore } from '@app/store/useWalletStore.ts'; export function useSetUp() { const isInitializingRef = useRef(false); @@ -17,6 +20,9 @@ export function useSetUp() { const setSetupDetails = useAppStateStore((s) => s.setSetupDetails); const setCriticalError = useAppStateStore((s) => s.setCriticalError); const setSettingUpFinished = useAppStateStore((s) => s.setSettingUpFinished); + const setTransactions = useWalletStore((s) => s.setTransactions); + const setWalletBalance = useWalletStore((s) => s.setWalletBalance); + const fetchWalletDetails = useWalletStore((s) => s.fetchWalletDetails); const fetchApplicationsVersionsWithRetry = useAppStateStore((s) => s.fetchApplicationsVersionsWithRetry); const syncedAidropWithBackend = useAirdropStore((s) => s.syncedWithBackend); @@ -47,6 +53,36 @@ export function useSetUp() { await setSettingUpFinished(); }, [fetchApplicationsVersionsWithRetry, setSettingUpFinished]); + useEffect(() => { + const unlistenPromise = listen( + 'transaction_history_updated', + async ({ payload }: { payload: TransactionInfo[] }) => { + const sortedTransactions = payload.sort((a, b) => b.timestamp - a.timestamp); + const mapped = sortedTransactions?.map((tx) => { + const blockHeight = tx.message.split(': ')[1]; + return blockHeight ? { ...tx, blockHeight } : tx; + }) as Transaction[]; + + if (mapped?.length) { + setTransactions(mapped); + } + } + ); + return () => { + unlistenPromise.then((unlisten) => unlisten()); + }; + }, [setTransactions]); + + useEffect(() => { + const unlistenPromise = listen('wallet_balance_updated', async ({ payload }: { payload: WalletBalance }) => { + console.log('wallet_balance_updated', payload); + setWalletBalance(payload); + }); + return () => { + unlistenPromise.then((unlisten) => unlisten()); + }; + }, [setWalletBalance]); + useEffect(() => { if (adminShow === 'setup') return; const unlistenPromise = listen('message', async ({ event: e, payload: p }: TauriEvent) => { @@ -55,6 +91,9 @@ export function useSetUp() { if (p.progress > 0) { setSetupDetails(p.title, p.title_params, p.progress); } + if (p.progress >= 0.75) { + fetchWalletDetails(); + } if (p.progress >= 1) { await handlePostSetup(); } @@ -75,5 +114,13 @@ export function useSetUp() { return () => { unlistenPromise.then((unlisten) => unlisten()); }; - }, [clearStorage, handlePostSetup, setCriticalError, setSetupDetails, adminShow, syncedAidropWithBackend]); + }, [ + clearStorage, + handlePostSetup, + setCriticalError, + setSetupDetails, + adminShow, + syncedAidropWithBackend, + fetchWalletDetails, + ]); } diff --git a/src/hooks/mining/useMiningMetricsUpdater.ts b/src/hooks/mining/useMiningMetricsUpdater.ts index 128f0193e..4b35b99bd 100644 --- a/src/hooks/mining/useMiningMetricsUpdater.ts +++ b/src/hooks/mining/useMiningMetricsUpdater.ts @@ -5,10 +5,7 @@ import { setAnimationState } from '@app/visuals.ts'; import { useMiningStore } from '@app/store/useMiningStore'; import { useBlockchainVisualisationStore } from '@app/store/useBlockchainVisualisationStore.ts'; -import useFetchTx from './useTransactions.ts'; - export default function useMiningMetricsUpdater() { - const fetchTx = useFetchTx(); const currentBlockHeight = useMiningStore((s) => s.base_node.block_height); const baseNodeConnected = useMiningStore((s) => s.base_node.is_connected); const setMiningMetrics = useMiningStore((s) => s.setMiningMetrics); @@ -30,13 +27,7 @@ export default function useMiningMetricsUpdater() { const blockHeight = metrics.base_node.block_height; if (blockHeight > 0 && currentBlockHeight > 0 && blockHeight > currentBlockHeight) { try { - fetchTx() - .then(async () => { - await handleNewBlock(blockHeight, isMining); - }) - .catch(() => { - setDisplayBlockHeight(blockHeight); - }); + await handleNewBlock(blockHeight, isMining); } catch (_) { setDisplayBlockHeight(blockHeight); } @@ -52,7 +43,6 @@ export default function useMiningMetricsUpdater() { baseNodeConnected, currentBlockHeight, displayBlockHeight, - fetchTx, handleNewBlock, setDisplayBlockHeight, setMiningMetrics, diff --git a/src/hooks/mining/useMiningStatesSync.ts b/src/hooks/mining/useMiningStatesSync.ts index 1250fcce3..3adec45cd 100644 --- a/src/hooks/mining/useMiningStatesSync.ts +++ b/src/hooks/mining/useMiningStatesSync.ts @@ -1,8 +1,7 @@ import { MinerMetrics } from '@app/types/app-status'; import { listen } from '@tauri-apps/api/event'; -import { useCallback, useEffect } from 'react'; +import { useEffect } from 'react'; -import { useWalletStore } from '@app/store/useWalletStore.ts'; import { useAppStateStore } from '@app/store/appStateStore'; import { useBlockInfo } from './useBlockInfo.ts'; @@ -12,31 +11,12 @@ import useEarningsRecap from './useEarningsRecap.ts'; export function useMiningStatesSync() { const handleMiningMetrics = useMiningMetricsUpdater(); - const fetchWalletDetails = useWalletStore((s) => s.fetchWalletDetails); - const setupProgress = useAppStateStore((s) => s.setupProgress); const isSettingUp = useAppStateStore((s) => s.isSettingUp); useBlockInfo(); useUiMiningStateMachine(); useEarningsRecap(); - const callIntervalItems = useCallback(async () => { - if (setupProgress >= 0.75) { - await fetchWalletDetails(); - } - }, [fetchWalletDetails, setupProgress]); - - // intervalItems - useEffect(() => { - const fetchInterval = setInterval(async () => { - await callIntervalItems(); - }, 1000); - - return () => { - clearInterval(fetchInterval); - }; - }, [callIntervalItems]); - useEffect(() => { if (isSettingUp) return; const ul = listen('miner_metrics', async ({ payload }) => { diff --git a/src/hooks/mining/useTransactions.ts b/src/hooks/mining/useTransactions.ts deleted file mode 100644 index cddf30a08..000000000 --- a/src/hooks/mining/useTransactions.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { ALREADY_FETCHING } from '@app/App/sentryIgnore'; -import { useCallback } from 'react'; -import { invoke } from '@tauri-apps/api/core'; -import { useAppStateStore } from '@app/store/appStateStore.ts'; -import { useWalletStore } from '@app/store/useWalletStore.ts'; -import { Transaction } from '@app/types/wallet.ts'; - -export default function useFetchTx() { - const transactions = useWalletStore((s) => s.transactions); - const isTransactionLoading = useWalletStore((s) => s.isTransactionLoading); - const setTransactionsLoading = useWalletStore((s) => s.setTransactionsLoading); - const setupProgress = useAppStateStore((s) => s.setupProgress); - const setTransactions = useWalletStore((s) => s.setTransactions); - - const setItems = useCallback( - async (newTx: Transaction[]) => { - const latestTx = newTx[0]; - const latestId = latestTx?.tx_id; - const hasNewItems = !transactions?.find((tx) => tx.tx_id === latestId); - if (hasNewItems) { - setTransactions(newTx); - } - }, - [setTransactions, transactions] - ); - - return useCallback(async () => { - if (isTransactionLoading || setupProgress < 0.75) return; - setTransactionsLoading(true); - - try { - const txs = await invoke('get_transaction_history'); - const sortedTransactions = txs.sort((a, b) => b.timestamp - a.timestamp); - const mapped = sortedTransactions?.map((tx) => { - const blockHeight = tx.message.split(': ')[1]; - - if (blockHeight) { - return { ...tx, blockHeight }; - } - - return tx; - }) as Transaction[]; - - if (mapped?.length) { - await setItems(mapped); - } - setTransactionsLoading(false); - } catch (error) { - setTransactionsLoading(false); - - if (error !== ALREADY_FETCHING.HISTORY) { - console.error('Could not get transaction history: ', error); - } - } finally { - setTransactionsLoading(false); - } - }, [isTransactionLoading, setItems, setTransactionsLoading, setupProgress]); -} diff --git a/src/store/useWalletStore.ts b/src/store/useWalletStore.ts index c9e83eda8..da77d3d59 100644 --- a/src/store/useWalletStore.ts +++ b/src/store/useWalletStore.ts @@ -10,14 +10,13 @@ interface State extends WalletBalance { tari_address?: string; balance: number | null; transactions: Transaction[]; - isTransactionLoading: boolean; is_wallet_importing: boolean; } interface Actions { fetchWalletDetails: () => Promise; - setTransactionsLoading: (isTransactionLoading: boolean) => void; setTransactions: (transactions?: Transaction[]) => void; + setWalletBalance: (walletBalance: WalletBalance) => void; importSeedWords: (seedWords: string[]) => Promise; } @@ -32,7 +31,6 @@ const initialState: State = { pending_incoming_balance: 0, pending_outgoing_balance: 0, transactions: [], - isTransactionLoading: false, is_wallet_importing: false, }; @@ -40,20 +38,10 @@ export const useWalletStore = create()((set) => ({ ...initialState, fetchWalletDetails: async () => { try { - const tari_wallet_details = await invoke('get_tari_wallet_details'); - const { - available_balance = 0, - timelocked_balance = 0, - pending_incoming_balance = 0, - } = tari_wallet_details.wallet_balance || {}; - // Q: Should we subtract pending_outgoing_balance here? - const newBalance = available_balance + timelocked_balance + pending_incoming_balance; //TM - + const { tari_address_base58, tari_address_emoji } = await invoke('get_tari_wallet_details'); set({ - ...tari_wallet_details.wallet_balance, - tari_address_base58: tari_wallet_details.tari_address_base58, - tari_address_emoji: tari_wallet_details.tari_address_emoji, - balance: tari_wallet_details?.wallet_balance ? newBalance : null, + tari_address_base58, + tari_address_emoji, }); } catch (error) { if (error !== ALREADY_FETCHING.BALANCE) { @@ -61,8 +49,16 @@ export const useWalletStore = create()((set) => ({ } } }, + setWalletBalance: (walletBalance) => { + const { available_balance = 0, timelocked_balance = 0, pending_incoming_balance = 0 } = walletBalance || {}; + const newBalance = available_balance + timelocked_balance + pending_incoming_balance; //TM + + set({ + ...walletBalance, + balance: walletBalance ? newBalance : null, + }); + }, setTransactions: (transactions) => set({ transactions }), - setTransactionsLoading: (isTransactionLoading) => set({ isTransactionLoading }), importSeedWords: async (seedWords: string[]) => { try { set({ is_wallet_importing: true }); diff --git a/src/types/app-status.ts b/src/types/app-status.ts index 84737ed6d..409e80424 100644 --- a/src/types/app-status.ts +++ b/src/types/app-status.ts @@ -95,7 +95,6 @@ export interface MinerMetrics { } export interface TariWalletDetails { - wallet_balance: WalletBalance; tari_address_base58: string; tari_address_emoji: string; } diff --git a/src/types/invoke.ts b/src/types/invoke.ts index 4f3041cb4..6e7c7253d 100644 --- a/src/types/invoke.ts +++ b/src/types/invoke.ts @@ -55,7 +55,6 @@ declare module '@tauri-apps/api/core' { function invoke(param: 'get_p2pool_connections'): Promise; function invoke(param: 'get_used_p2pool_stats_server_port'): Promise; function invoke(param: 'get_tari_wallet_details'): Promise; - function invoke(param: 'get_miner_metrics'): Promise; function invoke(param: 'set_gpu_mining_enabled', payload: { enabled: boolean }): Promise; function invoke( param: 'set_excluded_gpu_devices', @@ -65,7 +64,6 @@ declare module '@tauri-apps/api/core' { function invoke(param: 'exit_application'): Promise; function invoke(param: 'restart_application', payload: { shouldStopMiners: boolean }): Promise; function invoke(param: 'set_use_tor', payload: { useTor: boolean }): Promise; - function invoke(param: 'get_transaction_history'): Promise; function invoke(param: 'import_seed_words', payload: { seedWords: string[] }): Promise; function invoke(param: 'get_tor_config'): Promise; function invoke(param: 'set_tor_config', payload: { config: TorConfig }): Promise;