TRC20/WpfApp1TRC20/ViewModels/MainViewModel.cs
2025-07-25 16:05:44 +05:30

446 lines
15 KiB
C#

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<MainViewModel> _logger;
private TokenInfo _selectedToken;
private WalletAccount _selectedWallet;
private string _selectedTabItem = "Dashboard";
public MainViewModel(IDataService dataService, ITronService tronService, ILogger<MainViewModel> logger)
{
_dataService = dataService;
_tronService = tronService;
_logger = logger;
Tokens = new ObservableCollection<TokenInfo>();
Wallets = new ObservableCollection<WalletAccount>();
Transactions = new ObservableCollection<TransactionRecord>();
TokenBalances = new ObservableCollection<TokenBalance>();
// 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<TokenInfo> Tokens { get; }
public ObservableCollection<WalletAccount> Wallets { get; }
public ObservableCollection<TransactionRecord> Transactions { get; }
public ObservableCollection<TokenBalance> 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);
}
}
}