public async Task <IActionResult> GenerateWallet(string storeId, string cryptoCode, WalletSetupMethod method, WalletSetupRequest request) { var checkResult = IsAvailable(cryptoCode, out var store, out var network); if (checkResult != null) { return(checkResult); } var(hotWallet, rpcImport) = await CanUseHotWallet(); if (!hotWallet && request.SavePrivateKeys || !rpcImport && request.ImportKeysToRPC) { return(NotFound()); } var client = _ExplorerProvider.GetExplorerClient(cryptoCode); var isImport = method == WalletSetupMethod.Seed; var vm = new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, Method = method, SetupRequest = request, Confirmation = string.IsNullOrEmpty(request.ExistingMnemonic), Network = network, Source = isImport ? "SeedImported" : "NBXplorerGenerated", IsHotWallet = isImport ? request.SavePrivateKeys : method == WalletSetupMethod.HotWallet, DerivationSchemeFormat = "BTCPay", CanUseHotWallet = hotWallet, CanUseRPCImport = rpcImport, IsTaprootActivated = TaprootActivated(cryptoCode), SupportTaproot = network.NBitcoinNetwork.Consensus.SupportTaproot, SupportSegwit = network.NBitcoinNetwork.Consensus.SupportSegwit }; if (isImport && string.IsNullOrEmpty(request.ExistingMnemonic)) { ModelState.AddModelError(nameof(request.ExistingMnemonic), "Please provide your existing seed"); return(View(vm.ViewName, vm)); } GenerateWalletResponse response; try { response = await client.GenerateWalletAsync(request); if (response == null) { throw new Exception("Node unavailable"); } } catch (Exception e) { TempData.SetStatusMessageModel(new StatusMessageModel { Severity = StatusMessageModel.StatusSeverity.Error, Html = $"There was an error generating your wallet: {e.Message}" }); return(View(vm.ViewName, vm)); } var derivationSchemeSettings = new DerivationSchemeSettings(response.DerivationScheme, network); if (method == WalletSetupMethod.Seed) { derivationSchemeSettings.Source = "ImportedSeed"; derivationSchemeSettings.IsHotWallet = request.SavePrivateKeys; } else { derivationSchemeSettings.Source = "NBXplorerGenerated"; derivationSchemeSettings.IsHotWallet = method == WalletSetupMethod.HotWallet; } var accountSettings = derivationSchemeSettings.GetSigningAccountKeySettings(); accountSettings.AccountKeyPath = response.AccountKeyPath.KeyPath; accountSettings.RootFingerprint = response.AccountKeyPath.MasterFingerprint; derivationSchemeSettings.AccountOriginal = response.DerivationScheme.ToString(); // Set wallet properties from generate response vm.RootFingerprint = response.AccountKeyPath.MasterFingerprint.ToString(); vm.AccountKey = response.AccountHDKey.Neuter().ToWif(); vm.KeyPath = response.AccountKeyPath.KeyPath.ToString(); vm.Config = ProtectString(derivationSchemeSettings.ToJson()); var result = await UpdateWallet(vm); if (!ModelState.IsValid || !(result is RedirectToActionResult)) { return(result); } if (!isImport) { TempData.SetStatusMessageModel(new StatusMessageModel { Severity = StatusMessageModel.StatusSeverity.Success, Html = "<span class='text-centered'>Your wallet has been generated.</span>" }); var seedVm = new RecoverySeedBackupViewModel { CryptoCode = cryptoCode, Mnemonic = response.Mnemonic, Passphrase = response.Passphrase, IsStored = request.SavePrivateKeys, ReturnUrl = Url.Action(nameof(GenerateWalletConfirm), new { storeId, cryptoCode }) }; if (this._BTCPayEnv.IsDeveloping) { GenerateWalletResponse = response; } return(this.RedirectToRecoverySeedBackup(seedVm)); } TempData.SetStatusMessageModel(new StatusMessageModel { Severity = StatusMessageModel.StatusSeverity.Warning, Html = "Please check your addresses and confirm." }); return(result); }
public async Task <IActionResult> GenerateWallet(string storeId, string cryptoCode, WalletSetupMethod method, GenerateWalletRequest request) { var checkResult = IsAvailable(cryptoCode, out var store, out var network); if (checkResult != null) { return(checkResult); } var(hotWallet, rpcImport) = await CanUseHotWallet(); if (!hotWallet && request.SavePrivateKeys || !rpcImport && request.ImportKeysToRPC) { return(NotFound()); } var client = _ExplorerProvider.GetExplorerClient(cryptoCode); var isImport = method == WalletSetupMethod.Seed; var vm = new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, Method = method, SetupRequest = request, Confirmation = string.IsNullOrEmpty(request.ExistingMnemonic), Network = network, RootKeyPath = network.GetRootKeyPath(), Enabled = !store.GetStoreBlob().IsExcluded(new PaymentMethodId(cryptoCode, PaymentTypes.BTCLike)), Source = "NBXplorer", DerivationSchemeFormat = "BTCPay", CanUseHotWallet = true, CanUseRPCImport = rpcImport }; if (isImport && string.IsNullOrEmpty(request.ExistingMnemonic)) { ModelState.AddModelError(nameof(request.ExistingMnemonic), "Please provide your existing seed"); return(View(vm.ViewName, vm)); } GenerateWalletResponse response; try { response = await client.GenerateWalletAsync(request); if (response == null) { throw new Exception("Node unavailable"); } } catch (Exception e) { TempData.SetStatusMessageModel(new StatusMessageModel { Severity = StatusMessageModel.StatusSeverity.Error, Html = $"There was an error generating your wallet: {e.Message}" }); return(View(vm.ViewName, vm)); } // Set wallet properties from generate response vm.RootFingerprint = response.AccountKeyPath.MasterFingerprint.ToString(); vm.DerivationScheme = response.DerivationScheme.ToString(); vm.AccountKey = response.AccountHDKey.Neuter().ToWif(); vm.KeyPath = response.AccountKeyPath.KeyPath.ToString(); var result = await UpdateWallet(vm); if (!ModelState.IsValid || !(result is RedirectToActionResult)) { return(result); } if (!isImport) { TempData.SetStatusMessageModel(new StatusMessageModel { Severity = StatusMessageModel.StatusSeverity.Success, Html = "<span class='text-centered'>Your wallet has been generated.</span>" }); var seedVm = new RecoverySeedBackupViewModel { CryptoCode = cryptoCode, Mnemonic = response.Mnemonic, Passphrase = response.Passphrase, IsStored = request.SavePrivateKeys, ReturnUrl = Url.Action(nameof(GenerateWalletConfirm), new { storeId, cryptoCode }) }; return(this.RedirectToRecoverySeedBackup(seedVm)); } TempData.SetStatusMessageModel(new StatusMessageModel { Severity = StatusMessageModel.StatusSeverity.Warning, Html = "Please check your addresses and confirm." }); return(result); }