nostr publish event fix

This commit is contained in:
gitea
2025-11-06 21:43:09 +01:00
parent 120a04c69f
commit 947fb667cf
7 changed files with 207 additions and 459 deletions
+27 -5
View File
@@ -238,7 +238,7 @@ class NostrService {
}
}
/// Publishes an event to all connected relays.
/// Publishes an event to all enabled relays.
///
/// [event] - The Nostr event to publish.
///
@@ -247,14 +247,36 @@ class NostrService {
final results = <String, bool>{};
for (final relay in _relays) {
if (relay.isConnected) {
// Only publish to enabled relays
if (!relay.isEnabled) {
results[relay.url] = false;
continue;
}
// Try to connect if not already connected
if (!relay.isConnected) {
try {
await publishEvent(event, relay.url);
results[relay.url] = true;
final stream = await connectRelay(relay.url).timeout(
const Duration(seconds: 3),
onTimeout: () {
throw Exception('Connection timeout');
},
);
// Start listening to establish connection, then cancel immediately
final subscription = stream.listen(null);
await Future.delayed(const Duration(milliseconds: 100));
subscription.cancel();
} catch (e) {
results[relay.url] = false;
continue;
}
} else {
}
// Publish to the relay
try {
await publishEvent(event, relay.url);
results[relay.url] = true;
} catch (e) {
results[relay.url] = false;
}
}
+10
View File
@@ -20,6 +20,10 @@ class User {
/// Optional Nostr profile data (if logged in via Nostr).
final NostrProfile? nostrProfile;
/// Optional Nostr private key (nsec) if logged in with nsec.
/// This is stored to enable event publishing. Only set if user logged in with nsec.
final String? nostrPrivateKey;
/// Creates a [User] instance.
///
/// [id] - Unique identifier for the user.
@@ -27,12 +31,14 @@ class User {
/// [token] - Optional authentication token.
/// [createdAt] - Session creation timestamp (defaults to current time).
/// [nostrProfile] - Optional Nostr profile data.
/// [nostrPrivateKey] - Optional Nostr private key (nsec) for event publishing.
User({
required this.id,
required this.username,
this.token,
int? createdAt,
this.nostrProfile,
this.nostrPrivateKey,
}) : createdAt = createdAt ?? DateTime.now().millisecondsSinceEpoch;
/// Creates a [User] from a Map (e.g., from database or JSON).
@@ -45,6 +51,7 @@ class User {
nostrProfile: map['nostr_profile'] != null
? NostrProfile.fromJson(map['nostr_profile'] as Map<String, dynamic>)
: null,
nostrPrivateKey: map['nostr_private_key'] as String?,
);
}
@@ -56,6 +63,7 @@ class User {
'token': token,
'created_at': createdAt,
'nostr_profile': nostrProfile?.toJson(),
'nostr_private_key': nostrPrivateKey,
};
}
@@ -66,6 +74,7 @@ class User {
String? token,
int? createdAt,
NostrProfile? nostrProfile,
String? nostrPrivateKey,
}) {
return User(
id: id ?? this.id,
@@ -73,6 +82,7 @@ class User {
token: token ?? this.token,
createdAt: createdAt ?? this.createdAt,
nostrProfile: nostrProfile ?? this.nostrProfile,
nostrPrivateKey: nostrPrivateKey ?? this.nostrPrivateKey,
);
}
+7 -1
View File
@@ -156,10 +156,15 @@ class SessionService {
try {
// Parse the key
NostrKeyPair keyPair;
String? storedPrivateKey;
if (nsecOrNpub.startsWith('nsec')) {
keyPair = NostrKeyPair.fromNsec(nsecOrNpub);
// Store the nsec for event publishing
storedPrivateKey = nsecOrNpub;
} else if (nsecOrNpub.startsWith('npub')) {
keyPair = NostrKeyPair.fromNpub(nsecOrNpub);
// No private key available when using npub
storedPrivateKey = null;
} else {
throw SessionException('Invalid Nostr key format. Expected nsec or npub.');
}
@@ -173,11 +178,12 @@ class SessionService {
// Continue without profile - offline-first behavior
}
// Create user with Nostr profile
// Create user with Nostr profile and private key (if available)
final user = User(
id: keyPair.publicKey,
username: profile?.displayName ?? keyPair.publicKey.substring(0, 16),
nostrProfile: profile,
nostrPrivateKey: storedPrivateKey,
);
// Create user-specific storage paths