package _nft_hscs_hts.hedera;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.concurrent.TimeoutException;
import com.hedera.hashgraph.sdk.*;
import io.github.cdimascio.dotenv.Dotenv;
// Account creation function
private static AccountId accountCreator(PrivateKey pvKey, int iBal , Client client) throws TimeoutException, PrecheckStatusException, ReceiptStatusException {
AccountCreateTransaction transaction = new AccountCreateTransaction()
.setKey(pvKey.getPublicKey())
.setInitialBalance(new Hbar(iBal));
TransactionResponse txResponse = transaction.execute(client);
TransactionReceipt receipt = txResponse.getReceipt(client);
return receipt.accountId;
public static void main( String[] args ) throws TimeoutException, PrecheckStatusException, ReceiptStatusException, IOException
String metadata = ("ipfs://bafyreie3ichmqul4xa7e6xcy34tylbuq2vf3gnjf7c55trg3b6xyjr4bku/metadata.json");
byte[][] byteArray = new byte[1][metadata.length()];
byteArray[0] = metadata.getBytes();
AccountId operatorId = AccountId.fromString(Objects.requireNonNull(Dotenv.load().get("ACCOUNT_ID")));
PrivateKey operatorKey = PrivateKey.fromString(Objects.requireNonNull(Dotenv.load().get("PRIVATE_KEY")));
Client client = Client.forTestnet();
client.setOperator(operatorId, operatorKey);
PrivateKey aliceKey = PrivateKey.generateED25519();
AccountId aliceId = accountCreator(aliceKey, 100, client);
System.out.print(aliceId);
String bytecode = Files.readString(Paths.get("./NFTCreator_sol_NFTCreator.bin"));
ContractCreateFlow createContract = new ContractCreateFlow()
.setBytecode(bytecode) // Contract bytecode
.setGas(150_000); // Increase if revert
TransactionResponse createContractTx = createContract.execute(client);
TransactionReceipt createContractRx = createContractTx.getReceipt(client);
// Get the new contract ID
ContractId newContractId = createContractRx.contractId;
System.out.println("Contract created with ID: " + newContractId);
// Create NFT using contract
ContractExecuteTransaction createToken = new ContractExecuteTransaction()
.setContractId(newContractId) // Contract id
.setGas(300_000) // Increase if revert
.setPayableAmount(new Hbar(20)) // Increase if revert
.setFunction("createNft", new ContractFunctionParameters()
.addString("Fall Collection") // NFT Name
.addString("LEAF") // NFT Symbol
.addString("Just a memo") // NFT Memo
.addUint32(10) // NFT max supply
.addUint32(7_000_000)); // Expiration: Needs to be between 6999999 and 8000001
TransactionResponse createTokenTx = createToken.execute(client);
TransactionRecord createTokenRx = createTokenTx.getRecord(client);
String tokenIdSolidityAddr = createTokenRx.contractFunctionResult.getAddress(0);
AccountId tokenId = AccountId.fromSolidityAddress(tokenIdSolidityAddr);
System.out.println("Token created with ID: " + tokenId);
ContractExecuteTransaction mintToken = new ContractExecuteTransaction()
.setContractId(newContractId)
.setFunction("mintNft", new ContractFunctionParameters()
.addAddress(tokenIdSolidityAddr) // Token address
.addBytesArray(byteArray)); // Metadata
TransactionResponse mintTokenTx = mintToken.execute(client);
TransactionRecord mintTokenRx = mintTokenTx.getRecord(client);
long serial = mintTokenRx.contractFunctionResult.getInt64(0);
System.out.println("Minted NFT with serial: " + serial);
ContractExecuteTransaction transferToken = new ContractExecuteTransaction()
.setContractId(newContractId)
.setFunction("transferNft", new ContractFunctionParameters()
.addAddress(tokenIdSolidityAddr) // Token id
.addAddress(aliceId.toSolidityAddress()) // Token receiver (Alice)
.addInt64(serial)) // Serial number
.freezeWith(client) // Freeze transaction using client
.sign(aliceKey); //Sign using Alice Private Key
TransactionResponse transferTokenTx = transferToken.execute(client);
TransactionReceipt transferTokenRx = transferTokenTx.getReceipt(client);
System.out.println("Trasnfer status: " + transferTokenRx.status);