Skip to content

Commit

Permalink
Add SponsoredTransaction and ANS examples
Browse files Browse the repository at this point in the history
  • Loading branch information
GhostWalker562 committed Sep 25, 2024
1 parent f481389 commit c528326
Show file tree
Hide file tree
Showing 23 changed files with 287 additions and 74 deletions.
20 changes: 20 additions & 0 deletions Aptos.Examples/AptosNamesExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Aptos.Examples;

public class AptosNamesExample
{
public static async Task Run()
{
var aptos = new AptosClient(Networks.Mainnet);

Console.WriteLine("=== Aptos Names Example ===\n");

var aptosName = "aaron.apt";
var nameAddress = "0xa746e980ae21949a4f084db7403430f00bce3c9a1da4101ffcf0bf45ebd35e7e";

var address = await aptos.Ans.GetAnsAddress(aptosName);
var name = await aptos.Ans.GetAnsName(nameAddress);

Console.WriteLine($"Address for {aptosName}: {address}");
Console.WriteLine($"Aptos name for {nameAddress}: {name}");
}
}
74 changes: 40 additions & 34 deletions Aptos.Examples/Main.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,74 @@
using System.Text.RegularExpressions;

namespace Aptos.Examples;

public class RunExample
{
private static readonly Dictionary<string, Func<Task>> exampleMap =
new()
{
{ "1", KeylessTransferExample.Run },
{ "2", SimpleTransferExample.Run },
{ "3", SimpleTransferSingleKeyExample.Run },
{ "4", SimpleTransferMultiKeyExample.Run },
{ "5", PlaygroundExample.Run },
};
private static readonly Func<Task>[] exampleArray =
{
SimpleTransferKeylessExample.Run,
SimpleTransferEd25519Example.Run,
SimpleTransferSingleKeyExample.Run,
SimpleTransferMultiKeyExample.Run,
SponsoredTransferEd25519Example.Run,
SimulateTransferEd25519Example.Run,
AptosNamesExample.Run,
PlaygroundExample.Run,
};

public static async Task Main()
{
DisplayAsciiArt();
int selectedIndex = 0;
string[] keys = new string[exampleMap.Count];
exampleMap.Keys.CopyTo(keys, 0);

string errorMessage = string.Empty;

while (true)
{
DisplayMenu(keys, selectedIndex, errorMessage);
DisplayMenu(selectedIndex, errorMessage);

ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true);

if (keyInfo.Key == ConsoleKey.UpArrow)
{
selectedIndex = (selectedIndex == 0) ? keys.Length - 1 : selectedIndex - 1;
selectedIndex = (selectedIndex == 0) ? exampleArray.Length - 1 : selectedIndex - 1;
errorMessage = string.Empty; // Clear error on valid navigation
}
else if (keyInfo.Key == ConsoleKey.DownArrow)
{
selectedIndex = (selectedIndex == keys.Length - 1) ? 0 : selectedIndex + 1;
selectedIndex = (selectedIndex == exampleArray.Length - 1) ? 0 : selectedIndex + 1;
errorMessage = string.Empty; // Clear error on valid navigation
}
else if (keyInfo.Key == ConsoleKey.Enter)
{
// Run the selected example using arrow keys and enter
if (exampleMap.TryGetValue(keys[selectedIndex], out var selectedExample))
{
Console.WriteLine(
$"\nThe {exampleMap[keys[selectedIndex]].Method.DeclaringType.Name} example was selected...\n"
);
await selectedExample();
}
var selectedExample = exampleArray[selectedIndex];
Console.WriteLine(
$"\nThe {selectedExample.Method.DeclaringType.Name} example was selected...\n"
);
await selectedExample();
break;
}
else if (char.IsDigit(keyInfo.KeyChar))
{
// Check if the typed number is valid
string input = keyInfo.KeyChar.ToString();
if (exampleMap.TryGetValue(input, out var selectedExample))
// Check if the typed number is valid and within the array range
if (
int.TryParse(keyInfo.KeyChar.ToString(), out int inputIndex)
&& inputIndex > 0
&& inputIndex <= exampleArray.Length
)
{
var selectedExample = exampleArray[inputIndex - 1];
Console.WriteLine(
$"\nThe {exampleMap[keys[selectedIndex]].Method.DeclaringType.Name} example was selected...\n"
$"\nThe {selectedExample.Method.DeclaringType.Name} example was selected...\n"
);
await selectedExample();
break;
}
else
{
errorMessage = $"Invalid number '{input}'. Please choose a valid example.";
errorMessage =
$"Invalid number '{keyInfo.KeyChar}'. Please choose a valid example.";
}
}
else
Expand All @@ -74,29 +79,30 @@ public static async Task Main()
}
}

private static void DisplayMenu(string[] keys, int selectedIndex, string errorMessage)
private static void DisplayMenu(int selectedIndex, string errorMessage)
{
Console.Clear();
DisplayAsciiArt();

Console.WriteLine(
"Use arrow keys to navigate and press Enter or type a number to choose an example:"
);
for (int i = 0; i < keys.Length; i++)
for (int i = 0; i < exampleArray.Length; i++)
{
var name = Regex.Replace(
exampleArray[i].Method.DeclaringType?.Name,
"(?<!^)([A-Z])",
" $1"
);
if (i == selectedIndex)
{
Console.ForegroundColor = ConsoleColor.Yellow; // Highlight the selected option
Console.WriteLine(
$"> {keys[i]}. {exampleMap[keys[i]].Method.DeclaringType?.Name} Example"
);
Console.WriteLine($"> {i + 1}. {name}");
Console.ResetColor();
}
else
{
Console.WriteLine(
$" {keys[i]}. {exampleMap[keys[i]].Method.DeclaringType?.Name} Example"
);
Console.WriteLine($" {i + 1}. {name}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Aptos.Examples;

public class SimpleTransferExample
public class SimpleTransferEd25519Example
{
public static async Task Run()
{
Expand All @@ -20,7 +20,7 @@ public static async Task Run()
var txn = await aptos.Transaction.Build(
sender: account.Address,
data: new GenerateEntryFunctionPayloadData(
function: "0x1::coin::transfer",
function: "0x1::aptos_account::transfer_coins",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [account.Address, "100000"]
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Aptos.Examples;

public class KeylessTransferExample
public class SimpleTransferKeylessExample
{
public static async Task Run()
{
Expand Down Expand Up @@ -56,7 +56,7 @@ public static async Task Run()
var txn = await aptos.Transaction.Build(
sender: keylessAccount,
data: new GenerateEntryFunctionPayloadData(
function: "0x1::coin::transfer",
function: "0x1::aptos_account::transfer_coins",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [bob.Address, "100000"]
)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static async Task Run()
var txn = await aptos.Transaction.Build(
sender: account.Address,
data: new GenerateEntryFunctionPayloadData(
function: "0x1::coin::transfer",
function: "0x1::aptos_account::transfer_coins",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [account.Address, "100000"]
)
Expand Down
40 changes: 40 additions & 0 deletions Aptos.Examples/SimulateTransferEd25519Example.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Newtonsoft.Json;

namespace Aptos;

public class SimulateTransferEd25519Example
{
public static async Task Run()
{
var aptos = new AptosClient(new AptosConfig(Networks.Devnet));

Console.WriteLine("=== Addresses ===\n");

var alice = Ed25519Account.Generate();
Console.WriteLine($"Alice: {alice.Address}");

Console.WriteLine("\n=== Funding accounts ===\n");

var aliceFundTxn = await aptos.Faucet.FundAccount(alice.Address, 100_000_000);
Console.WriteLine($"Alice's fund transaction: {aliceFundTxn.Hash}");

Console.WriteLine("\n=== Building transaction ===\n");

var txn = await aptos.Transaction.Build(
sender: alice.Address,
data: new GenerateEntryFunctionPayloadData(
function: "0x1::aptos_account::transfer_coins",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [alice.Address, "100000"]
)
);
Console.WriteLine($"{JsonConvert.SerializeObject(txn)}");

Console.WriteLine("\n=== Simulating transaction ===\n");

var simulatedTxn = await aptos.Transaction.Simulate(new(txn, alice.PublicKey));
Console.WriteLine(
$"Simulated Transaction: {JsonConvert.SerializeObject(simulatedTxn, Formatting.Indented)}"
);
}
}
69 changes: 69 additions & 0 deletions Aptos.Examples/SponsoredTransferEd25519Example.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Newtonsoft.Json;

namespace Aptos.Examples;

public class SponsoredTransferEd25519Example
{
public static async Task Run()
{
var aptos = new AptosClient(new AptosConfig(Networks.Devnet));

Console.WriteLine("=== Addresses ===\n");

var alice = Ed25519Account.Generate();
var receiver = Ed25519Account.Generate();
var feePayer = Ed25519Account.Generate();
Console.WriteLine($"Alice: {alice.Address}");
Console.WriteLine($"Receiver: {receiver.Address}");
Console.WriteLine($"FeePayer: {feePayer.Address}");

Console.WriteLine("\n=== Funding accounts ===\n");

var aliceFundTxn = await aptos.Faucet.FundAccount(alice.Address, 100_000_000);
var feePayerFundTxn = await aptos.Faucet.FundAccount(feePayer.Address, 100_000_000);
Console.WriteLine($"Alice's fund transaction: {aliceFundTxn.Hash}");
Console.WriteLine($"FeePayer's fund transaction: {feePayerFundTxn.Hash}");

Console.WriteLine("\n=== Building transaction ===\n");

var txn = await aptos.Transaction.Build(
sender: alice.Address,
data: new GenerateEntryFunctionPayloadData(
function: "0x1::aptos_account::transfer_coins",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [receiver.Address, "100000"]
),
// It's important to set this flag to true to enable sponsored transactions
withFeePayer: true
);
Console.WriteLine($"{JsonConvert.SerializeObject(txn)}");

Console.WriteLine("\n=== Signing and submitting transaction ===\n");

var aliceSignature = alice.SignWithAuthenticator(txn);
Console.WriteLine($"Alice has signed the transaction: {aliceSignature.BcsToHex()}");

var feePayerSignature = aptos.Transaction.SignAsFeePayer(feePayer, txn);
Console.WriteLine($"FeePayer has signed the transaction: {feePayerSignature.BcsToHex()}");

var pendingTxn = await aptos.Transaction.SubmitTransaction(
new(txn, aliceSignature, feePayerSignature)
);
Console.WriteLine($"Submitted transaction with hash: {pendingTxn.Hash}");

Console.WriteLine("Waiting for transaction...");
var committedTxn = await aptos.Transaction.WaitForTransaction(pendingTxn.Hash.ToString());
Console.WriteLine(
$"Transaction {committedTxn.Hash} is {(committedTxn.Success ? "success" : "failure")}"
);

Console.WriteLine("\n=== Account Balance ===\n");

var aliceBalance = await aptos.Account.GetCoinBalance(alice.Address);
var feePayerBalance = await aptos.Account.GetCoinBalance(feePayer.Address);
var receiverBalance = await aptos.Account.GetCoinBalance(receiver.Address);
Console.WriteLine($"Alice {alice.Address} has {aliceBalance?.Amount ?? 0} APT");
Console.WriteLine($"Receiver {receiver.Address} has {receiverBalance?.Amount ?? 0} APT");
Console.WriteLine($"FeePayer {feePayer.Address} has {feePayerBalance?.Amount ?? 0} APT");
}
}
12 changes: 1 addition & 11 deletions Aptos.Indexer/.graphqlrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,7 @@
"name": "AptosIndexerClient",
"url": "https://api.mainnet.aptoslabs.com/v1/graphql",
"namespace": "Aptos.Indexer.GraphQL",
"dependencyInjection": false,
"records": {
"inputs": false,
"entities": false
},
"transportProfiles": [
{
"default": "Http",
"subscription": "WebSocket"
}
]
"dependencyInjection": true
}
}
}
27 changes: 27 additions & 0 deletions Aptos.Indexer/GetNames.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
fragment AptosNameData on current_aptos_names {
domain
expiration_timestamp
registered_address
subdomain
token_standard
is_primary
owner_address
subdomain_expiration_policy
domain_expiration_timestamp
}

query GetNames(
$offset: Int
$limit: Int
$where: current_aptos_names_bool_exp
$order_by: [current_aptos_names_order_by!]
) {
current_aptos_names(
limit: $limit
where: $where
order_by: $order_by
offset: $offset
) {
...AptosNameData
}
}
4 changes: 3 additions & 1 deletion Aptos/Aptos.Api/TransactionPayloadResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public abstract class TransactionPayloadResponse(string type)

public class TransactionPayloadResponseConverter : JsonConverter<TransactionPayloadResponse>
{
public override bool CanWrite => false;

static readonly JsonSerializerSettings SpecifiedSubclassConversion =
new()
{
Expand Down Expand Up @@ -56,7 +58,7 @@ public override void WriteJson(
JsonWriter writer,
TransactionPayloadResponse? value,
JsonSerializer serializer
) => serializer.Serialize(writer, value);
) => throw new NotImplementedException();
}

public class EntryFunctionPayloadResponse(
Expand Down
Loading

0 comments on commit c528326

Please sign in to comment.