1+ from hiero_sdk_python .channels import _Channel
2+ from hiero_sdk_python .executable import _Method
3+ from hiero_sdk_python .account .account_id import AccountId
4+ from hiero_sdk_python .tokens .nft_id import NftId
5+ from hiero_sdk_python .tokens .token_id import TokenId
6+ from hiero_sdk_python .tokens .token_nft_transfer import TokenNftTransfer
7+ from hiero_sdk_python .tokens .token_transfer import TokenTransfer
8+ from hiero_sdk_python .tokens .abstract_token_transfer_transaction import AbstractTokenTransferTransaction
9+ from hiero_sdk_python .hapi .services import token_airdrop_pb2
10+
11+ class TokenAirdropTransaction (AbstractTokenTransferTransaction ):
12+ """
13+ Represents a token airdrop transaction on the Hedera network.
14+
15+ The TokenAirdropTransaction allows users to transfer tokens to multiple accounts,
16+ handling both fungible tokens and NFTs.
17+ """
18+ def __init__ (self , token_transfers : list [TokenTransfer ]| None = None , nft_transfers : list [TokenNftTransfer ]| None = None ):
19+ """
20+ Initializes a new TokenAirdropTransaction instance.
21+
22+ Args:
23+ token_transfers (list[TokenTransfer], optional): Initial list of fungible token transfers.
24+ nft_transfers (list[TokenNftTransfer], optional): Initial list of NFT transfers.
25+ """
26+ super ().__init__ ()
27+ if token_transfers :
28+ self ._init_token_transfers (token_transfers )
29+ if nft_transfers :
30+ self ._init_nft_transfers (nft_transfers )
31+
32+ def add_token_transfer (self , token_id : TokenId , account_id : AccountId , amount : int ) -> 'TokenAirdropTransaction' :
33+ """
34+ Adds a tranfer to token_transfers list
35+ Args:
36+ token_id (TokenId): The ID of the token being transferred.
37+ account_id (AccountId): The accountId of sender/receiver.
38+ amount (int): The amount of the fungible token to transfer.
39+
40+ Returns:
41+ TokenAirdropTransaction: The current instance of the transaction for chaining.
42+ """
43+ self ._require_not_frozen ()
44+ self ._add_token_transfer (token_id , account_id , amount )
45+ return self
46+
47+ def add_token_transfer_with_decimals (self , token_id : TokenId , account_id : AccountId , amount : int , decimals : int ) -> 'TokenAirdropTransaction' :
48+ """
49+ Adds a tranfer with expected_decimals to token_transfers list
50+ Args:
51+ token_id (TokenId): The ID of the token being transferred.
52+ account_id (AccountId): The accountId of sender/receiver.
53+ amount (int): The amount of the fungible token to transfer.
54+ decimals (int): The number specifying the amount in the smallest denomination.
55+
56+ Returns:
57+ TokenAirdropTransaction: The current instance of the transaction for chaining.
58+ """
59+ self ._require_not_frozen ()
60+ self ._add_token_transfer (token_id , account_id , amount , expected_decimals = decimals )
61+ return self
62+
63+ def add_approved_token_transfer (self , token_id : TokenId , account_id : AccountId , amount : int ) -> 'TokenAirdropTransaction' :
64+ """
65+ Adds a tranfer with approve allowance to token_transfers list
66+ Args:
67+ token_id (TokenId): The ID of the token being transferred.
68+ account_id (AccountId): The accountId of sender/receiver.
69+ amount (int): The amount of the fungible token to transfer.
70+
71+ Returns:
72+ TokenAirdropTransaction: The current instance of the transaction for chaining.
73+ """
74+ self ._require_not_frozen ()
75+ self ._add_token_transfer (token_id , account_id , amount , is_approved = True )
76+ return self
77+
78+ def add_approved_token_transfer_with_decimals (self , token_id : TokenId , account_id : AccountId , amount : int , decimals : int ) -> 'TokenAirdropTransaction' :
79+ """
80+ Adds a tranfer with expected_decimals and approve allowance to token_transfers list
81+ Args:
82+ token_id (TokenId): The ID of the token being transferred.
83+ account_id (AccountId): The accountId of sender/receiver.
84+ amount (int): The amount of the fungible token to transfer.
85+ decimals (int): The number specifying the amount in the smallest denomination.
86+
87+ Returns:
88+ TokenAirdropTransaction: The current instance of the transaction for chaining.
89+ """
90+ self ._require_not_frozen ()
91+ self ._add_token_transfer (token_id , account_id , amount , decimals , True )
92+ return self
93+
94+ def add_nft_transfer (self , nft_id : NftId , sender : AccountId , receiver : AccountId ) -> 'TokenAirdropTransaction' :
95+ """
96+ Adds a transfer to the nft_transfers
97+
98+ Args:
99+ nft_id (NftId): The ID of the NFT being transferred.
100+ sender (AccountId): The sender's account ID.
101+ receiver (AccountId): The receiver's account ID.
102+
103+ Returns:
104+ TokenAirdropTransaction: The current instance of the transaction for chaining.
105+ """
106+ self ._require_not_frozen ()
107+ self ._add_nft_transfer (nft_id .tokenId , sender , receiver , nft_id .serialNumber )
108+ return self
109+
110+ def add_approved_nft_transfer (self , nft_id : NftId , sender : AccountId , receiver : AccountId ) -> 'TokenAirdropTransaction' :
111+ """
112+ Adds a transfer to the nft_transfers with approved allowance
113+
114+ Args:
115+ nft_id (NftId): The ID of the NFT being transferred.
116+ sender (AccountId): The sender's account ID.
117+ receiver (AccountId): The receiver's account ID.
118+
119+ Returns:
120+ TokenAirdropTransaction: The current instance of the transaction for chaining.
121+ """
122+ self ._require_not_frozen ()
123+ self ._add_nft_transfer (nft_id .tokenId , sender , receiver , nft_id .serialNumber ,True )
124+ return self
125+
126+ def build_transaction_body (self ):
127+ """
128+ Builds and returns the protobuf transaction body for token airdrop.
129+ """
130+ token_transfers = self .build_token_transfers ()
131+
132+ if (len (token_transfers ) < 1 or len (token_transfers ) > 10 ):
133+ raise ValueError ("Airdrop transfer list must contain mininum 1 and maximum 10 transfers." )
134+
135+ token_airdrop_body = token_airdrop_pb2 .TokenAirdropTransactionBody (
136+ token_transfers = token_transfers
137+ )
138+ transaction_body = self .build_base_transaction_body ()
139+ transaction_body .tokenAirdrop .CopyFrom (token_airdrop_body )
140+
141+ return transaction_body
142+
143+ def _get_method (self , channel : _Channel ) -> _Method :
144+ return _Method (
145+ transaction_func = channel .token .airdropTokens ,
146+ query_func = None
147+ )
0 commit comments