nostr_tools 1.0.9 copy "nostr_tools: ^1.0.9" to clipboard
nostr_tools: ^1.0.9 copied to clipboard

A Dart package that makes it easy to work with the nostr protocol and develop Nostr clients.

nostr_tools package logo

A Dart package that makes it easy to work with the nostr protocol and develop nostr clients.

Usage #

To use this package, add nostr_tools as a dependency in your pubspec.yaml file.

Generating a private key and a public key #

import 'package:nostr_tools/nostr_tools.dart';

void main() {
  final keyGenerator = KeyApi();

  final privateKey = keyGenerator.generatePrivateKey();
  print('[+] privateKey: $privateKey');
  // [+] privateKey: b2352adb186508e7f617105a6dc070df531f53b56cf8744816fdb838891dc9b7

  final publicKey = keyGenerator.getPublicKey(privateKey);
  print('[+] publicKey: $publicKey');
  // [+] publicKey: 9d088c4377b9866fad945d949de8f626784b1639f93bf090c1cea6727f17dd51
}
copied to clipboard

Creating, signing and verifying events #

import 'package:nostr_tools/nostr_tools.dart';

void main() {
  final keyApi = KeyApi();
  final eventApi = EventApi();

  final privateKey = keyApi.generatePrivateKey();
  final publicKey = keyApi.getPublicKey(privateKey);

  final event = Event(
    kind: 1,
    tags: [],
    content: 'content',
    created_at: DateTime.now().millisecondsSinceEpoch ~/ 1000,
    pubkey: publicKey,
  );

  event.id = eventApi.getEventHash(event);
  event.sig = eventApi.signEvent(event, privateKey);

  if (eventApi.verifySignature(event)) print('[+] sig is valid');
}
copied to clipboard

Interacting with a relay #

void main() async {
  final relay = RelayApi(relayUrl: 'wss://relay.damus.io');

  final stream = await relay.connect();

  relay.on((event) {
    if (event == RelayEvent.connect) {
      print('[+] connected to ${relay.relayUrl}');
    } else if (event == RelayEvent.error) {
      print('[!] failed to connect to ${relay.relayUrl}');
    }
  });

  relay.sub([
    Filter(
      kinds: [1],
      limit: 10,
      since: DateTime.now().millisecondsSinceEpoch ~/ 1000,
    )
  ]);

  stream.listen((Message message) {
    if (message.type == 'EVENT') {
      Event event = message.message;
      print('[+] Received event: ${event.content}');
    } else if (message.type == 'OK') {
      print('[+] Event Published: ${message.message}');
    }
  });

  // let's publish a new event while simultaneously monitoring the relay for it
  final privateKey =
      'b2352adb186508e7f617105a6dc070df531f53b56cf8744816fdb838891dc9b7';

  final event = EventApi().finishEvent(
    Event(
      kind: 1,
      tags: [],
      content: 'hello world',
      created_at: DateTime.now().millisecondsSinceEpoch ~/ 1000,
    ),
    privateKey,
  );

  relay.publish(event);
}
copied to clipboard

Interacting with multiple relays #

void main() async {
  final relaysList = [
    'wss://relay.damus.io',
    'wss://relay.nostr.info',
    'wss://eden.nostr.land',
    'wss://nostr-pub.wellorder.net',
    'wss://nos.lol'
  ];
  final relayPool = RelayPoolApi(relaysList: relaysList);

  final stream = await relayPool.connect();

  relayPool.on((event) {
    if (event == RelayEvent.connect) {
      print('[+] connected to: ${relayPool.connectedRelays}');
    } else if (event == RelayEvent.error) {
      print('[!] failed to connect to: ${relayPool.failedRelays}');
    }
  });

  relayPool.sub([
    Filter(
      kinds: [1],
      limit: 10,
      since: DateTime.now().millisecondsSinceEpoch ~/ 1000,
    )
  ]);

  stream.listen((Message message) {
    if (message.type == 'EVENT') {
      Event event = message.message;
      print('[+] Received event: ${event.content}');
    }
  });

  final privateKey =
      'ccbe92bd853e3661bace63df5b8338dcbaa2c766e2dbb0b90d45b2dd58efaae4';

  final event = EventApi().finishEvent(
    Event(
      kind: 1,
      tags: [],
      content: 'hello world',
      created_at: DateTime.now().millisecondsSinceEpoch ~/ 1000,
    ),
    privateKey,
  );

  relayPool.publish(event);
}
copied to clipboard

Querying profile data from a NIP-05 address #

void main() async {
  var nip05 = Nip05();
  var profile = await nip05.queryProfile('anipy@aniketambore.github.io');
  print('[+] Pubkey: ${profile?.pubkey}');
  // [+] Pubkey: c7c187ba76532d55723490af88e76dd570fe551a2461ca9ab542b503bbb25045

  print('[+] Relays: ${profile?.relays}');
  // [+] Relays: [wss://relay.damus.io, wss://nos.lol, wss://relay.snort.social]
}
copied to clipboard

Encoding and decoding NIP-19 codes #

void main() {
  final keyGenerator = KeyApi();
  final nip19 = Nip19();

  final sk = keyGenerator.generatePrivateKey();
  final nsec = nip19.nsecEncode(sk);
  final nsecDecoded = nip19.decode(nsec);
  assert(nsecDecoded['type'] == 'nsec');
  assert(nsecDecoded['data'] == sk);

  final pk = keyGenerator.getPublicKey(sk);
  final npub = nip19.npubEncode(pk);
  final npubDecoded = nip19.decode(npub);
  assert(npubDecoded['type'] == 'npub');
  assert(npubDecoded['data'] == pk);

  final relays = [
    'wss://relay.nostr.example.mydomain.example.com',
    'wss://nostr.banana.com'
  ];
  final nprofile =
      nip19.nprofileEncode(ProfilePointer(pubkey: pk, relays: relays));
  final nprofileDecode = nip19.decode(nprofile);
  assert(nprofileDecode['type'] == 'nprofile');
  assert(nprofileDecode['data']['pubkey'] == pk);
  assert(nprofileDecode['data']['relays'].length == 2);
}
copied to clipboard

Encrypting and decrypting direct messages #

void main() {
  final keyGenerator = KeyApi();
  final nip04 = Nip04();

  final aliceSK = keyGenerator.generatePrivateKey();
  final alicePK = keyGenerator.getPublicKey(aliceSK);
  final bobSK = keyGenerator.generatePrivateKey();
  final bobPK = keyGenerator.getPublicKey(bobSK);

  var aliceMessageToBob = 'Hello Bob!';
  var cipherText = nip04.encrypt(aliceSK, bobPK, aliceMessageToBob);
  print('[+] cipherText: $cipherText');

  var bobDecodingMessage = nip04.decrypt(bobSK, alicePK, cipherText);
  print('[+] plainText: $bobDecodingMessage');
}
copied to clipboard

Take a look at the example project for developing a simple basic nostr client in flutter.

Reference #

6
likes
130
points
226
downloads

Publisher

verified publisheraniketambore-github-io.blogspot.com

Weekly Downloads

2024.09.08 - 2025.03.23

A Dart package that makes it easy to work with the nostr protocol and develop Nostr clients.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

bech32, bip32, bip340, bip39, convert, crypto, http, kepler, meta, pointycastle, web_socket_channel

More

Packages that depend on nostr_tools