resolveObjectReferences method

Future<void> resolveObjectReferences(
  1. BuildOptions options
)

Implementation

Future<void> resolveObjectReferences(BuildOptions options) async {
  // Unresolved object inputs (kept by-reference to avoid re-resolving).
  final objectsToResolve = _blockData.inputs.where((input) {
    return (input["UnresolvedObject"] != null &&
        (input["UnresolvedObject"]["version"] == null &&
            input["UnresolvedObject"]["initialSharedVersion"] == null));
  });

  final dedupedIds = Set.from(
    objectsToResolve.map(
      (input) => normalizeSuiObjectId(input["UnresolvedObject"]["objectId"]),
    ),
  ).toList();

  final objectChunks = dedupedIds.isNotEmpty
      ? chunk(dedupedIds, MAX_OBJECTS_PER_FETCH)
      : [];

  final resolved = <ObjectResult>[];
  final objectsResult = (await Future.wait(
    objectChunks.map(
      (chunk) => expectClient(options).getObjects(chunk.cast<String>()),
    ),
  ));
  for (var item in objectsResult) {
    resolved.addAll(item);
  }

  final responsesById = Map.fromIterables(
    dedupedIds,
    dedupedIds
        .asMap()
        .map((index, id) => MapEntry(index, resolved[index]))
        .values,
  );

  final invalidObjects = responsesById.entries
      .where((entry) => entry.value is ObjectError)
      .map((entry) => (entry.value as ObjectError).error)
      .toList();

  if (invalidObjects.isNotEmpty) {
    throw ArgumentError(
      "The following input objects are invalid: ${invalidObjects.join(', ')}",
    );
  }

  final objects = resolved.map((result) {
    if (result is! ObjectSuccess) {
      throw ArgumentError(
        "Failed to fetch object: ${(result as ObjectError).error}",
      );
    }
    final data = result.data;
    final owner = data.owner;
    final initialSharedVersion = owner is SharedOwner
        ? int.parse(owner.initialSharedVersion)
        : null;

    return {
      "objectId": data.objectId,
      "digest": data.digest,
      "version": data.version,
      "initialSharedVersion": initialSharedVersion,
    };
  }).toList();

  final objectsById = Map.fromIterables(
    dedupedIds,
    dedupedIds
        .asMap()
        .map((index, id) => MapEntry(index, objects[index]))
        .values,
  );

  for (int index = 0; index < _blockData.inputs.length; index++) {
    final input = _blockData.inputs[index];
    if (input["UnresolvedObject"] == null) {
      continue;
    }

    CallArg updated;
    final id = normalizeSuiAddress(input["UnresolvedObject"]["objectId"]);
    final object = objectsById[id];

    if ((input["UnresolvedObject"]?["initialSharedVersion"] ??
            object?["initialSharedVersion"]) !=
        null) {
      updated = Inputs.sharedObjectRef({
        "objectId": id,
        "initialSharedVersion":
            input["UnresolvedObject"]["initialSharedVersion"] ??
            object?["initialSharedVersion"],
        "mutable":
            (input["UnresolvedObject"]?["mutable"] ?? false) ||
            isUsedAsMutable(_blockData, index),
      });
    } else if (isUsedAsReceiving(_blockData, index)) {
      updated = Inputs.receivingRef(
        SuiObjectRef(
          input["UnresolvedObject"]["digest"] ?? object?["digest"],
          id,
          input["UnresolvedObject"]["version"] ?? object?["version"],
        ),
      );
    }

    _blockData.inputs[_blockData.inputs.indexOf(input)] =
        updated ??
        Inputs.objectRef(
          SuiObjectRef(
            input["UnresolvedObject"]["digest"] ?? object?["digest"],
            id,
            input["UnresolvedObject"]["version"] ?? object?["version"],
          ),
        );
  }
}