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 }