From 3ea1d5eb66d19dbe30f1c321c762039a69231842 Mon Sep 17 00:00:00 2001 From: iliad Date: Thu, 20 Feb 2025 16:39:30 +0800 Subject: [PATCH] feat: add searchUserAssets & search activity by tokenName --- .github/workflows/mainnet-package.yaml | 4 +- .../UserAssets/Dto/SearchUserAssetsDto.cs | 47 ++++++++++ .../UserAssets/IUserAssetsAppService.cs | 2 + .../UserAssets/Request/GetTokenRequestDto.cs | 2 - .../Request/SearchUserAssetsRequestDto.cs | 12 +++ .../EoaServerApplicationAutoMapperProfile.cs | 4 + .../UserActivity/UserActivityAppService.cs | 28 +++--- .../UserAssets/UserAssetsAppService.cs | 86 ++++++++++++++++++- .../Controllers/UserAssetsController.cs | 9 +- 9 files changed, 176 insertions(+), 18 deletions(-) create mode 100644 src/EoaServer.Application.Contracts/UserAssets/Dto/SearchUserAssetsDto.cs create mode 100644 src/EoaServer.Application.Contracts/UserAssets/Request/SearchUserAssetsRequestDto.cs diff --git a/.github/workflows/mainnet-package.yaml b/.github/workflows/mainnet-package.yaml index 7a8eab7..c85c2b7 100644 --- a/.github/workflows/mainnet-package.yaml +++ b/.github/workflows/mainnet-package.yaml @@ -11,7 +11,7 @@ jobs: strategy: matrix: servicename: - [EoaServer.Silo,EoaServer.HttpApi.Host,EoaServer.EntityEventHandler,EoaServer.AuthServer,EoaServer.DbMigrator] + [EoaServer.HttpApi.Host,EoaServer.DbMigrator] steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 @@ -30,7 +30,7 @@ jobs: strategy: matrix: servicename: - [EoaServer.Silo,EoaServer.HttpApi.Host,EoaServer.EntityEventHandler,EoaServer.AuthServer,EoaServer.DbMigrator] + [EoaServer.HttpApi.Host,EoaServer.DbMigrator] permissions: contents: read steps: diff --git a/src/EoaServer.Application.Contracts/UserAssets/Dto/SearchUserAssetsDto.cs b/src/EoaServer.Application.Contracts/UserAssets/Dto/SearchUserAssetsDto.cs new file mode 100644 index 0000000..dfe6fb8 --- /dev/null +++ b/src/EoaServer.Application.Contracts/UserAssets/Dto/SearchUserAssetsDto.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using EoaServer.Commons; + +namespace EoaServer.UserAssets.Dto; + +public class SearchUserAssetsV2Dto +{ + public List TokenInfos { get; set; } = new(); + public List NftInfos { get; set; } = new(); + public long TotalRecordCount { get; set; } +} + +public class NftInfoDto : ChainDisplayNameDto +{ + public string ImageUrl { get; set; } + public string Alias { get; set; } + public string TokenId { get; set; } + public string CollectionName { get; set; } // nftItem collectionSymbol + public string Balance { get; set; } + public string TokenContractAddress { get; set; } + public string Decimals { get; set; } + public string TokenName { get; set; } + public bool IsSeed { get; set; } + public int SeedType { get; set; } + public string Label { get; set; } // new nftItem + public string Symbol { get; set; } +} + +public class TokenInfoV2Dto : ChainDisplayNameDto +{ + public string Symbol { get; set; } + public string Address { get; set; } // user address + public string Label { get; set; } + + public string Balance { get; set; } + public string Decimals { get; set; } + public string BalanceInUsd { get; set; } + public string TokenContractAddress { get; set; } + public string ImageUrl { get; set; } +} + +public class NftCollectionDto +{ + public string CollectionName { get; set; } + public string ImageUrl { get; set; } + public List Items { get; set; } = new(); +} \ No newline at end of file diff --git a/src/EoaServer.Application.Contracts/UserAssets/IUserAssetsAppService.cs b/src/EoaServer.Application.Contracts/UserAssets/IUserAssetsAppService.cs index 7c4abea..b423622 100644 --- a/src/EoaServer.Application.Contracts/UserAssets/IUserAssetsAppService.cs +++ b/src/EoaServer.Application.Contracts/UserAssets/IUserAssetsAppService.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using EoaServer.Awaken; using EoaServer.UserAssets; +using EoaServer.UserAssets.Dto; using EoaServer.UserAssets.Dtos; namespace EoaServer.UserAssets; @@ -12,4 +13,5 @@ public interface IUserAssetsAppService Task GetNFTItemsAsync(GetNftItemsRequestDto requestDto); Task ListAwakenSupportedTokensAsync(int skipCount, int maxResultCount, int page, string chainId, string caAddress); + Task SearchUserAssetsAsync(SearchUserAssetsRequestDto requestDto); } \ No newline at end of file diff --git a/src/EoaServer.Application.Contracts/UserAssets/Request/GetTokenRequestDto.cs b/src/EoaServer.Application.Contracts/UserAssets/Request/GetTokenRequestDto.cs index 83febad..458ff9d 100644 --- a/src/EoaServer.Application.Contracts/UserAssets/Request/GetTokenRequestDto.cs +++ b/src/EoaServer.Application.Contracts/UserAssets/Request/GetTokenRequestDto.cs @@ -1,5 +1,3 @@ -using EoaServer.UserAssets; - namespace EoaServer.UserAssets; public class GetTokenRequestDto : GetAssetsBase diff --git a/src/EoaServer.Application.Contracts/UserAssets/Request/SearchUserAssetsRequestDto.cs b/src/EoaServer.Application.Contracts/UserAssets/Request/SearchUserAssetsRequestDto.cs new file mode 100644 index 0000000..db85b06 --- /dev/null +++ b/src/EoaServer.Application.Contracts/UserAssets/Request/SearchUserAssetsRequestDto.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace EoaServer.UserAssets; + +public class SearchUserAssetsRequestDto : GetAssetsBase +{ + [MaxLength(100)] public string Keyword { get; set; } + + public int Width { get; set; } + + public int Height { get; set; } +} \ No newline at end of file diff --git a/src/EoaServer.Application/EoaServerApplicationAutoMapperProfile.cs b/src/EoaServer.Application/EoaServerApplicationAutoMapperProfile.cs index 4ec31e3..0b560c9 100644 --- a/src/EoaServer.Application/EoaServerApplicationAutoMapperProfile.cs +++ b/src/EoaServer.Application/EoaServerApplicationAutoMapperProfile.cs @@ -7,6 +7,8 @@ using EoaServer.Search.Dto; using EoaServer.Token.Eto; using EoaServer.Transfer.Dtos; +using EoaServer.UserAssets.Dto; +using EoaServer.UserAssets.Dtos; namespace EoaServer; @@ -21,6 +23,8 @@ public EoaServerApplicationAutoMapperProfile() CreateMap(); CreateMap(); CreateMap(); + CreateMap(); + CreateMap(); CreateMap().ForMember(des => des.ClientId, opt => opt.MapFrom(f => ETransferConstant.ClientId)) .ForMember(des => des.GrantType, diff --git a/src/EoaServer.Application/UserActivity/UserActivityAppService.cs b/src/EoaServer.Application/UserActivity/UserActivityAppService.cs index c377436..b584c0e 100644 --- a/src/EoaServer.Application/UserActivity/UserActivityAppService.cs +++ b/src/EoaServer.Application/UserActivity/UserActivityAppService.cs @@ -119,13 +119,6 @@ public async Task GetActivitiesAsync(GetActivitiesRequestDto r var txns = new IndexerTransactionListResultDto(); var tokenTransfers = new IndexerTokenTransferListDto(); - var txnsTask = _graphqlProvider.GetTransactionsAsync(new TransactionsRequestDto() - { - ChainId = chainId, - Address = address, - SkipCount = 0, - MaxResultCount = request.SkipCount + request.MaxResultCount - }); var tokenTransfersTask = _graphqlProvider.GetTokenTransferInfoAsync(new GetTokenTransferRequestDto() { Address = address, @@ -135,10 +128,25 @@ public async Task GetActivitiesAsync(GetActivitiesRequestDto r Symbol = request.Symbol }); - await Task.WhenAll(txnsTask, tokenTransfersTask); + if (!request.Symbol.IsNullOrWhiteSpace()) + { + tokenTransfers = await tokenTransfersTask; + } + else + { + var txnsTask = _graphqlProvider.GetTransactionsAsync(new TransactionsRequestDto() + { + ChainId = chainId, + Address = address, + SkipCount = 0, + MaxResultCount = request.SkipCount + request.MaxResultCount + }); + await Task.WhenAll(txnsTask, tokenTransfersTask); + + txns = await txnsTask; + tokenTransfers = await tokenTransfersTask; + } - txns = await txnsTask; - tokenTransfers = await tokenTransfersTask; var transactions = MergeTxns(txns, tokenTransfers); transactions = transactions.OrderByDescending(item => item.Timestamp) diff --git a/src/EoaServer.Application/UserAssets/UserAssetsAppService.cs b/src/EoaServer.Application/UserAssets/UserAssetsAppService.cs index f29fe56..700551e 100644 --- a/src/EoaServer.Application/UserAssets/UserAssetsAppService.cs +++ b/src/EoaServer.Application/UserAssets/UserAssetsAppService.cs @@ -9,6 +9,7 @@ using EoaServer.Token; using EoaServer.Token.Dto; using EoaServer.UserAssets; +using EoaServer.UserAssets.Dto; using EoaServer.UserAssets.Dtos; using EoaServer.UserAssets.Provider; using EoaServer.UserToken; @@ -75,8 +76,13 @@ public UserAssetsAppService( _tokenInfoOptions = tokenInfoOptions.Value; _nftToFtOptions = nftToFtOptions.Value; } - + public async Task GetTokenAsync(GetTokenRequestDto requestDto) + { + return await GetTokenAsync(requestDto, true); + } + + public async Task GetTokenAsync(GetAssetsBase requestDto, bool addDefaultToken) { var tokenList = new GetAddressTokenListResultDto(); foreach (var addressInfo in requestDto.AddressInfos) @@ -101,7 +107,10 @@ public async Task GetTokenAsync(GetTokenRequestDto requestDto) chainToken.Quantity = (long) ((double) chainToken.Quantity * Math.Pow(10, tokenInfoDto.Decimals)); } - AddDefaultTokens(tokenList); + if (addDefaultToken) + { + AddDefaultTokens(tokenList); + } var result = await ConvertDtoAsync(tokenList, requestDto); result.Data = SortTokens(result.Data); @@ -475,7 +484,7 @@ private static void DealWithDisplayChainImage(GetNftCollectionsDto dto) } } - private async Task ConvertDtoAsync(GetAddressTokenListResultDto fromDto, GetTokenRequestDto requestDto) + private async Task ConvertDtoAsync(GetAddressTokenListResultDto fromDto, GetAssetsBase requestDto) { var result = new GetTokenDto() { @@ -742,4 +751,75 @@ public async Task ListAwakenSupportedTokensAsync(i return tokens; } } + + public async Task SearchUserAssetsAsync(SearchUserAssetsRequestDto requestDto) + { + var result = new SearchUserAssetsV2Dto(); + var getTokenDto = await GetTokenAsync(requestDto, false); + foreach (var tokenInfo in getTokenDto.Data) + { + if (!requestDto.Keyword.IsNullOrWhiteSpace() && !tokenInfo.Symbol.Contains(requestDto.Keyword)) + { + continue; + } + var tokenInfoDtoList = ObjectMapper.Map, List>(tokenInfo.Tokens); + result.TokenInfos.AddRange(tokenInfoDtoList); + } + result.TokenInfos.ForEach(t => t.Address = requestDto.AddressInfos[0].Address); + + + var collectionDto = await GetNFTCollectionsAsync(new GetNftCollectionsRequestDto() + { + SkipCount = requestDto.SkipCount, + MaxResultCount = requestDto.MaxResultCount, + AddressInfos = requestDto.AddressInfos, + Height = requestDto.Height, + Width = requestDto.Width + }); + var nftItemsTask = collectionDto.Data.Select(t => GetNFTItemsAsync(new GetNftItemsRequestDto() + { + SkipCount = requestDto.SkipCount, + MaxResultCount = requestDto.MaxResultCount, + AddressInfos = requestDto.AddressInfos, + Height = requestDto.Height, + Width = requestDto.Width, + Symbol = t.Symbol + })); + var nftItemsDtoList = await Task.WhenAll(nftItemsTask); + var nftItemsMap = nftItemsDtoList.ToDictionary(t => t.Data[0].CollectionSymbol, t => t); + foreach (var collection in collectionDto.Data) + { + var collectionInfo = new NftCollectionDto(); + collectionInfo.CollectionName = collection.CollectionName; + collectionInfo.ImageUrl = collection.ImageUrl; + if (!nftItemsMap.TryGetValue(collection.Symbol, out var nftItems) || nftItems.Data.IsNullOrEmpty()) + { + continue; + } + foreach (var nftItem in nftItems.Data) + { + if (!requestDto.Keyword.IsNullOrWhiteSpace() && !nftItem.Symbol.Contains(requestDto.Keyword)) + { + continue; + } + var nftItemInfo = ObjectMapper.Map(nftItem); + nftItemInfo.CollectionName = collection.CollectionName; + var nftToFtInfo = _nftToFtOptions.NftToFtInfos.GetOrDefault(nftItem.Symbol); + if (nftToFtInfo != null) + { + nftItemInfo.Label = nftToFtInfo.Label; + nftItemInfo.ImageUrl = nftToFtInfo.ImageUrl; + } + collectionInfo.Items.Add(nftItemInfo); + } + + if (collectionInfo.Items.Count > 0) + { + result.NftInfos.Add(collectionInfo); + } + } + + result.TotalRecordCount = result.TokenInfos.Count + result.NftInfos.Sum(t => t.Items.Count); + return result; + } } \ No newline at end of file diff --git a/src/EoaServer.HttpApi/Controllers/UserAssetsController.cs b/src/EoaServer.HttpApi/Controllers/UserAssetsController.cs index eecf237..22b74c9 100644 --- a/src/EoaServer.HttpApi/Controllers/UserAssetsController.cs +++ b/src/EoaServer.HttpApi/Controllers/UserAssetsController.cs @@ -2,9 +2,10 @@ using System.Threading.Tasks; using Asp.Versioning; using EoaServer.Awaken; +using EoaServer.Commons; using EoaServer.UserAssets; +using EoaServer.UserAssets.Dto; using EoaServer.UserAssets.Dtos; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Volo.Abp; @@ -54,4 +55,10 @@ public async Task ListAwakenSupportedTokensAsync(i page = page <= 1 ? 1 : page; return await _userAssetsAppService.ListAwakenSupportedTokensAsync(skipCount, maxResultCount, page, chainId, address); } + + [HttpPost("searchUserAssets")] + public async Task SearchUserAssetsAsync(SearchUserAssetsRequestDto requestDto) + { + return await _userAssetsAppService.SearchUserAssetsAsync(requestDto); + } } \ No newline at end of file