resolveRecord function
Future<ResolvedRecordResponse?>
resolveRecord(
- String domain,
- String context,
- String directive,
- bool proven,
- StateApi state,
- StatusApi status,
- EntityDetails entities,
Implementation
Future<ResolvedRecordResponse?> resolveRecord(
String domain,
String context,
String directive,
bool proven,
StateApi state,
StatusApi status,
EntityDetails entities,
) async {
try {
final domainId = await domainToNonFungId(domain);
final parsedContext = context.isNotEmpty ? '-$context' : '';
final parsedDirective = directive.isNotEmpty ? '-$directive' : '';
final recordId =
await domainToNonFungId('$domainId$parsedContext$parsedDirective');
final nft = await state.nonFungibleData(
stateNonFungibleDataRequest: StateNonFungibleDataRequest((builder) {
builder.resourceAddress = entities.resolverRecordResource;
builder.nonFungibleIds.add(recordId);
}),
).then((response) => response.data?.nonFungibleIds.first);
if (nft?.data?.programmaticJson.kind ==
ProgrammaticScryptoSborValueKind.tuple) {
final value =
(nft?.data?.programmaticJson as ProgrammaticScryptoSborValueTuple)
.fields
.where((field) =>
field.fieldName == 'value' &&
field.kind == ProgrammaticScryptoSborValueKind.enum_)
.map((field) {
if (field.fieldName == 'value' &&
field.kind == ProgrammaticScryptoSborValueKind.enum_) {
return ((field as ProgrammaticScryptoSborValueEnum).fields[0]
as ProgrammaticScryptoSborValueString)
.value;
}
return null;
}).first;
if (!proven) {
return ResolvedRecordResponse(value: value!);
}
if (!value!.startsWith('(') || !value.endsWith(')')) {
return null;
}
final provenResources =
RegExp(r'\(\"(.+)\"\)').firstMatch(value)?.group(1);
if (provenResources == null) {
return null;
}
final domainDetails =
await requestDomainDetails(domain, state: state, entities: entities);
final accountAddress = domainDetails?.address;
final provenResourcesList = provenResources
.split(',')
.fold<List<Map<String, dynamic>>>([], (acc, resource) {
final parts = resource.split(':');
final resourceAddress = parts[0];
final id = parts.length > 1 ? parts[1] : null;
final foundResource = acc.firstWhere(
(a) => a['resourceAddress'] == resourceAddress,
orElse: () => {
'resourceAddress': resourceAddress,
'ids': <String>[],
},
);
if (id != null) {
foundResource['ids'].add(id);
}
if (!acc.contains(foundResource)) {
acc.add(foundResource);
}
return acc;
});
final fungibleResourcesAddresses = provenResourcesList
.where((r) => r['ids'].isEmpty)
.map((r) => r['resourceAddress'])
.toList();
final accountNonFungibleVaultIds = await Future.wait([
fungibleVaults(
accountAddress: accountAddress!, state: state, status: status),
nonFungibleVaults(
accountAddress: accountAddress, state: state, status: status)
]).then((r) {
final fungibleVaultList = r[0] as List<FungibleResourcesCollectionItem>;
final nonFungibleVaultList =
r[1] as List<NonFungibleResourcesCollectionItem>;
final nonFungibleVaultAddresses = nonFungibleVaultList
.map((v) => (v as NonFungibleResourcesCollectionItemVaultAggregated)
.vaults
.items[0]
.vaultAddress)
.toSet();
final areAllResourcesProven =
fungibleResourcesAddresses.every((resource) {
return fungibleVaultList.any((v) =>
v.resourceAddress == resource &&
double.parse((v as FungibleResourcesCollectionItemVaultAggregated)
.vaults
.items[0]
.amount) >
0);
});
if (!areAllResourcesProven) {
return null;
}
return nonFungibleVaultAddresses.toList();
});
if (accountNonFungibleVaultIds == null) {
return null;
}
final nonFungibleLocationResponse = await Future.wait(
provenResourcesList.where((r) => r['ids'].isNotEmpty).map((resource) {
return state.nonFungibleLocation(stateNonFungibleLocationRequest:
StateNonFungibleLocationRequest((builder) {
builder.resourceAddress = resource['resourceAddress'];
builder.nonFungibleIds.addAll(resource['ids']);
}));
})).then(
(s) => s.map((r) => r.data?.nonFungibleIds.toList() ?? []).toList());
final requiredVaultIds = nonFungibleLocationResponse
.expand((r) => r)
.map((r) => r.owningVaultAddress)
.toSet();
final areAllNftsProven = requiredVaultIds
.every((vaultId) => accountNonFungibleVaultIds.contains(vaultId));
if (!areAllNftsProven) {
return null;
}
final nftDataList = await Future.wait(provenResourcesList.map((r) {
return state.nonFungibleData(
stateNonFungibleDataRequest: StateNonFungibleDataRequest((builder) {
builder.resourceAddress = r['resourceAddress'];
builder.nonFungibleIds.addAll(r['ids']);
}),
).then((response) =>
response.data?.nonFungibleIds.toList() ??
[] as List<StateNonFungibleDetailsResponseItem>);
}));
return ResolvedRecordResponse(
value: value,
nonFungibleDataList: nftDataList.expand((r) => r).toList(),
);
}
return null;
} catch (e) {
print(e);
return null;
}
}