Skip to content

Commit

Permalink
Generate encrypted wallets
Browse files Browse the repository at this point in the history
  • Loading branch information
michielpost committed Oct 18, 2024
1 parent 7badc6e commit 34de312
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 13 deletions.
54 changes: 54 additions & 0 deletions src/aoWebWallet/Pages/GenerateWalletPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@page "/generate-wallet"
@inherits MvvmComponentBase<MainViewModel>
@inject ISnackbar Snackbar

<PageTitle>Generate Wallet - @Program.PageTitlePostFix</PageTitle>

<MudContainer Class="mt-2 px-8" MaxWidth="MaxWidth.False">
<MudBreadcrumbs Class="breadcrumbs-aoww" Items="_items"></MudBreadcrumbs>

@if (BindingContext.SecretKey == null)
{
<MudPaper Class="pa-4 mt-4" Elevation="3">
<MudText Typo="Typo.h4" Class="mb-4">Generate Wallet</MudText>
<MudText Typo="Typo.body1" Class="mb-4">Enter a password to encrypt your wallet. The password must be at least 6 characters long.</MudText>

<MudTextField @bind-Value="Password"
Label="Password"
Variant="Variant.Outlined"
InputType="@PasswordInput"
Adornment="Adornment.End"
AdornmentIcon="@PasswordInputIcon"
OnAdornmentClick="TogglePasswordVisibility"
/>

<MudTextField @bind-Value="ConfirmPassword"
Label="Confirm Password"
Variant="Variant.Outlined"
InputType="@PasswordInput"
Adornment="Adornment.End"
AdornmentIcon="@PasswordInputIcon"
OnAdornmentClick="TogglePasswordVisibility"
/>

<MudButton Variant="Variant.Filled"
Color="Color.Primary"
OnClick="GenerateWallet"
Class="mt-4">
Generate Wallet
</MudButton>
</MudPaper>
}
else
{
<AddGenerateWalletComponent />
}
</MudContainer>

@code {
private List<BreadcrumbItem> _items = new List<BreadcrumbItem>
{
new BreadcrumbItem("Home", href: "/"),
new BreadcrumbItem("Generate Wallet", href: null, disabled: true)
};
}
57 changes: 57 additions & 0 deletions src/aoWebWallet/Pages/GenerateWalletPage.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using aoWebWallet.ViewModels;
using Microsoft.AspNetCore.Components;
using MudBlazor;

namespace aoWebWallet.Pages
{
public partial class GenerateWalletPage : MvvmComponentBase<MainViewModel>
{
private string Password { get; set; } = string.Empty;
private string ConfirmPassword { get; set; } = string.Empty;
private bool PasswordVisible { get; set; } = false;
private InputType PasswordInput { get; set; } = InputType.Password;
private string PasswordInputIcon { get; set; } = Icons.Material.Filled.VisibilityOff;

private void TogglePasswordVisibility()
{
if (PasswordVisible)
{
PasswordVisible = false;
PasswordInputIcon = Icons.Material.Filled.VisibilityOff;
PasswordInput = InputType.Password;
}
else
{
PasswordVisible = true;
PasswordInputIcon = Icons.Material.Filled.Visibility;
PasswordInput = InputType.Text;
}
}

private void GenerateWallet()
{
if (string.IsNullOrWhiteSpace(Password) || string.IsNullOrWhiteSpace(ConfirmPassword))
{
Snackbar.Add("Please enter and confirm your password.", Severity.Warning);
return;
}

if (Password != ConfirmPassword)
{
Snackbar.Add("Passwords do not match.", Severity.Error);
return;
}

if (Password.Length < 6)
{
Snackbar.Add("Password must be at least 6 characters long.", Severity.Warning);
return;
}

BindingContext.SecretKey = Password;

// TODO: Implement wallet generation logic here
Snackbar.Add("Wallet generated successfully!", Severity.Success);
}
}
}
28 changes: 18 additions & 10 deletions src/aoWebWallet/Shared/AddGenerateWalletComponent.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@using aoWebWallet.Models
@using aoww.Services
@inherits MvvmComponentBase<MainViewModel>
@inject ArweaveService ArweaveService
@inject ISnackbar Snackbar
Expand All @@ -7,16 +8,16 @@
<MudPaper Elevation="0" Class="pa-8 trigger-transparency">
<MudStack Spacing="2">

<MudFocusTrap Disabled="@Disabled" DefaultFocus="@DefaultFocus">
<MudTextField @bind-Value="Name" Label="Wallet Name" Variant="Variant.Text"></MudTextField>
</MudFocusTrap>
<MudFocusTrap Disabled="@Disabled" DefaultFocus="@DefaultFocus">
<MudTextField @bind-Value="Name" Label="Wallet Name" Variant="Variant.Text"></MudTextField>
</MudFocusTrap>

<MudText DefaultFocus="DefaultFocus" Color="Color.Secondary">@Progress</MudText>
<div Class="d-w-100 d-flex justify-center mt-2">
<MudButton Disabled="ButtonDisabled" Class="text-transform-none" Color="Color.Primary" Variant="Variant.Filled" OnClick="Submit">
Create aoWW Wallet
</MudButton>
</div>
<MudText DefaultFocus="DefaultFocus" Color="Color.Secondary">@Progress</MudText>
<div Class="d-w-100 d-flex justify-center mt-2">
<MudButton Disabled="ButtonDisabled" Class="text-transform-none" Color="Color.Primary" Variant="Variant.Filled" OnClick="Submit">
Create aoWW Wallet
</MudButton>
</div>
</MudStack>
</MudPaper>

Expand Down Expand Up @@ -52,17 +53,24 @@
var jwk = await ArweaveService.GenerateWallet();
var address = await ArweaveService.GetAddress(jwk);


var wallet = new Wallet
{
Address = address,
Name = Name,
Jwk = jwk,
JwkSecret = jwk,
Source = WalletTypes.Generated,
IsReadOnly = false,
LastBackedUpDate = null,
AddedDate = DateTimeOffset.UtcNow
};

if(!string.IsNullOrEmpty(BindingContext.SecretKey))
{
var jwkEncrypted = EncryptionService.EncryptWallet(BindingContext.SecretKey, jwk);
wallet.JwkEncrypted = jwkEncrypted;
}

await BindingContext.SaveWallet(wallet);

Snackbar.Add($"Wallet added ({address})", Severity.Info);
Expand Down
8 changes: 7 additions & 1 deletion src/aoWebWallet/Shared/AddWalletComponent.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
<MudImage Src="images/ths.svg" Alt="hello" Elevation="25" Class="ww-image-start" />
</div>
</div>
<AddGenerateWalletComponent></AddGenerateWalletComponent>
<div Class="d-w-100 d-flex justify-center mt-2">
<MudButton Href="/generate-wallet"
Variant="Variant.Filled"
Color="Color.Primary">
Generate new wallet
</MudButton>
</div>
</MudPaper>
</MudItem>
<MudItem xs="12" md="12" lg="4">
Expand Down
4 changes: 4 additions & 0 deletions src/aoWebWallet/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public partial class MainViewModel : ObservableRecipient

[ObservableProperty]
private string? activeWalletAddress;

[ObservableProperty]
private string? secretKey;

public Wallet? ActiveWallet { get; set; }
public DataLoaderViewModel<Transaction> LastTransactionId { get; set; } = new();
public DataLoaderViewModel<List<Wallet>> WalletList { get; set; } = new();
Expand Down
15 changes: 13 additions & 2 deletions src/aoww.Services.Tests/EncryptionTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using aoww.Services;
using SiaSkynet;
using System.IO;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace SiaSkynet.Tests
namespace aoww.Services.Tests
{
[TestClass]
public class EncryptionTests
Expand All @@ -29,6 +28,18 @@ public void BasicEncryptionTest()
Assert.AreEqual(testValue, dString);
}

[TestMethod]
public void WalletTest()
{
var key = "test";
var jwk = "1234";

var encrypted = EncryptionService.EncryptWallet(key, jwk);
var decrypt = EncryptionService.DecryptWallet(key, encrypted);

Assert.AreEqual(jwk, decrypt);
}


}
}
31 changes: 31 additions & 0 deletions src/aoww.Services/EncryptionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,37 @@ namespace aoww.Services
{
public static class EncryptionService
{
public static string EncryptWallet(string secretKey, string jwk)
{
var key = EncryptionService.GenerateKeys(secretKey);

var encrypted = EncryptionService.Encrypt(System.Text.Encoding.UTF8.GetBytes(jwk), key.privateKey);
//var encryptedString = System.Text.Encoding.UTF8.GetString(encrypted);
var encryptedString = BitConverter.ToString(encrypted).Replace("-", "");

return encryptedString;
}

public static string DecryptWallet(string secretKey, string encryptedJwk)
{
var key = EncryptionService.GenerateKeys(secretKey);

var cipherData = HexStringToByteArray(encryptedJwk);

var decrypt = EncryptionService.Decrypt(cipherData, key.privateKey);
var dString = System.Text.Encoding.UTF8.GetString(decrypt);

return dString;
}

public static byte[] HexStringToByteArray(string hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}

/// <summary>
/// Generates a predicatable key pair based on the seed
Expand Down

0 comments on commit 34de312

Please sign in to comment.