Skip to main content

hiero_sdk/token/
token_unpause_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 tonic::transport::Channel;
6
7use crate::ledger_id::RefLedgerId;
8use crate::protobuf::{
9    FromProtobuf,
10    ToProtobuf,
11};
12use crate::transaction::{
13    AnyTransactionData,
14    ChunkInfo,
15    ToSchedulableTransactionDataProtobuf,
16    ToTransactionDataProtobuf,
17    TransactionData,
18    TransactionExecute,
19};
20use crate::{
21    BoxGrpcFuture,
22    TokenId,
23    Transaction,
24    ValidateChecksums,
25};
26
27/// Unpauses the Token. Must be signed with the Token's pause key.
28///
29/// Once executed the Token is marked as Unpaused and can be used in Transactions.
30///
31/// The operation is idempotent - becomes a no-op if the Token is already unpaused.
32///
33/// - If the provided token is not found, the transaction will resolve to `INVALID_TOKEN_ID`.
34/// - If the provided token has been deleted, the transaction will resolve to `TOKEN_WAS_DELETED`.
35/// - If no Pause Key is defined, the transaction will resolve to `TOKEN_HAS_NO_PAUSE_KEY`.
36pub type TokenUnpauseTransaction = Transaction<TokenUnpauseTransactionData>;
37
38#[derive(Debug, Clone, Default)]
39pub struct TokenUnpauseTransactionData {
40    /// The token to be unpaused.
41    token_id: Option<TokenId>,
42}
43
44impl TokenUnpauseTransaction {
45    /// Returns the token to be unpaused.
46    #[must_use]
47    pub fn get_token_id(&self) -> Option<TokenId> {
48        self.data().token_id
49    }
50
51    /// Sets the token to be unpaused.
52    pub fn token_id(&mut self, token_id: impl Into<TokenId>) -> &mut Self {
53        self.data_mut().token_id = Some(token_id.into());
54        self
55    }
56}
57
58impl TransactionData for TokenUnpauseTransactionData {}
59
60impl TransactionExecute for TokenUnpauseTransactionData {
61    fn execute(
62        &self,
63        channel: Channel,
64        request: services::Transaction,
65    ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
66        Box::pin(async { TokenServiceClient::new(channel).unpause_token(request).await })
67    }
68}
69
70impl ValidateChecksums for TokenUnpauseTransactionData {
71    fn validate_checksums(&self, ledger_id: &RefLedgerId) -> crate::Result<()> {
72        self.token_id.validate_checksums(ledger_id)
73    }
74}
75
76impl ToTransactionDataProtobuf for TokenUnpauseTransactionData {
77    fn to_transaction_data_protobuf(
78        &self,
79        chunk_info: &ChunkInfo,
80    ) -> services::transaction_body::Data {
81        let _ = chunk_info.assert_single_transaction();
82
83        services::transaction_body::Data::TokenUnpause(self.to_protobuf())
84    }
85}
86
87impl ToSchedulableTransactionDataProtobuf for TokenUnpauseTransactionData {
88    fn to_schedulable_transaction_data_protobuf(
89        &self,
90    ) -> services::schedulable_transaction_body::Data {
91        services::schedulable_transaction_body::Data::TokenUnpause(self.to_protobuf())
92    }
93}
94
95impl From<TokenUnpauseTransactionData> for AnyTransactionData {
96    fn from(transaction: TokenUnpauseTransactionData) -> Self {
97        Self::TokenUnpause(transaction)
98    }
99}
100
101impl FromProtobuf<services::TokenUnpauseTransactionBody> for TokenUnpauseTransactionData {
102    fn from_protobuf(pb: services::TokenUnpauseTransactionBody) -> crate::Result<Self> {
103        Ok(Self { token_id: Option::from_protobuf(pb.token)? })
104    }
105}
106
107impl ToProtobuf for TokenUnpauseTransactionData {
108    type Protobuf = services::TokenUnpauseTransactionBody;
109
110    fn to_protobuf(&self) -> Self::Protobuf {
111        services::TokenUnpauseTransactionBody { token: self.token_id.to_protobuf() }
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use expect_test::expect;
118    use hiero_sdk_proto::services;
119
120    use crate::protobuf::{
121        FromProtobuf,
122        ToProtobuf,
123    };
124    use crate::token::TokenUnpauseTransactionData;
125    use crate::transaction::test_helpers::{
126        check_body,
127        transaction_body,
128    };
129    use crate::{
130        AnyTransaction,
131        TokenId,
132        TokenUnpauseTransaction,
133    };
134
135    const TEST_TOKEN_ID: TokenId = TokenId::new(4, 2, 0);
136
137    fn make_transaction() -> TokenUnpauseTransaction {
138        let mut tx = TokenUnpauseTransaction::new_for_tests();
139
140        tx.token_id(TEST_TOKEN_ID).freeze().unwrap();
141
142        tx
143    }
144
145    #[test]
146    fn seriralize() {
147        let tx = make_transaction();
148
149        let tx = transaction_body(tx);
150
151        let tx = check_body(tx);
152
153        expect![[r#"
154            TokenUnpause(
155                TokenUnpauseTransactionBody {
156                    token: Some(
157                        TokenId {
158                            shard_num: 4,
159                            realm_num: 2,
160                            token_num: 0,
161                        },
162                    ),
163                },
164            )
165        "#]]
166        .assert_debug_eq(&tx);
167    }
168
169    #[test]
170    fn to_from_bytes() {
171        let tx = make_transaction();
172
173        let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
174
175        let tx = transaction_body(tx);
176        let tx2 = transaction_body(tx2);
177
178        assert_eq!(tx, tx2);
179    }
180
181    #[test]
182    fn from_proto_body() {
183        let tx = services::TokenUnpauseTransactionBody { token: Some(TEST_TOKEN_ID.to_protobuf()) };
184
185        let tx = TokenUnpauseTransactionData::from_protobuf(tx).unwrap();
186
187        assert_eq!(tx.token_id, Some(TEST_TOKEN_ID));
188    }
189
190    #[test]
191    fn get_set_token_id() {
192        let mut tx = TokenUnpauseTransaction::new();
193        tx.token_id(TEST_TOKEN_ID);
194
195        assert_eq!(tx.get_token_id(), Some(TEST_TOKEN_ID));
196    }
197
198    #[test]
199    #[should_panic]
200    fn get_set_token_id_frozen_panic() {
201        let mut tx = make_transaction();
202        tx.token_id(TEST_TOKEN_ID);
203    }
204}