resolveObjectReferences method

Future<void> resolveObjectReferences(
  1. BuildOptions options
)

Implementation

Future<void> resolveObjectReferences(BuildOptions options) async {
  // Keep track of the object references that will need to be resolved at the end of the transaction.
  // We keep the input by-reference to avoid needing to re-resolve it:
  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 = <SuiObjectResponse>[];
  final objectsResult = (await Future.wait(
    objectChunks.map(
      (chunk) => expectClient(options)
          .multiGetObjects(chunk.cast<String>(), options: SuiObjectDataOptions(showOwner: true)),
    ),
  ));
  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.error != null)
      .map((entry) => entry.value.error?.toJson())
      .toList();

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

  final objects = resolved.map((object) {
    if (object.error != null || object.data == null) {
      throw ArgumentError("Failed to fetch object: ${object.error}");
    }
    final owner = object.data?.owner;
    final initialSharedVersion = owner?.shared?.initialSharedVersion;

    return {
      "objectId": object.data?.objectId,
      "digest": object.data?.digest,
      "version": object.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": 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"],
        ));
  }
}