diff --git a/Aptos.Examples/AptosNamesExample.cs b/Aptos.Examples/AptosNamesExample.cs new file mode 100644 index 0000000..b54012a --- /dev/null +++ b/Aptos.Examples/AptosNamesExample.cs @@ -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}"); + } +} diff --git a/Aptos.Examples/Main.cs b/Aptos.Examples/Main.cs index cc34e16..73a933f 100644 --- a/Aptos.Examples/Main.cs +++ b/Aptos.Examples/Main.cs @@ -1,69 +1,74 @@ +using System.Text.RegularExpressions; + namespace Aptos.Examples; public class RunExample { - private static readonly Dictionary> exampleMap = - new() - { - { "1", KeylessTransferExample.Run }, - { "2", SimpleTransferExample.Run }, - { "3", SimpleTransferSingleKeyExample.Run }, - { "4", SimpleTransferMultiKeyExample.Run }, - { "5", PlaygroundExample.Run }, - }; + private static readonly Func[] 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 @@ -74,7 +79,7 @@ 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(); @@ -82,21 +87,22 @@ private static void DisplayMenu(string[] keys, int selectedIndex, string errorMe 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, + "(? {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}"); } } diff --git a/Aptos.Examples/SimpleTransfer.cs b/Aptos.Examples/SimpleTransferEd25519Example.cs similarity index 92% rename from Aptos.Examples/SimpleTransfer.cs rename to Aptos.Examples/SimpleTransferEd25519Example.cs index 4f9572c..9253c88 100644 --- a/Aptos.Examples/SimpleTransfer.cs +++ b/Aptos.Examples/SimpleTransferEd25519Example.cs @@ -2,7 +2,7 @@ namespace Aptos.Examples; -public class SimpleTransferExample +public class SimpleTransferEd25519Example { public static async Task Run() { @@ -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"] ) diff --git a/Aptos.Examples/KeylessTransfer.cs b/Aptos.Examples/SimpleTransferKeylessExample.cs similarity index 97% rename from Aptos.Examples/KeylessTransfer.cs rename to Aptos.Examples/SimpleTransferKeylessExample.cs index fec4891..1b0e77a 100644 --- a/Aptos.Examples/KeylessTransfer.cs +++ b/Aptos.Examples/SimpleTransferKeylessExample.cs @@ -1,6 +1,6 @@ namespace Aptos.Examples; -public class KeylessTransferExample +public class SimpleTransferKeylessExample { public static async Task Run() { @@ -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"] ) diff --git a/Aptos.Examples/SimpleTransferMultiKey.cs b/Aptos.Examples/SimpleTransferMultiKeyExample.cs similarity index 100% rename from Aptos.Examples/SimpleTransferMultiKey.cs rename to Aptos.Examples/SimpleTransferMultiKeyExample.cs diff --git a/Aptos.Examples/SimpleTransferSingleKey.cs b/Aptos.Examples/SimpleTransferSingleKeyExample.cs similarity index 96% rename from Aptos.Examples/SimpleTransferSingleKey.cs rename to Aptos.Examples/SimpleTransferSingleKeyExample.cs index 4bad861..590382d 100644 --- a/Aptos.Examples/SimpleTransferSingleKey.cs +++ b/Aptos.Examples/SimpleTransferSingleKeyExample.cs @@ -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"] ) diff --git a/Aptos.Examples/SimulateTransferEd25519Example.cs b/Aptos.Examples/SimulateTransferEd25519Example.cs new file mode 100644 index 0000000..06aa41d --- /dev/null +++ b/Aptos.Examples/SimulateTransferEd25519Example.cs @@ -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)}" + ); + } +} diff --git a/Aptos.Examples/SponsoredTransferEd25519Example.cs b/Aptos.Examples/SponsoredTransferEd25519Example.cs new file mode 100644 index 0000000..453eb11 --- /dev/null +++ b/Aptos.Examples/SponsoredTransferEd25519Example.cs @@ -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"); + } +} diff --git a/Aptos.Indexer/.graphqlrc.json b/Aptos.Indexer/.graphqlrc.json index 55dee6f..ef1b5da 100644 --- a/Aptos.Indexer/.graphqlrc.json +++ b/Aptos.Indexer/.graphqlrc.json @@ -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 } } } diff --git a/Aptos.Indexer/GetNames.graphql b/Aptos.Indexer/GetNames.graphql new file mode 100644 index 0000000..db970c8 --- /dev/null +++ b/Aptos.Indexer/GetNames.graphql @@ -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 + } +} diff --git a/Aptos/Aptos.Api/TransactionPayloadResponse.cs b/Aptos/Aptos.Api/TransactionPayloadResponse.cs index a22c88a..9a739f5 100644 --- a/Aptos/Aptos.Api/TransactionPayloadResponse.cs +++ b/Aptos/Aptos.Api/TransactionPayloadResponse.cs @@ -12,6 +12,8 @@ public abstract class TransactionPayloadResponse(string type) public class TransactionPayloadResponseConverter : JsonConverter { + public override bool CanWrite => false; + static readonly JsonSerializerSettings SpecifiedSubclassConversion = new() { @@ -56,7 +58,7 @@ public override void WriteJson( JsonWriter writer, TransactionPayloadResponse? value, JsonSerializer serializer - ) => serializer.Serialize(writer, value); + ) => throw new NotImplementedException(); } public class EntryFunctionPayloadResponse( diff --git a/Aptos/Aptos.Api/TransactionResponse.cs b/Aptos/Aptos.Api/TransactionResponse.cs index c6d01bd..2e6fdae 100644 --- a/Aptos/Aptos.Api/TransactionResponse.cs +++ b/Aptos/Aptos.Api/TransactionResponse.cs @@ -1,5 +1,6 @@ namespace Aptos; +using System.Reflection; using System.Runtime.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -42,6 +43,8 @@ public abstract class TransactionResponse(TransactionResponseType type, Hex hash public class TransactionResponseConverter : JsonConverter { + public override bool CanWrite => false; + static readonly JsonSerializerSettings SpecifiedSubclassConversion = new() { @@ -59,6 +62,14 @@ JsonSerializer serializer var jsonObject = JObject.Load(reader); var type = jsonObject["type"]?.ToString(); + // If the type is `null`, it is a transaction simulation. + // In this case, we override to "user_transaction". + if (type == null) + { + type = "user_transaction"; + jsonObject["type"] = "user_transaction"; + } + return type switch { "user_transaction" => JsonConvert.DeserializeObject( @@ -100,7 +111,7 @@ public override void WriteJson( JsonWriter writer, TransactionResponse? value, JsonSerializer serializer - ) => serializer.Serialize(writer, value); + ) => throw new NotImplementedException(); } [Serializable] diff --git a/Aptos/Aptos.Api/TransactionSignature.cs b/Aptos/Aptos.Api/TransactionSignature.cs index dd5e5a0..bc1a54e 100644 --- a/Aptos/Aptos.Api/TransactionSignature.cs +++ b/Aptos/Aptos.Api/TransactionSignature.cs @@ -33,6 +33,8 @@ public abstract class TransactionSignature(TransactionSignatureVariant type) public class TransactionSignatureConverter : JsonConverter { + public override bool CanWrite => false; + static readonly JsonSerializerSettings SpecifiedSubclassConversion = new() { @@ -121,7 +123,7 @@ public override void WriteJson( JsonWriter writer, TransactionSignature? value, JsonSerializer serializer - ) => serializer.Serialize(writer, value); + ) => throw new NotImplementedException(); } [Serializable] diff --git a/Aptos/Aptos.Api/WriteSetChange.cs b/Aptos/Aptos.Api/WriteSetChange.cs index f704ad5..22f8b5b 100644 --- a/Aptos/Aptos.Api/WriteSetChange.cs +++ b/Aptos/Aptos.Api/WriteSetChange.cs @@ -15,6 +15,8 @@ public abstract class WriteSetChange(string type, string stateKeyHash) public class WritesSetChangeConverter : JsonConverter { + public override bool CanWrite => false; + static readonly JsonSerializerSettings SpecifiedSubclassConversion = new() { ContractResolver = new SubclassSpecifiedConcreteClassConverter() }; @@ -63,7 +65,7 @@ public override void WriteJson( JsonWriter writer, WriteSetChange? value, JsonSerializer serializer - ) => serializer.Serialize(writer, value); + ) => throw new NotImplementedException(); } public class WriteSetChangeDeleteModule( diff --git a/Aptos/Aptos.Clients/ANSClient.cs b/Aptos/Aptos.Clients/ANSClient.cs index cf8fb62..b604e8d 100644 --- a/Aptos/Aptos.Clients/ANSClient.cs +++ b/Aptos/Aptos.Clients/ANSClient.cs @@ -2,6 +2,7 @@ namespace Aptos; using Aptos.Core; using Aptos.Exceptions; +using Aptos.Indexer.GraphQL; public class ANSClient(AptosClient client) { @@ -12,7 +13,7 @@ public class ANSClient(AptosClient client) await GetAnsName(AccountAddress.From(address)); /// - /// Gets the ANS name of the given address. This includes the subdomain of the name. + /// Gets the registered ANS name of the given address. This includes the subdomain of the name. /// /// The address of the account. /// The ANS name of the given address. @@ -22,21 +23,26 @@ public class ANSClient(AptosClient client) if (routerAddress == null) throw new ANSUnsupportedNetwork(); - var response = await _client.Contract.View( - new( - function: $"{routerAddress}::router::get_primary_name", - functionArguments: [address] + var response = ( + await _client.Indexer.Query(async client => + await client.GetNames.ExecuteAsync( + 0, + 1, + new() + { + Registered_address = new() { _eq = address.ToString() }, + Is_active = new() { _eq = true }, + }, + [new() { Is_primary = Order_by.Desc }] + ) ) - ); - - var domainName = Utilities.UnwrapOption(response[1]); - var subdomainName = Utilities.UnwrapOption(response[0]); + ).Data.Current_aptos_names.ElementAtOrDefault(0); // Join the names removing any null values - var name = new List { subdomainName, domainName } - .Where(s => s != null) + var name = new List { response?.Subdomain, response?.Domain } + .Where(s => s != null && s != "") .ToList(); - return name.Count > 0 ? string.Join(".", name) : null; + return name.Count > 0 ? string.Join(".", name) + ".apt" : null; } /// diff --git a/Aptos/Aptos.Clients/AccountClient.cs b/Aptos/Aptos.Clients/AccountClient.cs index 0d334a3..7b9bcbe 100644 --- a/Aptos/Aptos.Clients/AccountClient.cs +++ b/Aptos/Aptos.Clients/AccountClient.cs @@ -242,7 +242,7 @@ await _client.FungibleAsset.GetAccountFungibleAssetBalances( /// Gets the coin balance of the given address and coin type. When providing the types, its important to include both the Fungible Asset address /// and the coin type if they both exist for the asset. ///
- /// The default will be "0x000000000000000000000000000000000000000000000000000000000000000a" and "0x1::aptos_coin::AptosCoin". + /// The default will be "0xa" and "0x1::aptos_coin::AptosCoin". /// /// The address of the account. /// The type of the coin. diff --git a/Aptos/Aptos.Clients/AptosClient/AptosClient.cs b/Aptos/Aptos.Clients/AptosClient/AptosClient.cs index 1c58dc7..fbf1c6c 100644 --- a/Aptos/Aptos.Clients/AptosClient/AptosClient.cs +++ b/Aptos/Aptos.Clients/AptosClient/AptosClient.cs @@ -29,6 +29,10 @@ public partial class AptosClient public readonly TableClient Table; + /// + public AptosClient(NetworkConfig networkConfig) + : this(new AptosConfig(networkConfig)) { } + /// /// Creates an instance of the AptosClient with a given . /// This client is used to interface with the Aptos blockchain and perform various operations such diff --git a/Aptos/Aptos.Clients/TransactionClient.cs b/Aptos/Aptos.Clients/TransactionClient.cs index f514e49..ef20aed 100644 --- a/Aptos/Aptos.Clients/TransactionClient.cs +++ b/Aptos/Aptos.Clients/TransactionClient.cs @@ -18,6 +18,28 @@ public class TransactionClient(AptosClient client) public AccountAuthenticator SignTransaction(Account signer, AnyRawTransaction transaction) => signer.SignWithAuthenticator(transaction); + /// + /// Helper method to sign a transaction as a FeePayer with an account. The FeePayerAddress + /// will be set to the signer's address. + /// + /// The fee payer account to sign the transaction with. + /// The transaction to sign. + /// The authenticator with the signed transaction and public key. + /// If the transaction is not a FeePayer transaction. + public AccountAuthenticator SignAsFeePayer(Account signer, AnyRawTransaction transaction) + { + if (transaction.FeePayerAddress == null) + { + throw new ArgumentException( + "The transaction is not a FeePayer transaction. When building the transaction, set the 'withFeePayer' flag to true." + ); + } + + transaction.FeePayerAddress = signer.Address; + + return signer.SignWithAuthenticator(transaction); + } + /// /// Submits a transaction to the blockchain. /// @@ -269,7 +291,7 @@ void HandleApiError(Exception e) if (checkSuccess && !((CommittedTransactionResponse)lastTxn).Success) { throw new FailedTransactionException( - $"Transaction {hash} failed after waiting for {timeoutSecs} seconds", + $"Transaction {hash} failed with an error {((CommittedTransactionResponse)lastTxn).VmStatus}", (CommittedTransactionResponse)lastTxn ); } diff --git a/Aptos/Aptos.Core/AccountAddress.cs b/Aptos/Aptos.Core/AccountAddress.cs index 3b60df8..4225868 100644 --- a/Aptos/Aptos.Core/AccountAddress.cs +++ b/Aptos/Aptos.Core/AccountAddress.cs @@ -51,11 +51,11 @@ byte[] seed [JsonConverter(typeof(AccountAddressConverter))] public partial class AccountAddress : TransactionArgument { - public static AccountAddress ZERO { get; } = new(new byte[LENGTH]); + public const int LENGTH = 32; - public static readonly int LENGTH = 32; + public const int LONG_LENGTH = 64; - public static readonly int LONG_LENGTH = 64; + public static AccountAddress ZERO { get; } = new(new byte[LENGTH]); public readonly byte[] Data; diff --git a/Aptos/Aptos.Core/Utilities.cs b/Aptos/Aptos.Core/Utilities.cs index 94eed4c..3e44c2f 100644 --- a/Aptos/Aptos.Core/Utilities.cs +++ b/Aptos/Aptos.Core/Utilities.cs @@ -9,7 +9,7 @@ public static class Utilities /// /// Parses a function string into its module address, module name, and function name. /// - /// An function split by "::". E.g. "0x1::coin::transfer" + /// An function split by "::". E.g. "0x1::aptos_account::transfer_coins" /// A tuple containing the module address, module name, and function name. /// If the function string is not in the correct format. public static ( diff --git a/Aptos/Aptos.Transactions/TransactionInstance/AnyRawTransaction.cs b/Aptos/Aptos.Transactions/TransactionInstance/AnyRawTransaction.cs index 1764bae..310433c 100644 --- a/Aptos/Aptos.Transactions/TransactionInstance/AnyRawTransaction.cs +++ b/Aptos/Aptos.Transactions/TransactionInstance/AnyRawTransaction.cs @@ -8,7 +8,7 @@ public abstract class AnyRawTransaction( { public RawTransaction RawTransaction { get; } = rawTransaction; - public AccountAddress? FeePayerAddress { get; } = feePayerAddress; + public AccountAddress? FeePayerAddress = feePayerAddress; public List? SecondarySignerAddresses { get; } = secondarySignerAddresses; } diff --git a/README.md b/README.md index cf85eb1..9df61ec 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ var account = Account.Generate(); var transaction = await client.Transaction.Build( sender: account, data: new GenerateEntryFunctionPayloadData( - function: "0x1::coin::transfer", + function: "0x1::aptos_account::transfer_coins", typeArguments: ["0x1::aptos_coin::AptosCoin"], functionArguments: [account.Address, "100000"] ) @@ -72,4 +72,16 @@ var committedTransaction = await client.Transaction.WaitForTransaction(pendingTr - Utilities for transaction building, signing, and submission - Abstractions over the Aptos Fullnode and Indexer APIs +## Examples + +Examples can be found in the [`Aptos.Examples`](./Aptos.Examples) project. Run the examples by using the following command: + +```bash +dotnet run --project ./Aptos.Examples --framework net8.0 +``` + +This will prompt the follow console. You can select an example to run by entering the corresponding number or using the arrow keys to navigate the menu. + +![examples-demonstration](./assets/examples_demo.png) + [github-license]: https://img.shields.io/github/license/aptos-labs/aptos-ts-sdk \ No newline at end of file diff --git a/assets/examples_demo.png b/assets/examples_demo.png new file mode 100644 index 0000000..e50578c Binary files /dev/null and b/assets/examples_demo.png differ