requestAccountDomains function

Future<List<DomainData?>> requestAccountDomains(
  1. String accountAddress,
  2. StateApi state,
  3. StatusApi status,
  4. EntityDetails entities,
)

Implementation

Future<List<DomainData?>> requestAccountDomains(
  String accountAddress,
  StateApi state,
  StatusApi status,
  EntityDetails entities,
) async {
  if (accountAddress.isEmpty) return [] as List<DomainData?>;

  try {
    final accountNfts = await getNonFungibles(
        state: state, status: status, accountAddress: accountAddress);

    final domainBalance = (accountNfts.firstWhere(
      (nft) => nft.resourceAddress == entities.domainNameResource,
    ) as NonFungibleResourcesCollectionItemVaultAggregated?)
        ?.vaults
        .items[0];

    final initialIds = domainBalance?.items?.toList() ?? [] as List<String>;

    final cursor = domainBalance?.nextCursor;

    final ledgerState = cursor != null
        ? (await status.gatewayStatus().then((s) => s.data?.ledgerState))
        : null;

    final ids = await recursiveBalanceDomainIds(
      state,
      accountAddress,
      domainBalance!.vaultAddress,
      entities.domainNameResource,
      cursor,
      ledgerState,
      initialIds,
    );

    final batchedSubdomainIds = batchArray(ids ?? [], BATCHED_KV_STORE_LIMIT);

    final subdomainKvStoreResponses = batchedSubdomainIds[0].isNotEmpty
        ? await Future.wait(batchedSubdomainIds.map((ids) async {
            final response = await state.keyValueStoreData(
                stateKeyValueStoreDataRequest:
                    StateKeyValueStoreDataRequest((builder) {
              builder.keyValueStoreAddress = entities.subdomainVaults;
              builder.keys.addAll(ids.map((id) {
                return StateKeyValueStoreDataRequestKeyItem((builder) {
                  builder.keyJson = ProgrammaticScryptoSborValueString((b) {
                    b.kind =
                        ProgrammaticScryptoSborValueKind.nonFungibleLocalId;
                    b.value = id;
                  });
                });
              }));
            }));

            return response.data?.entries;
          }))
        : [];

    final subdomainKvStoreResponse = subdomainKvStoreResponses
        .expand((x) => x ?? [] as List<StateKeyValueStoreDataResponseItem>)
        .toList();

    final subdomainVaultIds = subdomainKvStoreResponse.isNotEmpty
        ? subdomainKvStoreResponse
            .map((kvResponse) => (kvResponse.value.programmaticJson
                    as ProgrammaticScryptoSborValueOwn)
                .value)
            .toList()
        : [];

    final subdomainIds =
        await Future.wait(subdomainVaultIds.map((subdomainVaultId) async {
      final response = await state.entityNonFungibleIdsPage(
        stateEntityNonFungibleIdsPageRequest:
            StateEntityNonFungibleIdsPageRequest((builder) {
          builder.address = entities.rnsStorage;
          builder.resourceAddress = entities.domainNameResource;
          builder.vaultAddress = subdomainVaultId;
        }),
      );
      return response.data?.items;
    }));

    final allOwnedSubdomains =
        subdomainIds.expand((x) => x ?? [] as List<String>).toList();

    final nftData = await state.nonFungibleData(
        stateNonFungibleDataRequest: StateNonFungibleDataRequest((builder) {
      builder.resourceAddress = entities.domainNameResource;
      builder.nonFungibleIds.addAll(ids ?? []);
      builder.nonFungibleIds.addAll(allOwnedSubdomains);
    })).then((s) => s.data?.nonFungibleIds.toList());

    final subdomains = (nftData ?? []).where((r) {
      return r.data?.programmaticJson.kind ==
              ProgrammaticScryptoSborValueKind.tuple &&
          (r.data?.programmaticJson as ProgrammaticScryptoSborValueTuple)
              .fields
              .any((field) =>
                  field.fieldName == 'primary_domain' &&
                  field.kind == ProgrammaticScryptoSborValueKind.enum_ &&
                  (field as ProgrammaticScryptoSborValueEnum).variantName !=
                      'None');
    }).map((r) {
      return (r.data?.programmaticJson as ProgrammaticScryptoSborValueTuple)
          .fields
          .fold<DomainData>(
        DomainData(
          id: r.nonFungibleId,
          name: '',
          createdTimestamp: 0,
          lastValidTimestamp: 0,
          keyImageUrl: '',
          address: null,
        ),
        (acc, field) {
          return parseDomainData(field, acc);
        },
      );
    }).toList();

    return (nftData ?? []).where((r) {
      return r.data?.programmaticJson.kind ==
              ProgrammaticScryptoSborValueKind.tuple &&
          (r.data?.programmaticJson as ProgrammaticScryptoSborValueTuple)
              .fields
              .any((field) =>
                  field.fieldName == 'primary_domain' &&
                  field.kind == ProgrammaticScryptoSborValueKind.enum_ &&
                  (field as ProgrammaticScryptoSborValueEnum).variantName ==
                      'None');
    }).map((r) {
      if (r.data?.programmaticJson.kind ==
          ProgrammaticScryptoSborValueKind.tuple) {
        return (r.data?.programmaticJson as ProgrammaticScryptoSborValueTuple)
            .fields
            .fold<DomainData>(
          DomainData(
            id: r.nonFungibleId,
            name: '',
            createdTimestamp: 0,
            lastValidTimestamp: 0,
            keyImageUrl: '',
            address: null,
            subdomains: subdomains
                .where((s) => s.primaryDomain == r.nonFungibleId)
                .toList(),
          ),
          (acc, field) {
            return parseDomainData(field, acc);
          },
        );
      }
    }).toList();
  } catch (e) {
    print(e);
    return [] as List<DomainData?>;
  }
}