Skip to content

Commit c58ca78

Browse files
committed
Merge branch 'main' into TokenPauseTransaction
2 parents 4949156 + 9b827e7 commit c58ca78

File tree

8 files changed

+489
-14
lines changed

8 files changed

+489
-14
lines changed

examples/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ You can choose either syntax or even mix both styles in your projects.
3030
- [Token Update NFTs](#token-update-nfts)
3131
- [Pausing a Token](#pausing-a-token)
3232
- [Querying NFT Info](#querying-nft-info)
33+
- [Querying Fungible Token Info](#querying-fungible-token-info)
3334
- [HBAR Transactions](#hbar-transactions)
3435
- [Transferring HBAR](#transferring-hbar)
3536
- [Topic Transactions](#topic-transactions)
@@ -524,6 +525,25 @@ nft_info = nft_info_query.execute(client)
524525
print(nft_info)
525526
```
526527

528+
### Querying Fungible Token Info
529+
530+
#### Pythonic Syntax:
531+
```
532+
info_query = TokenInfoQuery(token_id=token_id)
533+
info = info_query.execute(client)
534+
print(info)
535+
```
536+
#### Method Chaining:
537+
```
538+
info_query = (
539+
TokenInfoQuery()
540+
.set_token_id(token_id)
541+
)
542+
543+
info = info_query.execute(client)
544+
print(info)
545+
```
546+
527547
## HBAR Transactions
528548

529549
### Transferring HBAR
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import os
2+
import sys
3+
4+
from dotenv import load_dotenv
5+
6+
from hiero_sdk_python import (
7+
Client,
8+
AccountId,
9+
PrivateKey,
10+
Network,
11+
)
12+
from hiero_sdk_python.hapi.services.basic_types_pb2 import TokenType
13+
from hiero_sdk_python.query.token_info_query import TokenInfoQuery
14+
from hiero_sdk_python.response_code import ResponseCode
15+
from hiero_sdk_python.tokens.supply_type import SupplyType
16+
from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction
17+
18+
load_dotenv()
19+
20+
def setup_client():
21+
"""Initialize and set up the client with operator account"""
22+
network = Network(network='testnet')
23+
client = Client(network)
24+
25+
operator_id = AccountId.from_string(os.getenv('OPERATOR_ID'))
26+
operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY'))
27+
client.set_operator(operator_id, operator_key)
28+
29+
return client, operator_id, operator_key
30+
31+
def create_fungible_token(client, operator_id, operator_key):
32+
"""Create a fungible token"""
33+
receipt = (
34+
TokenCreateTransaction()
35+
.set_token_name("MyExampleFT")
36+
.set_token_symbol("EXFT")
37+
.set_decimals(2)
38+
.set_initial_supply(100)
39+
.set_treasury_account_id(operator_id)
40+
.set_token_type(TokenType.FUNGIBLE_COMMON)
41+
.set_supply_type(SupplyType.FINITE)
42+
.set_max_supply(1000)
43+
.set_admin_key(operator_key)
44+
.set_supply_key(operator_key)
45+
.set_freeze_key(operator_key)
46+
.execute(client)
47+
)
48+
49+
# Check if token creation was successful
50+
if receipt.status != ResponseCode.SUCCESS:
51+
print(f"Fungible token creation failed with status: {ResponseCode.get_name(receipt.status)}")
52+
sys.exit(1)
53+
54+
# Get token ID from receipt
55+
token_id = receipt.tokenId
56+
print(f"Fungible token created with ID: {token_id}")
57+
58+
return token_id
59+
60+
def query_token_info():
61+
"""
62+
Demonstrates the token info query functionality by:
63+
1. Creating a fungible token
64+
2. Querying the token's information using TokenInfoQuery
65+
3. Printing the token details of the TokenInfo object
66+
"""
67+
client, operator_id, operator_key = setup_client()
68+
token_id = create_fungible_token(client, operator_id, operator_key)
69+
70+
info = TokenInfoQuery().set_token_id(token_id).execute(client)
71+
print(f"Fungible token info: {info}")
72+
73+
if __name__ == "__main__":
74+
query_token_info()

examples/query_token_info_nft.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import os
2+
import sys
3+
4+
from dotenv import load_dotenv
5+
6+
from hiero_sdk_python import (
7+
Client,
8+
AccountId,
9+
PrivateKey,
10+
Network,
11+
)
12+
from hiero_sdk_python.hapi.services.basic_types_pb2 import TokenType
13+
from hiero_sdk_python.query.token_info_query import TokenInfoQuery
14+
from hiero_sdk_python.response_code import ResponseCode
15+
from hiero_sdk_python.tokens.supply_type import SupplyType
16+
from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction
17+
18+
load_dotenv()
19+
20+
def setup_client():
21+
"""Initialize and set up the client with operator account"""
22+
network = Network(network='testnet')
23+
client = Client(network)
24+
25+
operator_id = AccountId.from_string(os.getenv('OPERATOR_ID'))
26+
operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY'))
27+
client.set_operator(operator_id, operator_key)
28+
29+
return client, operator_id, operator_key
30+
31+
def create_nft(client, operator_id, operator_key):
32+
"""Create a non-fungible token"""
33+
receipt = (
34+
TokenCreateTransaction()
35+
.set_token_name("MyExampleNFT")
36+
.set_token_symbol("EXNFT")
37+
.set_decimals(0)
38+
.set_initial_supply(0)
39+
.set_treasury_account_id(operator_id)
40+
.set_token_type(TokenType.NON_FUNGIBLE_UNIQUE)
41+
.set_supply_type(SupplyType.FINITE)
42+
.set_max_supply(100)
43+
.set_admin_key(operator_key)
44+
.set_supply_key(operator_key)
45+
.set_freeze_key(operator_key)
46+
.execute(client)
47+
)
48+
49+
# Check if nft creation was successful
50+
if receipt.status != ResponseCode.SUCCESS:
51+
print(f"NFT creation failed with status: {ResponseCode.get_name(receipt.status)}")
52+
sys.exit(1)
53+
54+
# Get token ID from receipt
55+
nft_token_id = receipt.tokenId
56+
print(f"NFT created with ID: {nft_token_id}")
57+
58+
return nft_token_id
59+
60+
def query_token_info():
61+
"""
62+
Demonstrates the token info query functionality by:
63+
1. Creating a NFT
64+
2. Querying the token's information using TokenInfoQuery
65+
3. Printing the token details of the TokenInfo object
66+
"""
67+
client, operator_id, operator_key = setup_client()
68+
token_id = create_nft(client, operator_id, operator_key)
69+
70+
info = TokenInfoQuery().set_token_id(token_id).execute(client)
71+
print(f"Non-fungible token info: {info}")
72+
73+
if __name__ == "__main__":
74+
query_token_info()

src/hiero_sdk_python/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from .query.transaction_get_receipt_query import TransactionGetReceiptQuery
5959
from .query.account_balance_query import CryptoGetAccountBalanceQuery
6060
from .query.token_nft_info_query import TokenNftInfoQuery
61+
from .query.token_info_query import TokenInfoQuery
6162

6263
# Address book
6364
from .address_book.endpoint import Endpoint
@@ -120,6 +121,7 @@
120121
"TransactionGetReceiptQuery",
121122
"CryptoGetAccountBalanceQuery",
122123
"TokenNftInfoQuery",
124+
"TokenInfoQuery",
123125

124126
# Address book
125127
"Endpoint",
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
from hiero_sdk_python.query.query import Query
2+
from hiero_sdk_python.hapi.services import query_pb2, token_get_info_pb2
3+
from hiero_sdk_python.executable import _Method
4+
from hiero_sdk_python.channels import _Channel
5+
6+
from hiero_sdk_python.tokens.token_id import TokenId
7+
from hiero_sdk_python.tokens.token_info import TokenInfo
8+
9+
class TokenInfoQuery(Query):
10+
"""
11+
A query to retrieve information about a specific Token.
12+
13+
This class constructs and executes a query to retrieve information
14+
about a fungible or non-fungible token on the network,
15+
including the token's properties and settings.
16+
17+
"""
18+
def __init__(self, token_id=None):
19+
"""
20+
Initializes a new TokenInfoQuery instance with an optional token_id.
21+
22+
Args:
23+
token_id (TokenId, optional): The ID of the token to query.
24+
"""
25+
super().__init__()
26+
self.token_id : TokenId = token_id
27+
28+
def set_token_id(self, token_id: TokenId):
29+
"""
30+
Sets the ID of the token to query.
31+
32+
Args:
33+
token_id (TokenID): The ID of the token.
34+
35+
Returns:
36+
TokenInfoQuery: Returns self for method chaining.
37+
"""
38+
self.token_id = token_id
39+
return self
40+
41+
def _make_request(self):
42+
"""
43+
Constructs the protobuf request for the query.
44+
45+
Builds a TokenGetInfoQuery protobuf message with the
46+
appropriate header and token ID.
47+
48+
Returns:
49+
Query: The protobuf query message.
50+
51+
Raises:
52+
ValueError: If the token ID is not set.
53+
Exception: If any other error occurs during request construction.
54+
"""
55+
try:
56+
if not self.token_id:
57+
raise ValueError("Token ID must be set before making the request.")
58+
59+
query_header = self._make_request_header()
60+
61+
token_info_query = token_get_info_pb2.TokenGetInfoQuery()
62+
token_info_query.header.CopyFrom(query_header)
63+
token_info_query.token.CopyFrom(self.token_id.to_proto())
64+
65+
query = query_pb2.Query()
66+
query.tokenGetInfo.CopyFrom(token_info_query)
67+
68+
return query
69+
except Exception as e:
70+
print(f"Exception in _make_request: {e}")
71+
raise
72+
73+
def _get_method(self, channel: _Channel) -> _Method:
74+
"""
75+
Returns the appropriate gRPC method for the token info query.
76+
77+
Implements the abstract method from Query to provide the specific
78+
gRPC method for getting token information.
79+
80+
Args:
81+
channel (_Channel): The channel containing service stubs
82+
83+
Returns:
84+
_Method: The method wrapper containing the query function
85+
"""
86+
return _Method(
87+
transaction_func=None,
88+
query_func=channel.token.getTokenInfo
89+
)
90+
91+
def execute(self, client):
92+
"""
93+
Executes the token info query.
94+
95+
Sends the query to the Hedera network and processes the response
96+
to return a TokenInfo object.
97+
98+
This function delegates the core logic to `_execute()`, and may propagate exceptions raised by it.
99+
100+
Args:
101+
client (Client): The client instance to use for execution
102+
103+
Returns:
104+
TokenInfo: The token info from the network
105+
106+
Raises:
107+
PrecheckError: If the query fails with a non-retryable error
108+
MaxAttemptsError: If the query fails after the maximum number of attempts
109+
ReceiptStatusError: If the query fails with a receipt status error
110+
"""
111+
self._before_execute(client)
112+
response = self._execute(client)
113+
114+
return TokenInfo._from_proto(response.tokenGetInfo.tokenInfo)
115+
116+
def _get_query_response(self, response):
117+
"""
118+
Extracts the token info response from the full response.
119+
120+
Implements the abstract method from Query to extract the
121+
specific token info response object.
122+
123+
Args:
124+
response: The full response from the network
125+
126+
Returns:
127+
The token get info response object
128+
"""
129+
return response.tokenGetInfo

0 commit comments

Comments
 (0)