encodeNaddr static method

String encodeNaddr({
  1. required String identifier,
  2. required String pubkey,
  3. required int kind,
  4. List<String>? relays,
})

Encode naddr (addressable event coordinate) identifier - the "d" tag value (empty string for normal replaceable events) pubkey - 32-byte hex public key of the event author (required) kind - event kind number (required) relays - optional list of relay URLs where the event may be found

Implementation

static String encodeNaddr({
  required String identifier,
  required String pubkey,
  required int kind,
  List<String>? relays,
}) {
  final tlvData = <int>[];

  // Type 0: identifier (special) - UTF-8 encoded string
  final identifierBytes = utf8.encode(identifier);
  tlvData.add(0); // type
  tlvData.add(identifierBytes.length); // length
  tlvData.addAll(identifierBytes); // value

  // Type 1: relays (optional, can be multiple)
  if (relays != null) {
    for (final relay in relays) {
      final relayBytes = utf8.encode(relay);
      if (relayBytes.length > 255) {
        throw ArgumentError(
            'Relay URL too long: ${relay.length} bytes (max 255)');
      }
      tlvData.add(1); // type
      tlvData.add(relayBytes.length); // length
      tlvData.addAll(relayBytes); // value
    }
  }

  // Type 2: author pubkey (required, 32 bytes)
  final pubkeyBytes = hex.decode(pubkey);
  if (pubkeyBytes.length != 32) {
    throw ArgumentError('Public key must be 32 bytes (64 hex characters)');
  }
  tlvData.add(2); // type
  tlvData.add(32); // length
  tlvData.addAll(pubkeyBytes); // value

  // Type 3: kind (required, 32-bit unsigned big-endian)
  final kindBytes = [
    (kind >> 24) & 0xFF,
    (kind >> 16) & 0xFF,
    (kind >> 8) & 0xFF,
    kind & 0xFF,
  ];
  tlvData.add(3); // type
  tlvData.add(4); // length (32-bit = 4 bytes)
  tlvData.addAll(kindBytes); // value

  // Convert to bech32
  final data = Nip19Utils.convertBits(tlvData, 8, 5, true);
  var encoder = Bech32Encoder();
  Bech32 input = Bech32(Hrps.kNaddr, data);
  var encoded = encoder.convert(input, input.hrp.length + data.length + 10);
  return encoded;
}