sendMessage method

Future<void> sendMessage({
  1. required String recipientPubKey,
  2. required String content,
  3. List<List<String>> additionalTags = const [],
})

Sends a direct message to recipientPubKey.

NDK creates a message rumor, wraps it once for the recipient and once for the sender, and broadcasts each wrapped copy to the corresponding DM relays.

Throws if either side has no published DM relay list.

Implementation

Future<void> sendMessage({
  required String recipientPubKey,
  required String content,
  List<List<String>> additionalTags = const [],
}) async {
  final senderPubKey = _requireLoggedPubKey();

  final senderDmRelays = await _userRelayLists.getDmRelays(senderPubKey);
  if (senderDmRelays == null || senderDmRelays.isEmpty) {
    throw Exception(
      'Sender has no NIP-17 DM relays (kind 10050). Publish one first.',
    );
  }

  final recipientDmRelays = await _userRelayLists.getDmRelays(
    recipientPubKey,
    forceRefresh: true,
  );
  if (recipientDmRelays == null || recipientDmRelays.isEmpty) {
    throw Exception('Recipient has no NIP-17 DM relays (kind 10050).');
  }

  final rumor = await _giftWrap.createRumor(
    content: content,
    kind: kMessageKind,
    tags: [
      ['p', recipientPubKey],
      ...additionalTags,
    ],
  );

  final recipientWrap = await _giftWrap.toGiftWrap(
    rumor: rumor,
    recipientPubkey: recipientPubKey,
  );
  final senderWrap = await _giftWrap.toGiftWrap(
    rumor: rumor,
    recipientPubkey: senderPubKey,
  );

  final recipientBroadcast = _broadcast.broadcast(
    nostrEvent: recipientWrap,
    specificRelays: recipientDmRelays,
  );
  final senderBroadcast = _broadcast.broadcast(
    nostrEvent: senderWrap,
    specificRelays: senderDmRelays,
  );

  await Future.wait([
    recipientBroadcast.broadcastDoneFuture,
    senderBroadcast.broadcastDoneFuture,
  ]);
}