Skip to main content

hiero_sdk/token/
token_update_transaction.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use hiero_sdk_proto::services;
4use hiero_sdk_proto::services::token_service_client::TokenServiceClient;
5use time::{
6    Duration,
7    OffsetDateTime,
8};
9use tonic::transport::Channel;
10
11use crate::ledger_id::RefLedgerId;
12use crate::protobuf::{
13    FromProtobuf,
14    ToProtobuf,
15};
16use crate::token::token_key_validation_type::TokenKeyValidation;
17use crate::transaction::{
18    AnyTransactionData,
19    ChunkInfo,
20    ToSchedulableTransactionDataProtobuf,
21    ToTransactionDataProtobuf,
22    TransactionData,
23    TransactionExecute,
24};
25use crate::{
26    AccountId,
27    BoxGrpcFuture,
28    Error,
29    Key,
30    TokenId,
31    Transaction,
32    ValidateChecksums,
33};
34
35/// At consensus, updates an already created token to the given values.
36///
37/// If no value is given for a field, that field is left unchanged. For an immutable token (that is,
38/// a token without an admin key), only the expiry may be updated. Setting any other field in that
39/// case will cause the transaction status to resolve to `TokenIsImmutable`.
40///
41/// ### --- Signing Requirements ---
42/// 1. Whether or not a token has an admin key, its expiry can be extended with only the transaction
43///    payer's signature.
44/// 2. Updating any other field of a mutable token requires the admin key's signature.
45/// 3. If a new admin key is set, this new key must sign **unless** it is exactly an empty
46///    `KeyList`. This special sentinel key removes the existing admin key and causes the
47///    token to become immutable. (Other [`Key`][Key] structures without a constituent
48///    `Ed25519` key will be rejected with `InvalidAdminKey`.
49/// 4. If a new treasury is set, the new treasury account's key must sign the transaction.
50///
51/// ### --- Nft Requirements ---
52/// 1. If a non fungible token has a positive treasury balance, the operation will abort with
53///    `CurrentTreasuryStillOwnsNfts`.
54pub type TokenUpdateTransaction = Transaction<TokenUpdateTransactionData>;
55
56#[derive(Debug, Clone, Default)]
57pub struct TokenUpdateTransactionData {
58    /// The token to be updated.
59    token_id: Option<TokenId>,
60
61    /// The publicly visible name of the token.
62    token_name: String,
63
64    /// The publicly visible token symbol.
65    token_symbol: String,
66
67    /// The account which will act as a treasury for the token.
68    treasury_account_id: Option<AccountId>,
69
70    /// The key which can perform update/delete operations on the token.
71    admin_key: Option<Key>,
72
73    /// The key which can grant or revoke KYC of an account for the token's transactions.
74    kyc_key: Option<Key>,
75
76    /// The key which can sign to freeze or unfreeze an account for token transactions.
77    freeze_key: Option<Key>,
78
79    /// The key which can wipe the token balance of an account.
80    wipe_key: Option<Key>,
81
82    /// The key which can change the supply of a token.
83    supply_key: Option<Key>,
84
85    /// An account which will be automatically charged to renew the token's expiration, at
86    /// autoRenewPeriod interval
87    auto_renew_account_id: Option<AccountId>,
88
89    /// The interval at which the auto-renew account will be charged to extend the token's expiry
90    auto_renew_period: Option<Duration>,
91
92    /// Sets the time at which the token should expire.
93    expiration_time: Option<OffsetDateTime>,
94
95    /// The memo associated with the token (UTF-8 encoding max 100 bytes)
96    token_memo: Option<String>,
97
98    /// The key which can change the token's custom fee schedule; must sign a TokenFeeScheduleUpdate
99    /// transaction
100    fee_schedule_key: Option<Key>,
101
102    /// The Key which can pause and unpause the Token.
103    /// If Empty the token pause status defaults to PauseNotApplicable, otherwise Unpaused.
104    pause_key: Option<Key>,
105
106    /// Metadata of the created token definition.
107    metadata: Option<Vec<u8>>,
108
109    /// The key which can change the metadata of a token
110    /// (token definition, partition definition, and individual NFTs).
111    metadata_key: Option<Key>,
112
113    /// Determines whether the system should check the validity of the passed keys for update.
114    key_verification_mode: TokenKeyValidation,
115}
116
117impl TokenUpdateTransaction {
118    /// Returns the token to be updated.
119    #[must_use]
120    pub fn get_token_id(&self) -> Option<TokenId> {
121        self.data().token_id
122    }
123
124    /// Sets the token to be updated.
125    pub fn token_id(&mut self, token_id: impl Into<TokenId>) -> &mut Self {
126        self.data_mut().token_id = Some(token_id.into());
127        self
128    }
129
130    /// Returns the new publicly visible name of the token.
131    #[must_use]
132    pub fn get_token_name(&self) -> &str {
133        &self.data().token_name
134    }
135
136    /// Sets the new publicly visible name of the token.
137    ///
138    /// Maximum 100 characters.
139    pub fn token_name(&mut self, token_name: impl Into<String>) -> &mut Self {
140        self.data_mut().token_name = token_name.into();
141        self
142    }
143
144    ///Returns the new publicly visible token symbol.
145    #[must_use]
146    pub fn get_token_symbol(&self) -> &str {
147        &self.data().token_symbol
148    }
149
150    /// Sets the new publicly visible token symbol.
151    ///
152    /// Maximum 100 characters.
153    pub fn token_symbol(&mut self, token_symbol: impl Into<String>) -> &mut Self {
154        self.data_mut().token_symbol = token_symbol.into();
155        self
156    }
157
158    /// Returns the new account which will act as a treasury for the token.
159    #[must_use]
160    pub fn get_treasury_account_id(&self) -> Option<AccountId> {
161        self.data().treasury_account_id
162    }
163
164    /// Sets the new account which will act as a treasury for the token.
165    ///
166    /// If the provided `treasury_account_id` does not exist or has been deleted, the response
167    /// will be `InvalidTreasuryAccountForToken`.
168    ///
169    /// If successful, the token balance held in the previous treasury account is transferred to the
170    /// new one.
171    pub fn treasury_account_id(&mut self, treasury_account_id: AccountId) -> &mut Self {
172        self.data_mut().treasury_account_id = Some(treasury_account_id);
173        self
174    }
175
176    /// Returns the new key which can perform update/delete operations on the token.
177    #[must_use]
178    pub fn get_admin_key(&self) -> Option<&Key> {
179        self.data().admin_key.as_ref()
180    }
181
182    /// Sets the new key which can perform update/delete operations on the token.
183    ///
184    /// If the token is immutable, transaction will resolve to `TokenIsImmutable`.
185    pub fn admin_key(&mut self, admin_key: impl Into<Key>) -> &mut Self {
186        self.data_mut().admin_key = Some(admin_key.into());
187        self
188    }
189
190    /// Returns the new key which can grant or revoke KYC of an account for the token's transactions.
191    #[must_use]
192    pub fn get_kyc_key(&self) -> Option<&Key> {
193        self.data().kyc_key.as_ref()
194    }
195
196    /// Sets the new key which can grant or revoke KYC of an account for the token's transactions.
197    ///
198    /// If the token does not currently have a KYC key, transaction will resolve to `TokenHasNoKycKey`.
199    pub fn kyc_key(&mut self, kyc_key: impl Into<Key>) -> &mut Self {
200        self.data_mut().kyc_key = Some(kyc_key.into());
201        self
202    }
203
204    /// Returns the new key which can sign to freeze or unfreeze an account for token transactions.
205    #[must_use]
206    pub fn get_freeze_key(&self) -> Option<&Key> {
207        self.data().freeze_key.as_ref()
208    }
209
210    /// Sets the new key which can sign to freeze or unfreeze an account for token transactions.
211    ///
212    /// If the token does not currently have a Freeze key, transaction will resolve to `TokenHasNoFreezeKey`.
213    pub fn freeze_key(&mut self, freeze_key: impl Into<Key>) -> &mut Self {
214        self.data_mut().freeze_key = Some(freeze_key.into());
215        self
216    }
217
218    /// Returns the new key which can wipe the token balance of an account.
219    #[must_use]
220    pub fn get_wipe_key(&self) -> Option<&Key> {
221        self.data().wipe_key.as_ref()
222    }
223
224    /// Sets the new key which can wipe the token balance of an account.
225    ///
226    /// If the token does not currently have a Wipe key, transaction will resolve to `TokenHasNoWipeKey`.
227    pub fn wipe_key(&mut self, wipe_key: impl Into<Key>) -> &mut Self {
228        self.data_mut().wipe_key = Some(wipe_key.into());
229        self
230    }
231
232    /// Returns the new key which can change the supply of a token.
233    #[must_use]
234    pub fn get_supply_key(&self) -> Option<&Key> {
235        self.data().supply_key.as_ref()
236    }
237
238    /// Sets the new key which can change the supply of a token.
239    ///
240    /// If the token does not currently have a Supply key, transaction will resolve to `TokenHasNoSupplyKey`.
241    pub fn supply_key(&mut self, supply_key: impl Into<Key>) -> &mut Self {
242        self.data_mut().supply_key = Some(supply_key.into());
243        self
244    }
245
246    /// Returns the new account which will be automatically charged to renew the token's expiration.
247    #[must_use]
248    pub fn get_auto_renew_account_id(&self) -> Option<AccountId> {
249        self.data().auto_renew_account_id
250    }
251
252    /// Sets the new account which will be automatically charged to renew the token's expiration.
253    pub fn auto_renew_account_id(&mut self, auto_renew_account_id: AccountId) -> &mut Self {
254        self.data_mut().auto_renew_account_id = Some(auto_renew_account_id);
255        self
256    }
257
258    /// Returns the new interval at which the auto renew account will be charged to extend the token's expiry.
259    #[must_use]
260    pub fn get_auto_renew_period(&self) -> Option<Duration> {
261        self.data().auto_renew_period
262    }
263
264    /// Sets the new interval at which the auto renew account will be charged to extend
265    /// the token's expiry.
266    pub fn auto_renew_period(&mut self, auto_renew_period: Duration) -> &mut Self {
267        self.data_mut().auto_renew_period = Some(auto_renew_period);
268        self
269    }
270
271    /// Returns the new time at which the token should expire.
272    #[must_use]
273    pub fn get_expiration_time(&self) -> Option<OffsetDateTime> {
274        self.data().expiration_time
275    }
276
277    /// Sets the new time at which the token should expire.
278    ///
279    /// If the new expiration time is earlier than the current expiration time, transaction
280    /// will resolve to `InvalidExpirationTime`.
281    pub fn expiration_time(&mut self, expiration_time: OffsetDateTime) -> &mut Self {
282        let data = self.data_mut();
283        data.expiration_time = Some(expiration_time);
284        data.auto_renew_period = None;
285
286        self
287    }
288
289    /// Returns the new memo associated with the token.
290    #[must_use]
291    pub fn get_token_memo(&self) -> Option<&str> {
292        self.data().token_memo.as_deref()
293    }
294
295    /// Sets the new memo associated with the token.
296    ///
297    /// Maximum of 100 bytes.
298    pub fn token_memo(&mut self, memo: Option<impl Into<String>>) -> &mut Self {
299        self.data_mut().token_memo = memo.map(|m| m.into());
300        self
301    }
302
303    /// Returns the new key which can change the token's custom fee schedule.
304    #[must_use]
305    pub fn get_fee_schedule_key(&self) -> Option<&Key> {
306        self.data().fee_schedule_key.as_ref()
307    }
308
309    /// Sets the new key which can change the token's custom fee schedule.
310    ///
311    /// If the token does not currently have a fee schedule key, transaction will resolve to
312    /// `TokenHasNoFeeScheduleKey`.
313    pub fn fee_schedule_key(&mut self, fee_schedule_key: impl Into<Key>) -> &mut Self {
314        self.data_mut().fee_schedule_key = Some(fee_schedule_key.into());
315        self
316    }
317
318    /// Returns the new key which can pause and unpause the token.
319    #[must_use]
320    pub fn get_pause_key(&self) -> Option<&Key> {
321        self.data().pause_key.as_ref()
322    }
323
324    /// Sets the new key which can pause and unpause the Token.
325    ///
326    /// If the token does not currently have a pause key, transaction will resolve to `TokenHasNoPauseKey`.
327    pub fn pause_key(&mut self, pause_key: impl Into<Key>) -> &mut Self {
328        self.data_mut().pause_key = Some(pause_key.into());
329        self
330    }
331
332    /// Returns the new metadata of the created token definition.
333    #[must_use]
334    pub fn get_metadata(&self) -> Option<Vec<u8>> {
335        self.data().metadata.clone()
336    }
337
338    /// Sets the new metadata of the token definition.
339    pub fn metadata(&mut self, metadata: Vec<u8>) -> &mut Self {
340        self.data_mut().metadata = Some(metadata);
341        self
342    }
343
344    /// Returns the new key which can change the metadata of a token.
345    #[must_use]
346    pub fn get_metadata_key(&self) -> Option<&Key> {
347        self.data().metadata_key.as_ref()
348    }
349
350    /// Sets the new key which can change the metadata of a token.
351    pub fn metadata_key(&mut self, metadata_key: impl Into<Key>) -> &mut Self {
352        self.data_mut().metadata_key = Some(metadata_key.into());
353        self
354    }
355
356    /// Returns key verification mode.
357    #[must_use]
358    pub fn get_key_verification_mode(&self) -> TokenKeyValidation {
359        self.data().key_verification_mode
360    }
361
362    /// Assignss key verification mode.
363    pub fn key_verification_mode(
364        &mut self,
365        key_verification_mode: TokenKeyValidation,
366    ) -> &mut Self {
367        self.data_mut().key_verification_mode = key_verification_mode;
368        self
369    }
370}
371
372impl TransactionData for TokenUpdateTransactionData {}
373
374impl TransactionExecute for TokenUpdateTransactionData {
375    fn execute(
376        &self,
377        channel: Channel,
378        request: services::Transaction,
379    ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
380        Box::pin(async { TokenServiceClient::new(channel).update_token(request).await })
381    }
382}
383
384impl ValidateChecksums for TokenUpdateTransactionData {
385    fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
386        self.token_id.validate_checksums(ledger_id)?;
387        self.auto_renew_account_id.validate_checksums(ledger_id)?;
388        self.treasury_account_id.validate_checksums(ledger_id)
389    }
390}
391
392impl ToTransactionDataProtobuf for TokenUpdateTransactionData {
393    fn to_transaction_data_protobuf(
394        &self,
395        chunk_info: &ChunkInfo,
396    ) -> services::transaction_body::Data {
397        let _ = chunk_info.assert_single_transaction();
398
399        services::transaction_body::Data::TokenUpdate(self.to_protobuf())
400    }
401}
402
403impl ToSchedulableTransactionDataProtobuf for TokenUpdateTransactionData {
404    fn to_schedulable_transaction_data_protobuf(
405        &self,
406    ) -> services::schedulable_transaction_body::Data {
407        services::schedulable_transaction_body::Data::TokenUpdate(self.to_protobuf())
408    }
409}
410
411impl From<TokenUpdateTransactionData> for AnyTransactionData {
412    fn from(transaction: TokenUpdateTransactionData) -> Self {
413        Self::TokenUpdate(transaction)
414    }
415}
416
417impl FromProtobuf<services::TokenUpdateTransactionBody> for TokenUpdateTransactionData {
418    fn from_protobuf(pb: services::TokenUpdateTransactionBody) -> crate::Result<Self> {
419        let key_verification_mode =
420            services::TokenKeyValidation::try_from(pb.key_verification_mode as i32)
421                .unwrap_or_default();
422
423        Ok(Self {
424            token_id: Option::from_protobuf(pb.token)?,
425            token_name: pb.name,
426            token_symbol: pb.symbol,
427            treasury_account_id: Option::from_protobuf(pb.treasury)?,
428            admin_key: Option::from_protobuf(pb.admin_key)?,
429            kyc_key: Option::from_protobuf(pb.kyc_key)?,
430            freeze_key: Option::from_protobuf(pb.freeze_key)?,
431            wipe_key: Option::from_protobuf(pb.wipe_key)?,
432            supply_key: Option::from_protobuf(pb.supply_key)?,
433            auto_renew_account_id: Option::from_protobuf(pb.auto_renew_account)?,
434            auto_renew_period: pb.auto_renew_period.map(Into::into),
435            expiration_time: pb.expiry.map(Into::into),
436            token_memo: pb.memo,
437            fee_schedule_key: Option::from_protobuf(pb.fee_schedule_key)?,
438            pause_key: Option::from_protobuf(pb.pause_key)?,
439            metadata: pb.metadata,
440            metadata_key: Option::from_protobuf(pb.metadata_key)?,
441            key_verification_mode: TokenKeyValidation::from_protobuf(key_verification_mode)?,
442        })
443    }
444}
445
446impl ToProtobuf for TokenUpdateTransactionData {
447    type Protobuf = services::TokenUpdateTransactionBody;
448
449    fn to_protobuf(&self) -> Self::Protobuf {
450        services::TokenUpdateTransactionBody {
451            token: self.token_id.to_protobuf(),
452            name: self.token_name.clone(),
453            symbol: self.token_symbol.clone(),
454            treasury: self.treasury_account_id.to_protobuf(),
455            admin_key: self.admin_key.to_protobuf(),
456            kyc_key: self.kyc_key.to_protobuf(),
457            freeze_key: self.freeze_key.to_protobuf(),
458            wipe_key: self.wipe_key.to_protobuf(),
459            supply_key: self.supply_key.to_protobuf(),
460            expiry: self.expiration_time.map(Into::into),
461            auto_renew_account: self.auto_renew_account_id.to_protobuf(),
462            auto_renew_period: self.auto_renew_period.map(Into::into),
463            memo: self.token_memo.clone(),
464            fee_schedule_key: self.fee_schedule_key.to_protobuf(),
465            pause_key: self.pause_key.to_protobuf(),
466            metadata: self.metadata.clone(),
467            metadata_key: self.metadata_key.to_protobuf(),
468            key_verification_mode: self.key_verification_mode.to_protobuf().into(),
469        }
470    }
471}
472
473#[cfg(test)]
474mod tests {
475    use std::str::FromStr;
476
477    use expect_test::expect_file;
478    use hiero_sdk_proto::services;
479    use time::{
480        Duration,
481        OffsetDateTime,
482    };
483
484    use super::TokenUpdateTransactionData;
485    use crate::protobuf::{
486        FromProtobuf,
487        ToProtobuf,
488    };
489    use crate::token::token_key_validation_type::TokenKeyValidation;
490    use crate::transaction::test_helpers::{
491        check_body,
492        transaction_body,
493        VALID_START,
494    };
495    use crate::{
496        AccountId,
497        AnyTransaction,
498        PrivateKey,
499        PublicKey,
500        TokenId,
501        TokenUpdateTransaction,
502    };
503
504    fn test_admin_key() -> PublicKey {
505        PrivateKey::from_str(
506            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e11").unwrap().public_key()
507    }
508
509    fn test_kyc_key() -> PublicKey {
510        PrivateKey::from_str(
511            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e12").unwrap().public_key()
512    }
513
514    fn test_freeze_key() -> PublicKey {
515        PrivateKey::from_str(
516            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e13").unwrap().public_key()
517    }
518
519    fn test_wipe_key() -> PublicKey {
520        PrivateKey::from_str(
521            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e14").unwrap().public_key()
522    }
523
524    fn test_supply_key() -> PublicKey {
525        PrivateKey::from_str(
526            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e15").unwrap().public_key()
527    }
528
529    fn test_fee_schedule_key() -> PublicKey {
530        PrivateKey::from_str(
531            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e16").unwrap().public_key()
532    }
533
534    fn test_pause_key() -> PublicKey {
535        PrivateKey::from_str(
536            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e17").unwrap().public_key()
537    }
538
539    fn test_metadata_key() -> PublicKey {
540        PrivateKey::from_str(
541            "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e18").unwrap().public_key()
542    }
543
544    const TEST_TREASURY_ACCOUNT_ID: AccountId = AccountId::new(7, 7, 7);
545    const TEST_AUTO_RENEW_ACCOUNT_ID: AccountId = AccountId::new(8, 8, 8);
546    const TEST_TOKEN_NAME: &str = "test name";
547    const TEST_TOKEN_SYMBOL: &str = "test symbol";
548    const TEST_TOKEN_MEMO: &str = "test memo";
549    const TEST_TOKEN_ID: TokenId = TokenId::new(4, 2, 0);
550    const TEST_AUTO_RENEW_PERIOD: Duration = Duration::hours(10);
551    const TEST_EXPIRATION_TIME: OffsetDateTime = VALID_START;
552    const TEST_METADATA: &str = "Token Metadata";
553    const TEST_KEY_VERIFICATION_MODE: TokenKeyValidation = TokenKeyValidation::FullValidation;
554
555    fn make_transaction() -> TokenUpdateTransaction {
556        let mut tx = TokenUpdateTransaction::new_for_tests();
557
558        tx.token_id(TEST_TOKEN_ID)
559            .fee_schedule_key(test_fee_schedule_key())
560            .supply_key(test_supply_key())
561            .admin_key(test_admin_key())
562            .auto_renew_account_id(TEST_AUTO_RENEW_ACCOUNT_ID)
563            .auto_renew_period(TEST_AUTO_RENEW_PERIOD)
564            .freeze_key(test_freeze_key())
565            .wipe_key(test_wipe_key())
566            .token_symbol(TEST_TOKEN_SYMBOL)
567            .kyc_key(test_kyc_key())
568            .pause_key(test_pause_key())
569            .expiration_time(TEST_EXPIRATION_TIME)
570            .treasury_account_id(TEST_TREASURY_ACCOUNT_ID)
571            .token_name(TEST_TOKEN_NAME)
572            .token_memo(Some(TEST_TOKEN_MEMO))
573            .metadata(TEST_METADATA.as_bytes().to_vec())
574            .metadata_key(test_metadata_key())
575            .key_verification_mode(TokenKeyValidation::NoValidation)
576            .freeze()
577            .unwrap();
578
579        tx
580    }
581
582    #[test]
583    fn serialize() {
584        let tx = make_transaction();
585
586        let tx = transaction_body(tx);
587
588        let tx = check_body(tx);
589
590        expect_file!["./snapshots/token_update_transaction/serialize.txt"].assert_debug_eq(&tx);
591    }
592
593    #[test]
594    fn to_from_bytes() {
595        let tx = make_transaction();
596
597        let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
598
599        let tx = transaction_body(tx);
600        let tx2 = transaction_body(tx2);
601
602        assert_eq!(tx, tx2);
603    }
604
605    #[test]
606    fn from_proto_body() {
607        let tx = services::TokenUpdateTransactionBody {
608            token: Some(TEST_TOKEN_ID.to_protobuf()),
609            symbol: TEST_TOKEN_SYMBOL.to_owned(),
610            name: TEST_TOKEN_NAME.to_owned(),
611            treasury: Some(TEST_TREASURY_ACCOUNT_ID.to_protobuf()),
612            admin_key: Some(test_admin_key().to_protobuf()),
613            kyc_key: Some(test_kyc_key().to_protobuf()),
614            freeze_key: Some(test_freeze_key().to_protobuf()),
615            wipe_key: Some(test_wipe_key().to_protobuf()),
616            supply_key: Some(test_supply_key().to_protobuf()),
617            auto_renew_account: Some(TEST_AUTO_RENEW_ACCOUNT_ID.to_protobuf()),
618            auto_renew_period: Some(TEST_AUTO_RENEW_PERIOD.to_protobuf()),
619            expiry: Some(TEST_EXPIRATION_TIME.to_protobuf()),
620            memo: Some(TEST_TOKEN_MEMO.to_owned()),
621            fee_schedule_key: Some(test_fee_schedule_key().to_protobuf()),
622            pause_key: Some(test_pause_key().to_protobuf()),
623            metadata: Some(TEST_METADATA.to_owned().into()),
624            metadata_key: Some(test_metadata_key().to_protobuf()),
625            key_verification_mode: TEST_KEY_VERIFICATION_MODE.to_protobuf().into(),
626        };
627
628        let tx = TokenUpdateTransactionData::from_protobuf(tx).unwrap();
629
630        assert_eq!(tx.token_id, Some(TEST_TOKEN_ID));
631        assert_eq!(tx.token_name, TEST_TOKEN_NAME);
632        assert_eq!(tx.token_symbol, TEST_TOKEN_SYMBOL);
633        assert_eq!(tx.treasury_account_id, Some(TEST_TREASURY_ACCOUNT_ID));
634        assert_eq!(tx.admin_key, Some(test_admin_key().into()));
635        assert_eq!(tx.kyc_key, Some(test_kyc_key().into()));
636        assert_eq!(tx.freeze_key, Some(test_freeze_key().into()));
637        assert_eq!(tx.wipe_key, Some(test_wipe_key().into()));
638        assert_eq!(tx.supply_key, Some(test_supply_key().into()));
639        assert_eq!(tx.auto_renew_account_id, Some(TEST_AUTO_RENEW_ACCOUNT_ID));
640        assert_eq!(tx.auto_renew_period, Some(TEST_AUTO_RENEW_PERIOD));
641        assert_eq!(tx.expiration_time, Some(TEST_EXPIRATION_TIME));
642        assert_eq!(tx.token_memo, Some(TEST_TOKEN_MEMO.into()));
643        assert_eq!(tx.fee_schedule_key, Some(test_fee_schedule_key().into()));
644        assert_eq!(tx.pause_key, Some(test_pause_key().into()));
645        assert_eq!(tx.metadata, Some(TEST_METADATA.as_bytes().into()));
646        assert_eq!(tx.metadata_key, Some(test_metadata_key().into()));
647        assert_eq!(tx.key_verification_mode, TEST_KEY_VERIFICATION_MODE);
648    }
649
650    #[test]
651    fn get_set_token_id() {
652        let mut tx = TokenUpdateTransaction::new();
653        tx.token_id(TEST_TOKEN_ID);
654        assert_eq!(tx.get_token_id(), Some(TEST_TOKEN_ID));
655    }
656
657    #[test]
658    #[should_panic]
659    fn get_set_token_id_frozen_panic() {
660        let mut tx = make_transaction();
661        tx.token_id(TEST_TOKEN_ID);
662    }
663
664    #[test]
665    fn get_set_name() {
666        let mut tx = TokenUpdateTransaction::new();
667        tx.token_name(TEST_TOKEN_NAME);
668        assert_eq!(tx.get_token_name(), TEST_TOKEN_NAME);
669    }
670
671    #[test]
672    #[should_panic]
673    fn get_set_name_frozen_panic() {
674        let mut tx = make_transaction();
675        tx.token_name(TEST_TOKEN_NAME);
676    }
677
678    #[test]
679    fn get_set_symbol() {
680        let mut tx = TokenUpdateTransaction::new();
681        tx.token_symbol(TEST_TOKEN_SYMBOL);
682        assert_eq!(tx.get_token_symbol(), TEST_TOKEN_SYMBOL);
683    }
684
685    #[test]
686    #[should_panic]
687    fn get_set_symbol_frozen_panic() {
688        let mut tx = make_transaction();
689        tx.token_symbol(TEST_TOKEN_SYMBOL);
690    }
691
692    #[test]
693    fn get_set_treasury_account_id() {
694        let mut tx = TokenUpdateTransaction::new();
695        tx.treasury_account_id(TEST_TREASURY_ACCOUNT_ID);
696        assert_eq!(tx.get_treasury_account_id(), Some(TEST_TREASURY_ACCOUNT_ID));
697    }
698
699    #[test]
700    #[should_panic]
701    fn get_set_treasury_account_id_frozen_panic() {
702        let mut tx = make_transaction();
703        tx.treasury_account_id(TEST_TREASURY_ACCOUNT_ID);
704    }
705
706    #[test]
707    fn get_set_admin_key() {
708        let mut tx = TokenUpdateTransaction::new();
709        tx.admin_key(test_admin_key());
710        assert_eq!(tx.get_admin_key(), Some(&test_admin_key().into()));
711    }
712
713    #[test]
714    #[should_panic]
715    fn get_set_admin_key_frozen_panic() {
716        let mut tx = make_transaction();
717        tx.admin_key(test_admin_key());
718    }
719
720    #[test]
721    fn get_set_kyc_key() {
722        let mut tx = TokenUpdateTransaction::new();
723        tx.kyc_key(test_kyc_key());
724        assert_eq!(tx.get_kyc_key(), Some(&test_kyc_key().into()));
725    }
726
727    #[test]
728    #[should_panic]
729    fn get_set_kyc_key_frozen_panic() {
730        let mut tx = make_transaction();
731        tx.kyc_key(test_kyc_key());
732    }
733
734    #[test]
735    fn get_set_freeze_key() {
736        let mut tx = TokenUpdateTransaction::new();
737        tx.freeze_key(test_freeze_key());
738        assert_eq!(tx.get_freeze_key(), Some(&test_freeze_key().into()));
739    }
740
741    #[test]
742    #[should_panic]
743    fn get_set_freeze_key_frozen_panic() {
744        let mut tx = make_transaction();
745        tx.freeze_key(test_freeze_key());
746    }
747
748    #[test]
749    fn get_set_wipe_key() {
750        let mut tx = TokenUpdateTransaction::new();
751        tx.wipe_key(test_wipe_key());
752        assert_eq!(tx.get_wipe_key(), Some(&test_wipe_key().into()));
753    }
754
755    #[test]
756    #[should_panic]
757    fn get_set_wipe_key_frozen_panic() {
758        let mut tx = make_transaction();
759        tx.wipe_key(test_wipe_key());
760    }
761
762    #[test]
763    fn get_set_supply_key() {
764        let mut tx = TokenUpdateTransaction::new();
765        tx.supply_key(test_supply_key());
766        assert_eq!(tx.get_supply_key(), Some(&test_supply_key().into()));
767    }
768
769    #[test]
770    #[should_panic]
771    fn get_set_supply_key_frozen_panic() {
772        let mut tx = make_transaction();
773        tx.supply_key(test_supply_key());
774    }
775
776    #[test]
777    fn get_set_auto_renew_account_id() {
778        let mut tx = TokenUpdateTransaction::new();
779        tx.auto_renew_account_id(TEST_AUTO_RENEW_ACCOUNT_ID);
780        assert_eq!(tx.get_auto_renew_account_id(), Some(TEST_AUTO_RENEW_ACCOUNT_ID));
781    }
782
783    #[test]
784    #[should_panic]
785    fn get_set_auto_renew_account_id_frozen_panic() {
786        let mut tx = make_transaction();
787        tx.auto_renew_account_id(TEST_AUTO_RENEW_ACCOUNT_ID);
788    }
789
790    #[test]
791    fn get_set_auto_renew_period() {
792        let mut tx = TokenUpdateTransaction::new();
793        tx.auto_renew_period(TEST_AUTO_RENEW_PERIOD);
794        assert_eq!(tx.get_auto_renew_period(), Some(TEST_AUTO_RENEW_PERIOD));
795    }
796
797    #[test]
798    #[should_panic]
799    fn get_set_auto_renew_period_frozen_panic() {
800        let mut tx = make_transaction();
801        tx.auto_renew_period(TEST_AUTO_RENEW_PERIOD);
802    }
803
804    #[test]
805    fn get_set_expiration_time() {
806        let mut tx = TokenUpdateTransaction::new();
807        tx.expiration_time(TEST_EXPIRATION_TIME);
808        assert_eq!(tx.get_expiration_time(), Some(TEST_EXPIRATION_TIME));
809    }
810
811    #[test]
812    #[should_panic]
813    fn get_set_expiration_time_frozen_panic() {
814        let mut tx = make_transaction();
815        tx.expiration_time(TEST_EXPIRATION_TIME);
816    }
817
818    #[test]
819    fn get_set_token_memo() {
820        let mut tx = TokenUpdateTransaction::new();
821        tx.token_memo(Some(TEST_TOKEN_MEMO));
822        assert_eq!(tx.get_token_memo(), Some(TEST_TOKEN_MEMO));
823    }
824
825    #[test]
826    #[should_panic]
827    fn get_set_token_memo_frozen_panic() {
828        let mut tx = make_transaction();
829        tx.token_memo(Some(TEST_TOKEN_MEMO));
830    }
831
832    #[test]
833    fn get_set_fee_schedule_key() {
834        let mut tx = TokenUpdateTransaction::new();
835        tx.fee_schedule_key(test_fee_schedule_key());
836        assert_eq!(tx.get_fee_schedule_key(), Some(&test_fee_schedule_key().into()));
837    }
838
839    #[test]
840    #[should_panic]
841    fn get_set_fee_schedule_key_frozen_panic() {
842        let mut tx = make_transaction();
843        tx.fee_schedule_key(test_fee_schedule_key());
844    }
845
846    #[test]
847    fn get_set_pause_key() {
848        let mut tx = TokenUpdateTransaction::new();
849        tx.pause_key(test_pause_key());
850        assert_eq!(tx.get_pause_key(), Some(&test_pause_key().into()));
851    }
852
853    #[test]
854    #[should_panic]
855    fn get_set_pause_key_frozen_panic() {
856        let mut tx = make_transaction();
857        tx.pause_key(test_pause_key());
858    }
859
860    #[test]
861    fn get_set_metadata() {
862        let mut tx = TokenUpdateTransaction::new();
863        tx.metadata(TEST_METADATA.as_bytes().to_vec());
864        assert_eq!(tx.get_metadata(), Some(TEST_METADATA.as_bytes().to_vec()));
865    }
866
867    #[test]
868    #[should_panic]
869    fn get_set_metadata_frozen_panic() {
870        let mut tx = make_transaction();
871        tx.metadata(TEST_METADATA.as_bytes().to_vec());
872    }
873
874    #[test]
875    fn get_set_metadata_key() {
876        let mut tx = TokenUpdateTransaction::new();
877        tx.metadata_key(test_metadata_key());
878        assert_eq!(tx.get_metadata_key(), Some(&test_metadata_key().into()));
879    }
880
881    #[test]
882    #[should_panic]
883    fn get_set_metadata_key_frozen_panic() {
884        let mut tx = make_transaction();
885        tx.metadata_key(test_metadata_key());
886    }
887
888    #[test]
889    fn get_set_key_verification_mode() {
890        let mut tx = TokenUpdateTransaction::new();
891        tx.key_verification_mode(TokenKeyValidation::NoValidation);
892        assert_eq!(tx.get_key_verification_mode(), TokenKeyValidation::NoValidation);
893    }
894
895    #[test]
896    #[should_panic]
897    fn get_set_key_verification_mode_frozen_panic() {
898        let mut tx = make_transaction();
899        tx.key_verification_mode(TokenKeyValidation::NoValidation);
900    }
901}