Skip to content

Commit

Permalink
Merge pull request #1082 from MutinyWallet/changing-key-handling
Browse files Browse the repository at this point in the history
Add handling for changed nostr keys
  • Loading branch information
TonyGiorgio committed Mar 26, 2024
2 parents fbf2133 + a3e10df commit dbad131
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 10 deletions.
76 changes: 68 additions & 8 deletions mutiny-core/src/nostr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,15 @@ impl<S: MutinyStorage> NostrManager<S> {
let event = self.storage.get_data::<Event>(NOSTR_CONTACT_LIST)?;

// listen for latest contact list events
let time_stamp = match event.map(|e| e.created_at) {
let time_stamp = match event {
None => Timestamp::from(0),
Some(time) => time + 1_i64, // add one so we get only new events
Some(event) => {
if event.pubkey == self.public_key {
event.created_at + 1_i64 // add one so we get only new events
} else {
Timestamp::from(0)
}
}
};

Ok(Filter::new()
Expand All @@ -262,7 +268,23 @@ impl<S: MutinyStorage> NostrManager<S> {
lnurl: Option<LnUrl>,
nip05: Option<String>,
) -> Result<Metadata, MutinyError> {
let current = self.get_profile()?;
// pull latest profile from primal
let current = match self.primal_client.get_user_profile(self.public_key).await {
Ok(Some(meta)) => meta,
Ok(None) => {
log_warn!(self.logger, "No profile found for user, creating new");
Metadata::default()
}
Err(e) => {
// if we can't get the profile from primal, fall back to local
// otherwise we can't create/edit profile if the primal server is down
log_error!(
self.logger,
"Failed to get user profile from primal, falling back to local: {e}"
);
self.storage.get_nostr_profile()?.unwrap_or_default()
}
};

let with_name = if let Some(name) = name {
current.name(name)
Expand Down Expand Up @@ -309,16 +331,35 @@ impl<S: MutinyStorage> NostrManager<S> {

let builder = match event {
Some(event) => {
// if event is for a different key, we need to pull down latest
let (mut tags, content) = if event.pubkey != self.public_key {
let (opt, _) = self
.primal_client
.get_nostr_contacts(self.public_key)
.await?;

// if key doesn't have a contact list, create a new one
match opt {
None => (vec![], String::new()),
Some(event) => {
let tags = event.tags.clone();
let content = event.content.clone();
(tags, content)
}
}
} else {
(event.tags.clone(), event.content.clone())
};

// check if we're already following
if event.iter_tags().any(|tag| {
if tags.iter().any(|tag| {
matches!(tag, Tag::PublicKey { public_key, uppercase: false, .. } if *public_key == npub)
}) {
return Ok(());
}

let mut tags = event.tags.clone();
tags.push(Tag::public_key(npub));
EventBuilder::new(Kind::ContactList, &event.content, tags)
EventBuilder::new(Kind::ContactList, content, tags)
}
None => EventBuilder::new(Kind::ContactList, "", [Tag::public_key(npub)]),
};
Expand Down Expand Up @@ -346,7 +387,26 @@ impl<S: MutinyStorage> NostrManager<S> {
match event {
None => Ok(()), // no follow list, nothing to unfollow
Some(event) => {
let mut tags = event.tags.clone();
// if event is for a different key, we need to pull down latest
let (mut tags, content) = if event.pubkey != self.public_key {
let (opt, _) = self
.primal_client
.get_nostr_contacts(self.public_key)
.await?;

// if key doesn't have a contact list, create a new one
match opt {
None => (vec![], String::new()),
Some(event) => {
let tags = event.tags.clone();
let content = event.content.clone();
(tags, content)
}
}
} else {
(event.tags.clone(), event.content.clone())
};

tags.retain(|tag| {
!matches!(tag, Tag::PublicKey { public_key, uppercase: false, .. } if *public_key == npub)
});
Expand All @@ -357,7 +417,7 @@ impl<S: MutinyStorage> NostrManager<S> {
return Ok(());
}

let builder = EventBuilder::new(Kind::ContactList, &event.content, tags);
let builder = EventBuilder::new(Kind::ContactList, content, tags);
let event = self.primary_key.sign_event_builder(builder).await?;
let event_id = self.client.send_event(event.clone()).await?;

Expand Down
10 changes: 8 additions & 2 deletions mutiny-core/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,10 +989,16 @@ pub(crate) fn update_nostr_contact_list<S: MutinyStorage>(
return Err(MutinyError::InvalidArgumentsError);
}

// if the event is newer than the one in storage, update it
// if the event is for the same key and is older than the one in storage
// if it is a different key, always save it, that means the user has imported an nsec
// otherwise ignore it
match storage.get_data::<Event>(NOSTR_CONTACT_LIST) {
Ok(Some(event)) if event.created_at > contact_list_event.created_at => Ok(false),
Ok(Some(event))
if event.created_at > contact_list_event.created_at
&& contact_list_event.pubkey == event.pubkey =>
{
Ok(false)
}
_ => storage
.set_data(NOSTR_CONTACT_LIST.to_string(), contact_list_event, None)
.map(|_| true),
Expand Down

0 comments on commit dbad131

Please sign in to comment.