nostr tools added
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import '../../nostr/models/nostr_profile.dart';
|
||||
|
||||
/// Data model representing a user session.
|
||||
///
|
||||
/// This model stores user identification and authentication information
|
||||
@@ -15,17 +17,22 @@ class User {
|
||||
/// Timestamp when the session was created (milliseconds since epoch).
|
||||
final int createdAt;
|
||||
|
||||
/// Optional Nostr profile data (if logged in via Nostr).
|
||||
final NostrProfile? nostrProfile;
|
||||
|
||||
/// Creates a [User] instance.
|
||||
///
|
||||
/// [id] - Unique identifier for the user.
|
||||
/// [username] - Display name or username.
|
||||
/// [token] - Optional authentication token.
|
||||
/// [createdAt] - Session creation timestamp (defaults to current time).
|
||||
/// [nostrProfile] - Optional Nostr profile data.
|
||||
User({
|
||||
required this.id,
|
||||
required this.username,
|
||||
this.token,
|
||||
int? createdAt,
|
||||
this.nostrProfile,
|
||||
}) : createdAt = createdAt ?? DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
/// Creates a [User] from a Map (e.g., from database or JSON).
|
||||
@@ -35,6 +42,9 @@ class User {
|
||||
username: map['username'] as String,
|
||||
token: map['token'] as String?,
|
||||
createdAt: map['created_at'] as int?,
|
||||
nostrProfile: map['nostr_profile'] != null
|
||||
? NostrProfile.fromJson(map['nostr_profile'] as Map<String, dynamic>)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,6 +55,7 @@ class User {
|
||||
'username': username,
|
||||
'token': token,
|
||||
'created_at': createdAt,
|
||||
'nostr_profile': nostrProfile?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,12 +65,14 @@ class User {
|
||||
String? username,
|
||||
String? token,
|
||||
int? createdAt,
|
||||
NostrProfile? nostrProfile,
|
||||
}) {
|
||||
return User(
|
||||
id: id ?? this.id,
|
||||
username: username ?? this.username,
|
||||
token: token ?? this.token,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
nostrProfile: nostrProfile ?? this.nostrProfile,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ import 'package:path_provider/path_provider.dart';
|
||||
import '../local/local_storage_service.dart';
|
||||
import '../sync/sync_engine.dart';
|
||||
import '../firebase/firebase_service.dart';
|
||||
import '../nostr/nostr_service.dart';
|
||||
import '../nostr/models/nostr_keypair.dart';
|
||||
import '../nostr/models/nostr_profile.dart';
|
||||
import 'models/user.dart';
|
||||
|
||||
/// Exception thrown when session operations fail.
|
||||
@@ -42,6 +45,9 @@ class SessionService {
|
||||
/// Firebase service for optional cloud sync (optional).
|
||||
final FirebaseService? _firebaseService;
|
||||
|
||||
/// Nostr service for Nostr authentication (optional).
|
||||
final NostrService? _nostrService;
|
||||
|
||||
/// Map of user IDs to their session storage paths.
|
||||
final Map<String, String> _userDbPaths = {};
|
||||
|
||||
@@ -59,17 +65,20 @@ class SessionService {
|
||||
/// [localStorage] - Local storage service for data persistence.
|
||||
/// [syncEngine] - Optional sync engine for coordinating sync operations.
|
||||
/// [firebaseService] - Optional Firebase service for cloud sync.
|
||||
/// [nostrService] - Optional Nostr service for Nostr authentication.
|
||||
/// [testDbPath] - Optional database path for testing.
|
||||
/// [testCacheDir] - Optional cache directory for testing.
|
||||
SessionService({
|
||||
required LocalStorageService localStorage,
|
||||
SyncEngine? syncEngine,
|
||||
FirebaseService? firebaseService,
|
||||
NostrService? nostrService,
|
||||
String? testDbPath,
|
||||
Directory? testCacheDir,
|
||||
}) : _localStorage = localStorage,
|
||||
_syncEngine = syncEngine,
|
||||
_firebaseService = firebaseService,
|
||||
_nostrService = nostrService,
|
||||
_testDbPath = testDbPath,
|
||||
_testCacheDir = testCacheDir;
|
||||
|
||||
@@ -128,6 +137,71 @@ class SessionService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Logs in a user using Nostr key (nsec or npub).
|
||||
///
|
||||
/// [nsecOrNpub] - Nostr key in nsec (private) or npub (public) format.
|
||||
///
|
||||
/// Returns the logged-in [User] with fetched profile data.
|
||||
///
|
||||
/// Throws [SessionException] if login fails or if user is already logged in.
|
||||
Future<User> loginWithNostr(String nsecOrNpub) async {
|
||||
if (_currentUser != null) {
|
||||
throw SessionException('User already logged in. Logout first.');
|
||||
}
|
||||
|
||||
if (_nostrService == null) {
|
||||
throw SessionException('Nostr service not available');
|
||||
}
|
||||
|
||||
try {
|
||||
// Parse the key
|
||||
NostrKeyPair keyPair;
|
||||
if (nsecOrNpub.startsWith('nsec')) {
|
||||
keyPair = NostrKeyPair.fromNsec(nsecOrNpub);
|
||||
} else if (nsecOrNpub.startsWith('npub')) {
|
||||
keyPair = NostrKeyPair.fromNpub(nsecOrNpub);
|
||||
} else {
|
||||
throw SessionException('Invalid Nostr key format. Expected nsec or npub.');
|
||||
}
|
||||
|
||||
// Fetch profile from relays
|
||||
NostrProfile? profile;
|
||||
try {
|
||||
profile = await _nostrService!.fetchProfile(keyPair.publicKey);
|
||||
} catch (e) {
|
||||
debugPrint('Warning: Failed to fetch Nostr profile: $e');
|
||||
// Continue without profile - offline-first behavior
|
||||
}
|
||||
|
||||
// Create user with Nostr profile
|
||||
final user = User(
|
||||
id: keyPair.publicKey,
|
||||
username: profile?.displayName ?? keyPair.publicKey.substring(0, 16),
|
||||
nostrProfile: profile,
|
||||
);
|
||||
|
||||
// Create user-specific storage paths
|
||||
await _setupUserStorage(user);
|
||||
|
||||
// Sync with Firebase if enabled
|
||||
if (_firebaseService != null && _firebaseService!.isEnabled) {
|
||||
try {
|
||||
await _firebaseService!.syncItemsFromFirestore(user.id);
|
||||
} catch (e) {
|
||||
// Log error but don't fail login - offline-first behavior
|
||||
debugPrint('Warning: Failed to sync from Firebase on login: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Set as current user
|
||||
_currentUser = user;
|
||||
|
||||
return user;
|
||||
} catch (e) {
|
||||
throw SessionException('Failed to login with Nostr: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Logs out the current user and clears session data.
|
||||
///
|
||||
/// [clearCache] - Whether to clear cached data (default: true).
|
||||
|
||||
Reference in New Issue
Block a user