github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/token_transfer_transaction_unit_test.go (about)

     1  //go:build all || unit
     2  // +build all unit
     3  
     4  package hedera
     5  
     6  /*-
     7   *
     8   * Hedera Go SDK
     9   *
    10   * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
    11   *
    12   * Licensed under the Apache License, Version 2.0 (the "License");
    13   * you may not use this file except in compliance with the License.
    14   * You may obtain a copy of the License at
    15   *
    16   *      http://www.apache.org/licenses/LICENSE-2.0
    17   *
    18   * Unless required by applicable law or agreed to in writing, software
    19   * distributed under the License is distributed on an "AS IS" BASIS,
    20   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    21   * See the License for the specific language governing permissions and
    22   * limitations under the License.
    23   *
    24   */
    25  
    26  import (
    27  	"testing"
    28  	"time"
    29  
    30  	protobuf "google.golang.org/protobuf/proto"
    31  
    32  	"github.com/hashgraph/hedera-protobufs-go/services"
    33  
    34  	"github.com/stretchr/testify/assert"
    35  
    36  	"github.com/stretchr/testify/require"
    37  )
    38  
    39  func TestUnitTokenTransferTransactionTransfers(t *testing.T) {
    40  	t.Parallel()
    41  
    42  	amount := NewHbar(1)
    43  	accountID1 := AccountID{Account: 3}
    44  	accountID2 := AccountID{Account: 4}
    45  	tokenID1 := TokenID{Token: 5}
    46  	tokenID2 := TokenID{Token: 6}
    47  	tokenID3 := TokenID{Token: 7}
    48  	tokenID4 := TokenID{Token: 8}
    49  	nftID1 := NftID{TokenID: tokenID3, SerialNumber: 9}
    50  	nftID2 := NftID{TokenID: tokenID4, SerialNumber: 10}
    51  
    52  	transactionID := TransactionIDGenerate(AccountID{Account: 1111})
    53  
    54  	tokenTransfer := NewTransferTransaction().
    55  		AddHbarTransfer(accountID1, amount).
    56  		AddHbarTransfer(accountID2, amount.Negated()).
    57  		AddTokenTransfer(tokenID1, accountID1, 10).
    58  		AddTokenTransfer(tokenID1, accountID2, -10).
    59  		AddTokenTransfer(tokenID2, accountID1, 10).
    60  		AddTokenTransfer(tokenID2, accountID2, -10).
    61  		SetTransactionID(transactionID).
    62  		SetNodeAccountIDs([]AccountID{{Account: 3}}).
    63  		AddNftTransfer(nftID1, accountID1, accountID2).
    64  		AddNftTransfer(nftID2, accountID2, accountID1).
    65  		build()
    66  
    67  	require.ElementsMatch(t, tokenTransfer.GetCryptoTransfer().Transfers.AccountAmounts, []*services.AccountAmount{
    68  		{
    69  			AccountID: accountID1._ToProtobuf(),
    70  			Amount:    amount.AsTinybar(),
    71  		},
    72  		{
    73  			AccountID: accountID2._ToProtobuf(),
    74  			Amount:    amount.Negated().AsTinybar(),
    75  		},
    76  	})
    77  
    78  	require.ElementsMatch(t, tokenTransfer.GetCryptoTransfer().TokenTransfers, []*services.TokenTransferList{
    79  		{
    80  			Token: tokenID1._ToProtobuf(),
    81  			Transfers: []*services.AccountAmount{
    82  				{
    83  					AccountID: accountID1._ToProtobuf(),
    84  					Amount:    10,
    85  				},
    86  				{
    87  					AccountID: accountID2._ToProtobuf(),
    88  					Amount:    -10,
    89  				},
    90  			}},
    91  		{
    92  			Token: tokenID2._ToProtobuf(),
    93  			Transfers: []*services.AccountAmount{
    94  				{
    95  					AccountID: accountID1._ToProtobuf(),
    96  					Amount:    10,
    97  				},
    98  				{
    99  					AccountID: accountID2._ToProtobuf(),
   100  					Amount:    -10,
   101  				},
   102  			}},
   103  		{
   104  			Token: tokenID3._ToProtobuf(),
   105  			NftTransfers: []*services.NftTransfer{
   106  				{
   107  					SenderAccountID:   accountID1._ToProtobuf(),
   108  					ReceiverAccountID: accountID2._ToProtobuf(),
   109  					SerialNumber:      int64(9),
   110  				},
   111  			},
   112  		},
   113  		{
   114  			Token: tokenID4._ToProtobuf(),
   115  			NftTransfers: []*services.NftTransfer{
   116  				{
   117  					SenderAccountID:   accountID2._ToProtobuf(),
   118  					ReceiverAccountID: accountID1._ToProtobuf(),
   119  					SerialNumber:      int64(10),
   120  				},
   121  			},
   122  		},
   123  	})
   124  }
   125  
   126  func TestUnitTokenTransferTransactionValidate(t *testing.T) {
   127  	t.Parallel()
   128  
   129  	client, err := _NewMockClient()
   130  	client.SetLedgerID(*NewLedgerIDTestnet())
   131  	require.NoError(t, err)
   132  	client.SetAutoValidateChecksums(true)
   133  	accountID, err := AccountIDFromString("0.0.123-esxsf")
   134  	require.NoError(t, err)
   135  	tokenID, err := TokenIDFromString("0.0.123-esxsf")
   136  	require.NoError(t, err)
   137  	nftID, err := NftIDFromString("2@0.0.123-esxsf")
   138  	require.NoError(t, err)
   139  
   140  	tokenTransfer := NewTransferTransaction().
   141  		AddTokenTransfer(tokenID, accountID, 1).
   142  		AddNftTransfer(nftID, accountID, accountID)
   143  
   144  	err = tokenTransfer.validateNetworkOnIDs(client)
   145  	require.NoError(t, err)
   146  }
   147  
   148  func TestUnitTokenTransferTransactionValidateWrong(t *testing.T) {
   149  	t.Parallel()
   150  
   151  	client, err := _NewMockClient()
   152  	client.SetLedgerID(*NewLedgerIDTestnet())
   153  	require.NoError(t, err)
   154  	client.SetAutoValidateChecksums(true)
   155  	accountID, err := AccountIDFromString("0.0.123-rmkykd")
   156  	require.NoError(t, err)
   157  	tokenID, err := TokenIDFromString("0.0.123-rmkykd")
   158  	require.NoError(t, err)
   159  	nftID, err := NftIDFromString("2@0.0.123-rmkykd")
   160  	require.NoError(t, err)
   161  
   162  	tokenTransfer := NewTransferTransaction().
   163  		AddTokenTransfer(tokenID, accountID, 1).
   164  		AddNftTransfer(nftID, accountID, accountID)
   165  
   166  	err = tokenTransfer.validateNetworkOnIDs(client)
   167  	assert.Error(t, err)
   168  	if err != nil {
   169  		assert.Equal(t, "network mismatch or wrong checksum given, given checksum: rmkykd, correct checksum esxsf, network: testnet", err.Error())
   170  	}
   171  }
   172  
   173  func TestUnitTransferTransactionGet(t *testing.T) {
   174  	t.Parallel()
   175  
   176  	tokenID := TokenID{Token: 7}
   177  	accountID := AccountID{Account: 3}
   178  	nftID := tokenID.Nft(32)
   179  
   180  	nodeAccountID := []AccountID{{Account: 10}, {Account: 11}, {Account: 12}}
   181  	transactionID := TransactionIDGenerate(AccountID{Account: 324})
   182  
   183  	transaction, err := NewTransferTransaction().
   184  		SetTransactionID(transactionID).
   185  		SetNodeAccountIDs(nodeAccountID).
   186  		SetHbarTransferApproval(accountID, true).
   187  		SetTokenTransferApproval(tokenID, accountID, true).
   188  		SetNftTransferApproval(nftID, true).
   189  		AddHbarTransfer(accountID, NewHbar(34)).
   190  		AddTokenTransferWithDecimals(tokenID, accountID, 123, 12).
   191  		AddTokenTransfer(tokenID, accountID, 123).
   192  		AddNftTransfer(nftID, accountID, accountID).
   193  		SetMaxTransactionFee(NewHbar(10)).
   194  		SetTransactionMemo("").
   195  		SetTransactionValidDuration(60 * time.Second).
   196  		SetRegenerateTransactionID(false).
   197  		Freeze()
   198  	require.NoError(t, err)
   199  
   200  	transaction.GetTransactionID()
   201  	transaction.GetNodeAccountIDs()
   202  
   203  	_, err = transaction.GetTransactionHash()
   204  	require.NoError(t, err)
   205  
   206  	transaction.GetHbarTransfers()
   207  	transaction.GetTokenTransfers()
   208  	transaction.GetNftTransfers()
   209  	transaction.GetTokenIDDecimals()
   210  	transaction.GetMaxTransactionFee()
   211  	transaction.GetTransactionMemo()
   212  	transaction.GetRegenerateTransactionID()
   213  	_, err = transaction.GetSignatures()
   214  	require.NoError(t, err)
   215  	transaction.GetRegenerateTransactionID()
   216  	transaction.GetMaxTransactionFee()
   217  	transaction.GetRegenerateTransactionID()
   218  }
   219  
   220  func TestUnitTransferTransactionNothingSet(t *testing.T) {
   221  	t.Parallel()
   222  
   223  	nodeAccountID := []AccountID{{Account: 10}, {Account: 11}, {Account: 12}}
   224  	transactionID := TransactionIDGenerate(AccountID{Account: 324})
   225  
   226  	transaction, err := NewTransferTransaction().
   227  		SetTransactionID(transactionID).
   228  		SetNodeAccountIDs(nodeAccountID).
   229  		Freeze()
   230  	require.NoError(t, err)
   231  
   232  	transaction.GetTransactionID()
   233  	transaction.GetNodeAccountIDs()
   234  
   235  	_, err = transaction.GetTransactionHash()
   236  	require.NoError(t, err)
   237  
   238  	transaction.GetHbarTransfers()
   239  	transaction.GetTokenTransfers()
   240  	transaction.GetNftTransfers()
   241  	transaction.GetTokenIDDecimals()
   242  	transaction.GetMaxTransactionFee()
   243  	transaction.GetTransactionMemo()
   244  	transaction.GetRegenerateTransactionID()
   245  	_, err = transaction.GetSignatures()
   246  	require.NoError(t, err)
   247  	transaction.GetRegenerateTransactionID()
   248  	transaction.GetMaxTransactionFee()
   249  	transaction.GetRegenerateTransactionID()
   250  }
   251  
   252  func TestUnitTransferTransactionMock(t *testing.T) {
   253  	t.Parallel()
   254  
   255  	newKey, err := PrivateKeyFromStringEd25519("302e020100300506032b657004220420a869f4c6191b9c8c99933e7f6b6611711737e4b1a1a5a4cb5370e719a1f6df98")
   256  	require.NoError(t, err)
   257  
   258  	call := func(request *services.Transaction) *services.TransactionResponse {
   259  		require.NotEmpty(t, request.SignedTransactionBytes)
   260  		signedTransaction := services.SignedTransaction{}
   261  		_ = protobuf.Unmarshal(request.SignedTransactionBytes, &signedTransaction)
   262  
   263  		require.NotEmpty(t, signedTransaction.BodyBytes)
   264  		transactionBody := services.TransactionBody{}
   265  		_ = protobuf.Unmarshal(signedTransaction.BodyBytes, &transactionBody)
   266  
   267  		require.NotNil(t, transactionBody.TransactionID)
   268  		transactionId := transactionBody.TransactionID.String()
   269  		require.NotEqual(t, "", transactionId)
   270  
   271  		sigMap := signedTransaction.GetSigMap()
   272  		require.NotNil(t, sigMap)
   273  
   274  		return &services.TransactionResponse{
   275  			NodeTransactionPrecheckCode: services.ResponseCodeEnum_OK,
   276  		}
   277  	}
   278  	responses := [][]interface{}{{
   279  		call,
   280  	}}
   281  
   282  	client, server := NewMockClientAndServer(responses)
   283  	defer server.Close()
   284  
   285  	freez, err := NewTransferTransaction().
   286  		SetNodeAccountIDs([]AccountID{{Account: 3}}).
   287  		FreezeWith(client)
   288  	require.NoError(t, err)
   289  
   290  	_, err = freez.Sign(newKey).Execute(client)
   291  	require.NoError(t, err)
   292  }
   293  
   294  func TestUnitTokenTransferEncodeDecode(t *testing.T) {
   295  	transfer := NewTokenTransfer(AccountID{Account: 5}, 123)
   296  	decoded, err := TokenTransferFromBytes(transfer.ToBytes())
   297  
   298  	require.NoError(t, err)
   299  	require.Equal(t, transfer, decoded)
   300  }