All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hedera.hashgraph.sdk.TransferTransaction Maven / Gradle / Ivy

The newest version!
/*-
 *
 * Hedera Java SDK
 *
 * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.hedera.hashgraph.sdk;

import com.google.common.base.MoreObjects;
import com.google.protobuf.InvalidProtocolBufferException;
import com.hedera.hashgraph.sdk.proto.AccountAmount;
import com.hedera.hashgraph.sdk.proto.CryptoServiceGrpc;
import com.hedera.hashgraph.sdk.proto.CryptoTransferTransactionBody;
import com.hedera.hashgraph.sdk.proto.SchedulableTransactionBody;
import com.hedera.hashgraph.sdk.proto.TransactionBody;
import com.hedera.hashgraph.sdk.proto.TransactionResponse;
import com.hedera.hashgraph.sdk.proto.TransferList;
import io.grpc.MethodDescriptor;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * A transaction that transfers hbars and tokens between Hedera accounts. You can enter multiple transfers in a single
 * transaction. The net value of hbars between the sending accounts and receiving accounts must equal zero.
 * 

* See Hedera * Documentation */ public class TransferTransaction extends AbstractTokenTransferTransaction { private final ArrayList hbarTransfers = new ArrayList<>(); private static class HbarTransfer { final AccountId accountId; Hbar amount; boolean isApproved; HbarTransfer(AccountId accountId, Hbar amount, boolean isApproved) { this.accountId = accountId; this.amount = amount; this.isApproved = isApproved; } AccountAmount toProtobuf() { return AccountAmount.newBuilder() .setAccountID(accountId.toProtobuf()) .setAmount(amount.toTinybars()) .setIsApproval(isApproved) .build(); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("accountId", accountId) .add("amount", amount) .add("isApproved", isApproved) .toString(); } } /** * Constructor. */ public TransferTransaction() { defaultMaxTransactionFee = new Hbar(1); } /** * Constructor. * * @param txs Compound list of transaction id's list of (AccountId, Transaction) records * @throws InvalidProtocolBufferException when there is an issue with the protobuf */ TransferTransaction( LinkedHashMap> txs) throws InvalidProtocolBufferException { super(txs); initFromTransactionBody(); } /** * Constructor. * * @param txBody protobuf TransactionBody */ TransferTransaction(com.hedera.hashgraph.sdk.proto.TransactionBody txBody) { super(txBody); initFromTransactionBody(); } /** * Extract the of hbar transfers. * * @return list of hbar transfers */ public Map getHbarTransfers() { Map transfers = new HashMap<>(); for (var transfer : hbarTransfers) { transfers.put(transfer.accountId, transfer.amount); } return transfers; } private TransferTransaction doAddHbarTransfer(AccountId accountId, Hbar value, boolean isApproved) { requireNotFrozen(); for (var transfer : hbarTransfers) { if (transfer.accountId.equals(accountId) && transfer.isApproved == isApproved) { transfer.amount = Hbar.fromTinybars(transfer.amount.toTinybars() + value.toTinybars()); return this; } } hbarTransfers.add(new HbarTransfer(accountId, value, isApproved)); return this; } /** * Add a non approved hbar transfer to an EVM address. * * @param evmAddress the EVM address * @param value the value * @return the updated transaction */ public TransferTransaction addHbarTransfer(EvmAddress evmAddress, Hbar value) { AccountId accountId = AccountId.fromEvmAddress(evmAddress); return doAddHbarTransfer(accountId, value, false); } /** * Add a non approved hbar transfer. * * @param accountId the account id * @param value the value * @return the updated transaction */ public TransferTransaction addHbarTransfer(AccountId accountId, Hbar value) { return doAddHbarTransfer(accountId, value, false); } /** * Add an approved hbar transfer. * * @param accountId the account id * @param value the value * @return the updated transaction */ public TransferTransaction addApprovedHbarTransfer(AccountId accountId, Hbar value) { return doAddHbarTransfer(accountId, value, true); } /** * @param accountId the account id * @param isApproved whether the transfer is approved * @return {@code this} * @deprecated - Use {@link #addApprovedHbarTransfer(AccountId, Hbar)} instead */ @Deprecated public TransferTransaction setHbarTransferApproval(AccountId accountId, boolean isApproved) { requireNotFrozen(); for (var transfer : hbarTransfers) { if (transfer.accountId.equals(accountId)) { transfer.isApproved = isApproved; return this; } } return this; } /** * Build the transaction body. * * @return {@link com.hedera.hashgraph.sdk.proto.CryptoTransferTransactionBody} */ CryptoTransferTransactionBody.Builder build() { var transfers = sortTransfersAndBuild(); var builder = CryptoTransferTransactionBody.newBuilder(); this.hbarTransfers.sort(Comparator.comparing((HbarTransfer a) -> a.accountId).thenComparing(a -> a.isApproved)); var hbarTransfersList = TransferList.newBuilder(); for (var transfer : hbarTransfers) { hbarTransfersList.addAccountAmounts(transfer.toProtobuf()); } builder.setTransfers(hbarTransfersList); for (var transfer : transfers) { builder.addTokenTransfers(transfer.toProtobuf()); } return builder; } @Override void validateChecksums(Client client) throws BadEntityIdException { super.validateChecksums(client); for (var transfer : hbarTransfers) { transfer.accountId.validateChecksum(client); } } @Override MethodDescriptor getMethodDescriptor() { return CryptoServiceGrpc.getCryptoTransferMethod(); } @Override void onFreeze(TransactionBody.Builder bodyBuilder) { bodyBuilder.setCryptoTransfer(build()); } @Override void onScheduled(SchedulableTransactionBody.Builder scheduled) { scheduled.setCryptoTransfer(build()); } /** * Initialize from the transaction body. */ void initFromTransactionBody() { var body = sourceTransactionBody.getCryptoTransfer(); for (var transfer : body.getTransfers().getAccountAmountsList()) { hbarTransfers.add(new HbarTransfer( AccountId.fromProtobuf(transfer.getAccountID()), Hbar.fromTinybars(transfer.getAmount()), transfer.getIsApproval() )); } for (var tokenTransferList : body.getTokenTransfersList()) { var token = TokenId.fromProtobuf(tokenTransferList.getToken()); for (var transfer : tokenTransferList.getTransfersList()) { tokenTransfers.add(new TokenTransfer( token, AccountId.fromProtobuf(transfer.getAccountID()), transfer.getAmount(), tokenTransferList.hasExpectedDecimals() ? tokenTransferList.getExpectedDecimals().getValue() : null, transfer.getIsApproval() )); } for (var transfer : tokenTransferList.getNftTransfersList()) { nftTransfers.add(new TokenNftTransfer( token, AccountId.fromProtobuf(transfer.getSenderAccountID()), AccountId.fromProtobuf(transfer.getReceiverAccountID()), transfer.getSerialNumber(), transfer.getIsApproval() )); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy