-
Notifications
You must be signed in to change notification settings - Fork 11
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
fix for issue 139 #197
base: main
Are you sure you want to change the base?
fix for issue 139 #197
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ | |
@inject IRelayService _RelayService | ||
@inject ILogger<Create> _Logger; | ||
@inject IHtmlStripperService HtmlStripperService; | ||
@inject IFounderKeyService FounderKeyService | ||
|
||
|
||
@inject IFounderTransactionActions _founderTransactionActions | ||
<NotificationComponent @ref="notificationComponent"/> | ||
|
@@ -847,6 +849,21 @@ | |
|
||
try | ||
{ | ||
// Check if the FounderKey is in use and get the total keys used | ||
var keyCheckResult = await FounderKeyService.CheckFounderKeyAsync(project.ProjectInfo.FounderKey); | ||
|
||
if (keyCheckResult.IsKeyInUse) | ||
{ | ||
notificationComponent.ShowErrorMessage("The FounderKey is already in use. Please use a different key."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case we need to "fix" the data in the local storage because the user can't select a founder key to use, perhaps add a message to rescan or wipe the storage and recover the wallet again. |
||
return; | ||
} | ||
|
||
if (keyCheckResult.TotalKeysInUse >= 14) | ||
{ | ||
notificationComponent.ShowErrorMessage("You cannot create more than 15 projects."); | ||
return; | ||
} | ||
|
||
var words = await passwordComponent.GetWalletAsync(); | ||
var accountInfo = storage.GetAccountInfo(network.Name); | ||
|
||
|
@@ -863,7 +880,6 @@ | |
} | ||
catch (Exception e) | ||
{ | ||
_Logger.LogError(e, e.Message); | ||
notificationComponent.ShowErrorMessage(e.Message,e); | ||
} | ||
finally | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using Angor.Shared.Models; | ||
using Angor.Shared.Services; | ||
using Nostr.Client.Messages; | ||
using Angor.Client.Storage; | ||
|
||
public class FounderKeyService : IFounderKeyService | ||
{ | ||
private readonly IWalletStorage _walletStorage; | ||
private readonly IRelayService _relayService; | ||
private readonly ISerializer _serializer; | ||
|
||
|
||
|
||
|
||
public FounderKeyService( | ||
IWalletStorage walletStorage, | ||
IIndexerService indexerService, | ||
IRelayService relayService, | ||
IClientStorage storage, | ||
ISerializer serializer) | ||
{ | ||
_walletStorage = walletStorage; | ||
_relayService = relayService; | ||
_serializer = serializer; | ||
} | ||
|
||
public async Task<bool> IsFounderKeyInUseAsync(string founderKey) | ||
{ | ||
var keys = _walletStorage.GetFounderKeys(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure the relay is the right place to check, we need to check with the indexer if the transaction exists. |
||
var inUseKeys = new HashSet<string>(); | ||
|
||
await _relayService.RequestProjectCreateEventsByPubKeyAsync( | ||
keys.Keys.Select(k => k.NostrPubKey).ToArray(), | ||
eventMessage => | ||
{ | ||
if (eventMessage.Kind == NostrKind.ApplicationSpecificData) | ||
{ | ||
var projectInfo = _serializer.Deserialize<ProjectInfo>(eventMessage.Content); | ||
inUseKeys.Add(projectInfo.FounderKey); | ||
dangershony marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}, | ||
null); | ||
|
||
return inUseKeys.Contains(founderKey); | ||
} | ||
|
||
public async Task<FounderKeyCheckResult> CheckFounderKeyAsync(string founderKey) | ||
{ | ||
var keys = _walletStorage.GetFounderKeys(); | ||
var usedKeys = new HashSet<string>(); | ||
|
||
// Perform the relay scan to get project data | ||
await _relayService.RequestProjectCreateEventsByPubKeyAsync( | ||
keys.Keys.Select(k => k.NostrPubKey).ToArray(), | ||
eventMessage => | ||
{ | ||
if (eventMessage.Kind == NostrKind.ApplicationSpecificData) | ||
{ | ||
var projectInfo = _serializer.Deserialize<ProjectInfo>(eventMessage.Content); | ||
usedKeys.Add(projectInfo.FounderKey); | ||
} | ||
}, | ||
null); | ||
|
||
return new FounderKeyCheckResult | ||
{ | ||
IsKeyInUse = usedKeys.Contains(founderKey), | ||
TotalKeysInUse = usedKeys.Count | ||
}; | ||
} | ||
|
||
|
||
} | ||
|
||
|
||
public class FounderKeyCheckResult | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class should be in the models folder |
||
{ | ||
public bool IsKeyInUse { get; set; } | ||
public int TotalKeysInUse { get; set; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
public interface IFounderKeyService | ||
{ | ||
Task<bool> IsFounderKeyInUseAsync(string founderKey); | ||
|
||
Task<FounderKeyCheckResult> CheckFounderKeyAsync(string founderKey); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,58 @@ public void RequestProjectCreateEventsByPubKey(Action<NostrEvent> onResponseActi | |
Kinds = [NostrKind.ApplicationSpecificData, NostrKind.Metadata], | ||
})); | ||
} | ||
|
||
// add the same as function ^^ as async | ||
public async Task RequestProjectCreateEventsByPubKeyAsync( | ||
string[] nPubs, | ||
Action<NostrEvent> onResponseAction, | ||
Action? onEoseAction) | ||
{ | ||
var subscriptionKey = Guid.NewGuid().ToString().Replace("-", ""); | ||
|
||
var nostrClient = _communicationFactory.GetOrCreateClient(_networkService); | ||
|
||
if (!_subscriptionsHandling.RelaySubscriptionAdded(subscriptionKey)) | ||
{ | ||
var subscription = nostrClient.Streams.EventStream | ||
.Where(_ => _.Subscription == subscriptionKey) | ||
.Where(_ => _.Event is not null) | ||
.Select(_ => _.Event) | ||
.Subscribe(onResponseAction!); | ||
|
||
_subscriptionsHandling.TryAddRelaySubscription(subscriptionKey, subscription); | ||
} | ||
|
||
if (onEoseAction != null) | ||
{ | ||
_subscriptionsHandling.TryAddEoseAction(subscriptionKey, onEoseAction); | ||
} | ||
|
||
var tcs = new TaskCompletionSource(); | ||
|
||
// Handle end-of-stream asynchronously | ||
if (onEoseAction == null) | ||
{ | ||
_subscriptionsHandling.TryAddEoseAction(subscriptionKey, () => tcs.SetResult()); | ||
} | ||
else | ||
{ | ||
_subscriptionsHandling.TryAddEoseAction(subscriptionKey, () => | ||
{ | ||
onEoseAction(); | ||
tcs.SetResult(); | ||
}); | ||
} | ||
|
||
nostrClient.Send(new NostrRequest(subscriptionKey, new NostrFilter | ||
{ | ||
Authors = nPubs, | ||
Kinds = new[] { NostrKind.ApplicationSpecificData, NostrKind.Metadata }, | ||
})); | ||
|
||
await tcs.Task; // Wait for the end of stream | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we awaiting the tcs and not just allowing the callback thread to perfome the action we need? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did it because of this why shouldnt we need either way copilot removed it 😉 |
||
} | ||
|
||
|
||
public Task LookupSignaturesDirectMessagesForPubKeyAsync(string nostrPubKey, DateTime? since, int? limit, Action<NostrEvent> onResponseAction) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting this in the
CreatProjectTransaction
is probably not the right thing to do, we must know much before this point if the key was already usedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do rescan before creating,
But there's a scenario this scenario.
unless you put a rescan when creating, you won't know that there's another project created on the same key.
but also now that i think of it we will need to refresh the data in the create a project. (almost everything except project info no?)
I know that this is an edge case that is not expected (especially when we suspect that per user there will be probably only 1 project), but still this should be addressed in some way because we cannot have any loophole of over riding a project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to have a meeting about trusting the relays for knowing if the project was created or only look at the indexer to see if a transaciton exists
Bare in mind that we keep the nostr event id on the transaction so it is not possible to show false data there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, then i'll wait with this PR until we do that,
We should align on how much we trust the relays, and on which instances we can trust it.
Also, according to that we should check if there are other places in angor that trust the relay instead of the indexer?