resolveObjectReferences method
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"],
)
);
}
}