Skip to content

Commit

Permalink
Refactored GraphQL query to also show Astro USDA transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
michielpost committed Jul 11, 2024
1 parent 77f1272 commit 1b83596
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 84 deletions.
2 changes: 1 addition & 1 deletion src/aoWebWallet/ViewModels/ReceiveViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public Task LoadTokenTransferList() => TokenTransferList.DataLoader.LoadAsync(as
{
var address = Address;
var incoming = await graphqlClient.GetTokenTransfersIn(address);
var incoming = await graphqlClient.GetTokenTransfers(address);
incoming = incoming.Where(x => x.Timestamp > StartTime).OrderByDescending(x => x.Timestamp).ToList();
Expand Down
14 changes: 4 additions & 10 deletions src/aoWebWallet/ViewModels/WalletDetailViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ public partial class WalletDetailViewModel : ObservableObject
private readonly ISnackbar snackbar;
private readonly MemoryDataCache memoryDataCache;

private List<TokenTransfer> incoming = new();
private List<TokenTransfer> outgoing = new();
private List<TokenTransfer> outgoingProcess = new();
private List<TokenTransfer> allTransactions = new();


[ObservableProperty]
Expand Down Expand Up @@ -133,9 +131,7 @@ public async Task RefreshTokenTransferList()

private void ResetTokenTransferlist()
{
incoming = new();
outgoing = new();
outgoingProcess = new();
allTransactions = new();
TokenTransferList.Data = new();
}

Expand Down Expand Up @@ -225,11 +221,9 @@ private async Task SelectWallet(string? address)

public Task LoadTokenTransferList(string address) => TokenTransferList.DataLoader.LoadAsync(async () =>
{
incoming = await graphqlClient.GetTokenTransfersIn(address, GetCursor(incoming));
outgoing = await graphqlClient.GetTransactionsOut(address, GetCursor(outgoing));
outgoingProcess = await graphqlClient.GetTransactionsOutFromProcess(address, GetCursor(outgoingProcess));
allTransactions = await graphqlClient.GetTokenTransfers(address, GetCursor(allTransactions));
var allNew = incoming.Concat(outgoing).Concat(outgoingProcess).OrderByDescending(x => x.Timestamp).ToList();
var allNew = allTransactions.OrderByDescending(x => x.Timestamp).ToList();
CanLoadMoreTransactions = allNew.Any();
var existing = TokenTransferList.Data ?? new();
Expand Down
4 changes: 2 additions & 2 deletions src/aoww.Services.Tests/GraphqlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public async Task GetTransactionsTest()
{
var graph = new GraphqlClient(new HttpClient(), Options.Create<GraphqlConfig>(new()));

var result = await graph.GetTokenTransfersIn("4NdFkWsgFQIEmJnzFSYrO88UmRPf0ABfVh_fRc2u130");
var result = await graph.GetTokenTransfers("aGeRSnWykicBEGESPbTXPQ0_q2IiMLBBMyemu2pBYoA");

Assert.IsNotNull(result);
}
Expand All @@ -21,7 +21,7 @@ public async Task GetMintTest()
{
var graph = new GraphqlClient(new HttpClient(), Options.Create<GraphqlConfig>(new()));

var result = await graph.GetTokenTransfersIn("CeiYr2VjUVAFXmPJvfj-Pfk6zmprBzeqNeRWAbImbOo");
var result = await graph.GetTokenTransfers("CeiYr2VjUVAFXmPJvfj-Pfk6zmprBzeqNeRWAbImbOo");

Assert.IsNotNull(result);
}
Expand Down
21 changes: 21 additions & 0 deletions src/aoww.Services/Extensions/EdgeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using aoww.Services.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace aoww.Services.Extensions
{
public static class EdgeResultExtensions
{
public static string? GetFirstTagValue(this Edge edge, string tag)
{
if (edge == null || edge.Node == null)
return null;

return edge.Node.Tags.Where(x => x.Name == tag).Select(x => x.Value).FirstOrDefault();
}

}
}
196 changes: 125 additions & 71 deletions src/aoww.Services/GraphqlClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using aoww.Services.Models;
using aoww.Services.Extensions;
using aoww.Services.Models;
using Microsoft.Extensions.Options;
using System.Net.Http.Json;

Expand Down Expand Up @@ -69,18 +70,18 @@ public async Task<List<AoTransaction>> GetTransactionsIn(string address, string?
}


public async Task<List<TokenTransfer>> GetTokenTransfersIn(string address, string? cursor = null)
public async Task<List<TokenTransfer>> GetTokenTransfers(string address, string? cursor = null)
{
string query = $$"""
query {
transactions(
first: 50
after: "{{cursor}}"
sort: HEIGHT_DESC
recipients: ["{{address}}"]
tags: [
{ name: "Data-Protocol", values: ["ao"] }
{ name: "Action", values: ["Transfer", "Mint-Token"] }
{ name: "Recipient", values: ["{{address}}"] }
{ name: "Action", values: ["Credit-Notice", "Debit-Notice", "Mint", "Mint-Token"] }
]
) {
edges {
Expand Down Expand Up @@ -140,12 +141,12 @@ public async Task<List<TokenTransfer>> GetTokenTransfersIn(string address, strin
else
transaction.Timestamp = DateTimeOffset.UtcNow;

var fromProcess = edge.Node.Tags.Where(x => x.Name == "From-Process").Select(x => x.Value).FirstOrDefault();
var fromProcess = edge.GetFirstTagValue("From-Process");
if (!string.IsNullOrEmpty(fromProcess))
transaction.From = fromProcess;


transaction.To = edge.Node.Tags.Where(x => x.Name == "Recipient").Select(x => x.Value).FirstOrDefault();
transaction.To = edge.GetFirstTagValue("Recipient");

return transaction;
}
Expand All @@ -155,21 +156,92 @@ public async Task<List<TokenTransfer>> GetTokenTransfersIn(string address, strin
if (edge == null || edge.Node == null)
return null;

var isTransfer = edge.Node.Tags.Where(x => x.Name == "Action" && x.Value == "Transfer").Any();
var isMint = edge.Node.Tags.Where(x => x.Name == "Action" && x.Value == "Mint-Token").Any();
if (!isTransfer && !isMint)
var action = edge.GetFirstTagValue("Action");

if (action == "Transfer")
return GetTransferAction(edge);
if (action == "Mint")
return GetMintAction(edge);
if (action == "Credit-Notice")
return GetCreditNoticeAction(edge);
if (action == "Debit-Notice")
return GetDebitNoticeAction(edge);

return null;
}

private static TokenTransfer? GetCreditNoticeAction(Edge edge)
{
if (edge == null || edge.Node == null)
return null;

var transaction = new TokenTransfer()
{
Id = edge.Node.Id,
Cursor = edge.Cursor,
From = edge.Node.Owner?.Address ?? string.Empty,
TokenId = edge.GetFirstTagValue("From-Process") ?? string.Empty,
From = edge.GetFirstTagValue("Sender") ?? string.Empty,
To = edge.Node.Recipient ?? string.Empty,
TokenTransferType = Enums.TokenTransferType.Transfer
};

if (edge.Node.Block != null)
{
transaction.Timestamp = DateTimeOffset.FromUnixTimeSeconds(edge.Node.Block.Timestamp);
transaction.BlockHeight = edge.Node.Block.Height;
}
else
transaction.Timestamp = DateTimeOffset.UtcNow;

string? quantity = edge.GetFirstTagValue("Quantity");
if (!string.IsNullOrWhiteSpace(quantity) && long.TryParse(quantity, out long quantityLong))
transaction.Quantity = quantityLong;

return transaction;
}

private static TokenTransfer? GetDebitNoticeAction(Edge edge)
{
if (edge == null || edge.Node == null)
return null;

var transaction = new TokenTransfer()
{
Id = edge.Node.Id,
Cursor = edge.Cursor,
TokenId = edge.GetFirstTagValue("From-Process") ?? string.Empty,
From = edge.Node.Recipient ?? string.Empty,
To = edge.GetFirstTagValue("Recipient") ?? string.Empty,
TokenTransferType = Enums.TokenTransferType.Transfer
};

if (isMint)
transaction.TokenTransferType = Enums.TokenTransferType.Mint;
if (edge.Node.Block != null)
{
transaction.Timestamp = DateTimeOffset.FromUnixTimeSeconds(edge.Node.Block.Timestamp);
transaction.BlockHeight = edge.Node.Block.Height;
}
else
transaction.Timestamp = DateTimeOffset.UtcNow;

string? quantity = edge.GetFirstTagValue("Quantity");
if (!string.IsNullOrWhiteSpace(quantity) && long.TryParse(quantity, out long quantityLong))
transaction.Quantity = quantityLong;

return transaction;
}

private static TokenTransfer? GetMintAction(Edge edge)
{
if (edge == null || edge.Node == null)
return null;

var transaction = new TokenTransfer()
{
Id = edge.Node.Id,
Cursor = edge.Cursor,
From = edge.Node.Owner?.Address ?? string.Empty,
TokenTransferType = Enums.TokenTransferType.Mint
};


if (edge.Node.Block != null)
Expand All @@ -180,18 +252,51 @@ public async Task<List<TokenTransfer>> GetTokenTransfersIn(string address, strin
else
transaction.Timestamp = DateTimeOffset.UtcNow;

var fromProcess = edge.Node.Tags.Where(x => x.Name == "From-Process").Select(x => x.Value).FirstOrDefault();
var fromProcess = edge.GetFirstTagValue("From-Process");
if (!string.IsNullOrEmpty(fromProcess))
transaction.From = fromProcess;

if (isMint)
transaction.TokenId = edge.Node.Tags.Where(x => x.Name == "TokenId").Select(x => x.Value).FirstOrDefault();
transaction.TokenId = edge.GetFirstTagValue("TokenId");

transaction.To = edge.GetFirstTagValue("Recipient");

string? quantity = edge.GetFirstTagValue("Quantity");
if (!string.IsNullOrWhiteSpace(quantity) && long.TryParse(quantity, out long quantityLong))
transaction.Quantity = quantityLong;
return transaction;
}

private static TokenTransfer? GetTransferAction(Edge edge)
{
if (edge == null || edge.Node == null)
return null;

var transaction = new TokenTransfer()
{
Id = edge.Node.Id,
Cursor = edge.Cursor,
From = edge.Node.Owner?.Address ?? string.Empty,
TokenTransferType = Enums.TokenTransferType.Transfer
};


if (edge.Node.Block != null)
{
transaction.Timestamp = DateTimeOffset.FromUnixTimeSeconds(edge.Node.Block.Timestamp);
transaction.BlockHeight = edge.Node.Block.Height;
}
else
transaction.TokenId = edge.Node.Recipient;
transaction.Timestamp = DateTimeOffset.UtcNow;

var fromProcess = edge.GetFirstTagValue("From-Process");
if (!string.IsNullOrEmpty(fromProcess))
transaction.From = fromProcess;

transaction.TokenId = edge.Node.Recipient;

transaction.To = edge.Node.Tags.Where(x => x.Name == "Recipient").Select(x => x.Value).FirstOrDefault();
transaction.To = edge.GetFirstTagValue("Recipient");

string? quantity = edge.Node.Tags.Where(x => x.Name == "Quantity").Select(x => x.Value).FirstOrDefault();
string? quantity = edge.GetFirstTagValue("Quantity");
if (!string.IsNullOrWhiteSpace(quantity) && long.TryParse(quantity, out long quantityLong))
transaction.Quantity = quantityLong;
return transaction;
Expand All @@ -203,7 +308,7 @@ public async Task<List<TokenTransfer>> GetTokenTransfersIn(string address, strin
return null;


var name = edge.Node.Tags.Where(x => x.Name == "Name").Select(x => x.Value).FirstOrDefault();
var name = edge.GetFirstTagValue("Name");
if (string.IsNullOrEmpty(name))
return null;

Expand All @@ -214,61 +319,11 @@ public async Task<List<TokenTransfer>> GetTokenTransfersIn(string address, strin
Name = name,
};

processInfo.Version = edge.Node.Tags.Where(x => x.Name == "Version").Select(x => x.Value).FirstOrDefault();
processInfo.Version = edge.GetFirstTagValue("Version");

return processInfo;
}

public async Task<List<TokenTransfer>> GetTransactionsOut(string address, string? cursor = null)
{
string query = $$"""
query {
transactions(
first: 50
after: "{{cursor}}"
sort: HEIGHT_DESC
owners: ["{{address}}"]
tags: [
{ name: "Data-Protocol", values: ["ao"] }
{ name: "Action", values: ["Transfer"] }
]
) {
edges {
cursor
node {
id
recipient
owner {
address
}
block {
timestamp
height
}
tags {
name
value
}
}
}
}
}
""";
var queryResult = await PostQueryAsync(query);

var result = new List<TokenTransfer>();

foreach (var edge in queryResult?.Data?.Transactions?.Edges ?? new())
{
TokenTransfer? transaction = GetTokenTransfer(edge);

if (transaction != null)
result.Add(transaction);
}

return result;
}

public async Task<List<TokenTransfer>> GetTransactionsOutFromProcess(string address, string? cursor = null)
{
string query = $$"""
Expand Down Expand Up @@ -330,7 +385,6 @@ public async Task<List<TokenTransfer>> GetTransactionsOutFromProcess(string addr
ids: ["{{txId}}"]
tags: [
{ name: "Data-Protocol", values: ["ao"] }
{ name: "Action", values: ["Transfer"] }
]
) {
edges {
Expand Down

0 comments on commit 1b83596

Please sign in to comment.