-
-
Congratulations, you are the founder!
- @* TODO Add stats here for pending signatures or unspent funds *@
-
-
+
+ @if (founder)
+ {
+
+
+
Congratulations, you are the founder!
+ @* TODO Add stats here for pending signatures or unspent funds *@
+
+
- }
- else if (invested)
- {
-
-
-
- Thank you for your investment in this project!
+
+ }
+ else if (invested)
+ {
+
- }
- else
- {
-
-
-
- Seize the opportunity to invest in this project.
-
-
-
+
+
+ }
+ else
+ {
+
+
+
+ Seize the opportunity to invest in this project.
+
+ @{
+ var timeLeft = (project.ProjectInfo.StartDate - DateTime.UtcNow).Days;
+ }
+
+
+ }
+
- }
+
+
+
+
+ @if (project.ProjectInfo.NostrPubKey != null)
+ {
+
+ @{
+ var Npub = NostrHelper.ConvertHexToNpub(project.ProjectInfo.NostrPubKey);
+ }
+
-
-
-
-
-
-
-
-
- Nostr
-
+
+
+
+
+
+
+
+
+
-
- @if (project.ProjectInfo.NostrPubKey != null)
- {
-
-
- @{
- var Npub = NostrHelper.ConvertHexToNpub(project.ProjectInfo.NostrPubKey);
- }
-
-
-
-
-
-
-
-
-
-
-
+ @if (founder)
+ {
+
- @if (founder)
+ @if (isGeneratingNsec)
{
-
-
- @if (isGeneratingNsec)
- {
-
- }
+
+ }
- @if (!string.IsNullOrEmpty(errorMessage))
- {
-
- @errorMessage
-
- }
+ @if (!string.IsNullOrEmpty(errorMessage))
+ {
+
+ @errorMessage
+
+ }
- @if (!string.IsNullOrEmpty(NostrHexSecKey) || !string.IsNullOrEmpty(NostrNsecSecKey))
- {
-
-
-
-
-
-
+ @if (!string.IsNullOrEmpty(NostrHexSecKey) || !string.IsNullOrEmpty(NostrNsecSecKey))
+ {
+
+
+
+
+
+
-
-
-
-
-
-
- }
+
+
+
+
+
+
}
-
- }
+ }
+
+ }
-
-
Relays
- @foreach (var relay in NostrClients)
- {
-
-
-
- }
-
- }
+
+
Relays
+ @foreach (var relay in NostrClients)
+ {
+
+
+
+ }
+
+}
@code {
- [Parameter]
- public string ProjectId { get; set; }
+ [Parameter] public string ProjectId { get; set; }
private Project? project;
@@ -424,15 +432,15 @@
private string NostrHexSecKey { get; set; } = string.Empty;
- private bool isGeneratingNsec = false;
+ private bool isGeneratingNsec;
private string errorMessage = string.Empty;
private string error;
private List<(string Hash, int Amount)> SelectedSeeders = new List<(string hash, int amount)>
{
- { (new uint256().ToString(), 10) },
- { (new uint256().ToString(), 20) },
+ (new uint256().ToString(), 10),
+ (new uint256().ToString(), 20)
};
public class ProjectStats
@@ -443,107 +451,135 @@
public int TotalSeeders { get; set; }
public int TimeLeft { get; set; }
public int FundingProgressPercent { get; set; }
+ }
+ readonly ProjectStats projectStats = new()
+ {
+ Loading = true,
+ TimeLeft = 0,
+ TotalInvestors = 0,
+ TotalRaised = 0,
+ TotalSeeders = 0,
+ FundingProgressPercent = 0
};
- ProjectStats projectStats = new ProjectStats
- {
- Loading = true,
- TimeLeft = 0,
- TotalInvestors = 0,
- TotalRaised = 0,
- TotalSeeders = 0,
- FundingProgressPercent = 0,
- };
-
- bool founder = false;
- bool invested = false;
- bool findInProgress = false;
- DateTime currentDate = DateTime.UtcNow;
+ bool founder;
+ bool invested;
+ bool findInProgress;
+ readonly DateTime currentDate = DateTime.UtcNow;
private List
NostrClients = new();
protected override async Task OnInitializedAsync()
{
- NostrClients = _NetworkConfiguration.GetDefaultRelayUrls().Select(_ => _.Url.ToString()).ToList();
-
- project = storage.GetInvestmentProjects().FirstOrDefault(p => p.ProjectInfo.ProjectIdentifier == ProjectId);
+ projectStats.Loading = true;
+ findInProgress = false;
+ error = string.Empty;
- if (project is InvestorProject findProject)
- {
- invested = findProject.InvestedInProject(); // TODO: need to scan for the invested projects when opening on a new browser
- myProjectExplorerLink = _NetworkConfiguration.GetExplorerUrl().Url + $"/transaction/{findProject.TransactionId}";
- }
- else
+ try
{
- project = storage.GetFounderProjects().FirstOrDefault(p => p.ProjectInfo.ProjectIdentifier == ProjectId);
+ NostrClients = _NetworkConfiguration.GetDefaultRelayUrls().Select(_ => _.Url.ToString()).ToList();
+ project = storage.GetFounderProjects().FirstOrDefault(p => p.ProjectInfo.ProjectIdentifier == ProjectId);
if (project != null)
{
founder = true;
+ projectStats.Loading = false;
+ SetProjectLinksAndRefreshBalance();
+ return;
}
- else
+
+ project = storage.GetInvestmentProjects().FirstOrDefault(p => p.ProjectInfo.ProjectIdentifier == ProjectId);
+ if (project is InvestorProject investorProject)
{
- project = SessionStorage.GetProjectById(ProjectId);
+ invested = investorProject.InvestedInProject();
+ myProjectExplorerLink = _NetworkConfiguration.GetExplorerUrl().Url + $"/transaction/{investorProject.TransactionId}";
+ projectStats.Loading = false;
+ SetProjectLinksAndRefreshBalance();
+ return;
+ }
- if (project == null)
- {
- findInProgress = true;
+ project = SessionStorage.GetProjectById(ProjectId);
+ if (project != null)
+ {
+ projectStats.Loading = false;
+ StateHasChanged();
+ return;
+ }
+
+ findInProgress = true;
+ var projectIndexerData = await _IndexerService.GetProjectByIdAsync(ProjectId);
- var projectIndexerData = await _IndexerService.GetProjectByIdAsync(ProjectId);
+ if (projectIndexerData != null)
+ {
+ project = new Project { CreationTransactionId = projectIndexerData.TrxId };
- if (projectIndexerData != null)
+ _RelayService.RequestProjectCreateEventsByPubKey(
+ e =>
{
- project = new Project { CreationTransactionId = projectIndexerData.TrxId };
- _RelayService.RequestProjectCreateEventsByPubKey(e =>
- {
- if (project != null)
- {
- switch (e)
- {
- case { Kind: NostrKind.Metadata }:
- var nostrMetadata = serializer.Deserialize(e.Content);
- project.Metadata ??= nostrMetadata;
- break;
- case { Kind: NostrKind.ApplicationSpecificData }:
- var projectInfo = serializer.Deserialize(e.Content);
- project.ProjectInfo ??= projectInfo;
- break;
- }
- }
- }, () =>
+ if (project != null)
{
- findInProgress = false;
- if (project?.ProjectInfo != null)
+ switch (e)
{
- SessionStorage.StoreProject(project);
+ case { Kind: NostrKind.Metadata }:
+ project.Metadata ??= serializer.Deserialize(e.Content);
+ break;
+ case { Kind: NostrKind.ApplicationSpecificData }:
+ project.ProjectInfo ??= serializer.Deserialize(e.Content);
+ break;
}
- else
- {
- // Handle case where project info is not available
- error = "Project not found...";
- }
- StateHasChanged();
- },
- new[] { projectIndexerData.NostrPubKey });
- }
- else
+ }
+ },
+ () =>
{
findInProgress = false;
- error = "Project not found...";
+ projectStats.Loading = false;
+
+ if (project?.ProjectInfo != null)
+ {
+ SessionStorage.StoreProject(project);
+ }
+ else
+ {
+ error = "Project not found...";
+ }
+
StateHasChanged();
- }
- }
+ },
+ projectIndexerData.NostrPubKey);
}
+ else
+ {
+ findInProgress = false;
+ projectStats.Loading = false;
+ error = "Project not found...";
+ StateHasChanged();
+ }
+ }
+ catch (Exception ex)
+ {
+ error = $"An error occurred: {ex.Message}";
+ projectStats.Loading = false;
+ StateHasChanged();
}
+ }
- if (project?.CreationTransactionId != null)
+ private async Task SetProjectLinksAndRefreshBalance()
+ {
+ if (!string.IsNullOrEmpty(project?.CreationTransactionId))
{
projectExplorerLink = _NetworkConfiguration.GetExplorerUrl().Url + $"/transaction/{project.CreationTransactionId}";
- await RefreshBalance();
}
+ else
+ {
+ error = "Project created; awaiting confirmation. Check back shortly.";
+ }
+
+ await RefreshBalance();
+ StateHasChanged();
}
+
private async Task RefreshBalance()
{
try
@@ -559,12 +595,21 @@
projectStats.TotalInvestors = (int)data.InvestorCount;
projectStats.TotalRaised = data.AmountInvested;
- projectStats.TimeLeft = (project.ProjectInfo.StartDate - DateTime.UtcNow).Days;
- if (projectStats.TimeLeft < 0)
- projectStats.TimeLeft = 0;
+ // Calculate time left based on the project start and expiry dates
+ if (DateTime.UtcNow < project.ProjectInfo.StartDate)
+ {
+ // Project has not started yet, so time left is until the start date
+ projectStats.TimeLeft = (project.ProjectInfo.StartDate - DateTime.UtcNow).Days;
+ }
+ else
+ {
+ // Project has expired
+ projectStats.TimeLeft = 0; // Ensure no negative time left
+ }
+ // Calculate funding progress as a percentage of the target amount
var targetSat = Money.Coins(project.ProjectInfo.TargetAmount).Satoshi;
- projectStats.FundingProgressPercent = (int)((projectStats.TotalRaised * 100) / targetSat);
+ projectStats.FundingProgressPercent = (int)(projectStats.TotalRaised * 100 / targetSat);
}
}
}
@@ -575,8 +620,8 @@
finally
{
projectStats.Loading = false;
+ StateHasChanged();
}
-
}
private async Task RecoverFunds()
@@ -597,10 +642,7 @@
{
if (!passwordComponent.HasPassword())
{
- passwordComponent.ShowPassword(async () =>
- {
- await GenerateNsec();
- });
+ passwordComponent.ShowPassword(async () => { await GenerateNsec(); });
}
else
{
@@ -620,7 +662,7 @@
{
var words = await passwordComponent.GetWalletAsync();
var nostrKey = _derivationOperations.DeriveProjectNostrPrivateKey(words, founderProject.ProjectIndex);
- NostrHexSecKey = NBitcoin.DataEncoders.Encoders.Hex.EncodeData(nostrKey.ToBytes());
+ NostrHexSecKey = Encoders.Hex.EncodeData(nostrKey.ToBytes());
NostrNsecSecKey = NostrHelper.ConvertHexToNsec(NostrHexSecKey)!;
StateHasChanged();
@@ -644,7 +686,6 @@
}
-
private async Task CopyNsecSecKeyToClipboardAsync()
{
if (!string.IsNullOrEmpty(NostrNsecSecKey))
@@ -676,11 +717,11 @@
// Reopen password prompt
passwordComponent.ShowPassword(async () =>
- {
- isGeneratingNsec = true;
- StateHasChanged();
- await GenerateNsec();
- });
+ {
+ isGeneratingNsec = true;
+ StateHasChanged();
+ await GenerateNsec();
+ });
}
private async void OpenInBrowseAsync()
@@ -704,4 +745,5 @@
string sanitizedInput = HtmlStripperService.StripHtmlTags(input);
return new MarkupString(sanitizedInput);
}
-}
+
+}
\ No newline at end of file
diff --git a/src/Angor/Client/Storage/ClientStorage.cs b/src/Angor/Client/Storage/ClientStorage.cs
index ffd03f50..dede6846 100644
--- a/src/Angor/Client/Storage/ClientStorage.cs
+++ b/src/Angor/Client/Storage/ClientStorage.cs
@@ -2,45 +2,41 @@
using Angor.Shared;
using Angor.Shared.Models;
using Blazored.LocalStorage;
-using Blazored.SessionStorage;
namespace Angor.Client.Storage;
public class ClientStorage : IClientStorage, INetworkStorage
{
- private readonly ISyncLocalStorageService _storage;
-
private const string CurrencyDisplaySettingKey = "currencyDisplaySetting";
-
+
private const string utxoKey = "utxo:{0}";
+ private readonly ISyncLocalStorageService _storage;
+
public ClientStorage(ISyncLocalStorageService storage)
{
_storage = storage;
}
-
+
public AccountInfo GetAccountInfo(string network)
{
- return _storage.GetItem(string.Format(utxoKey,network));
+ return _storage.GetItem(string.Format(utxoKey, network));
}
-
+
public void SetAccountInfo(string network, AccountInfo items)
{
- _storage.SetItem(string.Format(utxoKey,network), items);
+ _storage.SetItem(string.Format(utxoKey, network), items);
}
public void DeleteAccountInfo(string network)
{
- _storage.RemoveItem(string.Format(utxoKey,network));
+ _storage.RemoveItem(string.Format(utxoKey, network));
}
public void AddInvestmentProject(InvestorProject project)
{
var ret = GetInvestmentProjects();
- if (ret.Any(a => a.ProjectInfo?.ProjectIdentifier == project.ProjectInfo.ProjectIdentifier))
- {
- return;
- }
+ if (ret.Any(a => a.ProjectInfo?.ProjectIdentifier == project.ProjectInfo.ProjectIdentifier)) return;
ret.Add(project);
@@ -53,7 +49,7 @@ public void UpdateInvestmentProject(InvestorProject project)
var item = ret.First(_ => _.ProjectInfo?.ProjectIdentifier == project.ProjectInfo.ProjectIdentifier);
- if(!ret.Remove(item))
+ if (!ret.Remove(item))
throw new InvalidOperationException();
ret.Add(project);
@@ -61,8 +57,6 @@ public void UpdateInvestmentProject(InvestorProject project)
_storage.SetItem("projects", ret);
}
-
-
public void RemoveInvestmentProject(string projectId)
{
@@ -75,14 +69,9 @@ public void RemoveInvestmentProject(string projectId)
_storage.SetItem("projects", ret);
}
- public void DeleteInvestmentProjects()
- {
- _storage.RemoveItem("projects");
- }
-
public List GetInvestmentProjects()
{
- var ret = _storage.GetItem>("projects");
+ var ret = _storage.GetItem>("projects");
return ret ?? new List();
}
@@ -95,7 +84,7 @@ public void AddFounderProject(params FounderProject[] projects)
_storage.SetItem("founder-projects", ret.OrderBy(_ => _.ProjectIndex));
}
-
+
public List GetFounderProjects()
{
var ret = _storage.GetItem>("founder-projects");
@@ -113,16 +102,14 @@ public List GetFounderProjects()
public void UpdateFounderProject(FounderProject project)
{
var projects = _storage.GetItem>("founder-projects");
-
- var item = projects.FirstOrDefault(f => f.ProjectInfo.ProjectIdentifier == project.ProjectInfo.ProjectIdentifier);
-
- if (item != null)
- {
- projects.Remove(item);
- }
-
+
+ var item = projects.FirstOrDefault(
+ f => f.ProjectInfo.ProjectIdentifier == project.ProjectInfo.ProjectIdentifier);
+
+ if (item != null) projects.Remove(item);
+
projects.Add(project);
-
+
_storage.SetItem("founder-projects", projects.OrderBy(_ => _.ProjectIndex));
}
@@ -131,64 +118,41 @@ public void DeleteFounderProjects()
_storage.RemoveItem("founder-projects");
}
- public void AddOrUpdateSignatures(SignatureInfo signatureInfo)
+ public SettingsInfo GetSettingsInfo()
{
- var ret = GetSignatures();
-
- var item = ret.FirstOrDefault(f => f.ProjectIdentifier == signatureInfo.ProjectIdentifier);
-
- if (item != null)
- {
- ret.Remove(item);
- }
-
- ret.Add(signatureInfo);
+ var ret = _storage.GetItem("settings-info");
- _storage.SetItem("recovery-signatures", ret);
+ return ret ?? new SettingsInfo();
}
- public List GetSignatures()
+ public void SetSettingsInfo(SettingsInfo settingsInfo)
{
- var ret = _storage.GetItem>("recovery-signatures");
-
- return ret ?? new List();
+ _storage.SetItem("settings-info", settingsInfo);
}
- public void RemoveSignatures(SignatureInfo signatureInfo)
+ public void WipeStorage()
{
- var ret = GetSignatures();
-
- var item = ret.FirstOrDefault(f => f.ProjectIdentifier == signatureInfo.ProjectIdentifier);
-
- if (item != null)
- {
- ret.Remove(item);
- }
-
- _storage.SetItem("recovery-signatures", ret);
+ _storage.Clear();
}
- public void DeleteSignatures()
+ public void SetNostrPublicKeyPerProject(string projectId, string nostrPubKey)
{
- // signatures are valuable to have so to avoid losing them forever
- // we just store them in new entry we will lever use again.
- var sigs = GetSignatures();
- _storage.SetItem($"recovery-signatures-{DateTime.UtcNow.Ticks}", sigs);
-
- _storage.RemoveItem("recovery-signatures");
+ _storage.SetItem($"project:{projectId}:nostrKey", nostrPubKey);
}
- public SettingsInfo GetSettingsInfo()
+ public string GetNostrPublicKeyPerProject(string projectId)
{
- var ret = _storage.GetItem("settings-info");
-
- return ret ?? new SettingsInfo();
+ return _storage.GetItem($"project:{projectId}:nostrKey");
+ }
+ public string GetCurrencyDisplaySetting()
+ {
+ return _storage.GetItem(CurrencyDisplaySettingKey) ?? "BTC";
}
- public void SetSettingsInfo(SettingsInfo settingsInfo)
+ public void SetCurrencyDisplaySetting(string setting)
{
- _storage.SetItem("settings-info", settingsInfo);
+ _storage.SetItem(CurrencyDisplaySettingKey, setting);
}
public SettingsInfo GetSettings()
@@ -201,39 +165,59 @@ public void SetSettings(SettingsInfo settingsInfo)
SetSettingsInfo(settingsInfo);
}
- public void WipeStorage()
- {
- _storage.Clear();
- }
-
public void SetNetwork(string network)
{
_storage.SetItem("network", network);
-
}
public string GetNetwork()
{
return _storage.GetItem("network");
}
-
- public void SetNostrPublicKeyPerProject(string projectId,string nostrPubKey)
+
+ public void DeleteInvestmentProjects()
{
- _storage.SetItem($"project:{projectId}:nostrKey", nostrPubKey);
+ _storage.RemoveItem("projects");
}
-
- public string GetNostrPublicKeyPerProject(string projectId)
+
+ public void AddOrUpdateSignatures(SignatureInfo signatureInfo)
{
- return _storage.GetItem($"project:{projectId}:nostrKey");
+ var ret = GetSignatures();
+
+ var item = ret.FirstOrDefault(f => f.ProjectIdentifier == signatureInfo.ProjectIdentifier);
+
+ if (item != null) ret.Remove(item);
+
+ ret.Add(signatureInfo);
+
+ _storage.SetItem("recovery-signatures", ret);
}
-
- public string GetCurrencyDisplaySetting()
+
+ public List GetSignatures()
{
- return _storage.GetItem(CurrencyDisplaySettingKey) ?? "BTC";
+ var ret = _storage.GetItem>("recovery-signatures");
+
+ return ret ?? new List();
}
- public void SetCurrencyDisplaySetting(string setting)
+ public void RemoveSignatures(SignatureInfo signatureInfo)
{
- _storage.SetItem(CurrencyDisplaySettingKey, setting);
+ var ret = GetSignatures();
+
+ var item = ret.FirstOrDefault(f => f.ProjectIdentifier == signatureInfo.ProjectIdentifier);
+
+ if (item != null) ret.Remove(item);
+
+ _storage.SetItem("recovery-signatures", ret);
+ }
+
+ public void DeleteSignatures()
+ {
+ // signatures are valuable to have so to avoid losing them forever
+ // we just store them in new entry we will lever use again.
+ var sigs = GetSignatures();
+ _storage.SetItem($"recovery-signatures-{DateTime.UtcNow.Ticks}", sigs);
+
+ _storage.RemoveItem("recovery-signatures");
}
}
\ No newline at end of file