Skip to content
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Changelog
# Changelog

All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org).
Expand Down Expand Up @@ -180,6 +180,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- Enhance TopicInfo `__str__` method and tests with additional coverage, and update the format_key function in `key_format.py` to handle objects with a _to_proto method.

### Fixed
- Aligned token freeze example filename references and improved error handling by catching broader exceptions with clearer messages. (#1412)
- Fixed CodeRabbit plan trigger workflow running multiple times when issues are created with multiple labels by switching to labeled event trigger only. (#1427)
- Prevent LinkBot from posting duplicate “missing linked issue” comments on pull requests. (#1475)
- Refined intermediate assignment guard to validate Beginner issue completion with improved logging and GraphQL-based counting. (#1424)
Expand Down Expand Up @@ -242,6 +243,9 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.

- fixed workflow: changelog check with improved sensitivity to deletions, additions, new releases

- Aligned token freeze example filename references and improved error handling by catching broader exceptions with clearer messages. (#1412)


## [0.1.9] - 2025-11-26

### Added
Expand Down
67 changes: 37 additions & 30 deletions examples/tokens/token_freeze_transaction.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# uv run examples/tokens/token_freeze.py
# python examples/tokens/token_freeze.py
"""
Creates a freezeable token and demonstrates freezing and unfreezing
the token for the operator (treasury) account.

uv run examples/tokens/token_freeze_transaction.py
python examples/tokens/token_freeze_transaction.py
"""

import os
import sys

Expand All @@ -19,12 +19,17 @@
)



def setup_client():
"""Setup client from environment variables"""
client = Client.from_env()
operator_id = client.operator_account_id
operator_key = client.operator_private_key

print(f"Network: {client.network.network}")
print(f"Client set up with operator id {client.operator_account_id}")
return client
print(f"Client set up with operator id {operator_id}")

return client, operator_id, operator_key


def generate_freeze_key():
"""Generate a Freeze Key"""
Expand All @@ -38,59 +43,61 @@ def create_freezeable_token(client, operator_id, operator_key):
"""Create a token with the freeze key"""
freeze_key = generate_freeze_key()
print("\nSTEP 2: Creating a new freezeable token...")

try:
tx = (
TokenCreateTransaction()
.set_token_name("Freezeable Token")
.set_token_symbol("FRZ")
.set_initial_supply(1000)
.set_treasury_account_id(operator_id)
.set_freeze_key(freeze_key) # <-- THE FIX: Pass the private key directly
.set_freeze_key(freeze_key)
)

# Freeze, sign with BOTH operator and the new freeze key, then execute
receipt = (
tx.freeze_with(client)
.sign(operator_key)
.sign(freeze_key) # The new freeze key must sign to give consent
.sign(freeze_key)
.execute(client)
)

token_id = receipt.token_id
print(f"✅ Success! Created token with ID: {token_id}")

return freeze_key, token_id, client, operator_id, operator_key
except RuntimeError as e:

except Exception as e:
print(f"❌ Error creating token: {e}")
sys.exit(1)


def freeze_token(token_id, client, operator_id, freeze_key):
"""
Freeze the token for the operator account.
"""
"""Freeze the token for the operator account"""
print(f"\nSTEP 3: Freezing token {token_id} for operator account {operator_id}...")

try:
receipt = (
TokenFreezeTransaction()
.set_token_id(token_id)
.set_account_id(operator_id) # Target the operator account
.set_account_id(operator_id)
.freeze_with(client)
.sign(freeze_key) # Must be signed by the freeze key
.sign(freeze_key)
.execute(client)
)

print(
f"✅ Success! Token freeze complete. Status: {ResponseCode(receipt.status).name}"
)

except RuntimeError as e:
except Exception as e:
print(f"❌ Error freezing token: {e}")
sys.exit(1)


def verify_freeze(token_id, client, operator_id, operator_key):
"""Attempt a token transfer to confirm the account
cannot perform the operation while frozen."""
"""Attempt a token transfer to confirm the account is frozen"""
print("\nVerifying freeze: Attempting token transfer...")
# Try to transfer 1 token from operator to itself (should fail if frozen)

try:
transfer_receipt = (
TransferTransaction()
Expand All @@ -100,9 +107,9 @@ def verify_freeze(token_id, client, operator_id, operator_key):
.sign(operator_key)
.execute(client)
)
# Handle status code 165 (ACCOUNT_FROZEN_FOR_TOKEN) and print a clear message
status_code = transfer_receipt.status
status_name = ResponseCode(status_code).name

status_name = ResponseCode(transfer_receipt.status).name

if status_name in ["ACCOUNT_FROZEN_FOR_TOKEN", "ACCOUNT_FROZEN"]:
print(
f"✅ Verified: Transfer blocked as expected due to freeze. Status: {status_name}"
Expand All @@ -112,28 +119,28 @@ def verify_freeze(token_id, client, operator_id, operator_key):
"❌ Error: Transfer succeeded, but should have failed because the account is frozen."
)
else:
print(f"❌ Unexpected: Transfer result. Status: {status_name}")
except RuntimeError as e:
print(f"✅ Verified: Transfer failed as expected due to freeze. Error: {e}")
print(f"❌ Unexpected transfer result. Status: {status_name}")

except Exception as e:
print(f"❌ Error during transfer verification: {e}")
sys.exit(1)


def main():
"""
1. Create a freezeable token with a freeze key.
2. Freeze the token for the operator account using the freeze key.
3. Attempt a token transfer to verify the freeze (should fail).
4. Return token details for further operations."""

client = setup_client()
operator_id = client.operator_account_id
operator_key = client.operator_private_key
"""
client, operator_id, operator_key = setup_client()

freeze_key, token_id, client, operator_id, operator_key = create_freezeable_token(
client, operator_id, operator_key
)

freeze_token(token_id, client, operator_id, freeze_key)
verify_freeze(token_id, client, operator_id, operator_key)


if __name__ == "__main__":
main()
main()
Loading