public async Task <IActionResult> SignWithSeed([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId, SignWithSeedViewModel viewModel) { if (!ModelState.IsValid) { return(View(viewModel)); } var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode); if (network == null) { throw new FormatException("Invalid value for crypto code"); } ExtKey extKey = viewModel.GetExtKey(network.NBitcoinNetwork); if (extKey == null) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "Seed or Key was not in a valid format. It is either the 12/24 words or starts with xprv"); } var psbt = PSBT.Parse(viewModel.PSBT, network.NBitcoinNetwork); if (!psbt.IsReadyToSign()) { ModelState.AddModelError(nameof(viewModel.PSBT), "PSBT is not ready to be signed"); } if (!ModelState.IsValid) { return(View(viewModel)); } ExtKey signingKey = null; var settings = GetDerivationSchemeSettings(walletId); var signingKeySettings = settings.GetSigningAccountKeySettings(); if (signingKeySettings.RootFingerprint is null) { signingKeySettings.RootFingerprint = extKey.GetPublicKey().GetHDFingerPrint(); } RootedKeyPath rootedKeyPath = signingKeySettings.GetRootedKeyPath(); // The user gave the root key, let's try to rebase the PSBT, and derive the account private key if (rootedKeyPath?.MasterFingerprint == extKey.GetPublicKey().GetHDFingerPrint()) { psbt.RebaseKeyPaths(signingKeySettings.AccountKey, rootedKeyPath); signingKey = extKey.Derive(rootedKeyPath.KeyPath); } // The user maybe gave the account key, let's try to sign with it else { signingKey = extKey; } var balanceChange = psbt.GetBalance(settings.AccountDerivation, signingKey, rootedKeyPath); if (balanceChange == Money.Zero) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "This seed is unable to sign this transaction. Either the seed is incorrect, or the account path has not been properly configured in the Wallet Settings."); return(View(viewModel)); } psbt.SignAll(settings.AccountDerivation, signingKey, rootedKeyPath); ModelState.Remove(nameof(viewModel.PSBT)); return(await WalletPSBTReady(walletId, psbt.ToBase64(), signingKey.GetWif(network.NBitcoinNetwork).ToString(), rootedKeyPath?.ToString())); }
public async Task <IActionResult> SignWithSeed([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId, SignWithSeedViewModel viewModel) { if (!ModelState.IsValid) { return(View(viewModel)); } var network = NetworkProvider.GetNetwork <BTCPayNetwork>(walletId.CryptoCode); if (network == null) { throw new FormatException("Invalid value for crypto code"); } ExtKey extKey = viewModel.GetExtKey(network.NBitcoinNetwork); if (extKey == null) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "Seed or Key was not in a valid format. It is either the 12/24 words or starts with xprv"); } var psbt = PSBT.Parse(viewModel.PSBT, network.NBitcoinNetwork); if (!psbt.IsReadyToSign()) { ModelState.AddModelError(nameof(viewModel.PSBT), "PSBT is not ready to be signed"); } if (!ModelState.IsValid) { return(View(viewModel)); } ExtKey signingKey = null; var settings = GetDerivationSchemeSettings(walletId); var signingKeySettings = settings.GetSigningAccountKeySettings(); if (signingKeySettings.RootFingerprint is null) { signingKeySettings.RootFingerprint = extKey.GetPublicKey().GetHDFingerPrint(); } RootedKeyPath rootedKeyPath = signingKeySettings.GetRootedKeyPath(); if (rootedKeyPath == null) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "The master fingerprint and/or account key path of your seed are not set in the wallet settings."); return(View(viewModel)); } // The user gave the root key, let's try to rebase the PSBT, and derive the account private key if (rootedKeyPath.MasterFingerprint == extKey.GetPublicKey().GetHDFingerPrint()) { psbt.RebaseKeyPaths(signingKeySettings.AccountKey, rootedKeyPath); signingKey = extKey.Derive(rootedKeyPath.KeyPath); } else { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "The master fingerprint does not match the one set in your wallet settings. Probable cause are: wrong seed, wrong passphrase or wrong fingerprint in your wallet settings."); return(View(viewModel)); } var changed = PSBTChanged(psbt, () => psbt.SignAll(settings.AccountDerivation, signingKey, rootedKeyPath)); if (!changed) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "Impossible to sign the transaction. Probable cause: Incorrect account key path in wallet settings, PSBT already signed."); return(View(viewModel)); } ModelState.Remove(nameof(viewModel.PSBT)); return(await WalletPSBTReady(walletId, psbt.ToBase64(), signingKey.GetWif(network.NBitcoinNetwork).ToString(), rootedKeyPath?.ToString())); }
public async Task <IActionResult> SignWithSeed([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId, SignWithSeedViewModel viewModel) { if (!ModelState.IsValid) { return(View(viewModel)); } var network = NetworkProvider.GetNetwork(walletId.CryptoCode); if (network == null) { throw new FormatException("Valor no válido para el código criptográfico"); } ExtKey extKey = viewModel.GetExtKey(network.NBitcoinNetwork); if (extKey == null) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "La seed o la clave no estaban en un formato válido. Es el 12/24 palabras o comienza con xprv"); } var psbt = PSBT.Parse(viewModel.PSBT, network.NBitcoinNetwork); if (!psbt.IsReadyToSign()) { ModelState.AddModelError(nameof(viewModel.PSBT), "PSBT no está listo para ser firmado"); } if (!ModelState.IsValid) { return(View(viewModel)); } ExtKey signingKey = null; var settings = (await GetDerivationSchemeSettings(walletId)); var signingKeySettings = settings.GetSigningAccountKeySettings(); if (signingKeySettings.RootFingerprint is null) { signingKeySettings.RootFingerprint = extKey.GetPublicKey().GetHDFingerPrint(); } RootedKeyPath rootedKeyPath = signingKeySettings.GetRootedKeyPath(); // The user gave the root key, let's try to rebase the PSBT, and derive the account private key if (rootedKeyPath?.MasterFingerprint == extKey.GetPublicKey().GetHDFingerPrint()) { psbt.RebaseKeyPaths(signingKeySettings.AccountKey, rootedKeyPath); signingKey = extKey.Derive(rootedKeyPath.KeyPath); } // The user maybe gave the account key, let's try to sign with it else { signingKey = extKey; } var balanceChange = psbt.GetBalance(settings.AccountDerivation, signingKey, rootedKeyPath); if (balanceChange == Money.Zero) { ModelState.AddModelError(nameof(viewModel.SeedOrKey), "Esta seed no parece poder firmar esta transacción. Esta es la clave incorrecta o la configuración de la cartera no tiene la ruta de cuenta correcta en la configuración de la cartera."); return(View(viewModel)); } psbt.SignAll(settings.AccountDerivation, signingKey, rootedKeyPath); ModelState.Remove(nameof(viewModel.PSBT)); return(await WalletPSBTReady(walletId, psbt.ToBase64(), signingKey.GetWif(network.NBitcoinNetwork).ToString(), rootedKeyPath.ToString())); }