public static void Main(string[] args) { var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false) .Build(); var rpcConfig = configuration.GetSection("RpcConfig").Get <RpcConfig>(); rpcClient = new WalletRpcClient(rpcConfig.Port, rpcConfig.User, rpcConfig.Password, rpcConfig.Passphrase); optionsBuilder = new DbContextOptionsBuilder <DataContext>(); optionsBuilder.UseSqlServer(configuration.GetConnectionString("Database")); serviceBusConnectionString = configuration.GetConnectionString("ServiceBusConnectionString"); sendCoinsQueueName = configuration.GetConnectionString("SendCoinsQueueName"); contractAddress = configuration.GetValue <string>("ContractAddress"); network = configuration.GetValue <string>("Network"); nrOfCoins = configuration.GetValue <decimal>("NrOfCoins"); sleepTime = configuration.GetValue <int>("SleepTime"); sendCoinsQueueWriter = new QueueWriter <SendCoinsMessage>(serviceBusConnectionString, sendCoinsQueueName); dataManager = new DataManager(() => new DataContext(optionsBuilder.Options)); MainAsync().GetAwaiter().GetResult(); }
private async Task OnWalletProcessOpenedWallet() { try { var sdiff = await WalletRpcClient.TicketPriceAsync(); await App.Current.Dispatcher.InvokeAsync(() => TicketPrice = sdiff); var syncingWallet = await WalletRpcClient.Synchronize(OnWalletChangesProcessed); WalletMutex = syncingWallet.Item1; using (var guard = await WalletMutex.LockAsync()) { OnSyncedWallet(guard.Instance); } var syncTask = syncingWallet.Item2; await syncTask; } catch (ConnectTimeoutException) { MessageBox.Show("Unable to connect to wallet"); } catch (Grpc.Core.RpcException) when(WalletRpcClient.CancellationRequested) { } catch (Exception ex) { var ae = ex as AggregateException; if (ae != null) { Exception inner; if (ae.TryUnwrap(out inner)) { ex = inner; } } await HandleSyncFault(ex); } finally { if (WalletMutex != null) { using (var walletGuard = await WalletMutex.LockAsync()) { walletGuard.Instance.ChangesProcessed -= OnWalletChangesProcessed; } } var shell = (ShellViewModel)ViewModelLocator.ShellViewModel; shell.StartupWizardVisible = true; } }
private async Task OnWalletProcessOpenedWallet() { try { var syncingWallet = await WalletRpcClient.Synchronize(OnWalletChangesProcessed); Wallet = syncingWallet.Item1; OnSyncedWallet(); var syncTask = syncingWallet.Item2; await syncTask; } catch (ConnectTimeoutException) { MessageBox.Show("Unable to connect to wallet"); } catch (Exception ex) { var ae = ex as AggregateException; if (ae != null) { Exception inner; if (ae.TryUnwrap(out inner)) { ex = inner; } } HandleSyncFault(ex); } finally { var wallet = Wallet; if (wallet != null) { wallet.ChangesProcessed -= OnWalletChangesProcessed; } var shell = (ShellViewModel)ViewModelLocator.ShellViewModel; shell.StartupWizardVisible = true; } }
public void Initialize() { if (ConfigService.DaemonPort != null) { if (!string.IsNullOrWhiteSpace(ConfigService.DaemonPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.DaemonPassword)) { DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, ConfigService.DaemonPort.Value, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.DaemonPasswordProxyHeader, ConfigService.DaemonPassword)); } else { DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, ConfigService.DaemonPort.Value, ConfigService.DaemonUsername, ConfigService.DaemonPassword); } } else { if (!string.IsNullOrWhiteSpace(ConfigService.DaemonPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.DaemonPassword)) { DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.DaemonPasswordProxyHeader, ConfigService.DaemonPassword)); } else { DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, ConfigService.DaemonUsername, ConfigService.DaemonPassword); } } if (ConfigService.WalletPort != null) { if (!string.IsNullOrWhiteSpace(ConfigService.WalletPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.WalletPassword)) { WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, ConfigService.WalletPort.Value, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.WalletPasswordProxyHeader, ConfigService.WalletPassword)); } else { WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, ConfigService.WalletPort.Value, ConfigService.WalletUsername, ConfigService.WalletPassword); } } else { if (!string.IsNullOrWhiteSpace(ConfigService.WalletPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.WalletPassword)) { WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.WalletPasswordProxyHeader, ConfigService.WalletPassword)); } else { WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, ConfigService.WalletUsername, ConfigService.WalletPassword); } } Program.TasksToAwait.Add(Task.Factory.StartNew(async() => { NextCheck = DateTimeOffset.Now.AddMinutes(15); while (!Program.CancellationTokenSource.IsCancellationRequested) { if (DateTimeOffset.Now < NextCheck) { await Task.Delay(1000).ConfigureAwait(false); continue; } try { await LoggerService.LogMessageAsync("Attempting to save the wallet...").ConfigureAwait(false); await WalletRpcClient.StoreAsync(Program.CancellationTokenSource.Token).ConfigureAwait(false); await LoggerService.LogMessageAsync("Save complete!", ConsoleColor.Green).ConfigureAwait(false); } catch (Exception ex) { await LoggerService.LogErrorMessageAsync(ex).ConfigureAwait(false); } finally { NextCheck = DateTimeOffset.Now.AddMinutes(15); } } }, Program.CancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current).Unwrap()); }
public void Dispose() { DaemonRpcClient?.Dispose(); WalletRpcClient?.Dispose(); }
private void OnWalletChangesProcessed(object sender, Wallet.ChangesProcessedEventArgs e) { var wallet = (Wallet)sender; var currentHeight = e.NewChainTip?.Height ?? SyncedBlockHeight; // TODO: The OverviewViewModel should probably connect to this event. This could be // done after the wallet is synced. var overviewViewModel = ViewModelLocator.OverviewViewModel as OverviewViewModel; if (overviewViewModel != null) { var movedTxViewModels = overviewViewModel.RecentTransactions .Where(txvm => e.MovedTransactions.ContainsKey(txvm.TxHash)) .Select(txvm => Tuple.Create(txvm, e.MovedTransactions[txvm.TxHash])); var newTxViewModels = e.AddedTransactions.Select(tx => new TransactionViewModel(wallet, tx.Item1, tx.Item2)).ToList(); foreach (var movedTx in movedTxViewModels) { var txvm = movedTx.Item1; var location = movedTx.Item2; txvm.Location = location; txvm.Depth = BlockChain.Depth(currentHeight, location); } App.Current.Dispatcher.Invoke(() => { foreach (var txvm in newTxViewModels) { overviewViewModel.RecentTransactions.Insert(0, txvm); } while (overviewViewModel.RecentTransactions.Count > 10) { overviewViewModel.RecentTransactions.RemoveAt(10); } }); } // TODO: same.. in fact these tx viewmodels should be reused so changes don't need to be recalculated. // It would be a good idea for this synchronzier viewmodel to manage these and hand them out to other // viewmodels for sorting and organization. var transactionHistoryViewModel = ViewModelLocator.TransactionHistoryViewModel as TransactionHistoryViewModel; if (transactionHistoryViewModel != null) { foreach (var tx in transactionHistoryViewModel.Transactions) { var txvm = tx.Transaction; BlockIdentity newLocation; if (e.MovedTransactions.TryGetValue(txvm.TxHash, out newLocation)) { txvm.Location = newLocation; } txvm.Depth = BlockChain.Depth(currentHeight, txvm.Location); } transactionHistoryViewModel.AppendNewTransactions(wallet, e.AddedTransactions); } foreach (var modifiedAccount in e.ModifiedAccountProperties) { var accountNumber = checked ((int)modifiedAccount.Key.AccountNumber); var accountProperties = modifiedAccount.Value; if (accountNumber < Accounts.Count) { Accounts[accountNumber].AccountProperties = accountProperties; } } // TODO: this would be better if all new accounts were a field in the event message. var newAccounts = e.ModifiedAccountProperties. Where(kvp => kvp.Key.AccountNumber >= Accounts.Count && kvp.Key.AccountNumber != Wallet.ImportedAccountNumber). OrderBy(kvp => kvp.Key.AccountNumber); foreach (var modifiedAccount in newAccounts) { var accountNumber = checked ((int)modifiedAccount.Key.AccountNumber); var accountProperties = modifiedAccount.Value; // TODO: This is very inefficient because it recalculates balances of every account, for each new account. var accountBalance = wallet.CalculateBalances(2)[accountNumber]; var accountViewModel = new AccountViewModel(modifiedAccount.Key, accountProperties, accountBalance); App.Current.Dispatcher.Invoke(() => Accounts.Add(accountViewModel)); } if (e.NewChainTip != null) { SyncedBlockHeight = e.NewChainTip.Value.Height; var oldRetarget = BlocksUntilTicketPriceRetarget; BlocksUntilTicketPriceRetarget = BlockChain.BlocksUntilTicketPriceRetarget(SyncedBlockHeight, wallet.ActiveChain); if (BlocksUntilTicketPriceRetarget > oldRetarget) { Task.Run(async() => { var sdiff = await WalletRpcClient.TicketPriceAsync(); await App.Current.Dispatcher.InvokeAsync(() => TicketPrice = sdiff); }).ContinueWith(t => { if (t.Exception != null) { MessageBox.Show(t.Exception.InnerException.Message, "Error querying ticket price"); } }); } } if (e.AddedTransactions.Count != 0 || e.RemovedTransactions.Count != 0 || e.NewChainTip != null) { TotalBalance = wallet.TotalBalance; TransactionCount += e.AddedTransactions.Count - e.RemovedTransactions.Count; var balances = wallet.CalculateBalances(2); // TODO: don't hardcode confs for (var i = 0; i < balances.Length; i++) { Accounts[i].Balances = balances[i]; } } }