nostr_nips 0.2.0
nostr_nips: ^0.2.0 copied to clipboard
A comprehensive Dart library implementing all Nostr protocol NIPs (Nostr Implementation Possibilities).
import 'package:nostr_nips/nostr_nips.dart';
void main() async {
// ============================================================
// Key Management
// ============================================================
// Generate a random key pair
final keyPair = KeyPair.generate();
print('Public key: ${keyPair.publicKey}');
// Encode as bech32 (NIP-19)
final npub = Nip19.npubEncode(keyPair.publicKey);
final nsec = Nip19.nsecEncode(keyPair.privateKey);
print('npub: $npub');
print('nsec: $nsec');
// Derive from mnemonic (NIP-06)
final mnemonic = KeyDerivation.generateMnemonic();
print('Mnemonic: $mnemonic');
final derivedKeyPair = KeyDerivation.deriveKeyPair(mnemonic);
print('Derived pubkey: ${derivedKeyPair.publicKey}');
// ============================================================
// Create Events
// ============================================================
// Text note (NIP-01)
final note = Event.sign(
kind: EventKind.textNote,
content: 'Hello Nostr from dart_nostr!',
privateKey: keyPair.privateKey,
);
print('\nText note ID: ${note.id}');
print('Verified: ${note.verify()}');
// Set user metadata (NIP-24)
final metadata = Nip24.createMetadata(
privateKey: keyPair.privateKey,
name: 'dart_nostr_user',
displayName: 'Dart Nostr User',
about: 'Testing dart_nostr library',
nip05: 'user@example.com',
);
print('Metadata event: ${metadata.id}');
// Create a follow list (NIP-02)
final followList = Nip02.createFollowList(
privateKey: keyPair.privateKey,
follows: [
FollowEntry(
pubkey: 'deadbeef' * 8,
relayUrl: 'wss://relay.damus.io',
petname: 'friend',
),
],
);
print('Follow list: ${followList.id}');
// Create a reaction (NIP-25)
final reaction = Nip25.like(
privateKey: keyPair.privateKey,
eventId: note.id,
eventPubkey: note.pubkey,
);
print('Reaction: ${reaction.id}');
// Reply to a note (NIP-10)
final reply = Nip10.createReply(
privateKey: keyPair.privateKey,
content: 'Great post!',
replyToEventId: note.id,
replyToAuthorPubkey: note.pubkey,
);
print('Reply: ${reply.id}');
// Long-form content (NIP-23)
final article = Nip23.createArticle(
privateKey: keyPair.privateKey,
content: '# My Article\n\nThis is a long-form article...',
identifier: 'my-first-article',
title: 'My First Article',
summary: 'An introduction to Nostr development',
hashtags: ['nostr', 'dart', 'flutter'],
);
print('Article: ${article.id}');
// Delete an event (NIP-09)
final deletion = Nip09.createDeletionRequest(
privateKey: keyPair.privateKey,
eventIds: [note.id],
reason: 'Changed my mind',
);
print('Deletion request: ${deletion.id}');
// ============================================================
// Encoding (NIP-19, NIP-21)
// ============================================================
// Encode an event reference
final nevent = Nip19.neventEncode(
eventId: note.id,
relays: ['wss://relay.damus.io'],
author: note.pubkey,
);
print('\nnevent: $nevent');
// Create a nostr: URI (NIP-21)
final uri = Nip21.encodeNpub(keyPair.publicKey);
print('nostr URI: $uri');
// ============================================================
// Relay Communication
// ============================================================
print('\n--- Relay Example ---');
final relay = Relay('wss://relay.damus.io');
try {
await relay.connect();
print('Connected to ${relay.url}');
// Listen for messages
relay.messages.listen((message) {
switch (message) {
case EventMessage(:final event, :final subscriptionId):
print(
'[$subscriptionId] Event: ${event.content.substring(0, 50.clamp(0, event.content.length))}...',
);
case EoseMessage(:final subscriptionId):
print('[$subscriptionId] End of stored events');
case OkMessage(:final eventId, :final accepted):
print('Event $eventId: ${accepted ? "accepted" : "rejected"}');
case NoticeMessage(:final message):
print('Notice: $message');
case AuthMessage(:final challenge):
print('Auth challenge received');
// Respond with NIP-42 auth
final authEvent = Nip42.createAuthEvent(
privateKey: keyPair.privateKey,
challenge: challenge,
relayUrl: relay.url,
);
relay.sendAuth(authEvent);
default:
break;
}
});
// Publish the text note
relay.sendEvent(note);
// Subscribe to recent text notes
final subId = relay.subscribe([
Filter(kinds: [EventKind.textNote], limit: 5),
]);
print('Subscribed: $subId');
// Wait a bit for events to arrive
await Future.delayed(Duration(seconds: 3));
// Close subscription and disconnect
relay.closeSubscription(subId);
await relay.disconnect();
print('Disconnected');
} catch (e) {
print('Relay error: $e');
}
await relay.dispose();
}