diff --git a/src/aoWebWallet/Models/AoProcessInfo.cs b/src/aoWebWallet/Models/AoProcessInfo.cs new file mode 100644 index 0000000..ce9ed6c --- /dev/null +++ b/src/aoWebWallet/Models/AoProcessInfo.cs @@ -0,0 +1,9 @@ +namespace aoWebWallet.Models +{ + public class AoProcessInfo + { + public required string Id { get; set; } + public required string Name { get; set; } + public string? Version { get; set; } + } +} diff --git a/src/aoWebWallet/Pages/WalletDetail.razor b/src/aoWebWallet/Pages/WalletDetail.razor index 286052e..4707843 100644 --- a/src/aoWebWallet/Pages/WalletDetail.razor +++ b/src/aoWebWallet/Pages/WalletDetail.razor @@ -36,7 +36,7 @@ - @if(BindingContext.SelectedWallet?.Source == WalletTypes.Explorer) + @if (BindingContext.SelectedWallet?.Source == WalletTypes.Explorer) { @@ -69,7 +69,7 @@ Claim Reward (1/3) } - if(BindingContext.UserSettings.Claimed2) + if (BindingContext.UserSettings.Claimed2) { } @@ -88,8 +88,8 @@ } -@* - + @* + *@ @@ -147,31 +147,64 @@ + + + - - - - + + @if (BindingContext.TokenTransferList.Data != null) + { + + Transactions + + + + + - - + + @foreach (var transfer in BindingContext.TokenTransferList.Data) + { + + } + + + } + + + - - @if (BindingContext.TokenTransferList.Data != null) + @{ + var processes = BindingContext.ProcessesDataList?.Data?.Where(x => x.Data?.Address == BindingContext.SelectedAddress).FirstOrDefault(); + } + @if (processes?.Data?.Processes.Any() ?? false) { - Transactions + + + AOS + List of owned AOS processes - - @foreach (var transfer in BindingContext.TokenTransferList.Data) - { - - } - + + @foreach (var process in processes.Data.Processes) + { + var linkUrl = $"/wallet/{process.Id}"; + + @process.Name + + @process.Id.ToShortAddress() + + } + + + + + } - + + @@ -208,7 +241,7 @@ private async Task RefreshTransactions() { - if(BindingContext.SelectedAddress != null) + if (BindingContext.SelectedAddress != null) await BindingContext.LoadTokenTransferList(BindingContext.SelectedAddress); } diff --git a/src/aoWebWallet/Pages/Wallets.razor b/src/aoWebWallet/Pages/Wallets.razor index c9502f7..5b66410 100644 --- a/src/aoWebWallet/Pages/Wallets.razor +++ b/src/aoWebWallet/Pages/Wallets.razor @@ -68,6 +68,10 @@ + @if(BindingContext.ProcessesDataList?.Data?.Where(x => x.Data?.Address == wallet.Address && (x.Data?.Processes?.Any() ?? false)).Any() ?? false) + { + AOS + } @if(!string.IsNullOrEmpty(wallet.Jwk)) { diff --git a/src/aoWebWallet/Pages/Wallets.razor.cs b/src/aoWebWallet/Pages/Wallets.razor.cs index b3997e9..17980e8 100644 --- a/src/aoWebWallet/Pages/Wallets.razor.cs +++ b/src/aoWebWallet/Pages/Wallets.razor.cs @@ -8,6 +8,7 @@ protected override void OnInitialized() { WatchDataLoaderVM(BindingContext.TokenList); WatchDataLoaderVM(BindingContext.WalletList); + WatchDataLoaderVM(BindingContext.ProcessesDataList); base.OnInitialized(); } diff --git a/src/aoWebWallet/Services/GraphqlClient.cs b/src/aoWebWallet/Services/GraphqlClient.cs index 8a82d48..1a48a1e 100644 --- a/src/aoWebWallet/Services/GraphqlClient.cs +++ b/src/aoWebWallet/Services/GraphqlClient.cs @@ -70,6 +70,27 @@ public async Task> GetTransactionsIn(string adddress, string return transaction; } + private static AoProcessInfo? GetAoProcessInfo(Edge edge) + { + if (edge == null || edge.Node == null) + return null; + + + var name = edge.Node.Tags.Where(x => x.Name == "Name").Select(x => x.Value).FirstOrDefault(); + if (string.IsNullOrEmpty(name)) + return null; + + var processInfo = new AoProcessInfo() + { + Id = edge.Node.Id, + Name = name, + }; + + processInfo.Version = edge.Node.Tags.Where(x => x.Name == "Version").Select(x => x.Value).FirstOrDefault(); + + return processInfo; + } + public async Task> GetTransactionsOut(string adddress, string? fromTxId = null) { string query = "query {\r\n transactions(\r\n first: 100\r\n sort: HEIGHT_DESC\r\n owners: [\"" + adddress + "\"]\r\n tags: [\r\n { name: \"Data-Protocol\", values: [\"ao\"] }\r\n { name: \"Action\", values: [\"Transfer\"] }\r\n ]\r\n ) {\r\n edges {\r\n node {\r\n id\r\n recipient\r\n owner {\r\n address\r\n }\r\n block {\r\n timestamp\r\n height\r\n }\r\n tags {\r\n name\r\n value\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"; @@ -124,6 +145,24 @@ public async Task> GetTransactionsForToken(string tokenId, s return result; } + public async Task> GetAoProcessesForAddress(string address) + { + string query = "query {\r\n transactions(\r\n first: 100,\r\n owners: [\"" + address + "\"],\r\n tags: [\r\n { name: \"Data-Protocol\", values: [\"ao\"] },\r\n { name: \"Type\", values: [\"Process\"]},\r\n { name: \"App-Name\", values: [\"aos\"]},\r\n \r\n ]\r\n ) {\r\n edges {\r\n node {\r\n id\r\n tags {\r\n name\r\n value\r\n }\r\n }\r\n }\r\n }\r\n }"; + var queryResult = await PostQueryAsync(query); + + var result = new List(); + + foreach (var edge in queryResult?.Data?.Transactions?.Edges ?? new()) + { + AoProcessInfo? processInfo = GetAoProcessInfo(edge); + + if (processInfo != null) + result.Add(processInfo); + } + + return result; + } + //public async Task GetTransactionsForToken(string tokenId, string fromTxId) //{ diff --git a/src/aoWebWallet/ViewModels/MainViewModel.cs b/src/aoWebWallet/ViewModels/MainViewModel.cs index d79bc96..725f780 100644 --- a/src/aoWebWallet/ViewModels/MainViewModel.cs +++ b/src/aoWebWallet/ViewModels/MainViewModel.cs @@ -8,6 +8,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using MudBlazor; +using System.Net; using webvNext.DataLoader; using webvNext.DataLoader.Cache; @@ -73,6 +74,8 @@ public partial class MainViewModel : ObservableRecipient public DataLoaderViewModel> WalletList { get; set; } = new(); public DataLoaderViewModel> TokenTransferList { get; set; } = new(); public DataLoaderViewModel SelectedTransaction { get; set; } = new(); + public DataLoaderViewModel>> ProcessesDataList { get; set; } = new(); + //TODO: //Actions List (optional? address) @@ -208,6 +211,36 @@ public Task LoadBalanceDataList(string address) => BalanceDataList.DataLoader.Lo }); + public Task LoadProcessesDataList() => ProcessesDataList.DataLoader.LoadAsync(async () => + { + ProcessesDataList.Data = null; + + var result = new List>(); + + foreach (var wallet in WalletList.Data ?? new()) + { + var address = wallet.Address; + var processData = new DataLoaderViewModel(); + processData.Data = new WalletProcessDataViewModel { Address = address }; + + processData.DataLoader.LoadAsync(() => + { + return memoryDataCache!.GetAsync($"{nameof(LoadProcessesDataList)}-{address}", async () => + { + var data = await graphqlClient.GetAoProcessesForAddress(address); + return new WalletProcessDataViewModel() { Address = address, Processes = data }; + }, TimeSpan.FromMinutes(1)); + + + }, (x) => { processData.Data = x; ProcessesDataList.ForcePropertyChanged(); }); + result.Add(processData); + } + + ProcessesDataList.Data = result; + + return result; + + }); public async Task LoadWalletList(bool force = false) @@ -216,6 +249,8 @@ public async Task LoadWalletList(bool force = false) { var list = await storageService.GetWallets(); WalletList.Data = list; + + await LoadProcessesDataList(); } } diff --git a/src/aoWebWallet/ViewModels/WalletProcessDataViewModel.cs b/src/aoWebWallet/ViewModels/WalletProcessDataViewModel.cs new file mode 100644 index 0000000..677b1d0 --- /dev/null +++ b/src/aoWebWallet/ViewModels/WalletProcessDataViewModel.cs @@ -0,0 +1,12 @@ +using aoWebWallet.Models; +using ArweaveAO.Models.Token; + +namespace aoWebWallet.ViewModels +{ + public class WalletProcessDataViewModel + { + public required string Address { get; set; } + + public List Processes { get; set; } = new(); + } +}