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

     1  package hedera
     2  
     3  /*-
     4   *
     5   * Hedera Go SDK
     6   *
     7   * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
     8   *
     9   * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at
    12   *
    13   *      http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   *
    21   */
    22  
    23  import (
    24  	"time"
    25  
    26  	"github.com/hashgraph/hedera-protobufs-go/services"
    27  )
    28  
    29  // TokenDissociateTransaction
    30  // Dissociates the provided account with the provided tokens. Must be signed by the provided Account's key.
    31  // If the provided account is not found, the transaction will resolve to INVALID_ACCOUNT_ID.
    32  // If the provided account has been deleted, the transaction will resolve to ACCOUNT_DELETED.
    33  // If any of the provided tokens is not found, the transaction will resolve to INVALID_TOKEN_REF.
    34  // If any of the provided tokens has been deleted, the transaction will resolve to TOKEN_WAS_DELETED.
    35  // If an association between the provided account and any of the tokens does not exist, the
    36  // transaction will resolve to TOKEN_NOT_ASSOCIATED_TO_ACCOUNT.
    37  // If a token has not been deleted and has not expired, and the user has a nonzero balance, the
    38  // transaction will resolve to TRANSACTION_REQUIRES_ZERO_TOKEN_BALANCES.
    39  // If a <b>fungible token</b> has expired, the user can disassociate even if their token balance is
    40  // not zero.
    41  // If a <b>non fungible token</b> has expired, the user can <b>not</b> disassociate if their token
    42  // balance is not zero. The transaction will resolve to TRANSACTION_REQUIRED_ZERO_TOKEN_BALANCES.
    43  // On success, associations between the provided account and tokens are removed.
    44  type TokenDissociateTransaction struct {
    45  	Transaction
    46  	accountID *AccountID
    47  	tokens    []TokenID
    48  }
    49  
    50  // NewTokenDissociateTransaction creates TokenDissociateTransaction which
    51  // dissociates the provided account with the provided tokens. Must be signed by the provided Account's key.
    52  // If the provided account is not found, the transaction will resolve to INVALID_ACCOUNT_ID.
    53  // If the provided account has been deleted, the transaction will resolve to ACCOUNT_DELETED.
    54  // If any of the provided tokens is not found, the transaction will resolve to INVALID_TOKEN_REF.
    55  // If any of the provided tokens has been deleted, the transaction will resolve to TOKEN_WAS_DELETED.
    56  // If an association between the provided account and any of the tokens does not exist, the
    57  // transaction will resolve to TOKEN_NOT_ASSOCIATED_TO_ACCOUNT.
    58  // If a token has not been deleted and has not expired, and the user has a nonzero balance, the
    59  // transaction will resolve to TRANSACTION_REQUIRES_ZERO_TOKEN_BALANCES.
    60  // If a <b>fungible token</b> has expired, the user can disassociate even if their token balance is
    61  // not zero.
    62  // If a <b>non fungible token</b> has expired, the user can <b>not</b> disassociate if their token
    63  // balance is not zero. The transaction will resolve to TRANSACTION_REQUIRED_ZERO_TOKEN_BALANCES.
    64  // On success, associations between the provided account and tokens are removed.
    65  func NewTokenDissociateTransaction() *TokenDissociateTransaction {
    66  	tx := TokenDissociateTransaction{
    67  		Transaction: _NewTransaction(),
    68  	}
    69  
    70  	tx._SetDefaultMaxTransactionFee(NewHbar(5))
    71  
    72  	return &tx
    73  }
    74  
    75  func _TokenDissociateTransactionFromProtobuf(tx Transaction, pb *services.TransactionBody) *TokenDissociateTransaction {
    76  	tokens := make([]TokenID, 0)
    77  	for _, token := range pb.GetTokenDissociate().Tokens {
    78  		if tokenID := _TokenIDFromProtobuf(token); tokenID != nil {
    79  			tokens = append(tokens, *tokenID)
    80  		}
    81  	}
    82  
    83  	return &TokenDissociateTransaction{
    84  		Transaction: tx,
    85  		accountID:   _AccountIDFromProtobuf(pb.GetTokenDissociate().GetAccount()),
    86  		tokens:      tokens,
    87  	}
    88  }
    89  
    90  // SetAccountID Sets the account to be dissociated with the provided tokens
    91  func (tx *TokenDissociateTransaction) SetAccountID(accountID AccountID) *TokenDissociateTransaction {
    92  	tx._RequireNotFrozen()
    93  	tx.accountID = &accountID
    94  	return tx
    95  }
    96  
    97  func (tx *TokenDissociateTransaction) GetAccountID() AccountID {
    98  	if tx.accountID == nil {
    99  		return AccountID{}
   100  	}
   101  
   102  	return *tx.accountID
   103  }
   104  
   105  // SetTokenIDs Sets the tokens to be dissociated with the provided account
   106  func (tx *TokenDissociateTransaction) SetTokenIDs(ids ...TokenID) *TokenDissociateTransaction {
   107  	tx._RequireNotFrozen()
   108  	tx.tokens = make([]TokenID, len(ids))
   109  	copy(tx.tokens, ids)
   110  
   111  	return tx
   112  }
   113  
   114  // AddTokenID Adds the token to the list of tokens to be dissociated.
   115  func (tx *TokenDissociateTransaction) AddTokenID(id TokenID) *TokenDissociateTransaction {
   116  	tx._RequireNotFrozen()
   117  	if tx.tokens == nil {
   118  		tx.tokens = make([]TokenID, 0)
   119  	}
   120  
   121  	tx.tokens = append(tx.tokens, id)
   122  
   123  	return tx
   124  }
   125  
   126  // GetTokenIDs returns the tokens to be associated with the provided account
   127  func (tx *TokenDissociateTransaction) GetTokenIDs() []TokenID {
   128  	tokenIDs := make([]TokenID, len(tx.tokens))
   129  	copy(tokenIDs, tx.tokens)
   130  
   131  	return tokenIDs
   132  }
   133  
   134  // ---- Required Interfaces ---- //
   135  
   136  // Sign uses the provided privateKey to sign the transaction.
   137  func (tx *TokenDissociateTransaction) Sign(privateKey PrivateKey) *TokenDissociateTransaction {
   138  	tx.Transaction.Sign(privateKey)
   139  	return tx
   140  }
   141  
   142  // SignWithOperator signs the transaction with client's operator privateKey.
   143  func (tx *TokenDissociateTransaction) SignWithOperator(client *Client) (*TokenDissociateTransaction, error) {
   144  	_, err := tx.Transaction.signWithOperator(client, tx)
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  	return tx, nil
   149  }
   150  
   151  // SignWith executes the TransactionSigner and adds the resulting signature data to the Transaction's signature map
   152  // with the publicKey as the map key.
   153  func (tx *TokenDissociateTransaction) SignWith(
   154  	publicKey PublicKey,
   155  	signer TransactionSigner,
   156  ) *TokenDissociateTransaction {
   157  	tx.Transaction.SignWith(publicKey, signer)
   158  	return tx
   159  }
   160  
   161  // AddSignature adds a signature to the transaction.
   162  func (tx *TokenDissociateTransaction) AddSignature(publicKey PublicKey, signature []byte) *TokenDissociateTransaction {
   163  	tx.Transaction.AddSignature(publicKey, signature)
   164  	return tx
   165  }
   166  
   167  // When execution is attempted, a single attempt will timeout when this deadline is reached. (The SDK may subsequently retry the execution.)
   168  func (tx *TokenDissociateTransaction) SetGrpcDeadline(deadline *time.Duration) *TokenDissociateTransaction {
   169  	tx.Transaction.SetGrpcDeadline(deadline)
   170  	return tx
   171  }
   172  
   173  func (tx *TokenDissociateTransaction) Freeze() (*TokenDissociateTransaction, error) {
   174  	return tx.FreezeWith(nil)
   175  }
   176  
   177  func (tx *TokenDissociateTransaction) FreezeWith(client *Client) (*TokenDissociateTransaction, error) {
   178  	_, err := tx.Transaction.freezeWith(client, tx)
   179  	return tx, err
   180  }
   181  
   182  // SetMaxTransactionFee sets the max transaction fee for this TokenDissociateTransaction.
   183  func (tx *TokenDissociateTransaction) SetMaxTransactionFee(fee Hbar) *TokenDissociateTransaction {
   184  	tx.Transaction.SetMaxTransactionFee(fee)
   185  	return tx
   186  }
   187  
   188  // SetRegenerateTransactionID sets if transaction IDs should be regenerated when `TRANSACTION_EXPIRED` is received
   189  func (tx *TokenDissociateTransaction) SetRegenerateTransactionID(regenerateTransactionID bool) *TokenDissociateTransaction {
   190  	tx.Transaction.SetRegenerateTransactionID(regenerateTransactionID)
   191  	return tx
   192  }
   193  
   194  // SetTransactionMemo sets the memo for this TokenDissociateTransaction.
   195  func (tx *TokenDissociateTransaction) SetTransactionMemo(memo string) *TokenDissociateTransaction {
   196  	tx.Transaction.SetTransactionMemo(memo)
   197  	return tx
   198  }
   199  
   200  // SetTransactionValidDuration sets the valid duration for this TokenDissociateTransaction.
   201  func (tx *TokenDissociateTransaction) SetTransactionValidDuration(duration time.Duration) *TokenDissociateTransaction {
   202  	tx.Transaction.SetTransactionValidDuration(duration)
   203  	return tx
   204  }
   205  
   206  // ToBytes serialise the tx to bytes, no matter if it is signed (locked), or not
   207  func (tx *TokenDissociateTransaction) ToBytes() ([]byte, error) {
   208  	bytes, err := tx.Transaction.toBytes(tx)
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  	return bytes, nil
   213  }
   214  
   215  // SetTransactionID sets the TransactionID for this TokenDissociateTransaction.
   216  func (tx *TokenDissociateTransaction) SetTransactionID(transactionID TransactionID) *TokenDissociateTransaction {
   217  	tx.Transaction.SetTransactionID(transactionID)
   218  	return tx
   219  }
   220  
   221  // SetNodeAccountIDs sets the _Node AccountID for this TokenDissociateTransaction.
   222  func (tx *TokenDissociateTransaction) SetNodeAccountIDs(nodeID []AccountID) *TokenDissociateTransaction {
   223  	tx.Transaction.SetNodeAccountIDs(nodeID)
   224  	return tx
   225  }
   226  
   227  // SetMaxRetry sets the max number of errors before execution will fail.
   228  func (tx *TokenDissociateTransaction) SetMaxRetry(count int) *TokenDissociateTransaction {
   229  	tx.Transaction.SetMaxRetry(count)
   230  	return tx
   231  }
   232  
   233  // SetMaxBackoff The maximum amount of time to wait between retries.
   234  // Every retry attempt will increase the wait time exponentially until it reaches this time.
   235  func (tx *TokenDissociateTransaction) SetMaxBackoff(max time.Duration) *TokenDissociateTransaction {
   236  	tx.Transaction.SetMaxBackoff(max)
   237  	return tx
   238  }
   239  
   240  // SetMinBackoff sets the minimum amount of time to wait between retries.
   241  func (tx *TokenDissociateTransaction) SetMinBackoff(min time.Duration) *TokenDissociateTransaction {
   242  	tx.Transaction.SetMinBackoff(min)
   243  	return tx
   244  }
   245  
   246  func (tx *TokenDissociateTransaction) SetLogLevel(level LogLevel) *TokenDissociateTransaction {
   247  	tx.Transaction.SetLogLevel(level)
   248  	return tx
   249  }
   250  
   251  func (tx *TokenDissociateTransaction) Execute(client *Client) (TransactionResponse, error) {
   252  	return tx.Transaction.execute(client, tx)
   253  }
   254  
   255  func (tx *TokenDissociateTransaction) Schedule() (*ScheduleCreateTransaction, error) {
   256  	return tx.Transaction.schedule(tx)
   257  }
   258  
   259  // ----------- Overridden functions ----------------
   260  
   261  func (tx *TokenDissociateTransaction) getName() string {
   262  	return "TokenDissociateTransaction"
   263  }
   264  
   265  func (tx *TokenDissociateTransaction) validateNetworkOnIDs(client *Client) error {
   266  	if client == nil || !client.autoValidateChecksums {
   267  		return nil
   268  	}
   269  
   270  	if tx.accountID != nil {
   271  		if err := tx.accountID.ValidateChecksum(client); err != nil {
   272  			return err
   273  		}
   274  	}
   275  
   276  	for _, tokenID := range tx.tokens {
   277  		if err := tokenID.ValidateChecksum(client); err != nil {
   278  			return err
   279  		}
   280  	}
   281  
   282  	return nil
   283  }
   284  
   285  func (tx *TokenDissociateTransaction) build() *services.TransactionBody {
   286  	return &services.TransactionBody{
   287  		TransactionFee:           tx.transactionFee,
   288  		Memo:                     tx.Transaction.memo,
   289  		TransactionValidDuration: _DurationToProtobuf(tx.GetTransactionValidDuration()),
   290  		TransactionID:            tx.transactionID._ToProtobuf(),
   291  		Data: &services.TransactionBody_TokenDissociate{
   292  			TokenDissociate: tx.buildProtoBody(),
   293  		},
   294  	}
   295  }
   296  
   297  func (tx *TokenDissociateTransaction) buildScheduled() (*services.SchedulableTransactionBody, error) {
   298  	return &services.SchedulableTransactionBody{
   299  		TransactionFee: tx.transactionFee,
   300  		Memo:           tx.Transaction.memo,
   301  		Data: &services.SchedulableTransactionBody_TokenDissociate{
   302  			TokenDissociate: tx.buildProtoBody(),
   303  		},
   304  	}, nil
   305  }
   306  
   307  func (tx *TokenDissociateTransaction) buildProtoBody() *services.TokenDissociateTransactionBody {
   308  	body := &services.TokenDissociateTransactionBody{}
   309  	if tx.accountID != nil {
   310  		body.Account = tx.accountID._ToProtobuf()
   311  	}
   312  
   313  	if len(tx.tokens) > 0 {
   314  		for _, tokenID := range tx.tokens {
   315  			if body.Tokens == nil {
   316  				body.Tokens = make([]*services.TokenID, 0)
   317  			}
   318  			body.Tokens = append(body.Tokens, tokenID._ToProtobuf())
   319  		}
   320  	}
   321  
   322  	return body
   323  }
   324  
   325  func (tx *TokenDissociateTransaction) getMethod(channel *_Channel) _Method {
   326  	return _Method{
   327  		transaction: channel._GetToken().DissociateTokens,
   328  	}
   329  }
   330  
   331  func (tx *TokenDissociateTransaction) _ConstructScheduleProtobuf() (*services.SchedulableTransactionBody, error) {
   332  	return tx.buildScheduled()
   333  }