hiero_sdk/token/
token_freeze_transaction.rs1use 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 AccountId,
22 BoxGrpcFuture,
23 Error,
24 TokenId,
25 Transaction,
26 ValidateChecksums,
27};
28
29pub type TokenFreezeTransaction = Transaction<TokenFreezeTransactionData>;
42
43#[derive(Debug, Clone, Default)]
44pub struct TokenFreezeTransactionData {
45 account_id: Option<AccountId>,
47
48 token_id: Option<TokenId>,
50}
51
52impl TokenFreezeTransaction {
53 #[must_use]
55 pub fn get_account_id(&self) -> Option<AccountId> {
56 self.data().account_id
57 }
58
59 pub fn account_id(&mut self, account_id: AccountId) -> &mut Self {
61 self.data_mut().account_id = Some(account_id);
62 self
63 }
64
65 #[must_use]
67 pub fn get_token_id(&self) -> Option<TokenId> {
68 self.data().token_id
69 }
70
71 pub fn token_id(&mut self, token_id: impl Into<TokenId>) -> &mut Self {
73 self.data_mut().token_id = Some(token_id.into());
74 self
75 }
76}
77
78impl TransactionData for TokenFreezeTransactionData {}
79
80impl TransactionExecute for TokenFreezeTransactionData {
81 fn execute(
82 &self,
83 channel: Channel,
84 request: services::Transaction,
85 ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
86 Box::pin(async { TokenServiceClient::new(channel).freeze_token_account(request).await })
87 }
88}
89
90impl ValidateChecksums for TokenFreezeTransactionData {
91 fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
92 self.account_id.validate_checksums(ledger_id)?;
93 self.token_id.validate_checksums(ledger_id)
94 }
95}
96
97impl ToTransactionDataProtobuf for TokenFreezeTransactionData {
98 fn to_transaction_data_protobuf(
99 &self,
100 chunk_info: &ChunkInfo,
101 ) -> services::transaction_body::Data {
102 let _ = chunk_info.assert_single_transaction();
103
104 services::transaction_body::Data::TokenFreeze(self.to_protobuf())
105 }
106}
107
108impl ToSchedulableTransactionDataProtobuf for TokenFreezeTransactionData {
109 fn to_schedulable_transaction_data_protobuf(
110 &self,
111 ) -> services::schedulable_transaction_body::Data {
112 services::schedulable_transaction_body::Data::TokenFreeze(self.to_protobuf())
113 }
114}
115
116impl From<TokenFreezeTransactionData> for AnyTransactionData {
117 fn from(transaction: TokenFreezeTransactionData) -> Self {
118 Self::TokenFreeze(transaction)
119 }
120}
121
122impl FromProtobuf<services::TokenFreezeAccountTransactionBody> for TokenFreezeTransactionData {
123 fn from_protobuf(pb: services::TokenFreezeAccountTransactionBody) -> crate::Result<Self> {
124 Ok(Self {
125 account_id: Option::from_protobuf(pb.account)?,
126 token_id: Option::from_protobuf(pb.token)?,
127 })
128 }
129}
130
131impl ToProtobuf for TokenFreezeTransactionData {
132 type Protobuf = services::TokenFreezeAccountTransactionBody;
133
134 fn to_protobuf(&self) -> Self::Protobuf {
135 let account = self.account_id.to_protobuf();
136 let token = self.token_id.to_protobuf();
137
138 services::TokenFreezeAccountTransactionBody { token, account }
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use expect_test::expect;
145 use hiero_sdk_proto::services;
146
147 use crate::protobuf::{
148 FromProtobuf,
149 ToProtobuf,
150 };
151 use crate::token::TokenFreezeTransactionData;
152 use crate::transaction::test_helpers::{
153 check_body,
154 transaction_body,
155 };
156 use crate::{
157 AccountId,
158 AnyTransaction,
159 TokenFreezeTransaction,
160 TokenId,
161 };
162
163 const ACCOUNT_ID: AccountId = AccountId::new(0, 0, 222);
164
165 const TOKEN_ID: TokenId = TokenId::new(5, 3, 3);
166
167 fn make_transaction() -> TokenFreezeTransaction {
168 let mut tx = TokenFreezeTransaction::new_for_tests();
169
170 tx.account_id(ACCOUNT_ID).token_id(TOKEN_ID).freeze().unwrap();
171
172 tx
173 }
174
175 #[test]
176 fn serialize() {
177 let tx = make_transaction();
178
179 let tx = transaction_body(tx);
180
181 let tx = check_body(tx);
182
183 expect![[r#"
184 TokenFreeze(
185 TokenFreezeAccountTransactionBody {
186 token: Some(
187 TokenId {
188 shard_num: 5,
189 realm_num: 3,
190 token_num: 3,
191 },
192 ),
193 account: Some(
194 AccountId {
195 shard_num: 0,
196 realm_num: 0,
197 account: Some(
198 AccountNum(
199 222,
200 ),
201 ),
202 },
203 ),
204 },
205 )
206 "#]]
207 .assert_debug_eq(&tx)
208 }
209
210 #[test]
211 fn to_from_bytes() {
212 let tx = make_transaction();
213
214 let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
215
216 let tx = transaction_body(tx);
217
218 let tx2 = transaction_body(tx2);
219
220 assert_eq!(tx, tx2);
221 }
222
223 #[test]
224 fn from_proto_body() {
225 let tx = services::TokenFreezeAccountTransactionBody {
226 account: Some(ACCOUNT_ID.to_protobuf()),
227 token: Some(TOKEN_ID.to_protobuf()),
228 };
229
230 let data = TokenFreezeTransactionData::from_protobuf(tx).unwrap();
231
232 assert_eq!(data.account_id, Some(ACCOUNT_ID));
233 assert_eq!(data.token_id, Some(TOKEN_ID));
234 }
235
236 #[test]
237 fn get_set_token_id() {
238 let mut tx = TokenFreezeTransaction::new();
239 tx.token_id(TOKEN_ID);
240
241 assert_eq!(tx.get_token_id(), Some(TOKEN_ID));
242 }
243
244 #[test]
245 #[should_panic]
246 fn get_set_token_id_frozen_panic() {
247 make_transaction().token_id(TOKEN_ID);
248 }
249
250 #[test]
251 fn get_set_account_id() {
252 let mut tx = TokenFreezeTransaction::new();
253 tx.account_id(ACCOUNT_ID);
254
255 assert_eq!(tx.get_account_id(), Some(ACCOUNT_ID));
256 }
257
258 #[test]
259 #[should_panic]
260 fn get_set_account_id_frozen_panic() {
261 make_transaction().account_id(ACCOUNT_ID);
262 }
263}