github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/token_associate_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 // TokenAssociateTransaction Associates the provided account with the provided tokens. Must be signed by the provided Account's key. 30 // If the provided account is not found, the transaction will resolve to 31 // INVALID_ACCOUNT_ID. 32 // If the provided account has been deleted, the transaction will resolve to 33 // ACCOUNT_DELETED. 34 // If any of the provided tokens is not found, the transaction will resolve to 35 // INVALID_TOKEN_REF. 36 // If any of the provided tokens has been deleted, the transaction will resolve to 37 // TOKEN_WAS_DELETED. 38 // If an association between the provided account and any of the tokens already exists, the 39 // transaction will resolve to 40 // TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT. 41 // If the provided account's associations count exceed the constraint of maximum token 42 // associations per account, the transaction will resolve to 43 // TOKENS_PER_ACCOUNT_LIMIT_EXCEEDED. 44 // On success, associations between the provided account and tokens are made and the account is 45 // ready to interact with the tokens. 46 type TokenAssociateTransaction struct { 47 Transaction 48 accountID *AccountID 49 tokens []TokenID 50 } 51 52 // NewTokenAssociateTransaction creates TokenAssociateTransaction which associates the provided account with the provided tokens. 53 // Must be signed by the provided Account's key. 54 // If the provided account is not found, the transaction will resolve to 55 // INVALID_ACCOUNT_ID. 56 // If the provided account has been deleted, the transaction will resolve to 57 // ACCOUNT_DELETED. 58 // If any of the provided tokens is not found, the transaction will resolve to 59 // INVALID_TOKEN_REF. 60 // If any of the provided tokens has been deleted, the transaction will resolve to 61 // TOKEN_WAS_DELETED. 62 // If an association between the provided account and any of the tokens already exists, the 63 // transaction will resolve to 64 // TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT. 65 // If the provided account's associations count exceed the constraint of maximum token 66 // associations per account, the transaction will resolve to 67 // TOKENS_PER_ACCOUNT_LIMIT_EXCEEDED. 68 // On success, associations between the provided account and tokens are made and the account is 69 // ready to interact with the tokens. 70 func NewTokenAssociateTransaction() *TokenAssociateTransaction { 71 tx := TokenAssociateTransaction{ 72 Transaction: _NewTransaction(), 73 } 74 75 tx._SetDefaultMaxTransactionFee(NewHbar(5)) 76 77 return &tx 78 } 79 80 func _TokenAssociateTransactionFromProtobuf(tx Transaction, pb *services.TransactionBody) *TokenAssociateTransaction { 81 tokens := make([]TokenID, 0) 82 for _, token := range pb.GetTokenAssociate().Tokens { 83 if tokenID := _TokenIDFromProtobuf(token); tokenID != nil { 84 tokens = append(tokens, *tokenID) 85 } 86 } 87 88 return &TokenAssociateTransaction{ 89 Transaction: tx, 90 accountID: _AccountIDFromProtobuf(pb.GetTokenAssociate().GetAccount()), 91 tokens: tokens, 92 } 93 } 94 95 // SetAccountID Sets the account to be associated with the provided tokens 96 func (tx *TokenAssociateTransaction) SetAccountID(accountID AccountID) *TokenAssociateTransaction { 97 tx._RequireNotFrozen() 98 tx.accountID = &accountID 99 return tx 100 } 101 102 // GetAccountID returns the account to be associated with the provided tokens 103 func (tx *TokenAssociateTransaction) GetAccountID() AccountID { 104 if tx.accountID == nil { 105 return AccountID{} 106 } 107 108 return *tx.accountID 109 } 110 111 // SetTokenIDs Sets the tokens to be associated with the provided account 112 func (tx *TokenAssociateTransaction) SetTokenIDs(ids ...TokenID) *TokenAssociateTransaction { 113 tx._RequireNotFrozen() 114 tx.tokens = make([]TokenID, len(ids)) 115 copy(tx.tokens, ids) 116 117 return tx 118 } 119 120 // AddTokenID Adds the token to a token list to be associated with the provided account 121 func (tx *TokenAssociateTransaction) AddTokenID(id TokenID) *TokenAssociateTransaction { 122 tx._RequireNotFrozen() 123 if tx.tokens == nil { 124 tx.tokens = make([]TokenID, 0) 125 } 126 127 tx.tokens = append(tx.tokens, id) 128 129 return tx 130 } 131 132 // GetTokenIDs returns the tokens to be associated with the provided account 133 func (tx *TokenAssociateTransaction) GetTokenIDs() []TokenID { 134 tokenIDs := make([]TokenID, len(tx.tokens)) 135 copy(tokenIDs, tx.tokens) 136 137 return tokenIDs 138 } 139 140 // ---- Required Interfaces ---- // 141 142 // Sign uses the provided privateKey to sign the transaction. 143 func (tx *TokenAssociateTransaction) Sign(privateKey PrivateKey) *TokenAssociateTransaction { 144 tx.Transaction.Sign(privateKey) 145 return tx 146 } 147 148 // SignWithOperator signs the transaction with client's operator privateKey. 149 func (tx *TokenAssociateTransaction) SignWithOperator(client *Client) (*TokenAssociateTransaction, error) { 150 _, err := tx.Transaction.signWithOperator(client, tx) 151 if err != nil { 152 return nil, err 153 } 154 return tx, nil 155 } 156 157 // SignWith executes the TransactionSigner and adds the resulting signature data to the Transaction's signature map 158 // with the publicKey as the map key. 159 func (tx *TokenAssociateTransaction) SignWith( 160 publicKey PublicKey, 161 signer TransactionSigner, 162 ) *TokenAssociateTransaction { 163 tx.Transaction.SignWith(publicKey, signer) 164 return tx 165 } 166 167 // AddSignature adds a signature to the transaction. 168 func (tx *TokenAssociateTransaction) AddSignature(publicKey PublicKey, signature []byte) *TokenAssociateTransaction { 169 tx.Transaction.AddSignature(publicKey, signature) 170 return tx 171 } 172 173 // When execution is attempted, a single attempt will timeout when this deadline is reached. (The SDK may subsequently retry the execution.) 174 func (tx *TokenAssociateTransaction) SetGrpcDeadline(deadline *time.Duration) *TokenAssociateTransaction { 175 tx.Transaction.SetGrpcDeadline(deadline) 176 return tx 177 } 178 179 func (tx *TokenAssociateTransaction) Freeze() (*TokenAssociateTransaction, error) { 180 return tx.FreezeWith(nil) 181 } 182 183 func (tx *TokenAssociateTransaction) FreezeWith(client *Client) (*TokenAssociateTransaction, error) { 184 _, err := tx.Transaction.freezeWith(client, tx) 185 return tx, err 186 } 187 188 // SetMaxTransactionFee sets the max transaction fee for this TokenAssociateTransaction. 189 func (tx *TokenAssociateTransaction) SetMaxTransactionFee(fee Hbar) *TokenAssociateTransaction { 190 tx.Transaction.SetMaxTransactionFee(fee) 191 return tx 192 } 193 194 // SetRegenerateTransactionID sets if transaction IDs should be regenerated when `TRANSACTION_EXPIRED` is received 195 func (tx *TokenAssociateTransaction) SetRegenerateTransactionID(regenerateTransactionID bool) *TokenAssociateTransaction { 196 tx.Transaction.SetRegenerateTransactionID(regenerateTransactionID) 197 return tx 198 } 199 200 // SetTransactionMemo sets the memo for this TokenAssociateTransaction. 201 func (tx *TokenAssociateTransaction) SetTransactionMemo(memo string) *TokenAssociateTransaction { 202 tx.Transaction.SetTransactionMemo(memo) 203 return tx 204 } 205 206 // SetTransactionValidDuration sets the valid duration for this TokenAssociateTransaction. 207 func (tx *TokenAssociateTransaction) SetTransactionValidDuration(duration time.Duration) *TokenAssociateTransaction { 208 tx.Transaction.SetTransactionValidDuration(duration) 209 return tx 210 } 211 212 // ToBytes serialise the tx to bytes, no matter if it is signed (locked), or not 213 func (tx *TokenAssociateTransaction) ToBytes() ([]byte, error) { 214 bytes, err := tx.Transaction.toBytes(tx) 215 if err != nil { 216 return nil, err 217 } 218 return bytes, nil 219 } 220 221 // SetTransactionID sets the TransactionID for this TokenAssociateTransaction. 222 func (tx *TokenAssociateTransaction) SetTransactionID(transactionID TransactionID) *TokenAssociateTransaction { 223 tx.Transaction.SetTransactionID(transactionID) 224 return tx 225 } 226 227 // SetNodeAccountIDs sets the _Node AccountID for this TokenAssociateTransaction. 228 func (tx *TokenAssociateTransaction) SetNodeAccountIDs(nodeID []AccountID) *TokenAssociateTransaction { 229 tx.Transaction.SetNodeAccountIDs(nodeID) 230 return tx 231 } 232 233 // SetMaxRetry sets the max number of errors before execution will fail. 234 func (tx *TokenAssociateTransaction) SetMaxRetry(count int) *TokenAssociateTransaction { 235 tx.Transaction.SetMaxRetry(count) 236 return tx 237 } 238 239 // SetMaxBackoff The maximum amount of time to wait between retries. 240 // Every retry attempt will increase the wait time exponentially until it reaches this time. 241 func (tx *TokenAssociateTransaction) SetMaxBackoff(max time.Duration) *TokenAssociateTransaction { 242 tx.Transaction.SetMaxBackoff(max) 243 return tx 244 } 245 246 // SetMinBackoff sets the minimum amount of time to wait between retries. 247 func (tx *TokenAssociateTransaction) SetMinBackoff(min time.Duration) *TokenAssociateTransaction { 248 tx.Transaction.SetMinBackoff(min) 249 return tx 250 } 251 252 func (tx *TokenAssociateTransaction) SetLogLevel(level LogLevel) *TokenAssociateTransaction { 253 tx.Transaction.SetLogLevel(level) 254 return tx 255 } 256 257 func (tx *TokenAssociateTransaction) Execute(client *Client) (TransactionResponse, error) { 258 return tx.Transaction.execute(client, tx) 259 } 260 261 func (tx *TokenAssociateTransaction) Schedule() (*ScheduleCreateTransaction, error) { 262 return tx.Transaction.schedule(tx) 263 } 264 265 // ----------- Overridden functions ---------------- 266 267 func (tx *TokenAssociateTransaction) getName() string { 268 return "TokenAssociateTransaction" 269 } 270 271 func (tx *TokenAssociateTransaction) validateNetworkOnIDs(client *Client) error { 272 if client == nil || !client.autoValidateChecksums { 273 return nil 274 } 275 276 if tx.accountID != nil { 277 if err := tx.accountID.ValidateChecksum(client); err != nil { 278 return err 279 } 280 } 281 282 for _, tokenID := range tx.tokens { 283 if err := tokenID.ValidateChecksum(client); err != nil { 284 return err 285 } 286 } 287 288 return nil 289 } 290 291 func (tx *TokenAssociateTransaction) build() *services.TransactionBody { 292 body := tx.buildProtoBody() 293 294 return &services.TransactionBody{ 295 TransactionFee: tx.transactionFee, 296 Memo: tx.Transaction.memo, 297 TransactionValidDuration: _DurationToProtobuf(tx.GetTransactionValidDuration()), 298 TransactionID: tx.transactionID._ToProtobuf(), 299 Data: &services.TransactionBody_TokenAssociate{ 300 TokenAssociate: body, 301 }, 302 } 303 } 304 305 func (tx *TokenAssociateTransaction) buildScheduled() (*services.SchedulableTransactionBody, error) { 306 return &services.SchedulableTransactionBody{ 307 TransactionFee: tx.transactionFee, 308 Memo: tx.Transaction.memo, 309 Data: &services.SchedulableTransactionBody_TokenAssociate{ 310 TokenAssociate: tx.buildProtoBody(), 311 }, 312 }, nil 313 } 314 315 func (tx *TokenAssociateTransaction) buildProtoBody() *services.TokenAssociateTransactionBody { 316 body := &services.TokenAssociateTransactionBody{} 317 if tx.accountID != nil { 318 body.Account = tx.accountID._ToProtobuf() 319 } 320 321 if len(tx.tokens) > 0 { 322 for _, tokenID := range tx.tokens { 323 if body.Tokens == nil { 324 body.Tokens = make([]*services.TokenID, 0) 325 } 326 body.Tokens = append(body.Tokens, tokenID._ToProtobuf()) 327 } 328 } 329 return body 330 } 331 332 func (tx *TokenAssociateTransaction) getMethod(channel *_Channel) _Method { 333 return _Method{ 334 transaction: channel._GetToken().AssociateTokens, 335 } 336 } 337 func (tx *TokenAssociateTransaction) _ConstructScheduleProtobuf() (*services.SchedulableTransactionBody, error) { 338 return tx.buildScheduled() 339 }