diff --git a/hcs/src/main/java/hcs/ScriptHcsTopic.java b/hcs/src/main/java/hcs/ScriptHcsTopic.java index 45f583e..e5a4d44 100644 --- a/hcs/src/main/java/hcs/ScriptHcsTopic.java +++ b/hcs/src/main/java/hcs/ScriptHcsTopic.java @@ -22,7 +22,7 @@ public class ScriptHcsTopic { public static void main(String[] args) throws Exception { System.out.println("🏁 Hello Future World - HCS Topic - start"); - // Load environment variables from .env file + // Load environment variables from .env file Dotenv dotenv = Dotenv.configure().directory("../").load(); String operatorIdStr = dotenv.get("OPERATOR_ACCOUNT_ID"); String operatorKeyStr = dotenv.get("OPERATOR_ACCOUNT_PRIVATE_KEY"); @@ -33,75 +33,82 @@ public static void main(String[] args) throws Exception { operatorKeyStr = operatorKeyStr.substring(2); } - // Initialize the operator account + // Initialize the operator account AccountId operatorId = AccountId.fromString(operatorIdStr); PrivateKey operatorKey = PrivateKey.fromStringECDSA(operatorKeyStr); Client client = Client.forTestnet().setOperator(operatorId, operatorKey); System.out.println("Using account: " + operatorIdStr); - //Set the default maximum transaction fee (in HBAR) + // Set the default maximum transaction fee (in HBAR) client.setDefaultMaxTransactionFee(new Hbar(100)); - //Set the default maximum payment for queries (in HBAR) + // Set the default maximum payment for queries (in HBAR) client.setDefaultMaxQueryPayment(new Hbar(50)); // Create a Hedera Consensus Service (HCS) topic System.out.println("🟣 Creating new HCS topic"); TopicCreateTransaction topicCreateTx = new TopicCreateTransaction() - .setTopicMemo("Hello Future World topic - xyz") - // Freeze the transaction to prepare for signing - .freezeWith(client); + .setTopicMemo("Hello Future World topic - xyz") + // Freeze the transaction to prepare for signing + .freezeWith(client); // Get the transaction ID of the transaction. - // The SDK automatically generates and assigns a transaction ID when the transaction is created + // The SDK automatically generates and assigns a transaction ID when the + // transaction is created TransactionId topicCreateTxId = topicCreateTx.getTransactionId(); System.out.println("The topic create transaction ID: " + topicCreateTxId.toString()); - // Sign the transaction with the account key that will be paying for this transaction + // Sign the transaction with the account key that will be paying for this + // transaction TopicCreateTransaction topicCreateTxSigned = topicCreateTx.sign(operatorKey); // Submit the transaction to the Hedera Testnet TransactionResponse topicCreateTxSubmitted = topicCreateTxSigned.execute(client); - // Get the transaction receipt + // Check transaction status for topic creation TransactionReceipt topicCreateTxReceipt = topicCreateTxSubmitted.getReceipt(client); + if (topicCreateTxReceipt.status != Status.SUCCESS) { + throw new RuntimeException( + "❌ Topic creation transaction failed with status: " + topicCreateTxReceipt.status); + } - // Get the topic ID TopicId topicId = topicCreateTxReceipt.topicId; - System.out.println("Topic ID:" + topicId.toString()); + System.out.println("✅ Topic created successfully. Topic ID: " + topicId.toString()); // Publish a message to the Hedera Consensus Service (HCS) topic System.out.println("🟣 Publish message to HCS topic"); TopicMessageSubmitTransaction topicMsgSubmitTx = new TopicMessageSubmitTransaction() - //Set the transaction memo with the hello future world ID - .setTransactionMemo("Hello Future World topic message - xyz") - .setTopicId(topicId) - //Set the topic message contents - .setMessage("Hello HCS!") - // Freeze the transaction to prepare for signing - .freezeWith(client); + // Set the transaction memo with the hello future world ID + .setTransactionMemo("Hello Future World topic message - xyz") + .setTopicId(topicId) + // Set the topic message contents + .setMessage("Hello HCS!") + // Freeze the transaction to prepare for signing + .freezeWith(client); // Get the transaction ID of the transaction. - // The SDK automatically generates and assigns a transaction ID when the transaction is created + // The SDK automatically generates and assigns a transaction ID when the + // transaction is created TransactionId topicMsgSubmitTxId = topicMsgSubmitTx.getTransactionId(); System.out.println( - "The topic message submit transaction ID: " + - topicMsgSubmitTxId.toString() - ); + "The topic message submit transaction ID: " + + topicMsgSubmitTxId.toString()); - // Sign the transaction with the account key that will be paying for this transaction + // Sign the transaction with the account key that will be paying for this + // transaction TopicMessageSubmitTransaction topicMsgSubmitTxSigned = topicMsgSubmitTx.sign(operatorKey); // Submit the transaction to the Hedera Testnet - TransactionResponse topicMsgSubmitTxSubmitted = - topicMsgSubmitTxSigned.execute(client); + TransactionResponse topicMsgSubmitTxSubmitted = topicMsgSubmitTxSigned.execute(client); - // Get the transaction receipt - TransactionReceipt topicMsgSubmitTxReceipt = - topicMsgSubmitTxSubmitted.getReceipt(client); + // Check transaction status for message submission + TransactionReceipt topicMsgSubmitTxReceipt = topicMsgSubmitTxSubmitted.getReceipt(client); + if (topicMsgSubmitTxReceipt.status != Status.SUCCESS) { + throw new RuntimeException( + "❌ Topic message submission transaction failed with status: " + topicMsgSubmitTxReceipt.status); + } - // Get the topic message sequence number Long topicMsgSeqNum = topicMsgSubmitTxReceipt.topicSequenceNumber; - System.out.println("Topic Message Sequence Number:" + topicMsgSeqNum.toString()); + System.out.println("✅ Message submitted successfully. Sequence Number: " + topicMsgSeqNum.toString()); client.close(); @@ -112,32 +119,30 @@ public static void main(String[] args) throws Exception { System.out.println("🟣 View the topic on HashScan"); String topicHashscanUrl = "https://hashscan.io/testnet/topic/" + topicId.toString(); System.out.println( - "Topic Hashscan URL:\n" + - topicHashscanUrl - ); + "Topic Hashscan URL:\n" + + topicHashscanUrl); // Wait for 6s for record files (blocks) to propagate to mirror nodes Thread.sleep(6000); // Verify topic using Mirror Node API System.out.println("Get topic data from the Hedera Mirror Node"); - String topicMirrorNodeApiUrl = - "https://testnet.mirrornode.hedera.com/api/v1/topics/" + topicId.toString() + "/messages?encoding=base64&limit=5&order=asc&sequencenumber=1"; + String topicMirrorNodeApiUrl = "https://testnet.mirrornode.hedera.com/api/v1/topics/" + topicId.toString() + + "/messages?encoding=base64&limit=5&order=asc&sequencenumber=1"; System.out.println( - "The topic Hedera Mirror Node API URL:\n" + - topicMirrorNodeApiUrl - ); + "The topic Hedera Mirror Node API URL:\n" + + topicMirrorNodeApiUrl); final HttpRequest httpRequest = HttpRequest.newBuilder() - .uri(URI.create(topicMirrorNodeApiUrl)) - .build(); + .uri(URI.create(topicMirrorNodeApiUrl)) + .build(); final HttpClient httpClient = HttpClient.newHttpClient(); final var mirrorNodeResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body(); JsonObject jsonResponse = JsonParser.parseString(mirrorNodeResponse).getAsJsonObject(); // Extract messages from the JSON (null check equivalent) JsonArray topicVerifyMessages = jsonResponse.has("messages") - ? jsonResponse.getAsJsonArray("messages") - : new JsonArray(); + ? jsonResponse.getAsJsonArray("messages") + : new JsonArray(); System.out.println("Number of messages retrieved from this topic: " + topicVerifyMessages.size()); List topicVerifyMessagesParsed = new ArrayList<>(); for (JsonElement messageElement : topicVerifyMessages) { diff --git a/transfer/src/main/java/transfer/ScriptTransferHbar.java b/transfer/src/main/java/transfer/ScriptTransferHbar.java index 976506f..378dd16 100644 --- a/transfer/src/main/java/transfer/ScriptTransferHbar.java +++ b/transfer/src/main/java/transfer/ScriptTransferHbar.java @@ -22,8 +22,8 @@ public class ScriptTransferHbar { public static void main(String[] args) throws Exception { System.out.println("🏁 Hello Future World - Transfer HBAR - start"); - // Load environment variables from .env file - Dotenv dotenv = Dotenv.configure().directory("../").load(); + // Load environment variables from .env file + Dotenv dotenv = Dotenv.configure().directory("./").load(); String operatorIdStr = dotenv.get("OPERATOR_ACCOUNT_ID"); String operatorKeyStr = dotenv.get("OPERATOR_ACCOUNT_PRIVATE_KEY"); if (operatorIdStr == null || operatorKeyStr == null) { @@ -33,37 +33,39 @@ public static void main(String[] args) throws Exception { operatorKeyStr = operatorKeyStr.substring(2); } - // Initialize the operator account + // Initialize the operator account AccountId operatorId = AccountId.fromString(operatorIdStr); PrivateKey operatorKey = PrivateKey.fromStringECDSA(operatorKeyStr); Client client = Client.forTestnet().setOperator(operatorId, operatorKey); System.out.println("Using account: " + operatorIdStr); - //Set the default maximum transaction fee (in HBAR) + // Set the default maximum transaction fee (in HBAR) client.setDefaultMaxTransactionFee(new Hbar(100)); - //Set the default maximum payment for queries (in HBAR) + // Set the default maximum payment for queries (in HBAR) client.setDefaultMaxQueryPayment(new Hbar(50)); System.out.println("🟣 Creating, signing, and submitting the transfer transaction"); AccountId recipientAccount1 = AccountId.fromString("0.0.200"); AccountId recipientAccount2 = AccountId.fromString("0.0.201"); TransferTransaction transferTx = new TransferTransaction() - .setTransactionMemo("Hello Future World transfer - xyz") - // Debit 3 HBAR from the operator account (sender) - .addHbarTransfer(operatorId, Hbar.from(-3, HbarUnit.HBAR)) - // Credit 1 HBAR to account 0.0.200 (1st recipient) - .addHbarTransfer(recipientAccount1, Hbar.from(1, HbarUnit.HBAR)) - // Credit 2 HBAR to account 0.0.201 (2nd recipient) - .addHbarTransfer(recipientAccount2, Hbar.from(2, HbarUnit.HBAR)) - // Freeze the transaction to prepare for signing - .freezeWith(client); + .setTransactionMemo("Hello Future World transfer - xyz") + // Debit 3 HBAR from the operator account (sender) + .addHbarTransfer(operatorId, Hbar.from(-3, HbarUnit.HBAR)) + // Credit 1 HBAR to account 0.0.200 (1st recipient) + .addHbarTransfer(recipientAccount1, Hbar.from(1, HbarUnit.HBAR)) + // Credit 2 HBAR to account 0.0.201 (2nd recipient) + .addHbarTransfer(recipientAccount2, Hbar.from(2, HbarUnit.HBAR)) + // Freeze the transaction to prepare for signing + .freezeWith(client); // Get the transaction ID for the transfer transaction TransactionId transferTxId = transferTx.getTransactionId(); System.out.println("The transfer transaction ID: " + transferTxId.toString()); - // Sign the transaction with the account that is being debited (operator account) and the transaction fee payer account (operator account) - // Since the account that is being debited and the account that is paying for the transaction are the same, only one account's signature is required + // Sign the transaction with the account that is being debited (operator + // account) and the transaction fee payer account (operator account) + // Since the account that is being debited and the account that is paying for + // the transaction are the same, only one account's signature is required TransferTransaction transferTxSigned = transferTx.sign(operatorKey); // Submit the transaction to the Hedera Testnet @@ -72,42 +74,42 @@ public static void main(String[] args) throws Exception { // Get the transfer transaction receipt TransactionReceipt transferTxReceipt = transferTxSubmitted.getReceipt(client); Status transactionStatus = transferTxReceipt.status; - System.out.println( - "The transfer transaction status is: " + - transactionStatus.toString() - ); + + // Check if the transaction was successful + if (transactionStatus == Status.SUCCESS) { + System.out.println("✅ The transfer transaction was successful."); + System.out.println("Transaction Hashscan URL:\nhttps://hashscan.io/testnet/transaction/" + transferTxId); + } else { + System.err.println("❌ The transfer transaction failed with status: " + transactionStatus); + throw new RuntimeException("Transaction failed: " + transactionStatus); + } // Query HBAR balance using AccountBalanceQuery AccountBalance newAccountBalance = new AccountBalanceQuery() - .setAccountId(operatorId) - .execute(client); + .setAccountId(operatorId) + .execute(client); Hbar newHbarBalance = newAccountBalance.hbars; System.out.println( - "The new account balance after the transfer: " + - newHbarBalance.toString() - ); + "The new account balance after the transfer: " + + newHbarBalance.toString()); client.close(); // View the transaction in HashScan System.out.println( - "🟣 View the transfer transaction transaction in HashScan" - ); - String transferTxVerifyHashscanUrl = - "https://hashscan.io/testnet/transaction/" + transferTxId; + "🟣 View the transfer transaction transaction in HashScan"); + String transferTxVerifyHashscanUrl = "https://hashscan.io/testnet/transaction/" + transferTxId; System.out.println( - "Transaction Hashscan URL:\n" + - transferTxVerifyHashscanUrl - ); + "Transaction Hashscan URL:\n" + + transferTxVerifyHashscanUrl); // Verify transfer transaction using Mirror Node API System.out.println("🟣 Get transfer transaction data from the Hedera Mirror Node"); Thread.sleep(6_000); - String transferTxIdMirrorNodeFormat = - convertTransactionIdForMirrorNodeApi(transferTxId.toString()); - String transferTxVerifyMirrorNodeApiUrl = - "https://testnet.mirrornode.hedera.com/api/v1/transactions/" + transferTxIdMirrorNodeFormat + "?nonce=0"; + String transferTxIdMirrorNodeFormat = convertTransactionIdForMirrorNodeApi(transferTxId.toString()); + String transferTxVerifyMirrorNodeApiUrl = "https://testnet.mirrornode.hedera.com/api/v1/transactions/" + + transferTxIdMirrorNodeFormat + "?nonce=0"; final HttpRequest httpRequest = HttpRequest.newBuilder() .uri(URI.create(transferTxVerifyMirrorNodeApiUrl)) @@ -131,8 +133,7 @@ public static void main(String[] args) throws Exception { } } filteredAndSortedTransfers.sort( - Comparator.comparingLong(obj -> obj.get("amount").getAsLong()) - ); + Comparator.comparingLong(obj -> obj.get("amount").getAsLong())); System.out.printf("%-15s %-15s%n", "AccountID", "Amount"); System.out.println("-".repeat(30));