Skip to main content

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