diff --git a/.gitignore b/.gitignore index 4a0b0830b..7f56a1bfc 100644 --- a/.gitignore +++ b/.gitignore @@ -885,6 +885,7 @@ src/proto/*.proto /proto/mirror /proto/state /proto/auxiliary +/proto/event ### Ignore Generated Package Files package diff --git a/HieroApi.cmake b/HieroApi.cmake index 8db58f3e0..b0450c423 100644 --- a/HieroApi.cmake +++ b/HieroApi.cmake @@ -1,7 +1,7 @@ -set(HAPI_VERSION_TAG "v0.57.0" CACHE STRING "Use the configured version tag for the Hiero API protobufs") +set(HAPI_VERSION_TAG "v0.59.0" CACHE STRING "Use the configured version tag for the Hiero API protobufs") if (HAPI_VERSION_TAG STREQUAL "") - set(HAPI_VERSION_TAG "v0.57.0") + set(HAPI_VERSION_TAG "v0.59.0") endif () # Fetch the protobuf definitions @@ -50,6 +50,7 @@ endif() file(INSTALL ${PROJECT_SOURCE_DIR}/proto/service-external-proto/mirror/ DESTINATION ${PROTO_SRC}/mirror) file(INSTALL ${hproto_SOURCE_DIR}/hapi/hedera-protobufs/services/ DESTINATION ${PROTO_SRC}) +file(INSTALL ${hproto_SOURCE_DIR}/hapi/hedera-protobufs/platform/ DESTINATION ${PROTO_SRC}) file(INSTALL ${PROJECT_SOURCE_DIR}/proto/service-external-proto/sdk/ DESTINATION ${PROTO_SRC}) add_subdirectory(proto) diff --git a/proto/CMakeLists.txt b/proto/CMakeLists.txt index 5c91ad046..499aa8663 100644 --- a/proto/CMakeLists.txt +++ b/proto/CMakeLists.txt @@ -98,7 +98,6 @@ set(PROTO_FILES token_update_nfts.proto token_wipe_account.proto transaction.proto - transaction_body.proto transaction_contents.proto transaction_get_fast_record.proto transaction_get_receipt.proto @@ -111,10 +110,16 @@ set(PROTO_FILES util_prng.proto util_service.proto + auxiliary/history/history_proof_signature.proto + auxiliary/history/history_proof_key_publication.proto + auxiliary/history/history_proof_vote.proto auxiliary/tss/tss_message.proto - auxiliary/tss/tss_share_signature.proto auxiliary/tss/tss_vote.proto + event/state_signature_transaction.proto + + state/history/history_types.proto + mirror/consensus_service.proto mirror/mirror_network_service.proto) # End Protobuf Definitions diff --git a/src/sdk/examples/CMakeLists.txt b/src/sdk/examples/CMakeLists.txt index bbf30b460..4ea2f37d9 100644 --- a/src/sdk/examples/CMakeLists.txt +++ b/src/sdk/examples/CMakeLists.txt @@ -44,6 +44,7 @@ set(MULTI_APP_TRANSFER_EXAMPLE_NAME ${PROJECT_NAME}-multi-app-transfer-example) set(MULTI_SIG_OFFLINE_EXAMPLE_NAME ${PROJECT_NAME}-multi-sig-offline-example) set(NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME ${PROJECT_NAME}-nft-add-remove-allowances-example) set(PRNG_EXAMPLE_NAME ${PROJECT_NAME}-prng-example) +set(REVENUE_GENERATING_TOPICS_EXAMPLE_NAME ${PROJECT_NAME}-revenue-generating-topics-example) set(SCHEDULE_EXAMPLE_NAME ${PROJECT_NAME}-schedule-example) set(SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME ${PROJECT_NAME}-schedule-identical-transaction-example) set(SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME ${PROJECT_NAME}-schedule-multisig-transaction-example) @@ -101,6 +102,7 @@ add_executable(${MULTI_APP_TRANSFER_EXAMPLE_NAME} MultiAppTransferExample.cc) add_executable(${MULTI_SIG_OFFLINE_EXAMPLE_NAME} MultiSigOfflineExample.cc) add_executable(${NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME} NftAddRemoveAllowancesExample.cc) add_executable(${PRNG_EXAMPLE_NAME} PrngExample.cc) +add_executable(${REVENUE_GENERATING_TOPICS_EXAMPLE_NAME} RevenueGeneratingTopicsExample.cc) add_executable(${SCHEDULE_EXAMPLE_NAME} ScheduleExample.cc) add_executable(${SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME} ScheduleIdenticalTransactionExample.cc) add_executable(${SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME} ScheduleMultiSigTransactionExample.cc) @@ -180,6 +182,7 @@ target_link_libraries(${MULTI_APP_TRANSFER_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) target_link_libraries(${MULTI_SIG_OFFLINE_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) target_link_libraries(${NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) target_link_libraries(${PRNG_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) +target_link_libraries(${REVENUE_GENERATING_TOPICS_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) target_link_libraries(${SCHEDULE_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) target_link_libraries(${SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) target_link_libraries(${SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) @@ -239,6 +242,7 @@ install(TARGETS ${MULTI_SIG_OFFLINE_EXAMPLE_NAME} ${NFT_ADD_REMOVE_ALLOWANCES_EXAMPLE_NAME} ${PRNG_EXAMPLE_NAME} + ${REVENUE_GENERATING_TOPICS_EXAMPLE_NAME} ${SCHEDULE_EXAMPLE_NAME} ${SCHEDULE_IDENTICAL_TRANSACTION_EXAMPLE_NAME} ${SCHEDULE_MULTI_SIG_TRANSACTION_EXAMPLE_NAME} diff --git a/src/sdk/examples/RevenueGeneratingTopicsExample.cc b/src/sdk/examples/RevenueGeneratingTopicsExample.cc new file mode 100644 index 000000000..74d9ce38c --- /dev/null +++ b/src/sdk/examples/RevenueGeneratingTopicsExample.cc @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: Apache-2.0 +#include "AccountBalance.h" +#include "AccountBalanceQuery.h" +#include "AccountCreateTransaction.h" +#include "AccountId.h" +#include "Client.h" +#include "CustomFixedFee.h" +#include "ED25519PrivateKey.h" +#include "TokenCreateTransaction.h" +#include "TopicCreateTransaction.h" +#include "TopicId.h" +#include "TopicMessageSubmitTransaction.h" +#include "TopicUpdateTransaction.h" +#include "TransactionReceipt.h" +#include "TransactionResponse.h" +#include "TransferTransaction.h" + +#include +#include + +using namespace Hiero; + +int main(int argc, char** argv) +{ + dotenv::init(); + const AccountId operatorAccountId = AccountId::fromString(std::getenv("OPERATOR_ID")); + const std::shared_ptr operatorPrivateKey = ED25519PrivateKey::fromString(std::getenv("OPERATOR_KEY")); + + // Get a client for the Hiero testnet, and set the operator account ID and key such that all generated transactions + // will be paid for by this account and be signed by this key. + Client client = Client::forTestnet(); + client.setOperator(operatorAccountId, operatorPrivateKey); + + /* + * Step 1: + * Create account - alice + */ + std::cout << "Creating account - alice" << std::endl; + + std::shared_ptr aliceKey = ED25519PrivateKey::generatePrivateKey(); + + AccountId alice = AccountCreateTransaction() + .setKeyWithoutAlias(aliceKey->getPublicKey()) + .setInitialBalance(Hbar(10LL)) + .execute(client) + .getReceipt(client) + .mAccountId.value(); + + std::cout << "Alice account id:" << alice.toString() << std::endl; + + /* + * Step 2: + * Create a topic with hbar custom fee + */ + int64_t feeAmount = 100000000; // 1 HBAR equivalent + + CustomFixedFee customFixedFee = CustomFixedFee().setAmount(feeAmount).setFeeCollectorAccountId(operatorAccountId); + + TopicId topicId = TopicCreateTransaction() + .setAdminKey(operatorPrivateKey->getPublicKey()) + .setFeeScheduleKey(operatorPrivateKey->getPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(client) + .getReceipt(client) + .mTopicId.value(); + + /* + * Step 3: + * Submit a message to that topic, paid for by alice, specifying max custom fee amount bigger than the topic’s amount. + */ + AccountBalance accountBalanceBefore = AccountBalanceQuery().setAccountId(alice).execute(client); + AccountBalance feeCollectorBalanceBefore = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client); + + CustomFeeLimit limit = CustomFeeLimit().setPayerId(alice).addCustomFee(CustomFixedFee().setAmount(feeAmount * 2)); + + client.setOperator(alice, aliceKey); + TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .addCustomFeeLimit(limit) + .execute(client) + .getReceipt(client); + + std::cout << "Message submitted successfully" << std::endl; + + /* + * Step 4: + * Verify alice was debited the fee amount and the fee collector account was credited the amount. + */ + client.setOperator(operatorAccountId, operatorPrivateKey); + + AccountBalance accountBalanceAfter = AccountBalanceQuery().setAccountId(alice).execute(client); + AccountBalance feeCollectorBalanceAfter = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client); + + std::cout << "Alice account balance before: " << accountBalanceBefore.toString() << std::endl; + std::cout << "Alice account balance after: " << accountBalanceAfter.toString() << std::endl; + std::cout << "Fee collector account balance before: " << feeCollectorBalanceBefore.toString() << std::endl; + std::cout << "Fee collector account balance after: " << feeCollectorBalanceAfter.toString() << std::endl; + + /* + * Step 5: + * Create a fungible token and transfer some tokens to alice + */ + TokenId tokenId = TokenCreateTransaction() + .setTokenName("revenueGeneratingToken") + .setTokenSymbol("RGT") + .setInitialSupply(10) + .setTreasuryAccountId(operatorAccountId) + .execute(client) + .getReceipt(client) + .mTokenId.value(); + + std::cout << "Created token with Id: " << tokenId.toString() << std::endl; + + TransferTransaction() + .addTokenTransfer(tokenId, operatorAccountId, -1ULL) + .addTokenTransfer(tokenId, alice, 1ULL) + .execute(client) + .getReceipt(client); + + /* + * Step 6: + * Update the topic to have a fee of the token. + */ + std::cout << "Updating the topic to have a custom fee of the token" << std::endl; + + CustomFixedFee customTokenFixedFee = + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId(operatorAccountId); + + TopicUpdateTransaction() + .setTopicId(topicId) + .setCustomFixedFees({ customTokenFixedFee }) + .execute(client) + .getReceipt(client); + + /* + * Step 7: + * Submit another message to that topic, paid by alice, without specifying max custom fee amount. + */ + accountBalanceBefore = AccountBalanceQuery().setAccountId(alice).execute(client); + feeCollectorBalanceBefore = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client); + + std::cout << "Submitting a message as alice to the topic" << std::endl; + + client.setOperator(alice, aliceKey); + TopicMessageSubmitTransaction().setTopicId(topicId).setMessage("message").execute(client).getReceipt(client); + + std::cout << "Message submitted successfully" << std::endl; + + /* + * Step 8: + * Verify alice was debited the new fee amount and the fee collector account was credited the amount. + */ + client.setOperator(operatorAccountId, operatorPrivateKey); + + accountBalanceAfter = AccountBalanceQuery().setAccountId(alice).execute(client); + feeCollectorBalanceAfter = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client); + + std::cout << "Alice account balance before: " << accountBalanceBefore.toString() << std::endl; + std::cout << "Alice account balance after: " << accountBalanceAfter.toString() << std::endl; + std::cout << "Fee collector account balance before: " << feeCollectorBalanceBefore.toString() << std::endl; + std::cout << "Fee collector account balance after: " << feeCollectorBalanceAfter.toString() << std::endl; + + /* + * Step 9: + * Create account - bob + */ + std::cout << "Creating account - bob" << std::endl; + + std::shared_ptr bobKey = ED25519PrivateKey::generatePrivateKey(); + + AccountId bob = AccountCreateTransaction() + .setKeyWithoutAlias(bobKey->getPublicKey()) + .setInitialBalance(Hbar(10LL)) + .setMaxAutomaticTokenAssociations(-1) + .execute(client) + .getReceipt(client) + .mAccountId.value(); + + std::cout << "Bob account id:" << bob.toString() << std::endl; + + /* + * Step 10: + * Update the topic’s fee exempt keys and add bob’s public key. + */ + std::cout << "Updating the topic fee exempt keys with bob's public key" << std::endl; + + TopicUpdateTransaction() + .setTopicId(topicId) + .addFeeExemptKey(bobKey->getPublicKey()) + .execute(client) + .getReceipt(client); + + /* + * Step 11: + * Submit another message to that topic, paid with bob, without specifying max custom fee amount. + */ + accountBalanceBefore = AccountBalanceQuery().setAccountId(bob).execute(client); + feeCollectorBalanceBefore = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client); + + std::cout << "Submitting a message as bob to the topic" << std::endl; + + client.setOperator(bob, bobKey); + TopicMessageSubmitTransaction().setTopicId(topicId).setMessage("message").execute(client).getReceipt(client); + + std::cout << "Message submitted successfully" << std::endl; + + /* + * Step 12: + * Verify bob was not debited the fee amount. + */ + client.setOperator(operatorAccountId, operatorPrivateKey); + + accountBalanceAfter = AccountBalanceQuery().setAccountId(bob).execute(client); + feeCollectorBalanceAfter = AccountBalanceQuery().setAccountId(operatorAccountId).execute(client); + + std::cout << "Bob account balance before: " << accountBalanceBefore.toString() << std::endl; + std::cout << "Bob account balance after: " << accountBalanceAfter.toString() << std::endl; + + // Clean up: + client.close(); + + return 0; +} \ No newline at end of file diff --git a/src/sdk/main/CMakeLists.txt b/src/sdk/main/CMakeLists.txt index e281d668a..d70175793 100644 --- a/src/sdk/main/CMakeLists.txt +++ b/src/sdk/main/CMakeLists.txt @@ -30,7 +30,6 @@ add_library(${PROJECT_NAME} STATIC src/AccountInfoQuery.cc src/AccountRecords.cc src/AccountRecordsQuery.cc - src/AccountStakersQuery.cc src/AccountUpdateTransaction.cc src/AddressBookQuery.cc src/AssessedCustomFee.cc @@ -53,6 +52,7 @@ add_library(${PROJECT_NAME} STATIC src/ContractUpdateTransaction.cc src/CustomFee.cc src/CustomFeeBase.cc + src/CustomFeeLimit.cc src/CustomFixedFee.cc src/CustomFractionalFee.cc src/CustomRoyaltyFee.cc diff --git a/src/sdk/main/include/AccountStakersQuery.h b/src/sdk/main/include/AccountStakersQuery.h deleted file mode 100644 index a830ec84a..000000000 --- a/src/sdk/main/include/AccountStakersQuery.h +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#ifndef HIERO_SDK_CPP_ACCOUNT_STAKERS_QUERY_H_ -#define HIERO_SDK_CPP_ACCOUNT_STAKERS_QUERY_H_ - -#include "AccountId.h" -#include "ProxyStaker.h" -#include "Query.h" - -#include - -namespace Hiero -{ -/** - * Get all the accounts that are proxy staking to this account. For each of them, give the amount currently staked. This - * is not yet implemented, but will be in a future version of the API. - */ -using AccountStakers = std::vector; -class AccountStakersQuery : public Query -{ -public: - /** - * Set the ID of the account of which to request the stakers. - * - * @param accountId The ID of the account of which to request the stakers. - * @return A reference to this AccountStakersQuery object with the newly-set account ID. - */ - AccountStakersQuery& setAccountId(const AccountId& accountId); - - /** - * Get the ID of the account of which this query is currently configured to get the stakers. - * - * @return The ID of the account for which this query is meant. - */ - [[nodiscard]] inline AccountId getAccountId() const { return mAccountId; } - -private: - /** - * Derived from Executable. Construct an AccountStakers object from a Response protobuf object. - * - * @param response The Response protobuf object from which to construct an AccountStakers object. - * @return An AccountStakers object filled with the Response protobuf object's data - */ - [[nodiscard]] AccountStakers mapResponse(const proto::Response& response) const override; - - /** - * Derived from Executable. Submit a Query protobuf object which contains this AccountStakersQuery's data to a Node. - * - * @param request The Query protobuf object to submit. - * @param node The Node to which to submit the request. - * @param deadline The deadline for submitting the request. - * @param response Pointer to the ProtoResponseType object that gRPC should populate with the response information - * from the gRPC server. - * @return The gRPC status of the submission. - */ - [[nodiscard]] grpc::Status submitRequest(const proto::Query& request, - const std::shared_ptr& node, - const std::chrono::system_clock::time_point& deadline, - proto::Response* response) const override; - - /** - * Derived from Query. Verify that all the checksums in this AccountStakersQuery are valid. - * - * @param client The Client that should be used to validate the checksums. - * @throws BadEntityException This AccountStakersQuery's checksums are not valid. - */ - void validateChecksums(const Client& client) const override; - - /** - * Derived from Query. Build a Query protobuf object with this AccountStakersQuery's data, with the input QueryHeader - * protobuf object. - * - * @param header A pointer to the QueryHeader protobuf object to add to the Query protobuf object. - * @return The constructed Query protobuf object. - */ - [[nodiscard]] proto::Query buildRequest(proto::QueryHeader* header) const override; - - /** - * Derived from Query. Get the ResponseHeader protobuf object from the input Response protobuf object. - * - * @param response The Response protobuf object from which to get the ResponseHeader protobuf object. - * @return The ResponseHeader protobuf object of the input Response protobuf object for this derived Query. - */ - [[nodiscard]] proto::ResponseHeader mapResponseHeader(const proto::Response& response) const override; - - /** - * The ID of the account of which this query should get the stakers. - */ - AccountId mAccountId; -}; - -} // namespace Hiero - -#endif // HIERO_SDK_CPP_ACCOUNT_STAKERS_QUERY_H_ diff --git a/src/sdk/main/include/CustomFeeLimit.h b/src/sdk/main/include/CustomFeeLimit.h new file mode 100644 index 000000000..67f8be8e8 --- /dev/null +++ b/src/sdk/main/include/CustomFeeLimit.h @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 +#ifndef HIERO_SDK_CPP_CUSTOM_FEE_LIMIT_H_ +#define HIERO_SDK_CPP_CUSTOM_FEE_LIMIT_H_ + +#include "AccountId.h" +#include "CustomFixedFee.h" +#include +#include +#include + +namespace proto +{ +class CustomFeeLimit; +} + +namespace Hiero +{ +/** + * Represents a maximum custom fee a user is willing to pay. + */ +class CustomFeeLimit +{ +public: + /** + * Creates a CustomFeeLimit object from a protobuf representation. + * + * @param protoFeeLimit The protobuf object to convert from. + * @return A CustomFeeLimit object constructed from the protobuf data. + */ + [[nodiscard]] static CustomFeeLimit fromProtobuf(const proto::CustomFeeLimit& protoFeeLimit); + + /** + * Converts this CustomFeeLimit object to a protobuf representation. + * + * @return A pointer to proto::CustomFeeLimit object. + */ + [[nodiscard]] std::unique_ptr toProtobuf() const; + + /** + * Sets the payer ID for the fee limit. + * + * @param payerId The AccountId to set. + * @return A reference to this object for method chaining. + */ + CustomFeeLimit& setPayerId(const AccountId& payerId); + + /** + * Gets the payer ID. + * + * @return The optional AccountId of the payer. + */ + [[nodiscard]] std::optional getPayerId() const; + + /** + * Sets the custom fees. + * + * @param customFees The list of custom fees. + * @return A reference to this object for method chaining. + */ + CustomFeeLimit& setCustomFees(const std::vector& customFees); + + /** + * Adds a custom fee to the list. + * + * @param customFee The CustomFixedFee to add. + * @return A reference to this object for method chaining. + */ + CustomFeeLimit& addCustomFee(const CustomFixedFee& customFee); + + /** + * Gets the custom fees. + * + * @return A vector of CustomFixedFee objects. + */ + [[nodiscard]] std::vector getCustomFees() const; + + /** + * Converts the CustomFeeLimit object to a human-readable string. + * + * @return A string representation of the CustomFeeLimit. + */ + [[nodiscard]] std::string toString() const; + +private: + /** + * Optional payer ID for the fee. + */ + std::optional mPayerId; + + /** + * List of custom fees. + */ + std::vector mCustomFees; +}; + +} // namespace Hiero + +#endif // HIERO_SDK_CPP_CUSTOM_FEE_LIMIT_H_ diff --git a/src/sdk/main/include/Status.h b/src/sdk/main/include/Status.h index 1a875111f..4c93a7329 100644 --- a/src/sdk/main/include/Status.h +++ b/src/sdk/main/include/Status.h @@ -1704,7 +1704,90 @@ enum class Status * A scheduled transaction configured to wait for expiry to execute was not * given an explicit expiration time. */ - MISSING_EXPIRY_TIME + MISSING_EXPIRY_TIME, + + /** + * A contract operation attempted to schedule another transaction after it + * had already scheduled a recursive contract call. + */ + NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION, + + /** + * A contract can schedule recursive calls a finite number of times (this is + * approximately four million times with typical network configuration.) + */ + RECURSIVE_SCHEDULING_LIMIT_REACHED, + + /** + * The target network is waiting for the ledger ID to be set, which is a + * side effect of finishing the network's TSS construction. + */ + WAITING_FOR_LEDGER_ID, + + /** + * The provided fee exempt key list size exceeded the limit. + */ + MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED, + + /** + * The provided fee exempt key list contains duplicated keys. + */ + FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS, + + /** + * The provided fee exempt key list contains an invalid key. + */ + INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST, + + /** + * The provided fee schedule key contains an invalid key. + */ + INVALID_FEE_SCHEDULE_KEY, + + /** + * If a fee schedule key is not set when we create a topic + * we cannot add it on update. + */ + FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED, + + /** + * If the topic's custom fees are updated the topic SHOULD have a + * fee schedule key + */ + FEE_SCHEDULE_KEY_NOT_SET, + + /** + * The fee amount is exceeding the amount that the payer + * is willing to pay. + */ + MAX_CUSTOM_FEE_LIMIT_EXCEEDED, + + /** + * There are no corresponding custom fees. + */ + NO_VALID_MAX_CUSTOM_FEE, + + /** + * The provided list contains invalid max custom fee. + */ + INVALID_MAX_CUSTOM_FEES, + + /** + * The provided max custom fee list contains fees with + * duplicate denominations. + */ + DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST, + + /** + * The provided max custom fee list contains fees with + * duplicate account id. + */ + DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST, + + /** + * Max custom fees list is not supported for this operation. + */ + MAX_CUSTOM_FEES_IS_NOT_SUPPORTED }; diff --git a/src/sdk/main/include/TopicCreateTransaction.h b/src/sdk/main/include/TopicCreateTransaction.h index 695baa4b3..10fa909a7 100644 --- a/src/sdk/main/include/TopicCreateTransaction.h +++ b/src/sdk/main/include/TopicCreateTransaction.h @@ -3,6 +3,7 @@ #define HIERO_SDK_CPP_TOPIC_CREATE_TRANSACTION_H_ #include "AccountId.h" +#include "CustomFixedFee.h" #include "Defaults.h" #include "Key.h" #include "Transaction.h" @@ -102,6 +103,51 @@ class TopicCreateTransaction : public Transaction */ TopicCreateTransaction& setAutoRenewAccountId(const AccountId& accountId); + /** + * Set the fee schedule key for the new topic. + * + * @param key The key that controls fee schedule updates. + * @return A reference to this TopicCreateTransaction object with the newly-set fee schedule key. + * @throws IllegalStateException If this TopicCreateTransaction is frozen. + */ + TopicCreateTransaction& setFeeScheduleKey(const std::shared_ptr& key); + + /** + * Set the list of keys exempt from paying custom fees. + * + * @param keys The list of keys that will not be charged custom fees when submitting messages to this topic. + * @return A reference to this TopicCreateTransaction object with the newly-set exempt keys. + * @throws IllegalStateException If this TopicCreateTransaction is frozen. + */ + TopicCreateTransaction& setFeeExemptKeys(const std::vector>& keys); + + /** + * Add a key to the list of keys exempt from paying custom fees. + * + * @param key The key to be added to the exempt list. + * @return A reference to this TopicCreateTransaction object with the newly-added exempt key. + * @throws IllegalStateException If this TopicCreateTransaction is frozen. + */ + TopicCreateTransaction& addFeeExemptKey(const std::shared_ptr& key); + + /** + * Set the list of custom fixed fees for this topic. + * + * @param fees The list of custom fixed fees. + * @return A reference to this TopicCreateTransaction object with the newly-set custom fees. + * @throws IllegalStateException If this TopicCreateTransaction is frozen. + */ + TopicCreateTransaction& setCustomFixedFees(const std::vector& fees); + + /** + * Add a custom fixed fee to this topic. + * + * @param fee The custom fixed fee to be added. + * @return A reference to this TopicCreateTransaction object with the newly-added fee. + * @throws IllegalStateException If this TopicCreateTransaction is frozen. + */ + TopicCreateTransaction& addCustomFixedFee(const CustomFixedFee& fee); + /** * Get the desired memo of the new topic. * @@ -123,6 +169,27 @@ class TopicCreateTransaction : public Transaction */ [[nodiscard]] inline std::shared_ptr getSubmitKey() const { return mSubmitKey; } + /** + * Get the desired fee schedule key for the new topic. + * + * @return The fee schedule key for the new topic. + */ + [[nodiscard]] inline std::shared_ptr getFeeScheduleKey() const { return mFeeScheduleKey; } + + /** + * Get the list of fee-exempt keys for the new topic. + * + * @return The list of fee-exempt keys. + */ + [[nodiscard]] inline std::vector> getFeeExemptKeys() const { return mFeeExemptKeys; } + + /** + * Get the list of custom fixed fees for the new topic. + * + * @return The list of custom fixed fees. + */ + [[nodiscard]] inline std::vector getCustomFixedFees() const { return mCustomFixedFees; } + /** * Get the desired auto-renew period for the new topic. * @@ -213,6 +280,46 @@ class TopicCreateTransaction : public Transaction * The account that should be charged to extend the lifetime of the new topic at its expiration time. */ std::optional mAutoRenewAccountId; + + /** + * Access control for update or delete of custom fees. + * If set, subsequent `consensus_update_topic` transactions signed with this + * key MAY update or delete the custom fees for this topic. + * If not set, the custom fees for this topic SHALL BE immutable. + * If not set when the topic is created, this field CANNOT be set via update. + * If set when the topic is created, this field MAY be changed via update. + */ + std::shared_ptr mFeeScheduleKey = nullptr; + + /** + * A set of keys. + * Keys in this list are permitted to submit messages to this topic without + * paying custom fees associated with this topic. + * If a submit transaction is signed by _any_ key included in this set, + * custom fees SHALL NOT be charged for that transaction. + * This field MUST NOT contain more than 10 keys. + * fee_exempt_key_list SHALL NOT contain any duplicate keys. + * fee_exempt_key_list MAY contain keys for accounts that are inactive, + * deleted, or non-existent. + * If fee_exempt_key_list is unset in this transaction, there SHALL NOT be + * any fee-exempt keys. In particular, the following keys SHALL NOT be + * implicitly or automatically added to this list: + * `adminKey`, `submitKey`, `fee_schedule_key`. + */ + std::vector> mFeeExemptKeys; + + /** + * A set of custom fee definitions. + * These are fees to be assessed for each submit to this topic. + * Each fee defined in this set SHALL be evaluated for + * each message submitted to this topic, and the resultant + * total assessed fees SHALL be charged. + * Custom fees defined here SHALL be assessed in addition to the base + * network and node fees. + * custom_fees list SHALL NOT contain more than + * `MAX_CUSTOM_FEE_ENTRIES_FOR_TOPICS` entries. + */ + std::vector mCustomFixedFees; }; } // namespace Hiero diff --git a/src/sdk/main/include/TopicInfo.h b/src/sdk/main/include/TopicInfo.h index fb580885d..1725e4472 100644 --- a/src/sdk/main/include/TopicInfo.h +++ b/src/sdk/main/include/TopicInfo.h @@ -3,6 +3,7 @@ #define HIERO_SDK_CPP_TOPIC_INFO_H_ #include "AccountId.h" +#include "CustomFixedFee.h" #include "Key.h" #include "LedgerId.h" #include "TopicId.h" @@ -125,6 +126,46 @@ class TopicInfo * The ID of the ledger from which this response was returned. */ LedgerId mLedgerId; + + /** + * Access control for update or delete of custom fees. + * If set, subsequent `consensus_update_topic` transactions signed with this + * key MAY update or delete the custom fees for this topic. + * If not set, the custom fees for this topic SHALL BE immutable. + * If not set when the topic is created, this field CANNOT be set via update. + * If set when the topic is created, this field MAY be changed via update. + */ + std::shared_ptr mFeeScheduleKey = nullptr; + + /** + * A set of keys. + * Keys in this list are permitted to submit messages to this topic without + * paying custom fees associated with this topic. + * If a submit transaction is signed by _any_ key included in this set, + * custom fees SHALL NOT be charged for that transaction. + * This field MUST NOT contain more than 10 keys. + * fee_exempt_key_list SHALL NOT contain any duplicate keys. + * fee_exempt_key_list MAY contain keys for accounts that are inactive, + * deleted, or non-existent. + * If fee_exempt_key_list is unset in this transaction, there SHALL NOT be + * any fee-exempt keys. In particular, the following keys SHALL NOT be + * implicitly or automatically added to this list: + * `adminKey`, `submitKey`, `fee_schedule_key`. + */ + std::vector> mFeeExemptKeys; + + /** + * A set of custom fee definitions. + * These are fees to be assessed for each submit to this topic. + * Each fee defined in this set SHALL be evaluated for + * each message submitted to this topic, and the resultant + * total assessed fees SHALL be charged. + * Custom fees defined here SHALL be assessed in addition to the base + * network and node fees. + * custom_fees list SHALL NOT contain more than + * `MAX_CUSTOM_FEE_ENTRIES_FOR_TOPICS` entries. + */ + std::vector mCustomFixedFees; }; } // namespace Hiero diff --git a/src/sdk/main/include/TopicMessageSubmitTransaction.h b/src/sdk/main/include/TopicMessageSubmitTransaction.h index 5219284a3..1e021e7e1 100644 --- a/src/sdk/main/include/TopicMessageSubmitTransaction.h +++ b/src/sdk/main/include/TopicMessageSubmitTransaction.h @@ -3,6 +3,7 @@ #define HIERO_SDK_CPP_TOPIC_MESSAGE_SUBMIT_TRANSACTION_H_ #include "ChunkedTransaction.h" +#include "CustomFeeLimit.h" #include "TopicId.h" #include "TransactionId.h" @@ -69,6 +70,32 @@ class TopicMessageSubmitTransaction : public ChunkedTransaction& message); TopicMessageSubmitTransaction& setMessage(std::string_view message); + /** + * Set the maximum custom fees that the user is willing to pay for the transaction. + * + * @param customFeeLimits The list of maximum custom fees. + * @return A reference to this derived Transaction object with the newly-set custom fee limits. + * @throws IllegalStateException If this Transaction is frozen. + */ + TopicMessageSubmitTransaction& setCustomFeeLimits(const std::vector& customFeeLimits); + + /** + * Add a maximum custom fee that the user is willing to pay for the transaction. + * + * @param customFeeLimit The custom fee limit to be added. + * @return A reference to this derived Transaction object with the newly-added custom fee limit. + * @throws IllegalStateException If this Transaction is frozen. + */ + TopicMessageSubmitTransaction& addCustomFeeLimit(const CustomFeeLimit& customFeeLimit); + + /** + * Clear all maximum custom fees that the user is willing to pay for the transaction. + * + * @return A reference to this derived Transaction object with cleared custom fee limits. + * @throws IllegalStateException If this Transaction is frozen. + */ + TopicMessageSubmitTransaction& clearCustomFeeLimits(); + /** * Get the ID of the topic to which to submit a message. * @@ -83,6 +110,13 @@ class TopicMessageSubmitTransaction : public ChunkedTransaction getMessage() const { return getData(); } + /** + * Get the maximum custom fees that the user is willing to pay for the transaction. + * + * @return A vector containing the current custom fee limits. + */ + [[nodiscard]] std::vector getCustomFeeLimits() const; + private: friend class WrappedTransaction; @@ -148,6 +182,14 @@ class TopicMessageSubmitTransaction : public ChunkedTransaction mCustomFeeLimits; }; } // namespace Hiero diff --git a/src/sdk/main/include/TopicUpdateTransaction.h b/src/sdk/main/include/TopicUpdateTransaction.h index 2dfa390f4..845efd828 100644 --- a/src/sdk/main/include/TopicUpdateTransaction.h +++ b/src/sdk/main/include/TopicUpdateTransaction.h @@ -3,6 +3,7 @@ #define HIERO_SDK_CPP_TOPIC_UPDATE_TRANSACTION_H_ #include "AccountId.h" +#include "CustomFixedFee.h" #include "Key.h" #include "TopicId.h" #include "Transaction.h" @@ -115,6 +116,51 @@ class TopicUpdateTransaction : public Transaction */ TopicUpdateTransaction& setAutoRenewAccountId(const AccountId& accountId); + /** + * Set the new fee schedule key for the topic. + * + * @param key The new fee schedule key. + * @return A reference to this TopicUpdateTransaction object with the newly-set fee schedule key. + * @throws IllegalStateException If this TopicUpdateTransaction is frozen. + */ + TopicUpdateTransaction& setFeeScheduleKey(const std::shared_ptr& key); + + /** + * Set the list of fee-exempt keys for the topic. + * + * @param keys The list of fee-exempt keys. + * @return A reference to this TopicUpdateTransaction object with the newly-set fee-exempt keys. + * @throws IllegalStateException If this TopicUpdateTransaction is frozen. + */ + TopicUpdateTransaction& setFeeExemptKeys(const std::vector>& keys); + + /** + * Add a key to the list of fee-exempt keys for the topic. + * + * @param key The key to add to the exempt list. + * @return A reference to this TopicUpdateTransaction object with the newly-added exempt key. + * @throws IllegalStateException If this TopicUpdateTransaction is frozen. + */ + TopicUpdateTransaction& addFeeExemptKey(const std::shared_ptr& key); + + /** + * Set the custom fixed fees for the topic. + * + * @param fees The new custom fixed fees. + * @return A reference to this TopicUpdateTransaction object with the newly-set custom fixed fees. + * @throws IllegalStateException If this TopicUpdateTransaction is frozen. + */ + TopicUpdateTransaction& setCustomFixedFees(const std::vector& fees); + + /** + * Add a custom fixed fee to the topic. + * + * @param fee The custom fixed fee to add. + * @return A reference to this TopicUpdateTransaction object with the newly-added custom fixed fee. + * @throws IllegalStateException If this TopicUpdateTransaction is frozen. + */ + TopicUpdateTransaction& addCustomFixedFee(const CustomFixedFee& fee); + /** * Clear the memo for the topic. * @@ -181,6 +227,27 @@ class TopicUpdateTransaction : public Transaction */ [[nodiscard]] inline std::shared_ptr getSubmitKey() const { return mSubmitKey; } + /** + * Get the desired fee schedule key for the new topic. + * + * @return The fee schedule key for the new topic. + */ + [[nodiscard]] inline std::shared_ptr getFeeScheduleKey() const { return mFeeScheduleKey; } + + /** + * Get the list of fee-exempt keys for the new topic. + * + * @return The list of fee-exempt keys. + */ + [[nodiscard]] inline std::vector> getFeeExemptKeys() const { return mFeeExemptKeys; } + + /** + * Get the list of custom fixed fees for the new topic. + * + * @return The list of custom fixed fees. + */ + [[nodiscard]] inline std::vector getCustomFixedFees() const { return mCustomFixedFees; } + /** * Get the new auto-renew period for the topic. * @@ -281,6 +348,46 @@ class TopicUpdateTransaction : public Transaction * The ID of the new account that should be charged to extend the lifetime of the topic at its expiration time. */ std::optional mAutoRenewAccountId; + + /** + * Access control for update or delete of custom fees. + * If set, subsequent `consensus_update_topic` transactions signed with this + * key MAY update or delete the custom fees for this topic. + * If not set, the custom fees for this topic SHALL BE immutable. + * If not set when the topic is created, this field CANNOT be set via update. + * If set when the topic is created, this field MAY be changed via update. + */ + std::shared_ptr mFeeScheduleKey = nullptr; + + /** + * A set of keys. + * Keys in this list are permitted to submit messages to this topic without + * paying custom fees associated with this topic. + * If a submit transaction is signed by _any_ key included in this set, + * custom fees SHALL NOT be charged for that transaction. + * This field MUST NOT contain more than 10 keys. + * fee_exempt_key_list SHALL NOT contain any duplicate keys. + * fee_exempt_key_list MAY contain keys for accounts that are inactive, + * deleted, or non-existent. + * If fee_exempt_key_list is unset in this transaction, there SHALL NOT be + * any fee-exempt keys. In particular, the following keys SHALL NOT be + * implicitly or automatically added to this list: + * `adminKey`, `submitKey`, `fee_schedule_key`. + */ + std::vector> mFeeExemptKeys; + + /** + * A set of custom fee definitions. + * These are fees to be assessed for each submit to this topic. + * Each fee defined in this set SHALL be evaluated for + * each message submitted to this topic, and the resultant + * total assessed fees SHALL be charged. + * Custom fees defined here SHALL be assessed in addition to the base + * network and node fees. + * custom_fees list SHALL NOT contain more than + * `MAX_CUSTOM_FEE_ENTRIES_FOR_TOPICS` entries. + */ + std::vector mCustomFixedFees; }; } // namespace Hiero diff --git a/src/sdk/main/src/AccountBalance.cc b/src/sdk/main/src/AccountBalance.cc index d6110a203..eaade591b 100644 --- a/src/sdk/main/src/AccountBalance.cc +++ b/src/sdk/main/src/AccountBalance.cc @@ -49,6 +49,11 @@ std::string AccountBalance::toString() const nlohmann::json json; json["mBalance"] = mBalance.toString(); + for (const auto& pair : mTokens) + { + json[pair.first.toString()] = pair.second; + } + return json.dump(); } diff --git a/src/sdk/main/src/AccountStakersQuery.cc b/src/sdk/main/src/AccountStakersQuery.cc deleted file mode 100644 index 28831c147..000000000 --- a/src/sdk/main/src/AccountStakersQuery.cc +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#include "AccountStakersQuery.h" -#include "Client.h" -#include "ProxyStaker.h" -#include "TransactionRecord.h" -#include "TransferTransaction.h" -#include "impl/Node.h" - -#include -#include -#include -#include - -namespace Hiero -{ -//----- -AccountStakersQuery& AccountStakersQuery::setAccountId(const AccountId& accountId) -{ - mAccountId = accountId; - return *this; -} - -//----- -AccountStakers AccountStakersQuery::mapResponse(const proto::Response& response) const -{ - AccountStakers accountStakers; - for (int i = 0; i < response.cryptogetproxystakers().stakers().proxystaker_size(); ++i) - { - accountStakers.push_back(ProxyStaker::fromProtobuf(response.cryptogetproxystakers().stakers().proxystaker(i))); - } - - return accountStakers; -} - -//----- -grpc::Status AccountStakersQuery::submitRequest(const proto::Query& request, - const std::shared_ptr& node, - const std::chrono::system_clock::time_point& deadline, - proto::Response* response) const -{ - return node->submitQuery(proto::Query::QueryCase::kCryptoGetProxyStakers, request, deadline, response); -} - -//----- -void AccountStakersQuery::validateChecksums(const Client& client) const -{ - mAccountId.validateChecksum(client); -} - -//----- -proto::Query AccountStakersQuery::buildRequest(proto::QueryHeader* header) const -{ - auto accountStakersQuery = std::make_unique(); - accountStakersQuery->set_allocated_header(header); - accountStakersQuery->set_allocated_accountid(mAccountId.toProtobuf().release()); - - proto::Query query; - query.set_allocated_cryptogetproxystakers(accountStakersQuery.release()); - return query; -} - -//----- -proto::ResponseHeader AccountStakersQuery::mapResponseHeader(const proto::Response& response) const -{ - saveCostFromHeader(response.cryptogetproxystakers().header()); - return response.cryptogetproxystakers().header(); -} - -} // namespace Hiero diff --git a/src/sdk/main/src/AccountUpdateTransaction.cc b/src/sdk/main/src/AccountUpdateTransaction.cc index 234eb1472..3a16d5968 100644 --- a/src/sdk/main/src/AccountUpdateTransaction.cc +++ b/src/sdk/main/src/AccountUpdateTransaction.cc @@ -6,7 +6,6 @@ #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/ContractDeleteTransaction.cc b/src/sdk/main/src/ContractDeleteTransaction.cc index 8be22c4db..ebae82c03 100644 --- a/src/sdk/main/src/ContractDeleteTransaction.cc +++ b/src/sdk/main/src/ContractDeleteTransaction.cc @@ -5,7 +5,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/ContractUpdateTransaction.cc b/src/sdk/main/src/ContractUpdateTransaction.cc index a95934cb4..7853342bb 100644 --- a/src/sdk/main/src/ContractUpdateTransaction.cc +++ b/src/sdk/main/src/ContractUpdateTransaction.cc @@ -7,7 +7,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/CustomFeeLimit.cc b/src/sdk/main/src/CustomFeeLimit.cc new file mode 100644 index 000000000..d157ac47d --- /dev/null +++ b/src/sdk/main/src/CustomFeeLimit.cc @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +#include "CustomFeeLimit.h" + +#include "custom_fees.pb.h" +#include + +namespace Hiero +{ +//----- +CustomFeeLimit CustomFeeLimit::fromProtobuf(const proto::CustomFeeLimit& protoFeeLimit) +{ + CustomFeeLimit customFeeLimit; + + if (protoFeeLimit.has_account_id()) + { + customFeeLimit.setPayerId(AccountId::fromProtobuf(protoFeeLimit.account_id())); + } + + for (const auto& protoFee : protoFeeLimit.fees()) + { + customFeeLimit.addCustomFee(CustomFixedFee::fromProtobuf(protoFee)); + } + + return customFeeLimit; +} + +//----- +std::unique_ptr CustomFeeLimit::toProtobuf() const +{ + auto protoFeeLimit = std::make_unique(); + + if (mPayerId) + { + protoFeeLimit->set_allocated_account_id(mPayerId->toProtobuf().release()); + } + + for (const auto& fee : mCustomFees) + { + protoFeeLimit->mutable_fees()->AddAllocated(fee.toFixedFeeProtobuf().release()); + } + + return protoFeeLimit; +} + +//----- +CustomFeeLimit& CustomFeeLimit::setPayerId(const AccountId& payerId) +{ + mPayerId = payerId; + return *this; +} + +//----- +std::optional CustomFeeLimit::getPayerId() const +{ + return mPayerId; +} + +//----- +CustomFeeLimit& CustomFeeLimit::setCustomFees(const std::vector& customFees) +{ + mCustomFees = customFees; + return *this; +} + +//----- +CustomFeeLimit& CustomFeeLimit::addCustomFee(const CustomFixedFee& customFee) +{ + mCustomFees.push_back(customFee); + return *this; +} + +//----- +std::vector CustomFeeLimit::getCustomFees() const +{ + return mCustomFees; +} + +//----- +std::string CustomFeeLimit::toString() const +{ + nlohmann::json json; + + json["mPayerId"] = mPayerId ? mPayerId->toString() : "None"; + + json["mCustomFees"] = nlohmann::json::array(); + for (const auto& fee : mCustomFees) + { + json["mCustomFees"].push_back(fee.toString()); + } + + return json.dump(); +} +} \ No newline at end of file diff --git a/src/sdk/main/src/EthereumTransaction.cc b/src/sdk/main/src/EthereumTransaction.cc index 09dada951..c1a66f968 100644 --- a/src/sdk/main/src/EthereumTransaction.cc +++ b/src/sdk/main/src/EthereumTransaction.cc @@ -5,7 +5,6 @@ #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/Executable.cc b/src/sdk/main/src/Executable.cc index d6241ca4b..308991b7d 100644 --- a/src/sdk/main/src/Executable.cc +++ b/src/sdk/main/src/Executable.cc @@ -10,7 +10,6 @@ #include "AccountInfoQuery.h" #include "AccountRecords.h" #include "AccountRecordsQuery.h" -#include "AccountStakersQuery.h" #include "AccountUpdateTransaction.h" #include "Client.h" #include "ContractByteCodeQuery.h" @@ -568,7 +567,6 @@ template class Executable; template class Executable; template class Executable; -template class Executable; template class Executable #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/FileCreateTransaction.cc b/src/sdk/main/src/FileCreateTransaction.cc index 40ee7db27..e1f9539dd 100644 --- a/src/sdk/main/src/FileCreateTransaction.cc +++ b/src/sdk/main/src/FileCreateTransaction.cc @@ -7,7 +7,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/FileDeleteTransaction.cc b/src/sdk/main/src/FileDeleteTransaction.cc index 8f2a2a6d5..bd968d5c0 100644 --- a/src/sdk/main/src/FileDeleteTransaction.cc +++ b/src/sdk/main/src/FileDeleteTransaction.cc @@ -5,7 +5,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/FileUpdateTransaction.cc b/src/sdk/main/src/FileUpdateTransaction.cc index 7ce68de22..69baf5edc 100644 --- a/src/sdk/main/src/FileUpdateTransaction.cc +++ b/src/sdk/main/src/FileUpdateTransaction.cc @@ -7,7 +7,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/FreezeTransaction.cc b/src/sdk/main/src/FreezeTransaction.cc index c1063feaa..f3bc920e5 100644 --- a/src/sdk/main/src/FreezeTransaction.cc +++ b/src/sdk/main/src/FreezeTransaction.cc @@ -7,7 +7,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/NodeCreateTransaction.cc b/src/sdk/main/src/NodeCreateTransaction.cc index 1501a52b9..54b91cddd 100644 --- a/src/sdk/main/src/NodeCreateTransaction.cc +++ b/src/sdk/main/src/NodeCreateTransaction.cc @@ -8,7 +8,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/NodeDeleteTransaction.cc b/src/sdk/main/src/NodeDeleteTransaction.cc index ceefb8414..b575b9044 100644 --- a/src/sdk/main/src/NodeDeleteTransaction.cc +++ b/src/sdk/main/src/NodeDeleteTransaction.cc @@ -7,7 +7,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/NodeUpdateTransaction.cc b/src/sdk/main/src/NodeUpdateTransaction.cc index f63745fb4..5873a52f8 100644 --- a/src/sdk/main/src/NodeUpdateTransaction.cc +++ b/src/sdk/main/src/NodeUpdateTransaction.cc @@ -8,7 +8,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/Query.cc b/src/sdk/main/src/Query.cc index 2a983dce3..a314f2209 100644 --- a/src/sdk/main/src/Query.cc +++ b/src/sdk/main/src/Query.cc @@ -6,7 +6,6 @@ #include "AccountInfoQuery.h" #include "AccountRecords.h" #include "AccountRecordsQuery.h" -#include "AccountStakersQuery.h" #include "Client.h" #include "ContractByteCodeQuery.h" #include "ContractCallQuery.h" @@ -367,7 +366,6 @@ std::optional Query::getTransact template class Query; template class Query; template class Query; -template class Query; template class Query; template class Query; template class Query; diff --git a/src/sdk/main/src/ScheduleCreateTransaction.cc b/src/sdk/main/src/ScheduleCreateTransaction.cc index 3b2a04e07..eba0c37f8 100644 --- a/src/sdk/main/src/ScheduleCreateTransaction.cc +++ b/src/sdk/main/src/ScheduleCreateTransaction.cc @@ -8,7 +8,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/Status.cc b/src/sdk/main/src/Status.cc index c43214eeb..5e46cfd05 100644 --- a/src/sdk/main/src/Status.cc +++ b/src/sdk/main/src/Status.cc @@ -349,7 +349,28 @@ const std::unordered_map gProtobufResponseCodeT { proto::ResponseCodeEnum::SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE, Status::SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE }, { proto::ResponseCodeEnum::SCHEDULE_EXPIRY_IS_BUSY, Status::SCHEDULE_EXPIRY_IS_BUSY }, - { proto::ResponseCodeEnum::MISSING_EXPIRY_TIME, Status::MISSING_EXPIRY_TIME } + { proto::ResponseCodeEnum::MISSING_EXPIRY_TIME, Status::MISSING_EXPIRY_TIME }, + { proto::ResponseCodeEnum::NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION, + Status::NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION }, + { proto::ResponseCodeEnum::RECURSIVE_SCHEDULING_LIMIT_REACHED, Status::RECURSIVE_SCHEDULING_LIMIT_REACHED }, + { proto::ResponseCodeEnum::WAITING_FOR_LEDGER_ID, Status::WAITING_FOR_LEDGER_ID }, + { proto::ResponseCodeEnum::MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED, + Status::MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED }, + { proto::ResponseCodeEnum::FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS, + Status::FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS }, + { proto::ResponseCodeEnum::INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST, Status::INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST }, + { proto::ResponseCodeEnum::INVALID_FEE_SCHEDULE_KEY, Status::INVALID_FEE_SCHEDULE_KEY }, + { proto::ResponseCodeEnum::FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED, Status::FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED }, + { proto::ResponseCodeEnum::FEE_SCHEDULE_KEY_NOT_SET, Status::FEE_SCHEDULE_KEY_NOT_SET }, + { proto::ResponseCodeEnum::MAX_CUSTOM_FEE_LIMIT_EXCEEDED, Status::MAX_CUSTOM_FEE_LIMIT_EXCEEDED }, + { proto::ResponseCodeEnum::NO_VALID_MAX_CUSTOM_FEE, Status::NO_VALID_MAX_CUSTOM_FEE }, + { proto::ResponseCodeEnum::INVALID_MAX_CUSTOM_FEES, Status::INVALID_MAX_CUSTOM_FEES }, + { proto::ResponseCodeEnum::DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST, + Status::DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST }, + { proto::ResponseCodeEnum::DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST, + Status::DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST }, + { proto::ResponseCodeEnum::MAX_CUSTOM_FEES_IS_NOT_SUPPORTED, Status::MAX_CUSTOM_FEES_IS_NOT_SUPPORTED } + }; //----- @@ -696,7 +717,28 @@ const std::unordered_map gStatusToProtobufRespo { Status::SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE, proto::ResponseCodeEnum::SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE }, { Status::SCHEDULE_EXPIRY_IS_BUSY, proto::ResponseCodeEnum::SCHEDULE_EXPIRY_IS_BUSY }, - { Status::MISSING_EXPIRY_TIME, proto::ResponseCodeEnum::MISSING_EXPIRY_TIME } + { Status::MISSING_EXPIRY_TIME, proto::ResponseCodeEnum::MISSING_EXPIRY_TIME }, + { Status::NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION, + proto::ResponseCodeEnum::NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION }, + { Status::RECURSIVE_SCHEDULING_LIMIT_REACHED, proto::ResponseCodeEnum::RECURSIVE_SCHEDULING_LIMIT_REACHED }, + { Status::WAITING_FOR_LEDGER_ID, proto::ResponseCodeEnum::WAITING_FOR_LEDGER_ID }, + { Status::MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED, + proto::ResponseCodeEnum::MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED }, + { Status::FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS, + proto::ResponseCodeEnum::FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS }, + { Status::INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST, proto::ResponseCodeEnum::INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST }, + { Status::INVALID_FEE_SCHEDULE_KEY, proto::ResponseCodeEnum::INVALID_FEE_SCHEDULE_KEY }, + { Status::FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED, proto::ResponseCodeEnum::FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED }, + { Status::FEE_SCHEDULE_KEY_NOT_SET, proto::ResponseCodeEnum::FEE_SCHEDULE_KEY_NOT_SET }, + { Status::MAX_CUSTOM_FEE_LIMIT_EXCEEDED, proto::ResponseCodeEnum::MAX_CUSTOM_FEE_LIMIT_EXCEEDED }, + { Status::NO_VALID_MAX_CUSTOM_FEE, proto::ResponseCodeEnum::NO_VALID_MAX_CUSTOM_FEE }, + { Status::INVALID_MAX_CUSTOM_FEES, proto::ResponseCodeEnum::INVALID_MAX_CUSTOM_FEES }, + { Status::DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST, + proto::ResponseCodeEnum::DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST }, + { Status::DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST, + proto::ResponseCodeEnum::DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST }, + { Status::MAX_CUSTOM_FEES_IS_NOT_SUPPORTED, proto::ResponseCodeEnum::MAX_CUSTOM_FEES_IS_NOT_SUPPORTED } + }; //----- @@ -1024,7 +1066,23 @@ const std::unordered_map gStatusToString = { "SCHEDULE_EXPIRATION_TIME_MUST_BE_HIGHER_THAN_CONSENSUS_TIME" }, { Status::SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE, "SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE" }, { Status::SCHEDULE_EXPIRY_IS_BUSY, "SCHEDULE_EXPIRY_IS_BUSY" }, - { Status::MISSING_EXPIRY_TIME, "MISSING_EXPIRY_TIME" } + { Status::MISSING_EXPIRY_TIME, "MISSING_EXPIRY_TIME" }, + { Status::NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION, "NO_SCHEDULING_ALLOWED_AFTER_SCHEDULED_RECURSION" }, + { Status::RECURSIVE_SCHEDULING_LIMIT_REACHED, "RECURSIVE_SCHEDULING_LIMIT_REACHED" }, + { Status::WAITING_FOR_LEDGER_ID, "WAITING_FOR_LEDGER_ID" }, + { Status::MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED, "MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED" }, + { Status::FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS, "FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS" }, + { Status::INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST, "INVALID_KEY_IN_FEE_EXEMPT_KEY_LIST" }, + { Status::INVALID_FEE_SCHEDULE_KEY, "INVALID_FEE_SCHEDULE_KEY" }, + { Status::FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED, "FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED" }, + { Status::FEE_SCHEDULE_KEY_NOT_SET, "FEE_SCHEDULE_KEY_NOT_SET" }, + { Status::MAX_CUSTOM_FEE_LIMIT_EXCEEDED, "MAX_CUSTOM_FEE_LIMIT_EXCEEDED" }, + { Status::NO_VALID_MAX_CUSTOM_FEE, "NO_VALID_MAX_CUSTOM_FEE" }, + { Status::INVALID_MAX_CUSTOM_FEES, "INVALID_MAX_CUSTOM_FEES" }, + { Status::DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST, "DUPLICATE_DENOMINATION_IN_MAX_CUSTOM_FEE_LIST" }, + { Status::DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST, "DUPLICATE_ACCOUNT_ID_IN_MAX_CUSTOM_FEE_LIST" }, + { Status::MAX_CUSTOM_FEES_IS_NOT_SUPPORTED, "MAX_CUSTOM_FEES_IS_NOT_SUPPORTED" } + }; diff --git a/src/sdk/main/src/TokenAirdropTransaction.cc b/src/sdk/main/src/TokenAirdropTransaction.cc index 13a77e199..09d01b0f5 100644 --- a/src/sdk/main/src/TokenAirdropTransaction.cc +++ b/src/sdk/main/src/TokenAirdropTransaction.cc @@ -9,7 +9,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenCancelAirdropTransaction.cc b/src/sdk/main/src/TokenCancelAirdropTransaction.cc index c0c65a1d3..97953bdba 100644 --- a/src/sdk/main/src/TokenCancelAirdropTransaction.cc +++ b/src/sdk/main/src/TokenCancelAirdropTransaction.cc @@ -9,7 +9,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenClaimAirdropTransaction.cc b/src/sdk/main/src/TokenClaimAirdropTransaction.cc index 5b40eaa91..62cded590 100644 --- a/src/sdk/main/src/TokenClaimAirdropTransaction.cc +++ b/src/sdk/main/src/TokenClaimAirdropTransaction.cc @@ -9,7 +9,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenCreateTransaction.cc b/src/sdk/main/src/TokenCreateTransaction.cc index 3400fd0a9..a7a112581 100644 --- a/src/sdk/main/src/TokenCreateTransaction.cc +++ b/src/sdk/main/src/TokenCreateTransaction.cc @@ -10,7 +10,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenMintTransaction.cc b/src/sdk/main/src/TokenMintTransaction.cc index 88c1ba732..cd4c87fbc 100644 --- a/src/sdk/main/src/TokenMintTransaction.cc +++ b/src/sdk/main/src/TokenMintTransaction.cc @@ -7,7 +7,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenRejectTransaction.cc b/src/sdk/main/src/TokenRejectTransaction.cc index 589584143..6cd6d13dd 100644 --- a/src/sdk/main/src/TokenRejectTransaction.cc +++ b/src/sdk/main/src/TokenRejectTransaction.cc @@ -9,7 +9,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenUpdateNftsTransaction.cc b/src/sdk/main/src/TokenUpdateNftsTransaction.cc index 50fbd4215..df795f327 100644 --- a/src/sdk/main/src/TokenUpdateNftsTransaction.cc +++ b/src/sdk/main/src/TokenUpdateNftsTransaction.cc @@ -9,7 +9,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TokenUpdateTransaction.cc b/src/sdk/main/src/TokenUpdateTransaction.cc index 75b955caa..c814e1dec 100644 --- a/src/sdk/main/src/TokenUpdateTransaction.cc +++ b/src/sdk/main/src/TokenUpdateTransaction.cc @@ -9,7 +9,6 @@ #include #include #include -#include namespace Hiero { diff --git a/src/sdk/main/src/TopicCreateTransaction.cc b/src/sdk/main/src/TopicCreateTransaction.cc index d7aaaac2b..dbee0f42b 100644 --- a/src/sdk/main/src/TopicCreateTransaction.cc +++ b/src/sdk/main/src/TopicCreateTransaction.cc @@ -6,7 +6,6 @@ #include #include #include -#include namespace Hiero { @@ -65,6 +64,46 @@ TopicCreateTransaction& TopicCreateTransaction::setAutoRenewAccountId(const Acco return *this; } +//----- +TopicCreateTransaction& TopicCreateTransaction::setFeeScheduleKey(const std::shared_ptr& key) +{ + requireNotFrozen(); + mFeeScheduleKey = key; + return *this; +} + +//----- +TopicCreateTransaction& TopicCreateTransaction::setFeeExemptKeys(const std::vector>& keys) +{ + requireNotFrozen(); + mFeeExemptKeys = keys; + return *this; +} + +//----- +TopicCreateTransaction& TopicCreateTransaction::addFeeExemptKey(const std::shared_ptr& key) +{ + requireNotFrozen(); + mFeeExemptKeys.push_back(key); + return *this; +} + +//----- +TopicCreateTransaction& TopicCreateTransaction::setCustomFixedFees(const std::vector& fees) +{ + requireNotFrozen(); + mCustomFixedFees = fees; + return *this; +} + +//----- +TopicCreateTransaction& TopicCreateTransaction::addCustomFixedFee(const CustomFixedFee& fee) +{ + requireNotFrozen(); + mCustomFixedFees.push_back(fee); + return *this; +} + //----- grpc::Status TopicCreateTransaction::submitRequest(const proto::Transaction& request, const std::shared_ptr& node, @@ -122,6 +161,22 @@ void TopicCreateTransaction::initFromSourceTransactionBody() { mAutoRenewAccountId = AccountId::fromProtobuf(body.autorenewaccount()); } + + if (body.has_fee_schedule_key()) + { + mFeeScheduleKey = Key::fromProtobuf(body.fee_schedule_key()); + } + + for (const auto& key : body.fee_exempt_key_list()) + { + mFeeExemptKeys.push_back(Key::fromProtobuf(key)); + } + + for (const auto& fee : body.custom_fees()) + { + mCustomFixedFees.push_back(CustomFixedFee::fromProtobuf(fee.fixed_fee()) + .setFeeCollectorAccountId(AccountId::fromProtobuf(fee.fee_collector_account_id()))); + } } //----- @@ -148,6 +203,24 @@ proto::ConsensusCreateTopicTransactionBody* TopicCreateTransaction::build() cons body->set_allocated_autorenewaccount(mAutoRenewAccountId->toProtobuf().release()); } + if (mFeeScheduleKey) + { + body->set_allocated_fee_schedule_key(mFeeScheduleKey->toProtobufKey().release()); + } + + for (const auto& key : mFeeExemptKeys) + { + body->mutable_fee_exempt_key_list()->AddAllocated(key->toProtobufKey().release()); + } + + for (const auto& fee : mCustomFixedFees) + { + std::unique_ptr fixedCustomFee = std::make_unique(); + fixedCustomFee->set_allocated_fixed_fee(fee.toFixedFeeProtobuf().release()); + fixedCustomFee->set_allocated_fee_collector_account_id(fee.getFeeCollectorAccountId().toProtobuf().release()); + body->mutable_custom_fees()->AddAllocated(fixedCustomFee.release()); + } + return body.release(); } diff --git a/src/sdk/main/src/TopicInfo.cc b/src/sdk/main/src/TopicInfo.cc index 933441aea..d599be678 100644 --- a/src/sdk/main/src/TopicInfo.cc +++ b/src/sdk/main/src/TopicInfo.cc @@ -53,6 +53,23 @@ TopicInfo TopicInfo::fromProtobuf(const proto::ConsensusGetTopicInfoResponse& pr topicInfo.mLedgerId = LedgerId(internal::Utilities::stringToByteVector(consensusTopicInfo.ledger_id())); + if (consensusTopicInfo.has_fee_schedule_key()) + { + topicInfo.mFeeScheduleKey = Key::fromProtobuf(consensusTopicInfo.fee_schedule_key()); + } + + for (const auto& key : consensusTopicInfo.fee_exempt_key_list()) + { + topicInfo.mFeeExemptKeys.push_back(Key::fromProtobuf(key)); + } + + for (const auto& fee : consensusTopicInfo.custom_fees()) + { + topicInfo.mCustomFixedFees.push_back( + CustomFixedFee::fromProtobuf(fee.fixed_fee()) + .setFeeCollectorAccountId(AccountId::fromProtobuf(fee.fee_collector_account_id()))); + } + return topicInfo; } @@ -98,6 +115,23 @@ std::unique_ptr TopicInfo::toProtobuf() co protoTopicInfo->mutable_topicinfo()->set_ledger_id(internal::Utilities::byteVectorToString(mLedgerId.toBytes())); + if (mFeeScheduleKey) + { + protoTopicInfo->mutable_topicinfo()->set_allocated_fee_schedule_key(mFeeScheduleKey->toProtobufKey().release()); + } + + for (const auto& key : mFeeExemptKeys) + { + protoTopicInfo->mutable_topicinfo()->mutable_fee_exempt_key_list()->AddAllocated(key->toProtobufKey().release()); + } + + for (const auto& fee : mCustomFixedFees) + { + std::unique_ptr fixedCustomFee = std::make_unique(); + fixedCustomFee->set_allocated_fixed_fee(fee.toFixedFeeProtobuf().release()); + protoTopicInfo->mutable_topicinfo()->mutable_custom_fees()->AddAllocated(fixedCustomFee.release()); + } + return protoTopicInfo; } @@ -138,6 +172,24 @@ std::string TopicInfo::toString() const } json["mLedgerId"] = mLedgerId.toString(); + + if (mFeeScheduleKey) + { + json["mFeeScheduleKey"] = internal::HexConverter::bytesToHex(mFeeScheduleKey->toBytes()); + } + + json["mFeeExemptKeys"] = nlohmann::json::array(); + for (const auto& key : mFeeExemptKeys) + { + json["mFeeExemptKeys"].push_back(internal::HexConverter::bytesToHex(key->toBytes())); + } + + json["mCustomFixedFees"] = nlohmann::json::array(); + for (const auto& fee : mCustomFixedFees) + { + json["mCustomFixedFees"].push_back(fee.toString()); + } + return json.dump(); } diff --git a/src/sdk/main/src/TopicMessageSubmitTransaction.cc b/src/sdk/main/src/TopicMessageSubmitTransaction.cc index 6a3029b95..d667469d9 100644 --- a/src/sdk/main/src/TopicMessageSubmitTransaction.cc +++ b/src/sdk/main/src/TopicMessageSubmitTransaction.cc @@ -8,7 +8,6 @@ #include #include #include -#include #include namespace Hiero @@ -52,6 +51,31 @@ TopicMessageSubmitTransaction& TopicMessageSubmitTransaction::setMessage(std::st return *this; } +//----- +TopicMessageSubmitTransaction& TopicMessageSubmitTransaction::setCustomFeeLimits( + const std::vector& customFeeLimits) +{ + requireNotFrozen(); + mCustomFeeLimits = customFeeLimits; + return *this; +} + +//----- +TopicMessageSubmitTransaction& TopicMessageSubmitTransaction::addCustomFeeLimit(const CustomFeeLimit& customFeeLimit) +{ + requireNotFrozen(); + mCustomFeeLimits.push_back(customFeeLimit); + return *this; +} + +//----- +TopicMessageSubmitTransaction& TopicMessageSubmitTransaction::clearCustomFeeLimits() +{ + requireNotFrozen(); + mCustomFeeLimits.clear(); + return *this; +} + //----- grpc::Status TopicMessageSubmitTransaction::submitRequest(const proto::Transaction& request, const std::shared_ptr& node, @@ -80,6 +104,10 @@ void TopicMessageSubmitTransaction::addToChunk(uint32_t chunk, uint32_t total, p body.set_allocated_consensussubmitmessage(build(static_cast(chunk))); body.mutable_consensussubmitmessage()->mutable_chunkinfo()->set_allocated_initialtransactionid( getTransactionId().toProtobuf().release()); + for (const auto& fee : mCustomFeeLimits) + { + body.mutable_max_custom_fees()->AddAllocated(fee.toProtobuf().release()); + } body.mutable_consensussubmitmessage()->mutable_chunkinfo()->set_number(static_cast(chunk + 1)); body.mutable_consensussubmitmessage()->mutable_chunkinfo()->set_total(static_cast(total)); } @@ -123,6 +151,15 @@ void TopicMessageSubmitTransaction::initFromSourceTransactionBody() proto::TransactionBody txBody; txBody.ParseFromArray(signedTx.bodybytes().data(), static_cast(signedTx.bodybytes().size())); + // Should also set the custom fee limits but only once as every chunk would contain the limits. + if (mCustomFeeLimits.empty()) + { + for (const auto& feeLimit : txBody.max_custom_fees()) + { + mCustomFeeLimits.push_back(CustomFeeLimit::fromProtobuf(feeLimit)); + } + } + data += txBody.consensussubmitmessage().message(); } diff --git a/src/sdk/main/src/TopicUpdateTransaction.cc b/src/sdk/main/src/TopicUpdateTransaction.cc index 1f690cc44..626bebea5 100644 --- a/src/sdk/main/src/TopicUpdateTransaction.cc +++ b/src/sdk/main/src/TopicUpdateTransaction.cc @@ -8,7 +8,6 @@ #include #include #include -#include namespace Hiero { @@ -83,6 +82,46 @@ TopicUpdateTransaction& TopicUpdateTransaction::setAutoRenewAccountId(const Acco return *this; } +//----- +TopicUpdateTransaction& TopicUpdateTransaction::setFeeScheduleKey(const std::shared_ptr& key) +{ + requireNotFrozen(); + mFeeScheduleKey = key; + return *this; +} + +//----- +TopicUpdateTransaction& TopicUpdateTransaction::setFeeExemptKeys(const std::vector>& keys) +{ + requireNotFrozen(); + mFeeExemptKeys = keys; + return *this; +} + +//----- +TopicUpdateTransaction& TopicUpdateTransaction::addFeeExemptKey(const std::shared_ptr& key) +{ + requireNotFrozen(); + mFeeExemptKeys.push_back(key); + return *this; +} + +//----- +TopicUpdateTransaction& TopicUpdateTransaction::setCustomFixedFees(const std::vector& fees) +{ + requireNotFrozen(); + mCustomFixedFees = fees; + return *this; +} + +//----- +TopicUpdateTransaction& TopicUpdateTransaction::addCustomFixedFee(const CustomFixedFee& fee) +{ + requireNotFrozen(); + mCustomFixedFees.push_back(fee); + return *this; +} + //----- TopicUpdateTransaction& TopicUpdateTransaction::clearTopicMemo() { @@ -187,6 +226,22 @@ void TopicUpdateTransaction::initFromSourceTransactionBody() { mAutoRenewAccountId = AccountId::fromProtobuf(body.autorenewaccount()); } + + if (body.has_fee_schedule_key()) + { + mFeeScheduleKey = Key::fromProtobuf(body.fee_schedule_key()); + } + + for (const auto& key : body.fee_exempt_key_list().keys()) + { + mFeeExemptKeys.push_back(Key::fromProtobuf(key)); + } + + for (const auto& fee : body.custom_fees().fees()) + { + mCustomFixedFees.push_back(CustomFixedFee::fromProtobuf(fee.fixed_fee()) + .setFeeCollectorAccountId(AccountId::fromProtobuf(fee.fee_collector_account_id()))); + } } //----- @@ -229,6 +284,23 @@ proto::ConsensusUpdateTopicTransactionBody* TopicUpdateTransaction::build() cons body->set_allocated_autorenewaccount(mAutoRenewAccountId->toProtobuf().release()); } + if (mFeeScheduleKey) + { + body->set_allocated_fee_schedule_key(mFeeScheduleKey->toProtobufKey().release()); + } + + for (const auto& key : mFeeExemptKeys) + { + body->mutable_fee_exempt_key_list()->mutable_keys()->AddAllocated(key->toProtobufKey().release()); + } + + for (const auto& fee : mCustomFixedFees) + { + std::unique_ptr fixedCustomFee = std::make_unique(); + fixedCustomFee->set_allocated_fixed_fee(fee.toFixedFeeProtobuf().release()); + body->mutable_custom_fees()->mutable_fees()->AddAllocated(fixedCustomFee.release()); + } + return body.release(); } diff --git a/src/sdk/main/src/Transaction.cc b/src/sdk/main/src/Transaction.cc index 3a47b8da3..d5fd263e3 100644 --- a/src/sdk/main/src/Transaction.cc +++ b/src/sdk/main/src/Transaction.cc @@ -66,7 +66,7 @@ #include #include -#include + #include #include #include diff --git a/src/sdk/main/src/WrappedTransaction.cc b/src/sdk/main/src/WrappedTransaction.cc index e0e2efae6..ba4ab7600 100644 --- a/src/sdk/main/src/WrappedTransaction.cc +++ b/src/sdk/main/src/WrappedTransaction.cc @@ -3,7 +3,7 @@ #include "exceptions/UninitializedException.h" #include -#include +#include namespace Hiero { diff --git a/src/sdk/main/src/impl/Node.cc b/src/sdk/main/src/impl/Node.cc index 02e707ef9..d99bd54c3 100644 --- a/src/sdk/main/src/impl/Node.cc +++ b/src/sdk/main/src/impl/Node.cc @@ -50,8 +50,6 @@ grpc::Status Node::submitQuery(proto::Query::QueryCase funcEnum, return mCryptoStub->getAccountInfo(&context, query, response); case proto::Query::QueryCase::kCryptoGetLiveHash: return mCryptoStub->getLiveHash(&context, query, response); - case proto::Query::QueryCase::kCryptoGetProxyStakers: - return mCryptoStub->getStakersByAccountID(&context, query, response); case proto::Query::QueryCase::kFileGetContents: return mFileStub->getFileContent(&context, query, response); case proto::Query::QueryCase::kFileGetInfo: diff --git a/src/sdk/tests/integration/AccountCreateTransactionIntegrationTests.cc b/src/sdk/tests/integration/AccountCreateTransactionIntegrationTests.cc index 22fb7b465..10e1babdc 100644 --- a/src/sdk/tests/integration/AccountCreateTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/AccountCreateTransactionIntegrationTests.cc @@ -23,7 +23,6 @@ #include "impl/Network.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/BaseIntegrationTest.cc b/src/sdk/tests/integration/BaseIntegrationTest.cc index ada5c0f73..1818b8721 100644 --- a/src/sdk/tests/integration/BaseIntegrationTest.cc +++ b/src/sdk/tests/integration/BaseIntegrationTest.cc @@ -27,4 +27,17 @@ void BaseIntegrationTest::SetUp() .get()); } +//----- +void BaseIntegrationTest::setTestClientOperator(const AccountId& accountId, + const std::shared_ptr& privateKey) +{ + mClient.setOperator(accountId, privateKey); +} + +//----- +void BaseIntegrationTest::setDefaultTestClientOperator() +{ + setTestClientOperator(mDefaultTestAccountId, mDefaultTestPrivateKey); +} + } // namespace Hiero diff --git a/src/sdk/tests/integration/BaseIntegrationTest.h b/src/sdk/tests/integration/BaseIntegrationTest.h index 5b945616b..74cc46e1b 100644 --- a/src/sdk/tests/integration/BaseIntegrationTest.h +++ b/src/sdk/tests/integration/BaseIntegrationTest.h @@ -4,6 +4,8 @@ #include "AccountId.h" #include "Client.h" +#include "ED25519PrivateKey.h" +#include "PrivateKey.h" #include #include @@ -15,16 +17,19 @@ class BaseIntegrationTest : public testing::Test { protected: [[nodiscard]] inline const Client& getTestClient() const { return mClient; } - [[nodiscard]] inline const AccountId& getDefaultTestAccountId() const { return mDefaultTestAccountId; } [[nodiscard]] inline const std::vector& getTestFileContent() const { return mFileContent; } [[nodiscard]] inline const std::string& getTestSmartContractBytecode() const { return mTestContractBytecodeHex; } + void setTestClientOperator(const AccountId& accountId, const std::shared_ptr& privateKey); + void setDefaultTestClientOperator(); void SetUp() override; private: Client mClient; std::vector mFileContent; - const AccountId mDefaultTestAccountId = AccountId::fromString("0.0.1023"); + const AccountId mDefaultTestAccountId = AccountId::fromString("0.0.2"); + const std::shared_ptr mDefaultTestPrivateKey = ED25519PrivateKey::fromString( + "302e020100300506032b65700422042091132178e72057a1d7528025956fe39b0b847f200ab59b2fdd367017f3087137"); const std::string mTestContractBytecodeHex = "608060405234801561001057600080fd5b506040516104d73803806104d78339818101604052602081101561003357600080fd5b8101908080" "51604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081" diff --git a/src/sdk/tests/integration/CMakeLists.txt b/src/sdk/tests/integration/CMakeLists.txt index 2db3b20f5..d5bd8684f 100644 --- a/src/sdk/tests/integration/CMakeLists.txt +++ b/src/sdk/tests/integration/CMakeLists.txt @@ -6,7 +6,6 @@ add_executable(${TEST_PROJECT_NAME} AccountDeleteTransactionIntegrationTests.cc AccountInfoQueryIntegrationTests.cc AccountRecordsQueryIntegrationTests.cc - AccountStakersQueryIntegrationTests.cc AccountUpdateTransactionIntegrationTests.cc AddressBookQueryIntegrationTests.cc BaseIntegrationTest.cc diff --git a/src/sdk/tests/integration/ExecutableIntegrationTests.cc b/src/sdk/tests/integration/ExecutableIntegrationTests.cc index eabc16df9..07819230e 100644 --- a/src/sdk/tests/integration/ExecutableIntegrationTests.cc +++ b/src/sdk/tests/integration/ExecutableIntegrationTests.cc @@ -9,7 +9,6 @@ #include "AccountInfoQuery.h" #include "AccountRecords.h" #include "AccountRecordsQuery.h" -#include "AccountStakersQuery.h" #include "AccountUpdateTransaction.h" #include "BaseIntegrationTest.h" #include "ContractByteCodeQuery.h" @@ -91,7 +90,6 @@ using ExecutableTypes = ::testing::Types, std::tuple, std::tuple, - std::tuple, std::tuple, std::tuple, std::tuple, diff --git a/src/sdk/tests/integration/QueryIntegrationTests.cc b/src/sdk/tests/integration/QueryIntegrationTests.cc index 5d5c74d11..a545baa58 100644 --- a/src/sdk/tests/integration/QueryIntegrationTests.cc +++ b/src/sdk/tests/integration/QueryIntegrationTests.cc @@ -5,7 +5,6 @@ #include "AccountInfoQuery.h" #include "AccountRecords.h" #include "AccountRecordsQuery.h" -#include "AccountStakersQuery.h" #include "BaseIntegrationTest.h" #include "ContractByteCodeQuery.h" #include "ContractCallQuery.h" @@ -48,7 +47,6 @@ class QueryIntegrationTests : public BaseIntegrationTest using QueryTypes = ::testing::Types -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/ScheduleSignTransactionIntegrationTests.cc b/src/sdk/tests/integration/ScheduleSignTransactionIntegrationTests.cc index 426f48783..e18f2a9e0 100644 --- a/src/sdk/tests/integration/ScheduleSignTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/ScheduleSignTransactionIntegrationTests.cc @@ -17,7 +17,6 @@ #include "exceptions/ReceiptStatusException.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/SystemDeleteTransactionIntegrationTests.cc b/src/sdk/tests/integration/SystemDeleteTransactionIntegrationTests.cc index 9d9712442..0c740bb8b 100644 --- a/src/sdk/tests/integration/SystemDeleteTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/SystemDeleteTransactionIntegrationTests.cc @@ -16,7 +16,6 @@ #include "exceptions/ReceiptStatusException.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/SystemUndeleteTransactionIntegrationTests.cc b/src/sdk/tests/integration/SystemUndeleteTransactionIntegrationTests.cc index b57563ce3..b62bad716 100644 --- a/src/sdk/tests/integration/SystemUndeleteTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/SystemUndeleteTransactionIntegrationTests.cc @@ -12,7 +12,6 @@ #include "exceptions/PrecheckStatusException.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/TopicCreateTransactionIntegrationTests.cc b/src/sdk/tests/integration/TopicCreateTransactionIntegrationTests.cc index e5277ce33..3de52fa16 100644 --- a/src/sdk/tests/integration/TopicCreateTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/TopicCreateTransactionIntegrationTests.cc @@ -1,9 +1,11 @@ // SPDX-License-Identifier: Apache-2.0 #include "AccountDeleteTransaction.h" #include "BaseIntegrationTest.h" +#include "CustomFixedFee.h" #include "Defaults.h" #include "ECDSAsecp256k1PrivateKey.h" #include "ED25519PrivateKey.h" +#include "TokenCreateTransaction.h" #include "TopicCreateTransaction.h" #include "TopicDeleteTransaction.h" #include "TopicInfo.h" @@ -11,9 +13,11 @@ #include "TransactionReceipt.h" #include "TransactionRecord.h" #include "TransactionResponse.h" +#include "exceptions/PrecheckStatusException.h" +#include "exceptions/ReceiptStatusException.h" +#include "impl/HexConverter.h" #include -#include using namespace Hiero; @@ -76,3 +80,81 @@ TEST_F(TopicCreateTransactionIntegrationTests, CanCreateTopicWithNoFieldsSet) // Then EXPECT_TRUE(txReceipt.mTopicId.has_value()); } + +//----- +TEST_F(TopicCreateTransactionIntegrationTests, RevenueGeneratingTopicCanCreate) +{ + // Given + std::vector> exemptKeys; + for (int i = 0; i < 2; i++) + { + ASSERT_NO_THROW(exemptKeys.push_back(ED25519PrivateKey::generatePrivateKey())); + } + const std::string topicMemo = "memo"; + + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(2).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + // When + TopicId topicId; + EXPECT_NO_THROW(topicId = TopicCreateTransaction() + .setMemo(topicMemo) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeExemptKeys(exemptKeys) + .setCustomFixedFees({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + // Then + TopicInfo topicInfo; + EXPECT_NO_THROW(topicInfo = TopicInfoQuery().setTopicId(topicId).execute(getTestClient())); + + EXPECT_EQ(topicMemo, topicInfo.mMemo); + EXPECT_EQ(getTestClient().getOperatorPublicKey()->toBytes(), topicInfo.mAdminKey->toBytes()); + ASSERT_EQ(exemptKeys.size(), topicInfo.mFeeExemptKeys.size()); + EXPECT_EQ(std::dynamic_pointer_cast(exemptKeys[0])->getPublicKey()->toBytes(), + topicInfo.mFeeExemptKeys[0]->toBytes()); + EXPECT_EQ(std::dynamic_pointer_cast(exemptKeys[1])->getPublicKey()->toBytes(), + topicInfo.mFeeExemptKeys[1]->toBytes()); + EXPECT_EQ(customFixedFee.toString(), topicInfo.mCustomFixedFees[0].toString()); +} + +//----- +TEST_F(TopicCreateTransactionIntegrationTests, RevenueGeneratingTopicCannotCreateWithInvalidExemptKey) +{ + // Given + std::vector> exemptKeys; + for (int i = 0; i < 11; i++) + { + ASSERT_NO_THROW(exemptKeys.push_back(ED25519PrivateKey::generatePrivateKey())); + } + + // When / Then + // Duplicate exempt key + EXPECT_THROW(TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeExemptKeys({ exemptKeys[0], exemptKeys[0] }) + .execute(getTestClient()) + .getReceipt(getTestClient()), + PrecheckStatusException); // FEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS + + // Set 11 keys + EXPECT_THROW(TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeExemptKeys(exemptKeys) + .execute(getTestClient()) + .getReceipt(getTestClient()), + ReceiptStatusException); // MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST_EXCEEDED +} diff --git a/src/sdk/tests/integration/TopicDeleteTransactionIntegrationTests.cc b/src/sdk/tests/integration/TopicDeleteTransactionIntegrationTests.cc index 087ac7e56..375a2ca89 100644 --- a/src/sdk/tests/integration/TopicDeleteTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/TopicDeleteTransactionIntegrationTests.cc @@ -12,7 +12,6 @@ #include "exceptions/ReceiptStatusException.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/TopicMessageSubmitTransactionIntegrationTests.cc b/src/sdk/tests/integration/TopicMessageSubmitTransactionIntegrationTests.cc index 30d456c14..b672de0b4 100644 --- a/src/sdk/tests/integration/TopicMessageSubmitTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/TopicMessageSubmitTransactionIntegrationTests.cc @@ -1,6 +1,14 @@ // SPDX-License-Identifier: Apache-2.0 +#include "AccountBalance.h" +#include "AccountBalanceQuery.h" +#include "AccountCreateTransaction.h" +#include "AccountInfo.h" +#include "AccountInfoQuery.h" #include "BaseIntegrationTest.h" +#include "CustomFeeLimit.h" #include "ED25519PrivateKey.h" +#include "TokenAssociateTransaction.h" +#include "TokenCreateTransaction.h" #include "TopicCreateTransaction.h" #include "TopicDeleteTransaction.h" #include "TopicInfo.h" @@ -9,13 +17,13 @@ #include "TransactionReceipt.h" #include "TransactionRecord.h" #include "TransactionResponse.h" +#include "TransferTransaction.h" #include "exceptions/PrecheckStatusException.h" #include "exceptions/ReceiptStatusException.h" #include #include #include -#include using namespace Hiero; @@ -365,4 +373,606 @@ TEST_F(TopicMessageSubmitTransactionIntegrationTests, CanSubmitTopicMessageWitho // Clean up ASSERT_NO_THROW(const TransactionReceipt txReceipt = TopicDeleteTransaction().setTopicId(topicId).execute(getTestClient()).getReceipt(getTestClient())); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCanChargeHbarsWithLimit) +{ + // Given + int64_t feeAmount = 100000000; // 1 HBAR equivalent + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = CustomFixedFee().setAmount(feeAmount).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + Hbar initialBalance = Hbar(3LL); + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setInitialBalance(initialBalance) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + CustomFeeLimit limit; + ASSERT_NO_THROW(limit = CustomFeeLimit().setPayerId(accountId).addCustomFee(CustomFixedFee().setAmount(feeAmount))); + + // When + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .addCustomFeeLimit(limit) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountInfo accountInfo; + EXPECT_NO_THROW(accountInfo = AccountInfoQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_LT(accountInfo.mBalance.toTinybars(), initialBalance.toTinybars() - feeAmount); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCanChargeHbarsWithoutLimit) +{ + // Given + int64_t feeAmount = 100000000; // 1 HBAR equivalent + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = CustomFixedFee().setAmount(feeAmount).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + Hbar initialBalance = Hbar(3LL); + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setInitialBalance(initialBalance) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + // When + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountInfo accountInfo; + EXPECT_NO_THROW(accountInfo = AccountInfoQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_LT(accountInfo.mBalance.toTinybars(), initialBalance.toTinybars() - feeAmount); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCanChargeTokensWithLimit) +{ + // Given + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setInitialSupply(10) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + uint64_t accountTokenBalance = 1; + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setMaxAutomaticTokenAssociations(-1) + .setInitialBalance(Hbar(2LL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + // When + EXPECT_NO_THROW(TransferTransaction() + .addTokenTransfer(tokenId, getTestClient().getOperatorAccountId().value(), -accountTokenBalance) + .addTokenTransfer(tokenId, accountId, accountTokenBalance) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + CustomFeeLimit limit; + EXPECT_NO_THROW(limit = CustomFeeLimit().setPayerId(accountId).addCustomFee( + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId))); + + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .addCustomFeeLimit(limit) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountBalance accountBalance; + EXPECT_NO_THROW(accountBalance = AccountBalanceQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_LT(accountBalance.mTokens[tokenId], accountTokenBalance); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCanChargeTokensWithoutLimit) +{ + // Given + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setInitialSupply(10) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + uint64_t accountTokenBalance = 1; + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setMaxAutomaticTokenAssociations(-1) + .setInitialBalance(Hbar(2LL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + // When + EXPECT_NO_THROW(TransferTransaction() + .addTokenTransfer(tokenId, getTestClient().getOperatorAccountId().value(), -accountTokenBalance) + .addTokenTransfer(tokenId, accountId, accountTokenBalance) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountBalance accountBalance; + EXPECT_NO_THROW(accountBalance = AccountBalanceQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_LT(accountBalance.mTokens[tokenId], accountTokenBalance); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicDoesNotChargeHbarsFeeExemptKeys) +{ + // Given + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + Hbar initialBalance = Hbar(3LL); + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setInitialBalance(initialBalance) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + int64_t feeAmount = 100000000; // 1 HBAR equivalent + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = CustomFixedFee().setAmount(feeAmount).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addFeeExemptKey(accountKey) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + // When + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountInfo accountInfo; + EXPECT_NO_THROW(accountInfo = AccountInfoQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_LT(initialBalance.toTinybars() - accountInfo.mBalance.toTinybars(), feeAmount); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicDoesNotChargeTokensFeeExemptKeys) +{ + // Given + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + Hbar initialBalance = Hbar(3LL); + uint64_t accountTokenBalance = 1; + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setMaxAutomaticTokenAssociations(-1) + .setInitialBalance(initialBalance) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setInitialSupply(10) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addFeeExemptKey(accountKey) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + // When + EXPECT_NO_THROW(TransferTransaction() + .addTokenTransfer(tokenId, getTestClient().getOperatorAccountId().value(), -accountTokenBalance) + .addTokenTransfer(tokenId, accountId, accountTokenBalance) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountBalance accountBalance; + EXPECT_NO_THROW(accountBalance = AccountBalanceQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_EQ(accountBalance.mTokens[tokenId], accountTokenBalance); +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCannotChargeHbarsWithLowerLimit) +{ + // Given + int64_t feeAmount = 100000000; // 1 HBAR equivalent + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = CustomFixedFee().setAmount(feeAmount).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + Hbar initialBalance = Hbar(3LL); + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setInitialBalance(initialBalance) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + CustomFeeLimit limit; + ASSERT_NO_THROW(limit = + CustomFeeLimit().setPayerId(accountId).addCustomFee(CustomFixedFee().setAmount(feeAmount - 1))); + + // When / Then + // Submit a message to the revenue generating topic with lower fee limit than the actual fee required + setTestClientOperator(accountId, accountKey); + EXPECT_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .addCustomFeeLimit(limit) + .execute(getTestClient()) + .getReceipt(getTestClient()), + ReceiptStatusException); // MAX_CUSTOM_FEE_LIMIT_EXCEEDED +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCannotChargeTokensWithLowerLimit) +{ + // Given + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setInitialSupply(10) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(2).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + uint64_t accountTokenBalance = 1; + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setMaxAutomaticTokenAssociations(-1) + .setInitialBalance(Hbar(2LL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + // When / Then + EXPECT_NO_THROW(TransferTransaction() + .addTokenTransfer(tokenId, getTestClient().getOperatorAccountId().value(), -accountTokenBalance) + .addTokenTransfer(tokenId, accountId, accountTokenBalance) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + CustomFeeLimit limit; + EXPECT_NO_THROW(limit = CustomFeeLimit().setPayerId(accountId).addCustomFee( + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId))); + + setTestClientOperator(accountId, accountKey); + EXPECT_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .addCustomFeeLimit(limit) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient()), + ReceiptStatusException); // MAX_CUSTOM_FEE_LIMIT_EXCEEDED +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicCannotChargeTokensWithInvalidCustomFeeLimit) +{ + // Given + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setInitialSupply(10) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + uint64_t accountTokenBalance = 1; + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setMaxAutomaticTokenAssociations(-1) + .setInitialBalance(Hbar(2LL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + // When / Then + EXPECT_NO_THROW(TransferTransaction() + .addTokenTransfer(tokenId, getTestClient().getOperatorAccountId().value(), -accountTokenBalance) + .addTokenTransfer(tokenId, accountId, accountTokenBalance) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + CustomFeeLimit limit; + EXPECT_NO_THROW(limit = CustomFeeLimit().setPayerId(accountId).addCustomFee( + CustomFixedFee().setAmount(1).setDenominatingTokenId(TokenId(0, 0, 0)))); + + setTestClientOperator(accountId, accountKey); + EXPECT_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .addCustomFeeLimit(limit) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient()), + ReceiptStatusException); // NO_VALID_MAX_CUSTOM_FEE +} + +//----- +TEST_F(TopicMessageSubmitTransactionIntegrationTests, RevenueGeneratingTopicDoesNotChargeTreasuries) +{ + // Given + std::shared_ptr accountKey; + ASSERT_NO_THROW(accountKey = ED25519PrivateKey::generatePrivateKey()); + + uint64_t accountTokenBalance = 10; + + AccountId accountId; + ASSERT_NO_THROW(accountId = AccountCreateTransaction() + .setKeyWithoutAlias(accountKey->getPublicKey()) + .setMaxAutomaticTokenAssociations(-1) + .setInitialBalance(Hbar(2LL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mAccountId.value()); + + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setInitialSupply(10) + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setTreasuryAccountId(accountId) + .freezeWith(&getTestClient()) + .sign(accountKey) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + ASSERT_NO_THROW(TokenAssociateTransaction() + .setAccountId(getTestClient().getOperatorAccountId().value()) + .setTokenIds({ tokenId }) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(1).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + TopicId topicId; + ASSERT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .setFeeScheduleKey(getTestClient().getOperatorPublicKey()) + .addCustomFixedFee({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + // When + EXPECT_NO_THROW(TransferTransaction() + .addTokenTransfer(tokenId, accountId, -1ULL) + .addTokenTransfer(tokenId, getTestClient().getOperatorAccountId().value(), 1ULL) + .freezeWith(&getTestClient()) + .sign(accountKey) + .execute(getTestClient()) + .getReceipt(getTestClient())); + + setTestClientOperator(accountId, accountKey); + EXPECT_NO_THROW(TopicMessageSubmitTransaction() + .setTopicId(topicId) + .setMessage("message") + .execute(getTestClient()) + .getReceipt(getTestClient())); + + // Then + setDefaultTestClientOperator(); + AccountBalance accountBalance; + EXPECT_NO_THROW(accountBalance = AccountBalanceQuery().setAccountId(accountId).execute(getTestClient())); + + EXPECT_EQ(accountBalance.mTokens[tokenId], accountTokenBalance - 1); // -1 as 1 was sent to the operator account } \ No newline at end of file diff --git a/src/sdk/tests/integration/TopicUpdateTransactionIntegrationTests.cc b/src/sdk/tests/integration/TopicUpdateTransactionIntegrationTests.cc index 8fc1f66bc..03e83f37e 100644 --- a/src/sdk/tests/integration/TopicUpdateTransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/TopicUpdateTransactionIntegrationTests.cc @@ -3,6 +3,7 @@ #include "Defaults.h" #include "ECDSAsecp256k1PrivateKey.h" #include "ED25519PrivateKey.h" +#include "TokenCreateTransaction.h" #include "TopicCreateTransaction.h" #include "TopicDeleteTransaction.h" #include "TopicInfo.h" @@ -11,9 +12,10 @@ #include "TransactionReceipt.h" #include "TransactionRecord.h" #include "TransactionResponse.h" +#include "exceptions/PrecheckStatusException.h" +#include "exceptions/ReceiptStatusException.h" #include -#include using namespace Hiero; @@ -79,3 +81,64 @@ TEST_F(TopicUpdateTransactionIntegrationTests, ExecuteTopicUpdateTransaction) .execute(getTestClient()) .getReceipt(getTestClient())); } + +//----- +TEST_F(TopicUpdateTransactionIntegrationTests, RevenueGeneratingTopicCannotUpdateFeeScheduleKey) +{ + // Given + std::shared_ptr feeScheduleKey; + ASSERT_NO_THROW(feeScheduleKey = ED25519PrivateKey::generatePrivateKey()); + + // When + TopicId topicId; + EXPECT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + // Then + // Update the revenue generating topic with new fee schedule key + EXPECT_THROW(TopicUpdateTransaction() + .setTopicId(topicId) + .setFeeScheduleKey(feeScheduleKey->getPublicKey()) + .execute(getTestClient()) + .getReceipt(getTestClient()), + ReceiptStatusException); // FEE_SCHEDULE_KEY_CANNOT_BE_UPDATED +} + +//----- +TEST_F(TopicUpdateTransactionIntegrationTests, RevenueGeneratingTopicCannotUpdateCustomFees) +{ + // Given + TokenId tokenId; + ASSERT_NO_THROW(tokenId = TokenCreateTransaction() + .setTokenName("ffff") + .setTokenSymbol("F") + .setTreasuryAccountId(AccountId(2ULL)) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTokenId.value()); + + CustomFixedFee customFixedFee; + ASSERT_NO_THROW(customFixedFee = + CustomFixedFee().setAmount(2).setDenominatingTokenId(tokenId).setFeeCollectorAccountId( + getTestClient().getOperatorAccountId().value())); + + // When + TopicId topicId; + EXPECT_NO_THROW(topicId = TopicCreateTransaction() + .setAdminKey(getTestClient().getOperatorPublicKey()) + .execute(getTestClient()) + .getReceipt(getTestClient()) + .mTopicId.value()); + + // Then + // Update the revenue generating topic with new custom fees + EXPECT_THROW(TopicUpdateTransaction() + .setTopicId(topicId) + .setCustomFixedFees({ customFixedFee }) + .execute(getTestClient()) + .getReceipt(getTestClient()), + ReceiptStatusException); // FEE_SCHEDULE_KEY_NOT_SET +} diff --git a/src/sdk/tests/integration/TransactionIntegrationTests.cc b/src/sdk/tests/integration/TransactionIntegrationTests.cc index 5049c6cf6..dc2dec3a9 100644 --- a/src/sdk/tests/integration/TransactionIntegrationTests.cc +++ b/src/sdk/tests/integration/TransactionIntegrationTests.cc @@ -16,7 +16,6 @@ #include "impl/Utilities.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/TransactionReceiptIntegrationTests.cc b/src/sdk/tests/integration/TransactionReceiptIntegrationTests.cc index 3eab463a0..800f17418 100644 --- a/src/sdk/tests/integration/TransactionReceiptIntegrationTests.cc +++ b/src/sdk/tests/integration/TransactionReceiptIntegrationTests.cc @@ -18,7 +18,6 @@ #include "impl/Utilities.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/TransactionReceiptQueryIntegrationTests.cc b/src/sdk/tests/integration/TransactionReceiptQueryIntegrationTests.cc index b1f29c9a0..c31a2a9f7 100644 --- a/src/sdk/tests/integration/TransactionReceiptQueryIntegrationTests.cc +++ b/src/sdk/tests/integration/TransactionReceiptQueryIntegrationTests.cc @@ -12,7 +12,6 @@ #include "impl/Utilities.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/integration/TransactionRecordQueryIntegrationTests.cc b/src/sdk/tests/integration/TransactionRecordQueryIntegrationTests.cc index 79bdffcf2..e04965e6b 100644 --- a/src/sdk/tests/integration/TransactionRecordQueryIntegrationTests.cc +++ b/src/sdk/tests/integration/TransactionRecordQueryIntegrationTests.cc @@ -11,7 +11,6 @@ #include "impl/Utilities.h" #include -#include using namespace Hiero; diff --git a/src/sdk/tests/unit/AccountAllowanceApproveTransactionUnitTests.cc b/src/sdk/tests/unit/AccountAllowanceApproveTransactionUnitTests.cc index 27bdb67e5..04ba6fc8b 100644 --- a/src/sdk/tests/unit/AccountAllowanceApproveTransactionUnitTests.cc +++ b/src/sdk/tests/unit/AccountAllowanceApproveTransactionUnitTests.cc @@ -10,7 +10,7 @@ #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/AccountAllowanceDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/AccountAllowanceDeleteTransactionUnitTests.cc index 995c08dc0..582a7c089 100644 --- a/src/sdk/tests/unit/AccountAllowanceDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/AccountAllowanceDeleteTransactionUnitTests.cc @@ -9,7 +9,7 @@ #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/AccountCreateTransactionUnitTests.cc b/src/sdk/tests/unit/AccountCreateTransactionUnitTests.cc index 4ecca30d4..03f82aa2b 100644 --- a/src/sdk/tests/unit/AccountCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/AccountCreateTransactionUnitTests.cc @@ -12,7 +12,7 @@ #include "impl/Utilities.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/AccountDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/AccountDeleteTransactionUnitTests.cc index ca83dad97..2543926c7 100644 --- a/src/sdk/tests/unit/AccountDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/AccountDeleteTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/AccountStakersQueryUnitTests.cc b/src/sdk/tests/unit/AccountStakersQueryUnitTests.cc deleted file mode 100644 index abc8142e0..000000000 --- a/src/sdk/tests/unit/AccountStakersQueryUnitTests.cc +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#include "AccountStakersQuery.h" - -#include - -using namespace Hiero; - -class AccountStakersQueryUnitTests : public ::testing::Test -{ -protected: - [[nodiscard]] inline const AccountId& getTestAccountId() const { return mTestAccountId; } - -private: - const AccountId mTestAccountId = AccountId(1ULL); -}; - -//----- -TEST_F(AccountStakersQueryUnitTests, SetAccountId) -{ - // Given - AccountStakersQuery query; - - // When - query.setAccountId(getTestAccountId()); - - // Then - EXPECT_EQ(query.getAccountId(), getTestAccountId()); -} diff --git a/src/sdk/tests/unit/AccountUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/AccountUpdateTransactionUnitTests.cc index cdf8830f1..69fa9dd0d 100644 --- a/src/sdk/tests/unit/AccountUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/AccountUpdateTransactionUnitTests.cc @@ -6,10 +6,9 @@ #include "impl/DurationConverter.h" #include "impl/TimestampConverter.h" -#include #include #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/CMakeLists.txt b/src/sdk/tests/unit/CMakeLists.txt index 7b80fc8c1..8c152b76e 100644 --- a/src/sdk/tests/unit/CMakeLists.txt +++ b/src/sdk/tests/unit/CMakeLists.txt @@ -11,7 +11,6 @@ add_executable(${TEST_PROJECT_NAME} AccountInfoUnitTests.cc AccountRecordsQueryUnitTests.cc AccountRecordsUnitTests.cc - AccountStakersQueryUnitTests.cc AccountUpdateTransactionUnitTests.cc AddressBookQueryUnitTests.cc AssessedCustomFeesUnitTests.cc @@ -32,6 +31,7 @@ add_executable(${TEST_PROJECT_NAME} ContractLogInfoUnitTests.cc ContractNonceInfoUnitTests.cc ContractUpdateTransactionUnitTests.cc + CustomFeeLimitUnitTests.cc CustomFixedFeeUnitTests.cc CustomFractionalFeeUnitTests.cc CustomRoyaltyFeeUnitTests.cc diff --git a/src/sdk/tests/unit/ContractCreateFlowUnitTests.cc b/src/sdk/tests/unit/ContractCreateFlowUnitTests.cc index b403f075c..08b19f65a 100644 --- a/src/sdk/tests/unit/ContractCreateFlowUnitTests.cc +++ b/src/sdk/tests/unit/ContractCreateFlowUnitTests.cc @@ -9,7 +9,6 @@ #include #include -#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/ContractCreateTransactionUnitTests.cc b/src/sdk/tests/unit/ContractCreateTransactionUnitTests.cc index d690f62f8..4d14599bb 100644 --- a/src/sdk/tests/unit/ContractCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ContractCreateTransactionUnitTests.cc @@ -11,7 +11,7 @@ #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/ContractDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/ContractDeleteTransactionUnitTests.cc index c5800965d..5392513a6 100644 --- a/src/sdk/tests/unit/ContractDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ContractDeleteTransactionUnitTests.cc @@ -6,10 +6,9 @@ #include "ECDSAsecp256k1PrivateKey.h" #include "exceptions/IllegalStateException.h" -#include #include #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/ContractExecuteTransactionUnitTests.cc b/src/sdk/tests/unit/ContractExecuteTransactionUnitTests.cc index 3122e3bc4..35908f7e8 100644 --- a/src/sdk/tests/unit/ContractExecuteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ContractExecuteTransactionUnitTests.cc @@ -9,7 +9,7 @@ #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/ContractUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/ContractUpdateTransactionUnitTests.cc index 8d4b34e26..205b461d8 100644 --- a/src/sdk/tests/unit/ContractUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ContractUpdateTransactionUnitTests.cc @@ -10,7 +10,7 @@ #include #include #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/CustomFeeLimitUnitTests.cc b/src/sdk/tests/unit/CustomFeeLimitUnitTests.cc new file mode 100644 index 000000000..380d01e0d --- /dev/null +++ b/src/sdk/tests/unit/CustomFeeLimitUnitTests.cc @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 +#include "AccountId.h" +#include "CustomFeeLimit.h" +#include "CustomFixedFee.h" +#include +#include + +using namespace Hiero; + +class CustomFeeLimitUnitTests : public ::testing::Test +{ +}; + +//----- +TEST(CustomFeeLimitUnitTests, DefaultConstructor) +{ + CustomFeeLimit feeLimit; + + EXPECT_FALSE(feeLimit.getPayerId().has_value()); // PayerId should be empty + EXPECT_TRUE(feeLimit.getCustomFees().empty()); // Custom fees should be empty +} + +//----- +TEST(CustomFeeLimitUnitTests, SetAndGetPayerId) +{ + CustomFeeLimit feeLimit; + AccountId payerId(1, 2, 3); + + feeLimit.setPayerId(payerId); + + ASSERT_TRUE(feeLimit.getPayerId().has_value()); + EXPECT_EQ(feeLimit.getPayerId().value(), payerId); +} + +//----- +TEST(CustomFeeLimitUnitTests, SetAndGetCustomFees) +{ + CustomFeeLimit feeLimit; + CustomFixedFee fee1; + fee1.setAmount(10); + CustomFixedFee fee2; + fee2.setAmount(20); + + std::vector fees = { fee1, fee2 }; + feeLimit.setCustomFees(fees); + + std::vector retrievedFees = feeLimit.getCustomFees(); + ASSERT_EQ(retrievedFees.size(), 2); + EXPECT_EQ(retrievedFees[0].getAmount(), 10); + EXPECT_EQ(retrievedFees[1].getAmount(), 20); +} + +//----- +TEST(CustomFeeLimitTest, AddCustomFee) +{ + CustomFeeLimit feeLimit; + CustomFixedFee fee; + fee.setAmount(15); + + feeLimit.addCustomFee(fee); + + std::vector retrievedFees = feeLimit.getCustomFees(); + ASSERT_EQ(retrievedFees.size(), 1); + EXPECT_EQ(retrievedFees[0].getAmount(), 15); +} + +//----- +TEST(CustomFeeLimitUnitTests, ProtobufConversion) +{ + // Set up the protobuf message + proto::CustomFeeLimit protoFeeLimit; + protoFeeLimit.mutable_account_id()->set_shardnum(1); + protoFeeLimit.mutable_account_id()->set_realmnum(2); + protoFeeLimit.mutable_account_id()->set_accountnum(3); + + auto* protoFee = protoFeeLimit.add_fees(); + protoFee->set_amount(25); + + // Convert from protobuf + CustomFeeLimit feeLimit = CustomFeeLimit::fromProtobuf(protoFeeLimit); + + // Validate the conversion + ASSERT_TRUE(feeLimit.getPayerId().has_value()); + EXPECT_EQ(feeLimit.getPayerId()->toString(), "1.2.3"); + + std::vector fees = feeLimit.getCustomFees(); + ASSERT_EQ(fees.size(), 1); + EXPECT_EQ(fees[0].getAmount(), 25); + + // Convert back to protobuf and check values + std::unique_ptr convertedProto = feeLimit.toProtobuf(); + EXPECT_EQ(convertedProto->account_id().shardnum(), 1); + EXPECT_EQ(convertedProto->account_id().realmnum(), 2); + EXPECT_EQ(convertedProto->account_id().accountnum(), 3); + ASSERT_EQ(convertedProto->fees_size(), 1); + + // Test the scenario with no fees + proto::CustomFeeLimit protoFeeLimitEmpty; + CustomFeeLimit feeLimitEmpty = CustomFeeLimit::fromProtobuf(protoFeeLimitEmpty); + EXPECT_FALSE(feeLimitEmpty.getPayerId().has_value()); + EXPECT_TRUE(feeLimitEmpty.getCustomFees().empty()); +} diff --git a/src/sdk/tests/unit/EthereumTransactionUnitTests.cc b/src/sdk/tests/unit/EthereumTransactionUnitTests.cc index 75e41e3a7..44d800785 100644 --- a/src/sdk/tests/unit/EthereumTransactionUnitTests.cc +++ b/src/sdk/tests/unit/EthereumTransactionUnitTests.cc @@ -9,9 +9,8 @@ #include "impl/Utilities.h" #include -#include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/FileAppendTransactionUnitTests.cc b/src/sdk/tests/unit/FileAppendTransactionUnitTests.cc index 3ec961a5b..73f034933 100644 --- a/src/sdk/tests/unit/FileAppendTransactionUnitTests.cc +++ b/src/sdk/tests/unit/FileAppendTransactionUnitTests.cc @@ -7,11 +7,10 @@ #include #include -#include #include #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/FileCreateTransactionUnitTests.cc b/src/sdk/tests/unit/FileCreateTransactionUnitTests.cc index 33751905e..675473da9 100644 --- a/src/sdk/tests/unit/FileCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/FileCreateTransactionUnitTests.cc @@ -9,11 +9,10 @@ #include #include -#include #include #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/FileDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/FileDeleteTransactionUnitTests.cc index cefafa0ff..09bc8cb2e 100644 --- a/src/sdk/tests/unit/FileDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/FileDeleteTransactionUnitTests.cc @@ -4,9 +4,8 @@ #include "FileDeleteTransaction.h" #include "exceptions/IllegalStateException.h" -#include #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/FileUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/FileUpdateTransactionUnitTests.cc index d5e24cbce..ab04e2862 100644 --- a/src/sdk/tests/unit/FileUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/FileUpdateTransactionUnitTests.cc @@ -9,11 +9,10 @@ #include #include -#include #include #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/FreezeTransactionUnitTests.cc b/src/sdk/tests/unit/FreezeTransactionUnitTests.cc index 864a92135..d529ff16d 100644 --- a/src/sdk/tests/unit/FreezeTransactionUnitTests.cc +++ b/src/sdk/tests/unit/FreezeTransactionUnitTests.cc @@ -9,11 +9,10 @@ #include #include -#include #include #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/NodeCreateTransactionUnitTests.cc b/src/sdk/tests/unit/NodeCreateTransactionUnitTests.cc index 36ab6d34c..f6cf51182 100644 --- a/src/sdk/tests/unit/NodeCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/NodeCreateTransactionUnitTests.cc @@ -4,7 +4,7 @@ #include "impl/Utilities.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/NodeDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/NodeDeleteTransactionUnitTests.cc index ab14cb20f..91950c1ee 100644 --- a/src/sdk/tests/unit/NodeDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/NodeDeleteTransactionUnitTests.cc @@ -3,7 +3,7 @@ #include "NodeDeleteTransaction.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/NodeUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/NodeUpdateTransactionUnitTests.cc index 58e59c136..550335e21 100644 --- a/src/sdk/tests/unit/NodeUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/NodeUpdateTransactionUnitTests.cc @@ -4,7 +4,7 @@ #include "impl/Utilities.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/PrngTransactionUnitTests.cc b/src/sdk/tests/unit/PrngTransactionUnitTests.cc index 2ce178203..55b34b8d0 100644 --- a/src/sdk/tests/unit/PrngTransactionUnitTests.cc +++ b/src/sdk/tests/unit/PrngTransactionUnitTests.cc @@ -3,7 +3,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/ScheduleCreateTransactionUnitTests.cc b/src/sdk/tests/unit/ScheduleCreateTransactionUnitTests.cc index 5f4382425..0509f8b9f 100644 --- a/src/sdk/tests/unit/ScheduleCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ScheduleCreateTransactionUnitTests.cc @@ -8,7 +8,7 @@ #include "impl/TimestampConverter.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/ScheduleDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/ScheduleDeleteTransactionUnitTests.cc index a653a1243..39dc1457c 100644 --- a/src/sdk/tests/unit/ScheduleDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ScheduleDeleteTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/ScheduleSignTransactionUnitTests.cc b/src/sdk/tests/unit/ScheduleSignTransactionUnitTests.cc index 403adda0f..80c2b0d75 100644 --- a/src/sdk/tests/unit/ScheduleSignTransactionUnitTests.cc +++ b/src/sdk/tests/unit/ScheduleSignTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/SystemDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/SystemDeleteTransactionUnitTests.cc index a362fa251..7a5218c5a 100644 --- a/src/sdk/tests/unit/SystemDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/SystemDeleteTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "impl/TimestampConverter.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/SystemUndeleteTransactionUnitTests.cc b/src/sdk/tests/unit/SystemUndeleteTransactionUnitTests.cc index f9ed7db1c..bcc868576 100644 --- a/src/sdk/tests/unit/SystemUndeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/SystemUndeleteTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenAssociateTransactionUnitTests.cc b/src/sdk/tests/unit/TokenAssociateTransactionUnitTests.cc index b75d4a0e4..fb7041294 100644 --- a/src/sdk/tests/unit/TokenAssociateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenAssociateTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenBurnTransactionUnitTests.cc b/src/sdk/tests/unit/TokenBurnTransactionUnitTests.cc index 11eb173a5..946f26deb 100644 --- a/src/sdk/tests/unit/TokenBurnTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenBurnTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenCancelAirdropTransactionUnitTests.cc b/src/sdk/tests/unit/TokenCancelAirdropTransactionUnitTests.cc index 0b148a77b..b741b8018 100644 --- a/src/sdk/tests/unit/TokenCancelAirdropTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenCancelAirdropTransactionUnitTests.cc @@ -5,8 +5,7 @@ #include "TokenId.h" #include -#include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenClaimAirdropTransactionUnitTests.cc b/src/sdk/tests/unit/TokenClaimAirdropTransactionUnitTests.cc index 5a4e0ff2b..a8e993b35 100644 --- a/src/sdk/tests/unit/TokenClaimAirdropTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenClaimAirdropTransactionUnitTests.cc @@ -5,8 +5,7 @@ #include "TokenId.h" #include -#include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenCreateTransactionUnitTests.cc b/src/sdk/tests/unit/TokenCreateTransactionUnitTests.cc index ed395e591..dc3dfcc82 100644 --- a/src/sdk/tests/unit/TokenCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenCreateTransactionUnitTests.cc @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/TokenDeleteTransactionUnitTests.cc index e6bcfc210..4f5cb164f 100644 --- a/src/sdk/tests/unit/TokenDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenDeleteTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenDissociateTransactionUnitTests.cc b/src/sdk/tests/unit/TokenDissociateTransactionUnitTests.cc index 50cb0ed6b..745083179 100644 --- a/src/sdk/tests/unit/TokenDissociateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenDissociateTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenFeeScheduleUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/TokenFeeScheduleUpdateTransactionUnitTests.cc index 28ab1e3d8..588fb6e51 100644 --- a/src/sdk/tests/unit/TokenFeeScheduleUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenFeeScheduleUpdateTransactionUnitTests.cc @@ -9,7 +9,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenFreezeTransactionUnitTests.cc b/src/sdk/tests/unit/TokenFreezeTransactionUnitTests.cc index 0ea68d4ca..f7324a942 100644 --- a/src/sdk/tests/unit/TokenFreezeTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenFreezeTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenGrantKycTransactionUnitTests.cc b/src/sdk/tests/unit/TokenGrantKycTransactionUnitTests.cc index 8acfd035a..17e74c23f 100644 --- a/src/sdk/tests/unit/TokenGrantKycTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenGrantKycTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenMintTransactionUnitTests.cc b/src/sdk/tests/unit/TokenMintTransactionUnitTests.cc index 014024171..39b0cc057 100644 --- a/src/sdk/tests/unit/TokenMintTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenMintTransactionUnitTests.cc @@ -8,7 +8,7 @@ #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenPauseTransactionUnitTests.cc b/src/sdk/tests/unit/TokenPauseTransactionUnitTests.cc index 3200fb591..2af02dc6e 100644 --- a/src/sdk/tests/unit/TokenPauseTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenPauseTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenRejectTransactionUnitTests.cc b/src/sdk/tests/unit/TokenRejectTransactionUnitTests.cc index 8d7d70e52..b7c4f6095 100644 --- a/src/sdk/tests/unit/TokenRejectTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenRejectTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "TokenRejectTransaction.h" #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenRevokeKycTransactionUnitTests.cc b/src/sdk/tests/unit/TokenRevokeKycTransactionUnitTests.cc index aa59619e1..4427e7ad2 100644 --- a/src/sdk/tests/unit/TokenRevokeKycTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenRevokeKycTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenUnfreezeTransactionUnitTests.cc b/src/sdk/tests/unit/TokenUnfreezeTransactionUnitTests.cc index 0a7f0f797..0b8d6b8e9 100644 --- a/src/sdk/tests/unit/TokenUnfreezeTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenUnfreezeTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenUnpauseTransactionUnitTests.cc b/src/sdk/tests/unit/TokenUnpauseTransactionUnitTests.cc index 12d5da83e..a8fa23f73 100644 --- a/src/sdk/tests/unit/TokenUnpauseTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenUnpauseTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/TokenUpdateTransactionUnitTests.cc index b97d9891c..582c1c5d1 100644 --- a/src/sdk/tests/unit/TokenUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenUpdateTransactionUnitTests.cc @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include using namespace Hiero; diff --git a/src/sdk/tests/unit/TokenWipeTransactionUnitTests.cc b/src/sdk/tests/unit/TokenWipeTransactionUnitTests.cc index 10c464090..655a52407 100644 --- a/src/sdk/tests/unit/TokenWipeTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TokenWipeTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TopicCreateTransactionUnitTests.cc b/src/sdk/tests/unit/TopicCreateTransactionUnitTests.cc index 827848a73..c1cf8b786 100644 --- a/src/sdk/tests/unit/TopicCreateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TopicCreateTransactionUnitTests.cc @@ -8,7 +8,7 @@ #include "impl/Utilities.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TopicDeleteTransactionUnitTests.cc b/src/sdk/tests/unit/TopicDeleteTransactionUnitTests.cc index 80b10dc1f..50ba6e6e9 100644 --- a/src/sdk/tests/unit/TopicDeleteTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TopicDeleteTransactionUnitTests.cc @@ -5,7 +5,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TopicMessageSubmitTransactionUnitTests.cc b/src/sdk/tests/unit/TopicMessageSubmitTransactionUnitTests.cc index 17b8db867..c4caf9a92 100644 --- a/src/sdk/tests/unit/TopicMessageSubmitTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TopicMessageSubmitTransactionUnitTests.cc @@ -6,7 +6,7 @@ #include "impl/Utilities.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TopicUpdateTransactionUnitTests.cc b/src/sdk/tests/unit/TopicUpdateTransactionUnitTests.cc index fc0935774..272f31628 100644 --- a/src/sdk/tests/unit/TopicUpdateTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TopicUpdateTransactionUnitTests.cc @@ -9,7 +9,7 @@ #include "impl/Utilities.h" #include -#include +#include using namespace Hiero; diff --git a/src/sdk/tests/unit/TransactionUnitTests.cc b/src/sdk/tests/unit/TransactionUnitTests.cc index 0a5bd6b01..3e21e18fc 100644 --- a/src/sdk/tests/unit/TransactionUnitTests.cc +++ b/src/sdk/tests/unit/TransactionUnitTests.cc @@ -46,7 +46,7 @@ #include #include -#include + #include #include diff --git a/src/sdk/tests/unit/TransferTransactionUnitTests.cc b/src/sdk/tests/unit/TransferTransactionUnitTests.cc index 3688654e5..084624c4a 100644 --- a/src/sdk/tests/unit/TransferTransactionUnitTests.cc +++ b/src/sdk/tests/unit/TransferTransactionUnitTests.cc @@ -8,7 +8,7 @@ #include "exceptions/IllegalStateException.h" #include -#include +#include using namespace Hiero;