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

     1  //go:build all || e2e
     2  // +build all e2e
     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  
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestIntegrationCantTransferOnBehalfOfSpenderWithoutAllowanceApproval(t *testing.T) {
    33  	t.Parallel()
    34  	env := NewIntegrationTestEnv(t)
    35  	spenderKey, err := PrivateKeyGenerateEd25519()
    36  	require.NoError(t, err)
    37  	spenderCreate, err := NewAccountCreateTransaction().SetKey(spenderKey).SetInitialBalance(NewHbar(2)).Execute(env.Client)
    38  	require.NoError(t, err)
    39  	spenderReceipt, err := spenderCreate.SetValidateStatus(true).GetReceipt(env.Client)
    40  	spenderAccountId := spenderReceipt.AccountID
    41  	receiverKey, err := PrivateKeyGenerateEd25519()
    42  	require.NoError(t, err)
    43  	receiverCreate, err := NewAccountCreateTransaction().SetKey(receiverKey).SetInitialBalance(NewHbar(2)).SetMaxAutomaticTokenAssociations(10).Execute(env.Client)
    44  	require.NoError(t, err)
    45  	receiverReceipt, err := receiverCreate.SetValidateStatus(true).GetReceipt(env.Client)
    46  	require.NoError(t, err)
    47  	receiverAccountId := receiverReceipt.AccountID
    48  	tokenID, err := createNft(&env)
    49  	require.NoError(t, err)
    50  	frozenTxn, err := NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*spenderAccountId).FreezeWith(env.Client)
    51  	require.NoError(t, err)
    52  	_, err = frozenTxn.Sign(spenderKey).Execute(env.Client)
    53  	require.NoError(t, err)
    54  
    55  	mint, err := NewTokenMintTransaction().
    56  		SetTokenID(tokenID).
    57  		SetMetadata([]byte{0x01}).
    58  		Execute(env.Client)
    59  	require.NoError(t, err)
    60  	mintReceipt, err := mint.SetValidateStatus(true).GetReceipt(env.Client)
    61  	require.NoError(t, err)
    62  	serials := mintReceipt.SerialNumbers
    63  	nft1 := NftID{TokenID: tokenID, SerialNumber: serials[0]}
    64  	onBehalfOfTxId := TransactionIDGenerate(*spenderAccountId)
    65  
    66  	frozenTransfer, err := NewTransferTransaction().AddApprovedNftTransfer(nft1, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTxId).FreezeWith(env.Client)
    67  	require.NoError(t, err)
    68  	resp, err := frozenTransfer.Sign(spenderKey).Execute(env.Client)
    69  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
    70  	require.Error(t, err)
    71  	require.Equal(t, "exceptional receipt status: SPENDER_DOES_NOT_HAVE_ALLOWANCE", err.Error())
    72  
    73  }
    74  
    75  func TestIntegrationCantTransferOnBehalfOfSpenderAfterRemovingTheAllowanceApproval(t *testing.T) {
    76  	t.Parallel()
    77  	env := NewIntegrationTestEnv(t)
    78  	spenderKey, err := PrivateKeyGenerateEd25519()
    79  	require.NoError(t, err)
    80  
    81  	spenderCreate, err := NewAccountCreateTransaction().
    82  		SetKey(spenderKey.PublicKey()).
    83  		SetInitialBalance(NewHbar(2)).
    84  		Execute(env.Client)
    85  	require.NoError(t, err)
    86  	spenderAccountReceipt, err := spenderCreate.SetValidateStatus(true).GetReceipt(env.Client)
    87  	spenderAccountId := spenderAccountReceipt.AccountID
    88  	receiverKey, err := PrivateKeyGenerateEd25519()
    89  	require.NoError(t, err)
    90  
    91  	receiverCreate, err := NewAccountCreateTransaction().
    92  		SetKey(receiverKey.PublicKey()).
    93  		SetInitialBalance(NewHbar(2)).
    94  		Execute(env.Client)
    95  	require.NoError(t, err)
    96  	receiverAccountReceipt, err := receiverCreate.SetValidateStatus(true).GetReceipt(env.Client)
    97  	receiverAccountId := receiverAccountReceipt.AccountID
    98  
    99  	tokenID, err := createNft(&env)
   100  	require.NoError(t, err)
   101  
   102  	frozenTx, err := NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*spenderAccountId).FreezeWith(env.Client)
   103  	require.NoError(t, err)
   104  	_, err = frozenTx.Sign(spenderKey).Execute(env.Client)
   105  	require.NoError(t, err)
   106  
   107  	frozenTx, err = NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*receiverAccountId).FreezeWith(env.Client)
   108  	require.NoError(t, err)
   109  	_, err = frozenTx.Sign(receiverKey).Execute(env.Client)
   110  	require.NoError(t, err)
   111  
   112  	mint, err := NewTokenMintTransaction().SetTokenID(tokenID).SetMetadata([]byte{0x01}).SetMetadata([]byte{0x02}).Execute(env.Client)
   113  	require.NoError(t, err)
   114  	mintReceipt, err := mint.SetValidateStatus(true).GetReceipt(env.Client)
   115  	require.NoError(t, err)
   116  	serials := mintReceipt.SerialNumbers
   117  	nft1 := NftID{TokenID: tokenID, SerialNumber: serials[0]}
   118  	nft2 := NftID{TokenID: tokenID, SerialNumber: serials[1]}
   119  	approveTx, err := NewAccountAllowanceApproveTransaction().ApproveTokenNftAllowance(nft1, env.OperatorID, *spenderAccountId).
   120  		ApproveTokenNftAllowance(nft2, env.OperatorID, *spenderAccountId).Execute(env.Client)
   121  	require.NoError(t, err)
   122  	_, err = approveTx.SetValidateStatus(true).GetReceipt(env.Client)
   123  	require.NoError(t, err)
   124  
   125  	deleteTx, err := NewAccountAllowanceDeleteTransaction().DeleteAllTokenNftAllowances(nft2, &env.OperatorID).Execute(env.Client)
   126  	require.NoError(t, err)
   127  	_, err = deleteTx.SetValidateStatus(true).GetReceipt(env.Client)
   128  
   129  	onBehalfOfTxId := TransactionIDGenerate(*spenderAccountId)
   130  	frozenTransfer, err := NewTransferTransaction().AddApprovedNftTransfer(nft1, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTxId).FreezeWith(env.Client)
   131  	require.NoError(t, err)
   132  	resp, err := frozenTransfer.Sign(spenderKey).Execute(env.Client)
   133  	require.NoError(t, err)
   134  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
   135  	require.NoError(t, err)
   136  
   137  	info, err := NewTokenNftInfoQuery().SetNftID(nft1).Execute(env.Client)
   138  	require.NoError(t, err)
   139  	require.Equal(t, *receiverAccountId, info[0].AccountID)
   140  
   141  	onBehalfOfTxId2 := TransactionIDGenerate(*spenderAccountId)
   142  	frozenTransfer2, err := NewTransferTransaction().AddApprovedNftTransfer(nft2, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTxId2).FreezeWith(env.Client)
   143  	require.NoError(t, err)
   144  	resp, err = frozenTransfer2.Sign(spenderKey).Execute(env.Client)
   145  	require.NoError(t, err)
   146  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
   147  	require.Error(t, err)
   148  	require.Equal(t, "exceptional receipt status: SPENDER_DOES_NOT_HAVE_ALLOWANCE", err.Error())
   149  
   150  }
   151  
   152  func TestIntegrationCantRemoveSingleSerialNumberAllowanceWhenAllowanceIsForAllSerials(t *testing.T) {
   153  	t.Parallel()
   154  	env := NewIntegrationTestEnv(t)
   155  	spenderKey, err := PrivateKeyGenerateEd25519()
   156  	require.NoError(t, err)
   157  
   158  	spenderCreate, err := NewAccountCreateTransaction().
   159  		SetKey(spenderKey.PublicKey()).
   160  		SetInitialBalance(NewHbar(2)).
   161  		Execute(env.Client)
   162  	require.NoError(t, err)
   163  	spenderAccountReceipt, err := spenderCreate.SetValidateStatus(true).GetReceipt(env.Client)
   164  	spenderAccountId := spenderAccountReceipt.AccountID
   165  
   166  	receiverKey, err := PrivateKeyGenerateEd25519()
   167  	require.NoError(t, err)
   168  	receiverCreate, err := NewAccountCreateTransaction().
   169  		SetKey(receiverKey.PublicKey()).
   170  		SetInitialBalance(NewHbar(2)).
   171  		Execute(env.Client)
   172  	require.NoError(t, err)
   173  	receiverAccountReceipt, err := receiverCreate.SetValidateStatus(true).GetReceipt(env.Client)
   174  	receiverAccountId := receiverAccountReceipt.AccountID
   175  
   176  	tokenID, err := createNft(&env)
   177  	require.NoError(t, err)
   178  
   179  	frozenTxn, err := NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*spenderAccountId).FreezeWith(env.Client)
   180  	require.NoError(t, err)
   181  	_, err = frozenTxn.Sign(spenderKey).Execute(env.Client)
   182  	require.NoError(t, err)
   183  
   184  	frozenTxn, err = NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*receiverAccountId).FreezeWith(env.Client)
   185  	require.NoError(t, err)
   186  	_, err = frozenTxn.Sign(receiverKey).Execute(env.Client)
   187  	require.NoError(t, err)
   188  
   189  	mint, err := NewTokenMintTransaction().SetTokenID(tokenID).SetMetadata([]byte{0x01}).SetMetadata([]byte{0x02}).Execute(env.Client)
   190  	require.NoError(t, err)
   191  	mintReceipt, err := mint.SetValidateStatus(true).GetReceipt(env.Client)
   192  	require.NoError(t, err)
   193  	serials := mintReceipt.SerialNumbers
   194  	nft1 := NftID{TokenID: tokenID, SerialNumber: serials[0]}
   195  	nft2 := NftID{TokenID: tokenID, SerialNumber: serials[1]}
   196  	approveTx, err := NewAccountAllowanceApproveTransaction().ApproveTokenNftAllowanceAllSerials(nft1.TokenID, env.OperatorID, *spenderAccountId).Execute(env.Client)
   197  	require.NoError(t, err)
   198  	_, err = approveTx.SetValidateStatus(true).GetReceipt(env.Client)
   199  	require.NoError(t, err)
   200  
   201  	onBehalfOfTransactionId := TransactionIDGenerate(*spenderAccountId)
   202  	frozenTransfer, err := NewTransferTransaction().AddApprovedNftTransfer(nft1, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTransactionId).FreezeWith(env.Client)
   203  	require.NoError(t, err)
   204  	resp, err := frozenTransfer.Sign(spenderKey).Execute(env.Client)
   205  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
   206  	require.NoError(t, err)
   207  
   208  	deleteTx, err := NewAccountAllowanceDeleteTransaction().DeleteAllTokenNftAllowances(nft2, &env.OperatorID).Execute(env.Client)
   209  	require.NoError(t, err)
   210  	_, err = deleteTx.SetValidateStatus(true).GetReceipt(env.Client)
   211  
   212  	onBehalfOfTransactionId2 := TransactionIDGenerate(*spenderAccountId)
   213  	frozenTransfer2, err := NewTransferTransaction().AddApprovedNftTransfer(nft2, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTransactionId2).FreezeWith(env.Client)
   214  	require.NoError(t, err)
   215  	resp, err = frozenTransfer2.Sign(spenderKey).Execute(env.Client)
   216  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
   217  
   218  	info, err := NewTokenNftInfoQuery().SetNftID(nft1).Execute(env.Client)
   219  	require.NoError(t, err)
   220  	require.Equal(t, *receiverAccountId, info[0].AccountID)
   221  
   222  	info2, err := NewTokenNftInfoQuery().SetNftID(nft2).Execute(env.Client)
   223  	require.NoError(t, err)
   224  	require.Equal(t, *receiverAccountId, info2[0].AccountID)
   225  }
   226  
   227  func TestIntegrationAfterGivenAllowanceForAllSerialsCanGiveSingleSerialToOtherAccounts(t *testing.T) {
   228  	t.Parallel()
   229  	env := NewIntegrationTestEnv(t)
   230  	spenderKey, err := PrivateKeyGenerateEd25519()
   231  	require.NoError(t, err)
   232  
   233  	spenderCreate, err := NewAccountCreateTransaction().
   234  		SetKey(spenderKey.PublicKey()).
   235  		SetInitialBalance(NewHbar(2)).
   236  		Execute(env.Client)
   237  	require.NoError(t, err)
   238  	spenderAccountReceipt, err := spenderCreate.SetValidateStatus(true).GetReceipt(env.Client)
   239  	spenderAccountId := spenderAccountReceipt.AccountID
   240  
   241  	delegateSpenderKey, err := PrivateKeyGenerateEd25519()
   242  	require.NoError(t, err)
   243  	delegateSpenderCreate, err := NewAccountCreateTransaction().SetKey(delegateSpenderKey.PublicKey()).SetInitialBalance(NewHbar(2)).Execute(env.Client)
   244  	require.NoError(t, err)
   245  	delegateSpenderAccountReceipt, err := delegateSpenderCreate.SetValidateStatus(true).GetReceipt(env.Client)
   246  	require.NoError(t, err)
   247  	delegateSpenderAccountId := delegateSpenderAccountReceipt.AccountID
   248  
   249  	receiverKey, err := PrivateKeyGenerateEd25519()
   250  	require.NoError(t, err)
   251  	receiverCreate, err := NewAccountCreateTransaction().SetKey(receiverKey.PublicKey()).SetInitialBalance(NewHbar(2)).Execute(env.Client)
   252  	require.NoError(t, err)
   253  	receiverAccountReceipt, err := receiverCreate.SetValidateStatus(true).GetReceipt(env.Client)
   254  	require.NoError(t, err)
   255  	receiverAccountId := receiverAccountReceipt.AccountID
   256  
   257  	tokenID, err := createNft(&env)
   258  	require.NoError(t, err)
   259  
   260  	frozenTx, err := NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*spenderAccountId).FreezeWith(env.Client)
   261  	require.NoError(t, err)
   262  	_, err = frozenTx.Sign(spenderKey).Execute(env.Client)
   263  	require.NoError(t, err)
   264  
   265  	frozenTxn, err := NewTokenAssociateTransaction().SetTokenIDs(tokenID).SetAccountID(*receiverAccountId).FreezeWith(env.Client)
   266  	require.NoError(t, err)
   267  	_, err = frozenTxn.Sign(receiverKey).Execute(env.Client)
   268  
   269  	mint, err := NewTokenMintTransaction().SetTokenID(tokenID).SetMetadata([]byte{0x01}).SetMetadata([]byte{0x02}).Execute(env.Client)
   270  	require.NoError(t, err)
   271  	mintReceipt, err := mint.SetValidateStatus(true).GetReceipt(env.Client)
   272  	require.NoError(t, err)
   273  	serials := mintReceipt.SerialNumbers
   274  	nft1 := NftID{TokenID: tokenID, SerialNumber: serials[0]}
   275  	nft2 := NftID{TokenID: tokenID, SerialNumber: serials[1]}
   276  
   277  	approveTx, err := NewAccountAllowanceApproveTransaction().
   278  		ApproveTokenNftAllowanceAllSerials(tokenID, env.OperatorID, *spenderAccountId).Execute(env.Client)
   279  	require.NoError(t, err)
   280  	_, err = approveTx.SetValidateStatus(true).GetReceipt(env.Client)
   281  	require.NoError(t, err)
   282  
   283  	env.Client.SetOperator(*spenderAccountId, spenderKey)
   284  
   285  	approveDelegateTx, err := NewAccountAllowanceApproveTransaction().
   286  		ApproveTokenNftAllowanceWithDelegatingSpender(nft1, env.OperatorID, *delegateSpenderAccountId, *spenderAccountId).
   287  		Execute(env.Client)
   288  	require.NoError(t, err)
   289  	_, err = approveDelegateTx.SetValidateStatus(true).GetReceipt(env.Client)
   290  	require.NoError(t, err)
   291  
   292  	env.Client.SetOperator(env.OperatorID, env.OperatorKey)
   293  
   294  	onBehalfOfTransactionId := TransactionIDGenerate(*delegateSpenderAccountId)
   295  	frozenTransfer, err := NewTransferTransaction().AddApprovedNftTransfer(nft1, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTransactionId).FreezeWith(env.Client)
   296  	require.NoError(t, err)
   297  	resp, err := frozenTransfer.Sign(delegateSpenderKey).Execute(env.Client)
   298  	require.NoError(t, err)
   299  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
   300  	require.NoError(t, err)
   301  
   302  	onBehalfOfTransactionId2 := TransactionIDGenerate(*delegateSpenderAccountId)
   303  	frozenTransfer2, err := NewTransferTransaction().AddApprovedNftTransfer(nft2, env.OperatorID, *receiverAccountId, true).SetTransactionID(onBehalfOfTransactionId2).FreezeWith(env.Client)
   304  	require.NoError(t, err)
   305  	resp, err = frozenTransfer2.Sign(delegateSpenderKey).Execute(env.Client)
   306  	require.NoError(t, err)
   307  	_, err = resp.SetValidateStatus(true).GetReceipt(env.Client)
   308  	require.Error(t, err)
   309  	require.Equal(t, "exceptional receipt status: SPENDER_DOES_NOT_HAVE_ALLOWANCE", err.Error())
   310  
   311  	info, err := NewTokenNftInfoQuery().SetNftID(nft1).Execute(env.Client)
   312  	require.NoError(t, err)
   313  	require.Equal(t, *receiverAccountId, info[0].AccountID)
   314  	info2, err := NewTokenNftInfoQuery().SetNftID(nft2).Execute(env.Client)
   315  	require.NoError(t, err)
   316  	require.Equal(t, env.OperatorID, info2[0].AccountID)
   317  }