register method

Future<Transaction> register(
  1. WriteFilesFlowRegisterOptions options
)

Step 2: Build the register transaction.

Returns an unsigned Transaction for external signing. Sets the _walrusBlobType: 'quilt' attribute automatically.

Implementation

Future<Transaction> register(WriteFilesFlowRegisterOptions options) async {
  if (_step != _WriteFilesFlowStep.encoded) {
    throw StateError('Must call encode() before register()');
  }

  _deletable = options.deletable;
  final metadata = _metadata!;
  final quiltBytes = _quiltBytes!;

  final tx = Transaction();
  tx.setSenderIfNotSet(options.owner);

  // Add upload relay tip if configured.
  if (_relayClient != null && _tipConfig != null) {
    _txBuilder.sendUploadRelayTip(
      size: quiltBytes.length,
      blobDigest: metadata.blobDigest,
      nonce: metadata.nonce,
      tipConfig: _tipConfig,
      transaction: tx,
    );
  }

  // Register the blob on-chain.
  String? walCoinObjectId = options.walCoinObjectId;
  String? walType = options.walType;
  BigInt? storageCost = options.storageCost;
  BigInt? writeCost = options.writeCost;
  int? encodedSize = options.encodedSize;

  // Auto-resolve from chain if state reader is available.
  if (_stateReader != null &&
      (walType == null ||
          storageCost == null ||
          writeCost == null ||
          encodedSize == null)) {
    walType ??= await _stateReader.getWalType();
    final costs = await _stateReader.storageCost(
      quiltBytes.length,
      options.epochs,
    );
    storageCost ??= costs.storageCost;
    writeCost ??= costs.writeCost;
    final state = await _stateReader.systemState();
    encodedSize ??= encodedBlobLength(quiltBytes.length, state.nShards);
  }

  // Auto-resolve WAL coin when not provided.
  if (walCoinObjectId == null &&
      _suiClient != null &&
      walType != null &&
      storageCost != null &&
      writeCost != null) {
    final totalWalNeeded = storageCost + writeCost;
    final coins = await _suiClient.getCoins(options.owner, coinType: walType);
    final coinList = coins.data as List?;
    if (coinList != null) {
      for (final coin in coinList) {
        final balance =
            BigInt.tryParse(coin.balance as String) ?? BigInt.zero;
        if (balance >= totalWalNeeded) {
          walCoinObjectId = coin.coinObjectId as String?;
          break;
        }
      }
    }
  }

  if (walCoinObjectId != null &&
      walType != null &&
      storageCost != null &&
      writeCost != null &&
      encodedSize != null) {
    _txBuilder.registerBlobWithWal(
      RegisterBlobOptions(
        size: quiltBytes.length,
        epochs: options.epochs,
        blobId: metadata.blobId,
        rootHash: metadata.rootHash,
        deletable: options.deletable,
        owner: options.owner,
      ),
      walCoinObjectId: walCoinObjectId,
      walType: walType,
      storageCost: storageCost,
      writeCost: writeCost,
      encodedSize: encodedSize,
      transaction: tx,
    );
  } else {
    throw StateError(
      'WAL payment requires a WAL coin with sufficient balance. '
      'Either provide walCoinObjectId explicitly, or ensure a SuiClient '
      'and SystemStateReader are available for auto-resolution. '
      'Resolved: walCoinObjectId=$walCoinObjectId, walType=$walType, '
      'storageCost=$storageCost, writeCost=$writeCost, encodedSize=$encodedSize',
    );
  }

  _step = _WriteFilesFlowStep.registered;
  return tx;
}