hiero-sdk-python 0.0.1.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hiero_sdk_python/__init__.py +93 -0
- hiero_sdk_python/account/__init__.py +0 -0
- hiero_sdk_python/account/account_balance.py +44 -0
- hiero_sdk_python/account/account_create_transaction.py +173 -0
- hiero_sdk_python/account/account_id.py +62 -0
- hiero_sdk_python/client/__init__.py +0 -0
- hiero_sdk_python/client/client.py +139 -0
- hiero_sdk_python/client/network.py +143 -0
- hiero_sdk_python/consensus/__init__.py +0 -0
- hiero_sdk_python/consensus/topic_create_transaction.py +83 -0
- hiero_sdk_python/consensus/topic_delete_transaction.py +67 -0
- hiero_sdk_python/consensus/topic_id.py +44 -0
- hiero_sdk_python/consensus/topic_info.py +91 -0
- hiero_sdk_python/consensus/topic_message.py +61 -0
- hiero_sdk_python/consensus/topic_message_submit_transaction.py +87 -0
- hiero_sdk_python/consensus/topic_update_transaction.py +173 -0
- hiero_sdk_python/crypto/__init__.py +0 -0
- hiero_sdk_python/crypto/private_key.py +196 -0
- hiero_sdk_python/crypto/public_key.py +162 -0
- hiero_sdk_python/hapi/mirror/__init__.py +0 -0
- hiero_sdk_python/hapi/services/__init__.py +0 -0
- hiero_sdk_python/hbar.py +33 -0
- hiero_sdk_python/query/__init__.py +0 -0
- hiero_sdk_python/query/account_balance_query.py +100 -0
- hiero_sdk_python/query/query.py +138 -0
- hiero_sdk_python/query/topic_info_query.py +105 -0
- hiero_sdk_python/query/topic_message_query.py +105 -0
- hiero_sdk_python/query/transaction_get_receipt_query.py +128 -0
- hiero_sdk_python/response_code.py +587 -0
- hiero_sdk_python/timestamp.py +166 -0
- hiero_sdk_python/tokens/__init__.py +0 -0
- hiero_sdk_python/tokens/token_associate_transaction.py +85 -0
- hiero_sdk_python/tokens/token_create_transaction.py +144 -0
- hiero_sdk_python/tokens/token_delete_transaction.py +84 -0
- hiero_sdk_python/tokens/token_dissociate_transaction.py +81 -0
- hiero_sdk_python/tokens/token_id.py +44 -0
- hiero_sdk_python/tokens/token_mint_transaction.py +143 -0
- hiero_sdk_python/transaction/__init__.py +0 -0
- hiero_sdk_python/transaction/query_payment.py +32 -0
- hiero_sdk_python/transaction/transaction.py +267 -0
- hiero_sdk_python/transaction/transaction_id.py +140 -0
- hiero_sdk_python/transaction/transaction_receipt.py +78 -0
- hiero_sdk_python/transaction/transfer_transaction.py +119 -0
- hiero_sdk_python/utils/key_format.py +22 -0
- hiero_sdk_python-0.0.1.dev0.dist-info/METADATA +822 -0
- hiero_sdk_python-0.0.1.dev0.dist-info/RECORD +49 -0
- hiero_sdk_python-0.0.1.dev0.dist-info/WHEEL +4 -0
- hiero_sdk_python-0.0.1.dev0.dist-info/entry_points.txt +4 -0
- hiero_sdk_python-0.0.1.dev0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from hiero_sdk_python.response_code import ResponseCode
|
|
2
|
+
from hiero_sdk_python.transaction.transaction import Transaction
|
|
3
|
+
from hiero_sdk_python.hapi.services import consensus_create_topic_pb2, duration_pb2
|
|
4
|
+
|
|
5
|
+
class TopicCreateTransaction(Transaction):
|
|
6
|
+
def __init__(self, memo=None, admin_key=None, submit_key=None, auto_renew_period=None, auto_renew_account=None):
|
|
7
|
+
super().__init__()
|
|
8
|
+
self.memo = memo or ""
|
|
9
|
+
self.admin_key = admin_key
|
|
10
|
+
self.submit_key = submit_key
|
|
11
|
+
self.auto_renew_period = auto_renew_period or 7890000
|
|
12
|
+
self.auto_renew_account = auto_renew_account
|
|
13
|
+
self.transaction_fee = 10_000_000
|
|
14
|
+
|
|
15
|
+
def set_memo(self, memo):
|
|
16
|
+
self._require_not_frozen()
|
|
17
|
+
self.memo = memo
|
|
18
|
+
return self
|
|
19
|
+
|
|
20
|
+
def set_admin_key(self, key):
|
|
21
|
+
self._require_not_frozen()
|
|
22
|
+
self.admin_key = key
|
|
23
|
+
return self
|
|
24
|
+
|
|
25
|
+
def set_submit_key(self, key):
|
|
26
|
+
self._require_not_frozen()
|
|
27
|
+
self.submit_key = key
|
|
28
|
+
return self
|
|
29
|
+
|
|
30
|
+
def set_auto_renew_period(self, seconds):
|
|
31
|
+
self._require_not_frozen()
|
|
32
|
+
self.auto_renew_period = seconds
|
|
33
|
+
return self
|
|
34
|
+
|
|
35
|
+
def set_auto_renew_account(self, account_id):
|
|
36
|
+
self._require_not_frozen()
|
|
37
|
+
self.auto_renew_account = account_id
|
|
38
|
+
return self
|
|
39
|
+
|
|
40
|
+
def build_transaction_body(self):
|
|
41
|
+
"""
|
|
42
|
+
Builds and returns the protobuf transaction body for topic creation.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
TransactionBody: The protobuf transaction body containing the topic creation details.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
ValueError: If required fields are missing.
|
|
49
|
+
"""
|
|
50
|
+
transaction_body = self.build_base_transaction_body()
|
|
51
|
+
transaction_body.consensusCreateTopic.CopyFrom(consensus_create_topic_pb2.ConsensusCreateTopicTransactionBody(
|
|
52
|
+
adminKey=self.admin_key.to_proto() if self.admin_key is not None else None,
|
|
53
|
+
submitKey=self.submit_key.to_proto() if self.submit_key is not None else None,
|
|
54
|
+
autoRenewPeriod=duration_pb2.Duration(seconds=self.auto_renew_period),
|
|
55
|
+
autoRenewAccount=self.auto_renew_account.to_proto() if self.auto_renew_account is not None else None,
|
|
56
|
+
memo=self.memo
|
|
57
|
+
))
|
|
58
|
+
|
|
59
|
+
return transaction_body
|
|
60
|
+
|
|
61
|
+
def _execute_transaction(self, client, transaction_proto):
|
|
62
|
+
"""
|
|
63
|
+
Executes the topic creation transaction using the provided client.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
client (Client): The client instance to use for execution.
|
|
67
|
+
transaction_proto (Transaction): The protobuf Transaction message.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
TransactionReceipt: The receipt from the network after transaction execution.
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
Exception: If the transaction submission fails or receives an error response.
|
|
74
|
+
"""
|
|
75
|
+
response = client.topic_stub.createTopic(transaction_proto)
|
|
76
|
+
|
|
77
|
+
if response.nodeTransactionPrecheckCode != ResponseCode.OK:
|
|
78
|
+
error_code = response.nodeTransactionPrecheckCode
|
|
79
|
+
error_message = ResponseCode.get_name(error_code)
|
|
80
|
+
raise Exception(f"Error during transaction submission: {error_code} ({error_message})")
|
|
81
|
+
|
|
82
|
+
receipt = self.get_receipt(client)
|
|
83
|
+
return receipt
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from hiero_sdk_python.response_code import ResponseCode
|
|
2
|
+
from hiero_sdk_python.transaction.transaction import Transaction
|
|
3
|
+
from hiero_sdk_python.hapi.services import consensus_delete_topic_pb2, duration_pb2
|
|
4
|
+
|
|
5
|
+
class TopicDeleteTransaction(Transaction):
|
|
6
|
+
def __init__(self, topic_id=None):
|
|
7
|
+
super().__init__()
|
|
8
|
+
self.topic_id = topic_id
|
|
9
|
+
self.transaction_fee = 10_000_000
|
|
10
|
+
|
|
11
|
+
def set_topic_id(self, topic_id):
|
|
12
|
+
"""
|
|
13
|
+
Sets the topic ID for the transaction.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
topic_id: The topic ID to delete.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
TopicDeleteTransaction: Returns the instance for method chaining.
|
|
20
|
+
"""
|
|
21
|
+
self._require_not_frozen()
|
|
22
|
+
self.topic_id = topic_id
|
|
23
|
+
return self
|
|
24
|
+
|
|
25
|
+
def build_transaction_body(self):
|
|
26
|
+
"""
|
|
27
|
+
Builds and returns the protobuf transaction body for topic delete.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
TransactionBody: The protobuf transaction body containing the topic delete details.
|
|
31
|
+
|
|
32
|
+
Raises:
|
|
33
|
+
ValueError: If required fields are missing.
|
|
34
|
+
"""
|
|
35
|
+
if self.topic_id is None:
|
|
36
|
+
raise ValueError("Missing required fields: topic_id")
|
|
37
|
+
|
|
38
|
+
transaction_body = self.build_base_transaction_body()
|
|
39
|
+
transaction_body.consensusDeleteTopic.CopyFrom(consensus_delete_topic_pb2.ConsensusDeleteTopicTransactionBody(
|
|
40
|
+
topicID=self.topic_id.to_proto()
|
|
41
|
+
))
|
|
42
|
+
|
|
43
|
+
return transaction_body
|
|
44
|
+
|
|
45
|
+
def _execute_transaction(self, client, transaction_proto):
|
|
46
|
+
"""
|
|
47
|
+
Executes the topic delete transaction using the provided client.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
client (Client): The client instance to use for execution.
|
|
51
|
+
transaction_proto (Transaction): The protobuf Transaction message.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
TransactionReceipt: The receipt from the network after transaction execution.
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
Exception: If the transaction submission fails or receives an error response.
|
|
58
|
+
"""
|
|
59
|
+
response = client.topic_stub.deleteTopic(transaction_proto)
|
|
60
|
+
|
|
61
|
+
if response.nodeTransactionPrecheckCode != ResponseCode.OK:
|
|
62
|
+
error_code = response.nodeTransactionPrecheckCode
|
|
63
|
+
error_message = ResponseCode.get_name(error_code)
|
|
64
|
+
raise Exception(f"Error during transaction submission: {error_code} ({error_message})")
|
|
65
|
+
|
|
66
|
+
receipt = self.get_receipt(client)
|
|
67
|
+
return receipt
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from hiero_sdk_python.hapi.services import basic_types_pb2
|
|
2
|
+
|
|
3
|
+
class TopicId:
|
|
4
|
+
def __init__(self, shard=0, realm=0, num=0):
|
|
5
|
+
self.shard = shard
|
|
6
|
+
self.realm = realm
|
|
7
|
+
self.num = num
|
|
8
|
+
|
|
9
|
+
@classmethod
|
|
10
|
+
def from_proto(cls, topic_id_proto: basic_types_pb2.TopicID):
|
|
11
|
+
"""
|
|
12
|
+
Creates a TopicId instance from a protobuf TopicID object.
|
|
13
|
+
"""
|
|
14
|
+
return cls(
|
|
15
|
+
shard=topic_id_proto.shardNum,
|
|
16
|
+
realm=topic_id_proto.realmNum,
|
|
17
|
+
num=topic_id_proto.topicNum
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def to_proto(self):
|
|
21
|
+
"""
|
|
22
|
+
Converts the TopicId instance to a protobuf TopicID object.
|
|
23
|
+
"""
|
|
24
|
+
topic_id_proto = basic_types_pb2.TopicID()
|
|
25
|
+
topic_id_proto.shardNum = self.shard
|
|
26
|
+
topic_id_proto.realmNum = self.realm
|
|
27
|
+
topic_id_proto.topicNum = self.num
|
|
28
|
+
return topic_id_proto
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
"""
|
|
32
|
+
Returns the string representation of the TopicId in the format 'shard.realm.num'.
|
|
33
|
+
"""
|
|
34
|
+
return f"{self.shard}.{self.realm}.{self.num}"
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def from_string(cls, topic_id_str):
|
|
38
|
+
"""
|
|
39
|
+
Parses a string in the format 'shard.realm.num' to create a TopicId instance.
|
|
40
|
+
"""
|
|
41
|
+
parts = topic_id_str.strip().split('.')
|
|
42
|
+
if len(parts) != 3:
|
|
43
|
+
raise ValueError("Invalid TopicId format. Expected 'shard.realm.num'")
|
|
44
|
+
return cls(shard=int(parts[0]), realm=int(parts[1]), num=int(parts[2]))
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from hiero_sdk_python.hapi.services.basic_types_pb2 import Key, AccountID
|
|
3
|
+
from hiero_sdk_python.hapi.services.timestamp_pb2 import Timestamp
|
|
4
|
+
from hiero_sdk_python.hapi.services.duration_pb2 import Duration
|
|
5
|
+
from hiero_sdk_python.utils.key_format import format_key
|
|
6
|
+
|
|
7
|
+
class TopicInfo:
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
memo: str,
|
|
11
|
+
running_hash: bytes,
|
|
12
|
+
sequence_number: int,
|
|
13
|
+
expiration_time: Timestamp,
|
|
14
|
+
admin_key: Key,
|
|
15
|
+
submit_key: Key,
|
|
16
|
+
auto_renew_period: Duration,
|
|
17
|
+
auto_renew_account: AccountID,
|
|
18
|
+
ledger_id: bytes,
|
|
19
|
+
):
|
|
20
|
+
self.memo = memo
|
|
21
|
+
self.running_hash = running_hash
|
|
22
|
+
self.sequence_number = sequence_number
|
|
23
|
+
self.expiration_time = expiration_time
|
|
24
|
+
self.admin_key = admin_key
|
|
25
|
+
self.submit_key = submit_key
|
|
26
|
+
self.auto_renew_period = auto_renew_period
|
|
27
|
+
self.auto_renew_account = auto_renew_account
|
|
28
|
+
self.ledger_id = ledger_id
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def from_proto(cls, topic_info_proto):
|
|
32
|
+
"""
|
|
33
|
+
Constructs a TopicInfo object from a protobuf ConsensusTopicInfo message.
|
|
34
|
+
"""
|
|
35
|
+
return cls(
|
|
36
|
+
memo=topic_info_proto.memo,
|
|
37
|
+
running_hash=topic_info_proto.runningHash,
|
|
38
|
+
sequence_number=topic_info_proto.sequenceNumber,
|
|
39
|
+
expiration_time=(
|
|
40
|
+
topic_info_proto.expirationTime
|
|
41
|
+
if topic_info_proto.HasField("expirationTime") else None
|
|
42
|
+
),
|
|
43
|
+
admin_key=(
|
|
44
|
+
topic_info_proto.adminKey
|
|
45
|
+
if topic_info_proto.HasField("adminKey") else None
|
|
46
|
+
),
|
|
47
|
+
submit_key=(
|
|
48
|
+
topic_info_proto.submitKey
|
|
49
|
+
if topic_info_proto.HasField("submitKey") else None
|
|
50
|
+
),
|
|
51
|
+
auto_renew_period=(
|
|
52
|
+
topic_info_proto.autoRenewPeriod
|
|
53
|
+
if topic_info_proto.HasField("autoRenewPeriod") else None
|
|
54
|
+
),
|
|
55
|
+
auto_renew_account=(
|
|
56
|
+
topic_info_proto.autoRenewAccount
|
|
57
|
+
if topic_info_proto.HasField("autoRenewAccount") else None
|
|
58
|
+
),
|
|
59
|
+
ledger_id=getattr(topic_info_proto, "ledger_id", None), # fallback if the field doesn't exist
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def __repr__(self):
|
|
63
|
+
"""
|
|
64
|
+
If you print the object with `repr(topic_info)`, you'll see this output.
|
|
65
|
+
"""
|
|
66
|
+
return self.__str__()
|
|
67
|
+
|
|
68
|
+
def __str__(self):
|
|
69
|
+
"""
|
|
70
|
+
Pretty-print the TopicInfo in a multi-line, user-friendly style.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
exp_dt = None
|
|
74
|
+
if self.expiration_time and hasattr(self.expiration_time, "seconds"):
|
|
75
|
+
exp_dt = datetime.fromtimestamp(self.expiration_time.seconds)
|
|
76
|
+
|
|
77
|
+
running_hash_hex = self.running_hash.hex() if self.running_hash else None
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
"TopicInfo(\n"
|
|
81
|
+
f" memo='{self.memo}',\n"
|
|
82
|
+
f" running_hash=0x{running_hash_hex},\n"
|
|
83
|
+
f" sequence_number={self.sequence_number},\n"
|
|
84
|
+
f" expiration_time={exp_dt},\n"
|
|
85
|
+
f" admin_key={format_key(self.admin_key)},\n"
|
|
86
|
+
f" submit_key={format_key(self.submit_key)},\n"
|
|
87
|
+
f" auto_renew_period={self.auto_renew_period},\n"
|
|
88
|
+
f" auto_renew_account={self.auto_renew_account},\n"
|
|
89
|
+
f" ledger_id={self.ledger_id}\n"
|
|
90
|
+
")"
|
|
91
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from hiero_sdk_python.hapi.mirror import consensus_service_pb2 as mirror_proto
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
class TopicMessage:
|
|
5
|
+
"""
|
|
6
|
+
Represents a single message returned from a Hedera Mirror Node subscription.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
def __init__(self, consensus_timestamp, message, running_hash, sequence_number,
|
|
10
|
+
running_hash_version=None, chunk_info=None, chunks=None, transaction_id=None):
|
|
11
|
+
self.consensus_timestamp = consensus_timestamp
|
|
12
|
+
self.message = message or b""
|
|
13
|
+
self.running_hash = running_hash or b""
|
|
14
|
+
self.sequence_number = sequence_number or 0
|
|
15
|
+
self.running_hash_version = running_hash_version
|
|
16
|
+
self.chunk_info = chunk_info
|
|
17
|
+
self.chunks = chunks
|
|
18
|
+
self.transaction_id = transaction_id
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_proto(cls, response: mirror_proto.ConsensusTopicResponse) -> "TopicMessage":
|
|
22
|
+
"""
|
|
23
|
+
Parse a Mirror Node response into a simpler object.
|
|
24
|
+
"""
|
|
25
|
+
transaction_id = (
|
|
26
|
+
response.chunkInfo.initialTransactionID
|
|
27
|
+
if response.HasField("chunkInfo") and response.chunkInfo.HasField("initialTransactionID")
|
|
28
|
+
else None
|
|
29
|
+
)
|
|
30
|
+
return cls(
|
|
31
|
+
consensus_timestamp=response.consensusTimestamp,
|
|
32
|
+
message=response.message,
|
|
33
|
+
running_hash=response.runningHash,
|
|
34
|
+
sequence_number=response.sequenceNumber,
|
|
35
|
+
running_hash_version=response.runningHashVersion if response.runningHashVersion != 0 else None,
|
|
36
|
+
chunk_info=response.chunkInfo if response.HasField("chunkInfo") else None,
|
|
37
|
+
transaction_id=transaction_id,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def __str__(self):
|
|
41
|
+
"""
|
|
42
|
+
Returns a nicely formatted string representation of the topic message.
|
|
43
|
+
"""
|
|
44
|
+
timestamp = datetime.utcfromtimestamp(self.consensus_timestamp.seconds).strftime('%Y-%m-%d %H:%M:%S UTC')
|
|
45
|
+
message = self.message.decode('utf-8', errors='ignore')
|
|
46
|
+
running_hash = self.running_hash.hex()
|
|
47
|
+
|
|
48
|
+
formatted_message = (
|
|
49
|
+
f"Received Topic Message:\n"
|
|
50
|
+
f" - Timestamp: {timestamp}\n"
|
|
51
|
+
f" - Sequence Number: {self.sequence_number}\n"
|
|
52
|
+
f" - Message: {message}\n"
|
|
53
|
+
f" - Running Hash: {running_hash}\n"
|
|
54
|
+
)
|
|
55
|
+
if self.running_hash_version:
|
|
56
|
+
formatted_message += f" - Running Hash Version: {self.running_hash_version}\n"
|
|
57
|
+
if self.chunk_info:
|
|
58
|
+
formatted_message += f" - Chunk Info: {self.chunk_info}\n"
|
|
59
|
+
if self.transaction_id:
|
|
60
|
+
formatted_message += f" - Transaction ID: {self.transaction_id}\n"
|
|
61
|
+
return formatted_message
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from hiero_sdk_python.response_code import ResponseCode
|
|
2
|
+
from hiero_sdk_python.transaction.transaction import Transaction
|
|
3
|
+
from hiero_sdk_python.hapi.services import consensus_submit_message_pb2
|
|
4
|
+
|
|
5
|
+
class TopicMessageSubmitTransaction(Transaction):
|
|
6
|
+
def __init__(self, topic_id=None, message=None):
|
|
7
|
+
"""
|
|
8
|
+
Initializes a new TopicMessageSubmitTransaction instance.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
topic_id (TopicId, optional): The ID of the topic.
|
|
12
|
+
message (str, optional): The message to submit.
|
|
13
|
+
"""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.topic_id = topic_id
|
|
16
|
+
self.message = message
|
|
17
|
+
|
|
18
|
+
def set_topic_id(self, topic_id):
|
|
19
|
+
"""
|
|
20
|
+
Sets the topic ID for the message submission.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
topic_id (TopicId): The ID of the topic to which the message is submitted.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
TopicMessageSubmitTransaction: This transaction instance (for chaining).
|
|
27
|
+
"""
|
|
28
|
+
self._require_not_frozen()
|
|
29
|
+
self.topic_id = topic_id
|
|
30
|
+
return self
|
|
31
|
+
|
|
32
|
+
def set_message(self, message):
|
|
33
|
+
"""
|
|
34
|
+
Sets the message to submit to the topic.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
message (str): The message to submit to the topic.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
TopicMessageSubmitTransaction: This transaction instance (for chaining).
|
|
41
|
+
"""
|
|
42
|
+
self._require_not_frozen()
|
|
43
|
+
self.message = message
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
def build_transaction_body(self):
|
|
47
|
+
"""
|
|
48
|
+
Builds and returns the protobuf transaction body for message submission.
|
|
49
|
+
Raises ValueError if required fields (topic_id, message) are missing.
|
|
50
|
+
"""
|
|
51
|
+
if self.topic_id is None:
|
|
52
|
+
raise ValueError("Missing required fields: topic_id.")
|
|
53
|
+
if self.message is None:
|
|
54
|
+
raise ValueError("Missing required fields: message.")
|
|
55
|
+
|
|
56
|
+
transaction_body = self.build_base_transaction_body()
|
|
57
|
+
transaction_body.consensusSubmitMessage.CopyFrom(
|
|
58
|
+
consensus_submit_message_pb2.ConsensusSubmitMessageTransactionBody(
|
|
59
|
+
topicID=self.topic_id.to_proto(),
|
|
60
|
+
message=bytes(self.message, 'utf-8')
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
return transaction_body
|
|
64
|
+
|
|
65
|
+
def _execute_transaction(self, client, transaction_proto):
|
|
66
|
+
"""
|
|
67
|
+
Executes the message submit transaction using the provided client.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
client (Client): The client instance to use for execution.
|
|
71
|
+
transaction_proto (Transaction): The protobuf Transaction message.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
TransactionReceipt: The receipt from the network after transaction execution.
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
Exception: If the transaction submission fails or receives an error response.
|
|
78
|
+
"""
|
|
79
|
+
response = client.topic_stub.submitMessage(transaction_proto)
|
|
80
|
+
|
|
81
|
+
if response.nodeTransactionPrecheckCode != ResponseCode.OK:
|
|
82
|
+
error_code = response.nodeTransactionPrecheckCode
|
|
83
|
+
error_message = ResponseCode.get_name(error_code)
|
|
84
|
+
raise Exception(f"Error during transaction submission: {error_code} ({error_message})")
|
|
85
|
+
|
|
86
|
+
receipt = self.get_receipt(client)
|
|
87
|
+
return receipt
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from hiero_sdk_python.response_code import ResponseCode
|
|
2
|
+
from hiero_sdk_python.transaction.transaction import Transaction
|
|
3
|
+
from hiero_sdk_python.hapi.services import consensus_update_topic_pb2, duration_pb2
|
|
4
|
+
from google.protobuf import wrappers_pb2 as _wrappers_pb2
|
|
5
|
+
|
|
6
|
+
class TopicUpdateTransaction(Transaction):
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
topic_id=None,
|
|
10
|
+
memo=None,
|
|
11
|
+
admin_key=None,
|
|
12
|
+
submit_key=None,
|
|
13
|
+
auto_renew_period=7890000,
|
|
14
|
+
auto_renew_account=None,
|
|
15
|
+
expiration_time=None,
|
|
16
|
+
):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.topic_id = topic_id
|
|
19
|
+
self.memo = memo or ""
|
|
20
|
+
self.admin_key = admin_key
|
|
21
|
+
self.submit_key = submit_key
|
|
22
|
+
self.auto_renew_period = auto_renew_period
|
|
23
|
+
self.auto_renew_account = auto_renew_account
|
|
24
|
+
self.expiration_time = expiration_time
|
|
25
|
+
self.transaction_fee = 10_000_000
|
|
26
|
+
|
|
27
|
+
def set_topic_id(self, topic_id):
|
|
28
|
+
"""
|
|
29
|
+
Sets the topic ID for the transaction.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
topic_id: The topic ID to update.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
36
|
+
"""
|
|
37
|
+
self._require_not_frozen()
|
|
38
|
+
self.topic_id = topic_id
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
def set_memo(self, memo):
|
|
42
|
+
"""
|
|
43
|
+
Sets the memo for the topic.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
memo: The memo to set.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
50
|
+
"""
|
|
51
|
+
self._require_not_frozen()
|
|
52
|
+
self.memo = memo
|
|
53
|
+
return self
|
|
54
|
+
|
|
55
|
+
def set_admin_key(self, key):
|
|
56
|
+
"""
|
|
57
|
+
Sets the admin key for the topic.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
key: The admin key to set.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
64
|
+
"""
|
|
65
|
+
self._require_not_frozen()
|
|
66
|
+
self.admin_key = key
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
def set_submit_key(self, key):
|
|
70
|
+
"""
|
|
71
|
+
Sets the submit key for the topic.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
key: The submit key to set.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
78
|
+
"""
|
|
79
|
+
self._require_not_frozen()
|
|
80
|
+
self.submit_key = key
|
|
81
|
+
return self
|
|
82
|
+
|
|
83
|
+
def set_auto_renew_period(self, seconds):
|
|
84
|
+
"""
|
|
85
|
+
Sets the auto-renew period for the topic.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
seconds: The auto-renew period in seconds.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
92
|
+
"""
|
|
93
|
+
self._require_not_frozen()
|
|
94
|
+
self.auto_renew_period = seconds
|
|
95
|
+
return self
|
|
96
|
+
|
|
97
|
+
def set_auto_renew_account(self, account_id):
|
|
98
|
+
"""
|
|
99
|
+
Sets the auto-renew account for the topic.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
account_id: The account ID to set as the auto-renew account.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
106
|
+
"""
|
|
107
|
+
self._require_not_frozen()
|
|
108
|
+
self.auto_renew_account = account_id
|
|
109
|
+
return self
|
|
110
|
+
|
|
111
|
+
def set_expiration_time(self, expiration_time):
|
|
112
|
+
"""
|
|
113
|
+
Sets the expiration time for the topic.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
expiration_time: The expiration time to set.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
TopicUpdateTransaction: Returns the instance for method chaining.
|
|
120
|
+
"""
|
|
121
|
+
self._require_not_frozen()
|
|
122
|
+
self.expiration_time = expiration_time
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
def build_transaction_body(self):
|
|
126
|
+
"""
|
|
127
|
+
Builds and returns the protobuf transaction body for topic update.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
TransactionBody: The protobuf transaction body containing the topic update details.
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
ValueError: If required fields are missing.
|
|
134
|
+
"""
|
|
135
|
+
if self.topic_id is None:
|
|
136
|
+
raise ValueError("Missing required fields: topic_id")
|
|
137
|
+
|
|
138
|
+
transaction_body = self.build_base_transaction_body()
|
|
139
|
+
transaction_body.consensusUpdateTopic.CopyFrom(consensus_update_topic_pb2.ConsensusUpdateTopicTransactionBody(
|
|
140
|
+
topicID=self.topic_id.to_proto(),
|
|
141
|
+
adminKey=self.admin_key.to_proto() if self.admin_key else None,
|
|
142
|
+
submitKey=self.submit_key.to_proto() if self.submit_key else None,
|
|
143
|
+
autoRenewPeriod=duration_pb2.Duration(seconds=self.auto_renew_period) if self.auto_renew_period else None,
|
|
144
|
+
autoRenewAccount=self.auto_renew_account.to_proto() if self.auto_renew_account else None,
|
|
145
|
+
expirationTime=self.expiration_time.to_proto() if self.expiration_time else None,
|
|
146
|
+
memo=_wrappers_pb2.StringValue(value=self.memo) if self.memo else None
|
|
147
|
+
))
|
|
148
|
+
|
|
149
|
+
return transaction_body
|
|
150
|
+
|
|
151
|
+
def _execute_transaction(self, client, transaction_proto):
|
|
152
|
+
"""
|
|
153
|
+
Executes the topic update transaction using the provided client.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
client (Client): The client instance to use for execution.
|
|
157
|
+
transaction_proto (Transaction): The protobuf Transaction message.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
TransactionReceipt: The receipt from the network after transaction execution.
|
|
161
|
+
|
|
162
|
+
Raises:
|
|
163
|
+
Exception: If the transaction submission fails or receives an error response.
|
|
164
|
+
"""
|
|
165
|
+
response = client.topic_stub.updateTopic(transaction_proto)
|
|
166
|
+
|
|
167
|
+
if response.nodeTransactionPrecheckCode != ResponseCode.OK:
|
|
168
|
+
error_code = response.nodeTransactionPrecheckCode
|
|
169
|
+
error_message = ResponseCode.get_name(error_code)
|
|
170
|
+
raise Exception(f"Error during transaction submission: {error_code} ({error_message})")
|
|
171
|
+
|
|
172
|
+
receipt = self.get_receipt(client)
|
|
173
|
+
return receipt
|
|
File without changes
|