You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.8 KiB
151 lines
3.8 KiB
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<List<String>> 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<dynamic> 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<dynamic>)
|
|
.map((tag) => (tag as List<dynamic>).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<dynamic> 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<List<String>>? 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)}...)';
|
|
}
|
|
}
|