using Microsoft.Extensions.Logging; using System; using System.Collections.ObjectModel; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using WpfApp1TRC20.Data; using WpfApp1TRC20.Services; using TransactionStatus = WpfApp1TRC20.Data.TransactionStatus; namespace WpfApp1TRC20.ViewModels { public class MainViewModel : ViewModelBase { private readonly IDataService _dataService; private readonly ITronService _tronService; private readonly ILogger _logger; private TokenInfo _selectedToken; private WalletAccount _selectedWallet; private string _selectedTabItem = "Dashboard"; public MainViewModel(IDataService dataService, ITronService tronService, ILogger logger) { _dataService = dataService; _tronService = tronService; _logger = logger; Tokens = new ObservableCollection(); Wallets = new ObservableCollection(); Transactions = new ObservableCollection(); TokenBalances = new ObservableCollection(); // Commands CreateTokenCommand = new RelayCommand(async () => await CreateTokenAsync()); CreateWalletCommand = new RelayCommand(async () => await CreateWalletAsync()); ImportWalletCommand = new RelayCommand(async () => await ImportWalletAsync()); TransferTokenCommand = new RelayCommand(async () => await TransferTokenAsync(), CanTransferToken); RefreshDataCommand = new RelayCommand(async () => await RefreshDataAsync()); // Load initial data _ = Task.Run(RefreshDataAsync); } // Properties public ObservableCollection Tokens { get; } public ObservableCollection Wallets { get; } public ObservableCollection Transactions { get; } public ObservableCollection TokenBalances { get; } public TokenInfo SelectedToken { get => _selectedToken; set => SetProperty(ref _selectedToken, value); } public WalletAccount SelectedWallet { get => _selectedWallet; set { SetProperty(ref _selectedWallet, value); if (value != null) _ = Task.Run(() => LoadTokenBalancesAsync(value.Address)); } } public string SelectedTabItem { get => _selectedTabItem; set => SetProperty(ref _selectedTabItem, value); } // Token Creation Properties private string _newTokenName; public string NewTokenName { get => _newTokenName; set => SetProperty(ref _newTokenName, value); } private string _newTokenSymbol; public string NewTokenSymbol { get => _newTokenSymbol; set => SetProperty(ref _newTokenSymbol, value); } private int _newTokenDecimals = 18; public int NewTokenDecimals { get => _newTokenDecimals; set => SetProperty(ref _newTokenDecimals, value); } private decimal _newTokenSupply = 1000000; public decimal NewTokenSupply { get => _newTokenSupply; set => SetProperty(ref _newTokenSupply, value); } private int _newTokenExpiryDays = 30; public int NewTokenExpiryDays { get => _newTokenExpiryDays; set => SetProperty(ref _newTokenExpiryDays, value); } // Transfer Properties private string _transferToAddress; public string TransferToAddress { get => _transferToAddress; set => SetProperty(ref _transferToAddress, value); } private decimal _transferAmount; public decimal TransferAmount { get => _transferAmount; set => SetProperty(ref _transferAmount, value); } private TokenBalance _selectedTokenBalance; public TokenBalance SelectedTokenBalance { get => _selectedTokenBalance; set => SetProperty(ref _selectedTokenBalance, value); } private string _newWalletName; public string NewWalletName { get => _newWalletName; set => SetProperty(ref _newWalletName, value); } private string _importPrivateKey; public string ImportPrivateKey { get => _importPrivateKey; set => SetProperty(ref _importPrivateKey, value); } private bool _isLoading; public bool IsLoading { get => _isLoading; set => SetProperty(ref _isLoading, value); } private string _statusMessage; public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } // Commands public ICommand CreateTokenCommand { get; } public ICommand CreateWalletCommand { get; } public ICommand ImportWalletCommand { get; } public ICommand TransferTokenCommand { get; } public ICommand RefreshDataCommand { get; } // Methods private async Task CreateTokenAsync() { if (string.IsNullOrWhiteSpace(NewTokenName) || string.IsNullOrWhiteSpace(NewTokenSymbol) || SelectedWallet == null) { StatusMessage = "Please fill all required fields and select a wallet"; return; } IsLoading = true; StatusMessage = "Creating token..."; try { var parameters = new TokenCreationParams { Name = NewTokenName, Symbol = NewTokenSymbol, Decimals = NewTokenDecimals, TotalSupply = NewTokenSupply, ExpiryDays = NewTokenExpiryDays, OwnerAddress = SelectedWallet.Address }; var privateKey = _tronService.DecryptPrivateKey(SelectedWallet.EncryptedPrivateKey); var txHash = await _tronService.CreateTokenAsync(parameters, privateKey); var token = new TokenInfo { Name = parameters.Name, Symbol = parameters.Symbol, Decimals = parameters.Decimals, TotalSupply = parameters.TotalSupply, OwnerAddress = parameters.OwnerAddress, CreationDate = DateTime.UtcNow, ExpiryDate = DateTime.UtcNow.AddDays(parameters.ExpiryDays), ExpiryDays = parameters.ExpiryDays, TransactionHash = txHash, Status = TokenStatus.Creating }; await _dataService.SaveTokenAsync(token); Tokens.Add(token); // Clear form NewTokenName = ""; NewTokenSymbol = ""; NewTokenDecimals = 18; NewTokenSupply = 1000000; NewTokenExpiryDays = 30; StatusMessage = $"Token creation initiated. Transaction: {txHash}"; // Monitor transaction status _ = Task.Run(() => MonitorTokenCreation(token)); } catch (Exception ex) { _logger.LogError(ex, "Error creating token"); StatusMessage = $"Error creating token: {ex.Message}"; } finally { IsLoading = false; } } private async Task CreateWalletAsync() { if (string.IsNullOrWhiteSpace(NewWalletName)) { StatusMessage = "Please enter a wallet name"; return; } try { var wallet = _tronService.CreateWallet(NewWalletName); await _dataService.SaveWalletAsync(wallet); Wallets.Add(wallet); NewWalletName = ""; StatusMessage = $"Wallet '{wallet.Name}' created successfully"; } catch (Exception ex) { _logger.LogError(ex, "Error creating wallet"); StatusMessage = $"Error creating wallet: {ex.Message}"; } } private async Task ImportWalletAsync() { if (string.IsNullOrWhiteSpace(NewWalletName) || string.IsNullOrWhiteSpace(ImportPrivateKey)) { StatusMessage = "Please enter wallet name and private key"; return; } try { var wallet = _tronService.ImportWallet(NewWalletName, ImportPrivateKey); await _dataService.SaveWalletAsync(wallet); Wallets.Add(wallet); NewWalletName = ""; ImportPrivateKey = ""; StatusMessage = $"Wallet '{wallet.Name}' imported successfully"; } catch (Exception ex) { _logger.LogError(ex, "Error importing wallet"); StatusMessage = $"Error importing wallet: {ex.Message}"; } } private bool CanTransferToken() { return SelectedWallet != null && SelectedTokenBalance != null && !string.IsNullOrWhiteSpace(TransferToAddress) && TransferAmount > 0; } private async Task TransferTokenAsync() { if (!CanTransferToken()) return; IsLoading = true; StatusMessage = "Transferring tokens..."; try { var privateKey = _tronService.DecryptPrivateKey(SelectedWallet.EncryptedPrivateKey); var txHash = await _tronService.TransferTokenAsync( SelectedTokenBalance.ContractAddress, privateKey, TransferToAddress, TransferAmount ); var transaction = new TransactionRecord { TransactionHash = txHash, FromAddress = SelectedWallet.Address, ToAddress = TransferToAddress, Amount = TransferAmount, TokenSymbol = SelectedTokenBalance.TokenSymbol, ContractAddress = SelectedTokenBalance.ContractAddress, Timestamp = DateTime.UtcNow, Status = TransactionStatus.Pending }; await _dataService.SaveTransactionAsync(transaction); Transactions.Insert(0, transaction); // Clear form TransferToAddress = ""; TransferAmount = 0; StatusMessage = $"Transfer initiated. Transaction: {txHash}"; // Refresh balances await LoadTokenBalancesAsync(SelectedWallet.Address); } catch (Exception ex) { _logger.LogError(ex, "Error transferring tokens"); StatusMessage = $"Error transferring tokens: {ex.Message}"; } finally { IsLoading = false; } } private async Task RefreshDataAsync() { try { var tokens = await _dataService.GetTokensAsync(); var wallets = await _dataService.GetWalletsAsync(); var transactions = await _dataService.GetTransactionsAsync(); Application.Current.Dispatcher.Invoke(() => { Tokens.Clear(); foreach (var token in tokens) Tokens.Add(token); Wallets.Clear(); foreach (var wallet in wallets) Wallets.Add(wallet); Transactions.Clear(); foreach (var transaction in transactions) Transactions.Add(transaction); }); if (SelectedWallet != null) { await LoadTokenBalancesAsync(SelectedWallet.Address); } } catch (Exception ex) { _logger.LogError(ex, "Error refreshing data"); } } private async Task LoadTokenBalancesAsync(string walletAddress) { try { var balances = await _dataService.GetTokenBalancesAsync(walletAddress); Application.Current.Dispatcher.Invoke(() => { TokenBalances.Clear(); foreach (var balance in balances) TokenBalances.Add(balance); }); } catch (Exception ex) { _logger.LogError(ex, "Error loading token balances"); } } private async Task MonitorTokenCreation(TokenInfo token) { // Wait for transaction confirmation for (int i = 0; i < 30; i++) // Wait up to 5 minutes { await Task.Delay(10000); // Wait 10 seconds try { var txInfo = await _tronService.GetTransactionAsync(token.TransactionHash); if (txInfo.Status == TransactionStatus.Confirmed) { // Extract contract address from transaction (simplified) // In real implementation, parse the transaction receipt token.ContractAddress = GenerateContractAddress(token.TransactionHash); token.Status = TokenStatus.Active; await _dataService.SaveTokenAsync(token); Application.Current.Dispatcher.Invoke(() => { StatusMessage = $"Token '{token.Symbol}' deployed successfully!"; }); break; } else if (txInfo.Status == TransactionStatus.Failed) { token.Status = TokenStatus.Failed; await _dataService.SaveTokenAsync(token); Application.Current.Dispatcher.Invoke(() => { StatusMessage = $"Token '{token.Symbol}' deployment failed"; }); break; } } catch (Exception ex) { _logger.LogError(ex, "Error monitoring token creation"); } } } private string GenerateContractAddress(string transactionHash) { // Simplified contract address generation // In real implementation, calculate from transaction details return "T" + transactionHash.Substring(0, 33); } } }