MoneroAddr.fromString constructor

MoneroAddr.fromString(
  1. String address, {
  2. required int standardByte,
  3. required int integratedByte,
  4. required int subaddrByte,
})

Network bytes distinguish address types during decoding.

Implementation

factory MoneroAddr.fromString(
  String address, {
  required int standardByte,
  required int integratedByte,
  required int subaddrByte,
}) {
  final raw = moneroBase58Decode(address);
  if (raw.length < 5) {
    throw FormatException(
        'Monero address too short: ${raw.length} bytes');
  }

  // Split payload and checksum.
  final payload = Uint8List.sublistView(raw, 0, raw.length - 4);
  final checksum = Uint8List.sublistView(raw, raw.length - 4);
  final expected = moneroChecksum(payload);

  if (!bytesEqual(checksum, expected)) {
    throw const FormatException('Monero address checksum mismatch');
  }

  final netByte = payload[0];

  if (netByte == standardByte) {
    if (payload.length != 65) {
      throw FormatException(
          'Standard address payload must be 65 bytes, got ${payload.length}');
    }
    return MoneroStandardAddr(
      Uint8List.fromList(payload.sublist(1, 33)),
      Uint8List.fromList(payload.sublist(33, 65)),
    );
  }

  if (netByte == subaddrByte) {
    if (payload.length != 65) {
      throw FormatException(
          'Subaddress payload must be 65 bytes, got ${payload.length}');
    }
    return MoneroSubaddr(
      Uint8List.fromList(payload.sublist(1, 33)),
      Uint8List.fromList(payload.sublist(33, 65)),
    );
  }

  if (netByte == integratedByte) {
    if (payload.length != 73) {
      throw FormatException(
          'Integrated address payload must be 73 bytes, got ${payload.length}');
    }
    return MoneroIntegratedAddr(
      Uint8List.fromList(payload.sublist(1, 33)),
      Uint8List.fromList(payload.sublist(33, 65)),
      Uint8List.fromList(payload.sublist(65, 73)),
    );
  }

  throw FormatException('Unknown Monero network byte: 0x${netByte.toRadixString(16)}');
}