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