Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed the relay service to connect to NOSTR #9

Merged
merged 8 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Angor/Client/Angor.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@

<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
<PackageReference Include="Blockcore.Core" Version="1.1.40" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
<PackageReference Include="NBitcoin" Version="7.0.25" />
<PackageReference Include="Nostr.Client" Version="1.4.3" />
</ItemGroup>

<ItemGroup>
Expand Down
79 changes: 61 additions & 18 deletions src/Angor/Client/Pages/Browse.razor
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
@page "/browse"
@using Angor.Client.Storage
@using Angor.Client.Services
@using Angor.Shared.Models
@inject HttpClient Http
@inject IClientStorage storage;
@using Angor.Shared.Services
@using Nostr.Client.Keys
@inject ISessionStorage SessionStorage;
@inject NavigationManager NavigationManager
@inject IRelayService _RelayService
@inject IIndexerService _IndexerService
Expand All @@ -13,30 +13,46 @@
<div class="col">
<h3>Browse Projects</h3>

<NotificationComponent @ref="notificationComponent"/>

<!-- Search form -->
<form @onsubmit="SearchProjects">
<div class="mb-3">
<label for="searchQuery" class="form-label">Search</label>
<input type="text" id="searchQuery" @bind="searchQuery" class="form-control" placeholder="Enter search query" />
</div>
<button type="submit" class="btn btn-primary">Search</button>
<button type="submit" class="btn btn-primary" disabled="@searchInProgress">Search</button>
<br /> <br />
</form>

<!-- List of projects -->
@if (projects.Count == 0)
{
<p>No projects found.</p>
@if (searchInProgress)
{
<div class="loader"></div>
}
else
{
<p>No projects found.</p>
}
}
else
{
foreach (var project in projects.OrderByDescending(d => d.StartDate))
foreach (var project in projects) //TODO set order (block created ?)
{
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">@project.ProjectIdentifier</h5>
<p class="card-text">Nostr ID: <a href="/" target="_blank">@(new Blockcore.NBitcoin.Key().PubKey.ToHex())</a></p>
<button @onclick="() => ImportProject(project)" class="btn btn-primary">View</button>
<p class="card-text">Nostr ID: <a href="/" target="_blank">@(NostrPublicKey.FromHex(project.NostrPubKey).Bech32)</a></p>
@if (SessionStorage.IsProjectInStorageById(project.ProjectIdentifier))
{
<button @onclick="() => ImportProject(project.ProjectIdentifier)" class="btn btn-primary">View</button>
}
else
{
<div class="loader"></div>
}
</div>
</div>
}
Expand All @@ -46,34 +62,61 @@
</div>

@code {
NotificationComponent notificationComponent;
private string searchQuery;
bool searchInProgress = false;

private List<ProjectInfo> projects= new();
private List<ProjectIndexerData> projects= new();

protected override async Task OnInitializedAsync()
{

await _RelayService.ConnectToRelaysAsync();
}

private async Task SearchProjects()
{
searchInProgress = true;
var blockchainProjects = await _IndexerService.GetProjectsAsync();

var projectCreators = SessionStorage.GetProjectSubscribedList();

projectCreators.AddRange(
blockchainProjects
.Select(_ => _.NostrPubKey)
.Where(nostrPubKey => !projectCreators.Contains(nostrPubKey)));

await _RelayService.RequestProjectDataAsync<ProjectInfo>(_ =>
{
if (!SessionStorage.IsProjectInStorageById(_.ProjectIdentifier))
SessionStorage.StoreProjectInfo(_);
StateHasChanged();
},
projectCreators.ToArray());

SessionStorage.SetProjectSubscribedList(projectCreators);

foreach (var blockchainProject in blockchainProjects)
{
var project = await _RelayService.GetProjectAsync(blockchainProject.ProjectIdentifier);

if (project != null)
if (projects.All(_ => _.ProjectIdentifier != blockchainProject.ProjectIdentifier))
{
projects.Add(project);
projects.Add(blockchainProject);
}
}

searchInProgress = false;
StateHasChanged();
}

private void ImportProject(ProjectInfo project)
private void ImportProject(string projectIdentifier)
{
storage.AddBrowseProject(project);

NavigationManager.NavigateTo($"/view/{project.ProjectIdentifier}");
if (SessionStorage.IsProjectInStorageById(projectIdentifier))
{
_RelayService.CloseConnection();
NavigationManager.NavigateTo($"/view/{projectIdentifier}");
}
else
{
notificationComponent.ShowNotificationMessage("The project was not loaded from the relay yet");
}
}
}
30 changes: 20 additions & 10 deletions src/Angor/Client/Pages/Create.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@
@using Angor.Shared.Models
@using Angor.Shared
@using Angor.Client.Storage
@using Angor.Shared.Protocol
@using Blockcore.Consensus.TransactionInfo
@using Angor.Client.Services
@using Angor.Shared.ProtocolNew
@using Angor.Shared.Services
@using Blockcore.NBitcoin
@using Blockcore.NBitcoin.DataEncoders

@inherits BaseComponent

@inject HttpClient Http
@inject IDerivationOperations _derivationOperations
@inject IWalletStorage _walletStorage;
@inject IClientStorage storage;
@inject NavigationManager NavigationManager
@inject IWalletOperations _WalletOperations
@inject INetworkConfiguration _NetworkConfiguration
@inject IRelayService _RelayService
@inject IIndexerService _IndexerService

@inject ISignService _SignService

Expand Down Expand Up @@ -178,7 +175,7 @@
}
};

protected override Task OnInitializedAsync()
protected override async Task OnInitializedAsync()
{
hasWallet = _walletStorage.HasWallet();

Expand All @@ -193,9 +190,10 @@
project.FounderKey = projectsKeys.FounderKey;
project.FounderRecoveryKey = projectsKeys.FounderRecoveryKey;
project.ProjectIdentifier = projectsKeys.ProjectIdentifier;
project.NostrPubKey = projectsKeys.NostrPubKey;
}

return Task.CompletedTask;
await _RelayService.ConnectToRelaysAsync();
}

private async Task CreatProject()
Expand Down Expand Up @@ -236,7 +234,7 @@
feeData.FeeEstimations.Fees.AddRange(fetchFees);
feeData.SelectedFeeEstimation = feeData.FeeEstimations.Fees.First();

unsignedTransaction = _founderTransactionActions.CreateNewProjectTransaction(project.FounderKey, _derivationOperations.AngorKeyToScript(project.ProjectIdentifier), 10000);
unsignedTransaction = _founderTransactionActions.CreateNewProjectTransaction(project.FounderKey, _derivationOperations.AngorKeyToScript(project.ProjectIdentifier), 10000, project.NostrPubKey);

signedTransaction = _WalletOperations.AddInputsAndSignTransaction(accountInfo.GetNextChangeReceiveAddress(), unsignedTransaction, _walletStorage.GetWallet(), accountInfo, feeData.SelectedFeeEstimation);

Expand Down Expand Up @@ -289,9 +287,21 @@
if (!response.Success)
return response;

await _RelayService.AddProjectAsync(project);
storage.AddFounderProject(project);

var nostrKey = _derivationOperations.DeriveProjectNostrPrivateKey(_walletStorage.GetWallet(), project.ProjectIndex);

var resultId = await _RelayService.AddProjectAsync(project, NBitcoin.DataEncoders.Encoders.Hex.EncodeData(nostrKey.ToBytes()));

// todo this code must be reviewed again as we send the recovery private key to the signing server
_RelayService.RegisterOKMessageHandler(resultId, _ =>
{
if (_.EventId != resultId)
return;
if (!_.Accepted)
notificationComponent.ShowErrorMessage("Failed to store the project information on the relay!!!"); //TODO add export project info
});

// todo this code must be reviewed again as we send the recovery private key to the signing server

var key = _derivationOperations.DeriveFounderRecoveryPrivateKey(_walletStorage.GetWallet(), project.ProjectIndex);

Expand All @@ -304,7 +314,7 @@
{
notificationComponent.ShowNotificationMessage("Project created", 1);

storage.AddFounderProject(project);
//storage.AddFounderProject(project);

NavigationManager.NavigateTo($"/view/{project.ProjectIdentifier}");
}
Expand Down
4 changes: 3 additions & 1 deletion src/Angor/Client/Pages/View.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
@using Angor.Client.Storage
@using Angor.Shared.Models
@using Blockcore.NBitcoin
@using Angor.Client.Services

@inject HttpClient Http
@inject IDerivationOperations _derivationOperations
@inject IWalletStorage _walletStorage;
@inject IClientStorage storage;
@inject ISessionStorage SessionStorage;
@inject NavigationManager NavigationManager
@inject INetworkConfiguration _NetworkConfiguration

Expand Down Expand Up @@ -218,7 +220,7 @@
}
else
{
findProject = storage.GetBrowseProjects().FirstOrDefault(p => p.ProjectIdentifier == ProjectId);
findProject = SessionStorage.GetProjectById(ProjectId);

if (findProject != null)
{
Expand Down
4 changes: 4 additions & 0 deletions src/Angor/Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
using Angor.Shared.ProtocolNew;
using Angor.Shared.ProtocolNew.Scripts;
using Angor.Shared.ProtocolNew.TransactionBuilders;
using Angor.Shared.Services;
using Blazored.LocalStorage;
using Blazored.SessionStorage;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

Expand All @@ -17,11 +19,13 @@
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddBlazoredLocalStorage();
builder.Services.AddBlazoredSessionStorage();

builder.Services.AddTransient<INetworkConfiguration, NetworkConfiguration>();
builder.Services.AddTransient<IHdOperations, HdOperations>();
builder.Services.AddTransient <IClientStorage, ClientStorage>();
builder.Services.AddTransient <IWalletStorage, WalletStorage>();
builder.Services.AddScoped<ISessionStorage, LocalSessionStorage>();
builder.Services.AddTransient<IWalletOperations, WalletOperations>();
builder.Services.AddScoped<IClipboardService, ClipboardService>();
builder.Services.AddScoped<IDerivationOperations, DerivationOperations>();
Expand Down
68 changes: 68 additions & 0 deletions src/Angor/Client/Storage/LocalSessionStorage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Angor.Client.Services;
using Angor.Shared.Models;
using Blazored.SessionStorage;

namespace Angor.Client.Storage;

public class LocalSessionStorage : ISessionStorage
{
private ISyncSessionStorageService _sessionStorageService;

private const string NostrKeyEventStreamSubscription = "subscriptions";

public LocalSessionStorage(ISyncSessionStorageService sessionStorageService)
{
_sessionStorageService = sessionStorageService;
}

public void StoreProjectInfo(ProjectInfo project)
{
_sessionStorageService.SetItem(project.ProjectIdentifier,project);
}

public void AddProjectToSubscribedList(string nostrPubKey)
{
var list = _sessionStorageService.GetItem<List<string>>(NostrKeyEventStreamSubscription) ?? new List<string>();

list.Add(nostrPubKey);

_sessionStorageService.SetItem(NostrKeyEventStreamSubscription, list);
}

public List<string> GetProjectSubscribedList()
{
return _sessionStorageService.GetItem<List<string>>(NostrKeyEventStreamSubscription) ?? new List<string>();
}
public void SetProjectSubscribedList(List<string> list)
{
_sessionStorageService.SetItem<List<string>>(NostrKeyEventStreamSubscription,list);
}

public bool IsProjectInSubscribedList(string nostrPubKey)
{
var list = _sessionStorageService.GetItem<List<string>>(NostrKeyEventStreamSubscription) ?? new List<string>();

return list.Contains(nostrPubKey);
}

public ProjectInfo? GetProjectById(string projectId)
{
return _sessionStorageService.GetItem<ProjectInfo>(projectId);
}
public bool IsProjectInStorageById(string projectId)
{
return _sessionStorageService.ContainKey(projectId);
}

public void StoreProjectInfoEventId(string eventId, string projectInfo)
{
_sessionStorageService.SetItem(eventId,projectInfo);
}

public ProjectInfo GetProjectInfoByEventId(string eventId)
{
var projectIdentifier = _sessionStorageService.GetItem<string>(eventId);

return _sessionStorageService.GetItem<ProjectInfo>(projectIdentifier);
}
}
1 change: 1 addition & 0 deletions src/Angor/Shared/Angor.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageReference Include="Blockcore.Core" Version="1.1.40" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
<PackageReference Include="NBitcoin" Version="7.0.25" />
<PackageReference Include="Nostr.Client" Version="1.4.3" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading