import 'package:nostr_tools/nostr_tools.dart'; /// Represents a Nostr event. class NostrEvent { /// Event ID (32-byte hex string). final String id; /// Public key of the event creator (pubkey). final String pubkey; /// Unix timestamp in seconds. final int createdAt; /// Event kind (integer). final int kind; /// Event tags (array of arrays). final List> tags; /// Event content (string). final String content; /// Event signature (64-byte hex string). final String sig; /// Event API instance for event operations. static final _eventApi = EventApi(); static final _keyApi = KeyApi(); /// Creates a [NostrEvent] with the provided values. NostrEvent({ required this.id, required this.pubkey, required this.createdAt, required this.kind, required this.tags, required this.content, required this.sig, }); /// Creates a [NostrEvent] from a JSON array (Nostr event format). factory NostrEvent.fromJson(List json) { return NostrEvent( id: json[0] as String, pubkey: json[1] as String, createdAt: json[2] as int, kind: json[3] as int, tags: (json[4] as List) .map((tag) => (tag as List).map((e) => e.toString()).toList()) .toList(), content: json[5] as String, sig: json[6] as String, ); } /// Creates a [NostrEvent] from a nostr_tools Event object. factory NostrEvent.fromNostrToolsEvent(Event event) { return NostrEvent( id: event.id, pubkey: event.pubkey, createdAt: event.created_at, kind: event.kind, tags: event.tags, content: event.content, sig: event.sig, ); } /// Converts this [NostrEvent] to a nostr_tools Event object. Event toNostrToolsEvent() { return Event( id: id, pubkey: pubkey, created_at: createdAt, kind: kind, tags: tags, content: content, sig: sig, verify: false, // Already verified if coming from our model ); } /// Converts the [NostrEvent] to a JSON array (Nostr event format). List toJson() { return [ id, pubkey, createdAt, kind, tags, content, sig, ]; } /// Creates an event from content and signs it with a private key using nostr_tools. /// /// [content] - Event content. /// [kind] - Event kind (default: 1 for text note). /// [privateKey] - Private key in hex format for signing. /// [tags] - Optional tags for the event. factory NostrEvent.create({ required String content, int kind = 1, required String privateKey, List>? tags, }) { // Get public key from private key using nostr_tools final pubkey = _keyApi.getPublicKey(privateKey); final createdAt = DateTime.now().millisecondsSinceEpoch ~/ 1000; final eventTags = tags ?? []; // Create event using nostr_tools Event model final event = Event( kind: kind, tags: eventTags, content: content, created_at: createdAt, pubkey: pubkey, verify: false, // We'll sign it next ); // Get event hash (ID) using nostr_tools event.id = _eventApi.getEventHash(event); // Sign the event using nostr_tools event.sig = _eventApi.signEvent(event, privateKey); // Convert to our NostrEvent model return NostrEvent.fromNostrToolsEvent(event); } /// Verifies the event signature using nostr_tools. /// /// Returns true if the signature is valid, false otherwise. bool verifySignature() { try { final event = toNostrToolsEvent(); return _eventApi.verifySignature(event); } catch (e) { return false; } } @override String toString() { return 'NostrEvent(id: ${id.substring(0, 8)}..., kind: $kind, content: ${content.substring(0, content.length > 20 ? 20 : content.length)}...)'; } }