1818 *
1919 */
2020
21+ use std:: collections:: HashMap ;
2122use std:: ops:: Not ;
2223
2324use hedera_proto:: services;
@@ -42,6 +43,7 @@ use crate::{
4243 NftId ,
4344 ToProtobuf ,
4445 TokenId ,
46+ TokenNftTransfer ,
4547 Transaction ,
4648 ValidateChecksums ,
4749} ;
@@ -79,23 +81,41 @@ struct TokenTransfer {
7981
8082 transfers : Vec < Transfer > ,
8183
82- nft_transfers : Vec < NftTransfer > ,
84+ nft_transfers : Vec < TokenNftTransfer > ,
8385
8486 expected_decimals : Option < u32 > ,
8587}
8688
87- #[ derive( Debug , Clone ) ]
88- #[ cfg_attr( test, derive( Eq , PartialEq ) ) ]
89- struct NftTransfer {
90- sender_account_id : AccountId ,
91- receiver_account_id : AccountId ,
89+ impl TransferTransaction {
90+ fn _hbar_transfer ( & mut self , account_id : AccountId , amount : Hbar , approved : bool ) -> & mut Self {
91+ self . data_mut ( ) . transfers . push ( Transfer {
92+ account_id,
93+ amount : amount. to_tinybars ( ) ,
94+ is_approval : approved,
95+ } ) ;
9296
93- serial : u64 ,
97+ self
98+ }
9499
95- is_approval : bool ,
96- }
100+ /// Add a non-approved hbar transfer to the transaction.
101+ pub fn hbar_transfer ( & mut self , account_id : AccountId , amount : Hbar ) -> & mut Self {
102+ self . _hbar_transfer ( account_id, amount, false )
103+ }
104+
105+ /// Add an approved hbar transfer to the transaction.
106+ pub fn approved_hbar_transfer ( & mut self , account_id : AccountId , amount : Hbar ) -> & mut Self {
107+ self . _hbar_transfer ( account_id, amount, true )
108+ }
109+
110+ /// Returns all transfers associated with this transaction.
111+ pub fn get_hbar_transfers ( & self ) -> HashMap < AccountId , Hbar > {
112+ self . data ( )
113+ . transfers
114+ . iter ( )
115+ . map ( |it| ( it. account_id , Hbar :: from_tinybars ( it. amount ) ) )
116+ . collect ( )
117+ }
97118
98- impl TransferTransaction {
99119 fn _token_transfer (
100120 & mut self ,
101121 token_id : TokenId ,
@@ -164,6 +184,27 @@ impl TransferTransaction {
164184 self . _token_transfer ( token_id, account_id, amount, true , Some ( expected_decimals) )
165185 }
166186
187+ /// Returns all the token transfers associated associated with this transaction.
188+ pub fn get_token_transfers ( & self ) -> HashMap < TokenId , HashMap < AccountId , i64 > > {
189+ use std:: collections:: hash_map:: Entry ;
190+
191+ // note: using fold instead of nested collects on the off chance a token is in here twice.
192+ self . data ( ) . token_transfers . iter ( ) . fold (
193+ HashMap :: with_capacity ( self . data ( ) . token_transfers . len ( ) ) ,
194+ |mut map, transfer| {
195+ let iter = transfer. transfers . iter ( ) . map ( |it| ( it. account_id , it. amount ) ) ;
196+ match map. entry ( transfer. token_id ) {
197+ Entry :: Occupied ( mut it) => it. get_mut ( ) . extend ( iter) ,
198+ Entry :: Vacant ( it) => {
199+ it. insert ( iter. collect ( ) ) ;
200+ }
201+ }
202+
203+ map
204+ } ,
205+ )
206+ }
207+
167208 fn _nft_transfer (
168209 & mut self ,
169210 nft_id : NftId ,
@@ -172,8 +213,13 @@ impl TransferTransaction {
172213 approved : bool ,
173214 ) -> & mut Self {
174215 let NftId { token_id, serial } = nft_id;
175- let transfer =
176- NftTransfer { serial, sender_account_id, receiver_account_id, is_approval : approved } ;
216+ let transfer = TokenNftTransfer {
217+ token_id,
218+ serial,
219+ sender : sender_account_id,
220+ receiver : receiver_account_id,
221+ is_approved : approved,
222+ } ;
177223
178224 let data = self . data_mut ( ) ;
179225
@@ -211,24 +257,13 @@ impl TransferTransaction {
211257 self . _nft_transfer ( nft_id. into ( ) , sender_account_id, receiver_account_id, false )
212258 }
213259
214- fn _hbar_transfer ( & mut self , account_id : AccountId , amount : Hbar , approved : bool ) -> & mut Self {
215- self . data_mut ( ) . transfers . push ( Transfer {
216- account_id,
217- amount : amount. to_tinybars ( ) ,
218- is_approval : approved,
219- } ) ;
220-
221- self
222- }
223-
224- /// Add a non-approved hbar transfer to the transaction.
225- pub fn hbar_transfer ( & mut self , account_id : AccountId , amount : Hbar ) -> & mut Self {
226- self . _hbar_transfer ( account_id, amount, false )
227- }
228-
229- /// Add an approved hbar transfer to the transaction.
230- pub fn approved_hbar_transfer ( & mut self , account_id : AccountId , amount : Hbar ) -> & mut Self {
231- self . _hbar_transfer ( account_id, amount, true )
260+ /// Returns all the NFT transfers associated with this transaction.
261+ pub fn get_nft_transfers ( & self ) -> HashMap < TokenId , Vec < TokenNftTransfer > > {
262+ self . data ( )
263+ . token_transfers
264+ . iter ( )
265+ . map ( |it| ( it. token_id , it. nft_transfers . clone ( ) ) )
266+ . collect ( )
232267 }
233268}
234269
@@ -256,8 +291,8 @@ impl ValidateChecksums for TransferTransactionData {
256291 transfer. account_id . validate_checksums ( ledger_id) ?;
257292 }
258293 for nft_transfer in & token_transfer. nft_transfers {
259- nft_transfer. sender_account_id . validate_checksums ( ledger_id) ?;
260- nft_transfer. receiver_account_id . validate_checksums ( ledger_id) ?;
294+ nft_transfer. sender . validate_checksums ( ledger_id) ?;
295+ nft_transfer. receiver . validate_checksums ( ledger_id) ?;
261296 }
262297 }
263298 Ok ( ( ) )
@@ -288,10 +323,16 @@ impl ToProtobuf for Transfer {
288323
289324impl FromProtobuf < services:: TokenTransferList > for TokenTransfer {
290325 fn from_protobuf ( pb : services:: TokenTransferList ) -> crate :: Result < Self > {
326+ let token_id = TokenId :: from_protobuf ( pb_getf ! ( pb, token) ?) ?;
327+
291328 Ok ( Self {
292- token_id : TokenId :: from_protobuf ( pb_getf ! ( pb , token ) ? ) ? ,
329+ token_id,
293330 transfers : Vec :: from_protobuf ( pb. transfers ) ?,
294- nft_transfers : Vec :: from_protobuf ( pb. nft_transfers ) ?,
331+ nft_transfers : pb
332+ . nft_transfers
333+ . into_iter ( )
334+ . map ( |pb| TokenNftTransfer :: from_protobuf ( pb, token_id) )
335+ . collect :: < Result < Vec < _ > , _ > > ( ) ?,
295336 expected_decimals : pb. expected_decimals ,
296337 } )
297338 }
@@ -313,26 +354,15 @@ impl ToProtobuf for TokenTransfer {
313354 }
314355}
315356
316- impl FromProtobuf < services:: NftTransfer > for NftTransfer {
317- fn from_protobuf ( pb : services:: NftTransfer ) -> crate :: Result < Self > {
318- Ok ( Self {
319- sender_account_id : AccountId :: from_protobuf ( pb_getf ! ( pb, sender_account_id) ?) ?,
320- receiver_account_id : AccountId :: from_protobuf ( pb_getf ! ( pb, receiver_account_id) ?) ?,
321- serial : pb. serial_number as u64 ,
322- is_approval : pb. is_approval ,
323- } )
324- }
325- }
326-
327- impl ToProtobuf for NftTransfer {
357+ impl ToProtobuf for TokenNftTransfer {
328358 type Protobuf = services:: NftTransfer ;
329359
330360 fn to_protobuf ( & self ) -> Self :: Protobuf {
331361 services:: NftTransfer {
332- sender_account_id : Some ( self . sender_account_id . to_protobuf ( ) ) ,
333- receiver_account_id : Some ( self . receiver_account_id . to_protobuf ( ) ) ,
362+ sender_account_id : Some ( self . sender . to_protobuf ( ) ) ,
363+ receiver_account_id : Some ( self . receiver . to_protobuf ( ) ) ,
334364 serial_number : self . serial as i64 ,
335- is_approval : self . is_approval ,
365+ is_approval : self . is_approved ,
336366 }
337367 }
338368}
0 commit comments