From f73f238ec6d26e0ec51143a26db65ce6d6ddf8b3 Mon Sep 17 00:00:00 2001 From: xandronus Date: Fri, 9 Oct 2020 11:40:26 -0600 Subject: [PATCH] Add API to retreive private key from wallet address --- .../Api/Controllers/WalletController.cs | 33 ++++++++++++++++++ .../Api/Models/RequestModels.cs | 34 +++++++++++++++++++ .../Interfaces/IWalletManager.cs | 10 ++++++ .../WalletManager.cs | 16 +++++++++ 4 files changed, 93 insertions(+) diff --git a/src/Features/Blockcore.Features.Wallet/Api/Controllers/WalletController.cs b/src/Features/Blockcore.Features.Wallet/Api/Controllers/WalletController.cs index c215b463c..a2fcfc1d6 100644 --- a/src/Features/Blockcore.Features.Wallet/Api/Controllers/WalletController.cs +++ b/src/Features/Blockcore.Features.Wallet/Api/Controllers/WalletController.cs @@ -1181,6 +1181,39 @@ public IActionResult GetExtPubKey([FromQuery] GetExtPubKeyModel request) } } + /// + /// Gets the private key of a specified wallet address. + /// + /// An object containing the necessary parameters to retrieve. + /// The Cancellation Token + /// A JSON object containing the private key of the address in WIF representation. + /// Returns private key + /// Invalid request, or unexpected exception occurred + /// Request is null + [Route("privatekey")] + [HttpPost] + public IActionResult RetrievePrivateKey([FromBody] RetrievePrivateKeyModel request) + { + Guard.NotNull(request, nameof(request)); + + // checks the request is valid + if (!this.ModelState.IsValid) + { + return ModelStateErrors.BuildErrorResponse(this.ModelState); + } + + try + { + string result = this.walletManager.RetrievePrivateKey(request.Password, request.WalletName, request.AccountName, request.Address); + return this.Json(result); + } + catch (Exception e) + { + this.logger.LogError("Exception occurred: {0}", e.ToString()); + return ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()); + } + } + /// /// Requests the node resyncs from a block specified by its block hash. /// Internally, the specified block is taken as the new wallet tip diff --git a/src/Features/Blockcore.Features.Wallet/Api/Models/RequestModels.cs b/src/Features/Blockcore.Features.Wallet/Api/Models/RequestModels.cs index e18caffb7..a9ccfd487 100644 --- a/src/Features/Blockcore.Features.Wallet/Api/Models/RequestModels.cs +++ b/src/Features/Blockcore.Features.Wallet/Api/Models/RequestModels.cs @@ -654,6 +654,40 @@ public GetExtPubKeyModel() public string AccountName { get; set; } } + /// + /// A class containing the necessary parameters for a private key retrieval request. + /// + public class RetrievePrivateKeyModel : RequestModel + { + public RetrievePrivateKeyModel() + { + this.AccountName = WalletManager.DefaultAccount; + } + + /// + /// The password for the wallet. + /// + [Required] + public string Password { get; set; } + + /// + /// The name of the wallet from which to get the private key. + /// + [Required] + public string WalletName { get; set; } + + /// + /// The name of the account for which to get the private key. + /// + public string AccountName { get; set; } + + /// + /// The address to retrieve the private key for. + /// + [Required] + public string Address { get; set; } + } + /// /// A class containing the necessary parameters for a new account request. /// diff --git a/src/Features/Blockcore.Features.Wallet/Interfaces/IWalletManager.cs b/src/Features/Blockcore.Features.Wallet/Interfaces/IWalletManager.cs index 298eb2f38..56fbd8486 100644 --- a/src/Features/Blockcore.Features.Wallet/Interfaces/IWalletManager.cs +++ b/src/Features/Blockcore.Features.Wallet/Interfaces/IWalletManager.cs @@ -81,6 +81,16 @@ public interface IWalletManager /// A mnemonic defining the wallet's seed used to generate addresses. Mnemonic CreateWallet(string password, string name, string passphrase = null, Mnemonic mnemonic = null, int? coinType = null); + /// + /// Gets the private key associated with an address in the wallet. + /// + /// The user's password. + /// The name of the wallet. + /// The name of the account. + /// Address to extract the private key of. + /// The private key associated with the given address, in WIF representation. + string RetrievePrivateKey(string password, string walletName, string accountName, string address); + /// /// Signs a string message. /// diff --git a/src/Features/Blockcore.Features.Wallet/WalletManager.cs b/src/Features/Blockcore.Features.Wallet/WalletManager.cs index 683237f33..faa228832 100644 --- a/src/Features/Blockcore.Features.Wallet/WalletManager.cs +++ b/src/Features/Blockcore.Features.Wallet/WalletManager.cs @@ -319,6 +319,22 @@ public Mnemonic CreateWallet(string password, string name, string passphrase, Mn return mnemonic; } + /// + public string RetrievePrivateKey(string password, string walletName, string accountName, string address) + { + Guard.NotEmpty(password, nameof(password)); + Guard.NotEmpty(walletName, nameof(walletName)); + Guard.NotEmpty(address, nameof(address)); + + Types.Wallet wallet = this.GetWallet(walletName); + + // Locate the address based on its base58 string representation. + HdAddress hdAddress = wallet.GetAddress(address, account => account.Name.Equals(accountName)); + + ISecret privateKey = wallet.GetExtendedPrivateKeyForAddress(password, hdAddress).PrivateKey.GetWif(this.network); + return privateKey.ToString(); + } + /// public SignMessageResult SignMessage(string password, string walletName, string accountName, string externalAddress, string message) {