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
}

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');
}

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);
}

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);
}

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]
}

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);
}

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');
}

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

Reference #

7
likes
130
points
48
downloads

Publisher

verified publisheraniketambore-github-io.blogspot.com

Weekly Downloads

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