# Blossom

low level

# Example

final downloadResult = await ndk.blossom.getBlob(
  sha256:
      "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553",
  serverUrls: ["https://cdn.hzrd149.com"],
);

print(
  "file of type: ${downloadResult.mimeType}, size: ${downloadResult.data.length}",
);

# When to use

For a simpler, more generic API, check out

Files
../files/

If no servers are specified the default user server list (kind 10063) is used for upload and delete.

The auth events get automatically signed and are valid for:

const Duration BLOSSOM_AUTH_EXPIRATION = Duration(minutes: 5);

# methods - Blossom

# uploadBlob

upload a blob, if serverMediaOptimisation is set to true the /media endpoint is used.

/// upload a blob to the server
/// if [serverUrls] is null, the userServerList is fetched from nostr. \
/// if the pukey has no UserServerList (kind: 10063), throws an error \
/// the current signer is used to sign the request \
/// [strategy] is the upload strategy, default is mirrorAfterSuccess \
/// [serverMediaOptimisation] is whether the server should optimise the media [BUD-05], IMPORTANT: the server hash will be different \
Future<List<BlobUploadResult>> uploadBlob({
  required Uint8List data,
  List<String>? serverUrls,
  String? contentType,
  UploadStrategy strategy = UploadStrategy.mirrorAfterSuccess,
  bool serverMediaOptimisation = false,
}) async {

# getBlob

Download the blob and use fallback if the blob is not found or the server is offline.

/// Gets a blob by trying servers sequentially until success (fallback) \
/// if [serverUrls] is null, the userServerList is fetched from nostr. \
/// if the pukey has no UserServerList (kind: 10063), throws an error
Future<BlobResponse> getBlob({
  required String sha256,
  bool useAuth = false,
  List<String>? serverUrls,
  String? pubkeyToFetchUserServerList,
}) async {

# checkBlob

/// checks if the blob exists on the server without downloading, useful to check before streaming a video via url \
/// if [serverUrls] is null, the userServerList is fetched from nostr. \
/// if the pukey has no UserServerList (kind: 10063), throws an error
///
/// returns the url of one server that has the blob e.g. https://myserver.com/hash.pdf \
/// otherwise  throws an error
Future<String> checkBlob({
  required String sha256,
  bool useAuth = false,
  List<String>? serverUrls,
  String? pubkeyToFetchUserServerList,
}) async {

# getBlobStream

Similar to getBlob, it streams the data, which is helpful for video files.

/// downloads a blob as a stream, useful for large files like videos \
/// if [serverUrls] is null, the userServerList is fetched from nostr. \
/// if the pukey has no UserServerList (kind: 10063), throws an error
Future<Stream<BlobResponse>> getBlobStream({
  required String sha256,
  bool useAuth = false,
  List<String>? serverUrls,
  String? pubkeyToFetchUserServerList,
  int chunkSize = 1024 * 1024, // 1MB chunks,
}) async {

# listBlobs

/// list the [pubkey] blobs \
/// if [serverUrls] is null, the userServerList is fetched from nostr. \
/// if the pukey has no UserServerList (kind: 10063), throws an error
///
Future<List<BlobDescriptor>> listBlobs({
  required String pubkey,
  List<String>? serverUrls,
  bool useAuth = true,
  DateTime? since,
  DateTime? until,
}) async {

# deleteBlob

/// delete a blob
/// if [serverUrls] is null, the userServerList is fetched from nostr. \
/// if the pukey has no UserServerList (kind: 10063), throws an error \
/// the current signer is used to sign the request
Future<List<BlobDeleteResult>> deleteBlob({
  required String sha256,
  List<String>? serverUrls,
}) async {

# directDownload

/// Directly downloads a blob from the url, without blossom
Future<BlobResponse> directDownload({
  required Uri url,
}) {

# report

/// Reports a blob to the server
/// [sha256] is the hash of the blob
/// [eventId] is the event id where the blob was mentioned
/// [reportType] is the type of report, e.g. malware @see nip56
/// [reportMsg] is the message to send to the server
/// [serverUrl] server url to report to
///
/// returns the http status code of the rcv server
Future<int> report({
  required String sha256,
  required String eventId,
  required String reportType,
  required String reportMsg,
  required String serverUrl,
}) async {

# methods - BlossomUserServerList

To get and set the user server list e.g. on settings page, you can use BlossomUserServerList

# getUserServerList

/// Get user server list \
/// returns list of server urls \
/// returns null if the user has no server list
Future<List<String>?> getUserServerList({
  required List<String> pubkeys,
}) async {

# publishUserServerList

/// Publish user server list \
/// order of [serverUrlsOrdered] is important, the first server is the most trusted server
Future<List<RelayBroadcastResponse>> publishUserServerList({
  required List<String> serverUrlsOrdered,
}) async {