resolveBlobId method

Future<String> resolveBlobId(
  1. String id
)

Resolve an input that may be either a base64 blob ID or a Sui object ID (0x...) into a base64 blob ID.

If id starts with 0x, reads the on-chain Blob object to extract its blob ID and checks whether the blob was actually certified. Throws a clear error for uncertified or expired blobs.

Otherwise returns id unchanged (assumed to be a base64 blob ID).

Implementation

Future<String> resolveBlobId(String id) async {
  if (!id.startsWith('0x')) return id;

  final info = await getBlobObjectInfo(objectId: id);
  if (info == null) {
    throw WalrusClientError(
      'Could not resolve blob ID from Sui object $id. '
      'The object may not exist or is not a Walrus Blob.',
    );
  }

  final blobId = info['blobId'] as String;
  final certifiedEpoch = info['certifiedEpoch'];
  final endEpoch = info['endEpoch'];
  final deletable = info['deletable'];

  if (certifiedEpoch == null) {
    throw WalrusClientError(
      'Blob object $id (blobId=$blobId) was never certified. '
      'It was registered in epoch ${info['registeredEpoch']} '
      'but no storage nodes confirmed the data. '
      '${deletable == true ? 'This was a deletable blob.' : ''} '
      'The blob data is not available on the network.',
    );
  }

  if (endEpoch != null && certifiedEpoch is int) {
    // Check if the blob might have expired. We can't know the current
    // epoch for sure without a Sui RPC call, but if endEpoch <= certifiedEpoch
    // that's clearly impossible/expired.
    if (endEpoch is int && endEpoch <= certifiedEpoch) {
      throw WalrusClientError(
        'Blob object $id (blobId=$blobId) storage has expired. '
        'endEpoch=$endEpoch, certifiedEpoch=$certifiedEpoch.',
      );
    }
  }

  return blobId;
}