You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.6 KiB

import 'dart:convert';
/// Represents a Nostr user profile (metadata from kind 0 events).
class NostrProfile {
/// Public key (npub or hex).
final String publicKey;
/// Display name or username.
final String? name;
/// About/bio text.
final String? about;
/// Profile picture URL.
final String? picture;
/// Website URL.
final String? website;
/// NIP-05 identifier (e.g., user@domain.com).
final String? nip05;
/// Banner image URL.
final String? banner;
/// LUD16 (Lightning address).
final String? lud16;
/// Raw metadata JSON for additional fields.
final Map<String, dynamic> rawMetadata;
/// Timestamp when profile was last updated.
final DateTime? updatedAt;
/// Creates a [NostrProfile] instance.
NostrProfile({
required this.publicKey,
this.name,
this.about,
this.picture,
this.website,
this.nip05,
this.banner,
this.lud16,
Map<String, dynamic>? rawMetadata,
this.updatedAt,
}) : rawMetadata = rawMetadata ?? {};
/// Creates a [NostrProfile] from Nostr metadata event content (JSON string).
///
/// [publicKey] - The public key of the profile owner.
/// [content] - JSON string from kind 0 event content.
/// [updatedAt] - Optional timestamp when profile was updated.
factory NostrProfile.fromEventContent({
required String publicKey,
required String content,
DateTime? updatedAt,
}) {
try {
final metadata = jsonDecode(content) as Map<String, dynamic>;
return NostrProfile(
publicKey: publicKey,
name: metadata['name'] as String?,
about: metadata['about'] as String?,
picture: metadata['picture'] as String?,
website: metadata['website'] as String?,
nip05: metadata['nip05'] as String?,
banner: metadata['banner'] as String?,
lud16: metadata['lud16'] as String?,
rawMetadata: metadata,
updatedAt: updatedAt ?? DateTime.now(),
);
} catch (e) {
// Return minimal profile if parsing fails
return NostrProfile(
publicKey: publicKey,
rawMetadata: {},
updatedAt: updatedAt ?? DateTime.now(),
);
}
}
/// Creates a [NostrProfile] from a JSON map.
factory NostrProfile.fromJson(Map<String, dynamic> json) {
return NostrProfile(
publicKey: json['publicKey'] as String,
name: json['name'] as String?,
about: json['about'] as String?,
picture: json['picture'] as String?,
website: json['website'] as String?,
nip05: json['nip05'] as String?,
banner: json['banner'] as String?,
lud16: json['lud16'] as String?,
rawMetadata: json['rawMetadata'] as Map<String, dynamic>? ?? {},
updatedAt: json['updatedAt'] != null
? DateTime.parse(json['updatedAt'] as String)
: null,
);
}
/// Converts [NostrProfile] to JSON.
Map<String, dynamic> toJson() {
return {
'publicKey': publicKey,
'name': name,
'about': about,
'picture': picture,
'website': website,
'nip05': nip05,
'banner': banner,
'lud16': lud16,
'rawMetadata': rawMetadata,
'updatedAt': updatedAt?.toIso8601String(),
};
}
/// Gets display name (name, nip05, or public key prefix).
String get displayName {
if (name != null && name!.isNotEmpty) return name!;
if (nip05 != null && nip05!.isNotEmpty) return nip05!;
return publicKey.length > 16
? '${publicKey.substring(0, 8)}...${publicKey.substring(publicKey.length - 8)}'
: publicKey;
}
@override
String toString() {
return 'NostrProfile(publicKey: ${publicKey.substring(0, 8)}..., name: $name)';
}
}

Powered by TurnKey Linux.