Skip to content

Commit 1b6ab3d

Browse files
authored
Add API to retreive private key from wallet address (#227)
1 parent de310f4 commit 1b6ab3d

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

src/Features/Blockcore.Features.Wallet/Api/Controllers/WalletController.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,39 @@ public IActionResult GetExtPubKey([FromQuery] GetExtPubKeyModel request)
11811181
}
11821182
}
11831183

1184+
/// <summary>
1185+
/// Gets the private key of a specified wallet address.
1186+
/// </summary>
1187+
/// <param name="request">An object containing the necessary parameters to retrieve.</param>
1188+
/// <param name="cancellationToken">The Cancellation Token</param>
1189+
/// <returns>A JSON object containing the private key of the address in WIF representation.</returns>
1190+
/// <response code="200">Returns private key</response>
1191+
/// <response code="400">Invalid request, or unexpected exception occurred</response>
1192+
/// <response code="500">Request is null</response>
1193+
[Route("privatekey")]
1194+
[HttpPost]
1195+
public IActionResult RetrievePrivateKey([FromBody] RetrievePrivateKeyModel request)
1196+
{
1197+
Guard.NotNull(request, nameof(request));
1198+
1199+
// checks the request is valid
1200+
if (!this.ModelState.IsValid)
1201+
{
1202+
return ModelStateErrors.BuildErrorResponse(this.ModelState);
1203+
}
1204+
1205+
try
1206+
{
1207+
string result = this.walletManager.RetrievePrivateKey(request.Password, request.WalletName, request.AccountName, request.Address);
1208+
return this.Json(result);
1209+
}
1210+
catch (Exception e)
1211+
{
1212+
this.logger.LogError("Exception occurred: {0}", e.ToString());
1213+
return ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString());
1214+
}
1215+
}
1216+
11841217
/// <summary>
11851218
/// Requests the node resyncs from a block specified by its block hash.
11861219
/// Internally, the specified block is taken as the new wallet tip

src/Features/Blockcore.Features.Wallet/Api/Models/RequestModels.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,40 @@ public GetExtPubKeyModel()
654654
public string AccountName { get; set; }
655655
}
656656

657+
/// <summary>
658+
/// A class containing the necessary parameters for a private key retrieval request.
659+
/// </summary>
660+
public class RetrievePrivateKeyModel : RequestModel
661+
{
662+
public RetrievePrivateKeyModel()
663+
{
664+
this.AccountName = WalletManager.DefaultAccount;
665+
}
666+
667+
/// <summary>
668+
/// The password for the wallet.
669+
/// </summary>
670+
[Required]
671+
public string Password { get; set; }
672+
673+
/// <summary>
674+
/// The name of the wallet from which to get the private key.
675+
/// </summary>
676+
[Required]
677+
public string WalletName { get; set; }
678+
679+
/// <summary>
680+
/// The name of the account for which to get the private key.
681+
/// <summary>
682+
public string AccountName { get; set; }
683+
684+
/// <summary>
685+
/// The address to retrieve the private key for.
686+
/// </summary>
687+
[Required]
688+
public string Address { get; set; }
689+
}
690+
657691
/// <summary>
658692
/// A class containing the necessary parameters for a new account request.
659693
/// </summary>

src/Features/Blockcore.Features.Wallet/Interfaces/IWalletManager.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ public interface IWalletManager
8181
/// <returns>A mnemonic defining the wallet's seed used to generate addresses.</returns>
8282
Mnemonic CreateWallet(string password, string name, string passphrase = null, Mnemonic mnemonic = null, int? coinType = null);
8383

84+
/// <summary>
85+
/// Gets the private key associated with an address in the wallet.
86+
/// </summary>
87+
/// <param name="password">The user's password.</param>
88+
/// <param name="walletName">The name of the wallet.</param>
89+
/// <param name="accountName">The name of the account.</param>
90+
/// <param name="address">Address to extract the private key of.</param>
91+
/// <returns>The private key associated with the given address, in WIF representation.</returns>
92+
string RetrievePrivateKey(string password, string walletName, string accountName, string address);
93+
8494
/// <summary>
8595
/// Signs a string message.
8696
/// </summary>

src/Features/Blockcore.Features.Wallet/WalletManager.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,22 @@ public Mnemonic CreateWallet(string password, string name, string passphrase, Mn
319319
return mnemonic;
320320
}
321321

322+
/// <inheritdoc />
323+
public string RetrievePrivateKey(string password, string walletName, string accountName, string address)
324+
{
325+
Guard.NotEmpty(password, nameof(password));
326+
Guard.NotEmpty(walletName, nameof(walletName));
327+
Guard.NotEmpty(address, nameof(address));
328+
329+
Types.Wallet wallet = this.GetWallet(walletName);
330+
331+
// Locate the address based on its base58 string representation.
332+
HdAddress hdAddress = wallet.GetAddress(address, account => account.Name.Equals(accountName));
333+
334+
ISecret privateKey = wallet.GetExtendedPrivateKeyForAddress(password, hdAddress).PrivateKey.GetWif(this.network);
335+
return privateKey.ToString();
336+
}
337+
322338
/// <inheritdoc />
323339
public SignMessageResult SignMessage(string password, string walletName, string accountName, string externalAddress, string message)
324340
{

0 commit comments

Comments
 (0)