Skip to content

Conversation

@Adityarya11
Copy link
Contributor

@Adityarya11 Adityarya11 commented Dec 18, 2025

Description:
Updates examples/tokens/custom_fee_fixed.py to be a functional end-to-end example that interacts with the Hedera network, rather than a static object demo.

  • Added setup_client() with required TLS configuration.
  • Implemented TokenCreateTransaction to deploy a token with a CustomFixedFee.
  • Added TokenInfoQuery to verify the fee was correctly attached to the created token on the network.

Fixes #1085

Checklist

  • Documented (Code comments, README, etc.)
  • Successfully ran the example.

Summary by CodeRabbit

  • Documentation
    • Formatted token examples for consistent code style and improved readability.
    • Upgraded the custom fee example into a complete end-to-end demo showing environment-driven setup, client initialization, creating a token with a fixed custom fee, executing transactions, retrieving token info, and robust error handling with clear runtime logs.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 18, 2025 16:09
@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Replaced a static demo with an end-to-end Hedera testnet example: dotenv-driven client setup, token creation using a CustomFixedFee, transaction submission, receipt/record retrieval, TokenInfoQuery verification, and improved error handling/cleanup.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added an "Unreleased" entry noting that examples/tokens/custom_fee_fixed.py was converted into an end-to-end Hedera network example and formatted token examples with Black.
End-to-end example
examples/tokens/custom_fee_fixed.py
Replaced the static object demo with a networked example. Added setup_client() and custom_fixed_fee_example(); removed custom_fixed_fee(). Implements dotenv-driven client init (OPERATOR_ID/KEY), builds CustomFixedFee, creates/finalizes/signs TokenCreateTransaction, executes and validates receipts/records, runs TokenInfoQuery to verify custom fees, and includes robust error handling and client cleanup.

Sequence Diagram(s)

sequenceDiagram
    participant User as Main
    participant Client as Hedera Client (local)
    participant Network as Hedera Testnet
    participant TokenSvc as Token Registry

    Note over User: Load environment (.env) OPERATOR_ID / OPERATOR_KEY / NETWORK
    User->>Client: setup_client() — create configured client with operator
    User->>User: build CustomFixedFee and TokenCreateTransaction (metadata, treasury, keys)
    User->>Client: freeze transaction & sign with operator/admin keys
    Client->>Network: submit TokenCreateTransaction
    Network->>Network: process transaction
    Network->>TokenSvc: persist token with custom fee config
    Network-->>Client: return Receipt / Record (tokenId, status)
    User->>Client: TokenInfoQuery(tokenId)
    Client->>Network: query token info
    Network->>TokenSvc: lookup token & fees
    TokenSvc-->>Network: return token metadata & custom fees
    Network-->>Client: return TokenInfo
    User->>User: validate & print TokenInfo
    User->>Client: close client (cleanup)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Inspect environment variable handling and clear error messages for missing OPERATOR vars.
  • Verify correct construction of CustomFixedFee and TokenCreateTransaction parameters (treasury, admin key, supply, decimals).
  • Check transaction freezing, signing, execution/receipt handling, and TokenInfoQuery parsing.
  • Confirm client cleanup in success and exception paths.

Poem

🐇 I hopped from static lines to network light,
I stitched a fee that now takes flight,
I read the .env and set my key,
I minted tokens on the testnet tree,
I close the client — hop, all's right! ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'feat: Transform custom_fee_fixed example to end-to-end test' directly reflects the main objective: converting a static example into a runnable end-to-end example.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #1085: implements setup_client(), creates tokens with CustomFixedFee via TokenCreateTransaction, executes transactions, and validates results with TokenInfoQuery.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the issue objectives: client setup, token creation with custom fees, transaction execution, and result validation. The CHANGELOG update is a standard accompanying change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9850b6 and fb6be05.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build-and-test (3.10)
  • GitHub Check: build-and-test (3.12)
  • GitHub Check: build-and-test (3.11)
  • GitHub Check: build-and-test (3.13)
  • GitHub Check: run-examples
  • GitHub Check: StepSecurity Harden-Runner

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Dec 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1148   +/-   ##
=======================================
  Coverage   91.19%   91.19%           
=======================================
  Files         139      139           
  Lines        8446     8446           
=======================================
  Hits         7702     7702           
  Misses        744      744           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR transforms the examples/tokens/custom_fee_fixed.py from a static object demonstration into a functional end-to-end example that interacts with the Hedera network.

Key changes:

  • Added client setup with operator credentials loaded from environment variables
  • Implemented TokenCreateTransaction to create a token with a CustomFixedFee on the network
  • Added TokenInfoQuery to verify the custom fee was correctly attached to the created token

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
examples/tokens/custom_fee_fixed.py Transformed from static demo to full E2E example with network interaction, including client setup, token creation with fixed fee, and verification query
CHANGELOG.md Added entry documenting the transformation of the custom_fee_fixed.py example

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
examples/tokens/custom_fee_fixed.py (1)

111-115: Consider more specific exception handling.

The broad Exception catch is acceptable for example scripts but could be more specific. Consider catching ReceiptStatusError or similar SDK-specific exceptions for better error reporting.

🔎 View suggested improvement:
-    except Exception as e:
-        print(f"Transaction failed: {e}")
+    except (ValueError, RuntimeError) as e:
+        print(f"Transaction failed: {e}")

However, the current approach with broad exception handling and finally block for cleanup is reasonable for an example script.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08ba48a and bb90363.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • examples/tokens/custom_fee_fixed.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.8)
examples/tokens/custom_fee_fixed.py

45-45: Abstract raise to an inner function

(TRY301)


45-45: Avoid specifying long messages outside the exception class

(TRY003)


52-52: Consider moving this statement to an else block

(TRY300)


111-111: Do not catch blind exception: Exception

(BLE001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build-and-test (3.12)
  • GitHub Check: build-and-test (3.11)
  • GitHub Check: build-and-test (3.13)
  • GitHub Check: build-and-test (3.10)
  • GitHub Check: run-examples
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: StepSecurity Harden-Runner
🔇 Additional comments (6)
examples/tokens/custom_fee_fixed.py (6)

7-28: LGTM! Clean imports and environment setup.

The imports are well-organized, and the environment loading with a sensible default network follows good practices for example scripts.


59-77: LGTM! Clear fee configuration.

The CustomFixedFee is properly configured with explicit parameters, and the print statements provide helpful context about what the fee does.


79-92: LGTM! Complete token creation setup.

The transaction is properly configured with all necessary parameters, follows the builder pattern correctly, and includes the custom fee as intended.


100-109: LGTM! Proper verification of custom fees.

The TokenInfoQuery correctly retrieves and validates that the custom fee was attached to the token on the network. The iteration through retrieved fees provides clear confirmation.


117-118: LGTM! Standard Python entry point.

The main execution guard follows Python conventions correctly.


94-97: The code is correct. The Python SDK's execute() method directly returns a receipt object, so receipt = transaction.execute(client) followed by accessing receipt.token_id is the proper pattern for hiero-sdk-python, which is the SDK used in this repository.

Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Adityarya11 great! Couple small details

@Adityarya11 Adityarya11 force-pushed the feat/end-to-end-custom-fee#1085 branch from bb90363 to d9850b6 Compare December 18, 2025 17:05
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
examples/tokens/custom_fee_fixed.py (2)

93-117: Consider catching more specific exceptions.

Line 115 catches the broad Exception type, which may hide unexpected errors. Consider catching more specific exceptions like ReceiptStatusError or network-related exceptions to provide more targeted error handling.

🔎 View suggested refinement:
     try:
         receipt = transaction.execute(client)
         
         # Check if the status is explicitly SUCCESS
         if receipt.status != ResponseCode.SUCCESS:
             print(f"Transaction failed with status: {ResponseCode(receipt.status).name}")
 
         token_id = receipt.token_id
         print(f"Token created successfully with ID: {token_id}")
 
         print("\n--- Verifying Fee on Network ---")
         token_info = TokenInfoQuery().set_token_id(token_id).execute(client)
 
         retrieved_fees = token_info.custom_fees
         if retrieved_fees:
             print(f"Success! Found {len(retrieved_fees)} custom fee(s) on token.")
             for fee in retrieved_fees:
                 print(f"Fee Collector: {fee.fee_collector_account_id}")
                 print(f"Fee Details: {fee}")
         else:
             print("Error: No custom fees found on the token.")
 
-    except Exception as e:
+    except (ReceiptStatusError, ValueError, RuntimeError) as e:
         print(f"Transaction failed: {e}")
         sys.exit(1)

65-119: Consider using a context manager for the client.

While the finally block ensures the client is closed, using a context manager (with statement) would provide a more Pythonic approach and automatically handle cleanup.

🔎 View alternative pattern:
def custom_fixed_fee_example():
    """
    Demonstrates how to create a token with a Custom Fixed Fee.
    """
    
    client, operator_id, operator_key = setup_client()
    
    with client:
        print("\n--- Creating Custom Fixed Fee ---")
        
        fixed_fee = CustomFixedFee(
            amount=Hbar(1).to_tinybars(), 
            fee_collector_account_id=operator_id,
            all_collectors_are_exempt=False
        )
        
        # ... rest of the function

Note: This pattern requires that the Client class implements the context manager protocol (__enter__ and __exit__ methods).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb90363 and d9850b6.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • examples/tokens/custom_fee_fixed.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
examples/tokens/custom_fee_fixed.py (6)
src/hiero_sdk_python/query/token_info_query.py (1)
  • TokenInfoQuery (11-131)
src/hiero_sdk_python/response_code.py (1)
  • ResponseCode (4-387)
src/hiero_sdk_python/tokens/supply_type.py (1)
  • SupplyType (11-19)
src/hiero_sdk_python/tokens/custom_fixed_fee.py (1)
  • CustomFixedFee (21-288)
src/hiero_sdk_python/tokens/token_create_transaction.py (1)
  • TokenCreateTransaction (207-585)
src/hiero_sdk_python/tokens/token_type.py (1)
  • TokenType (11-14)
🪛 Ruff (0.14.8)
examples/tokens/custom_fee_fixed.py

44-44: Abstract raise to an inner function

(TRY301)


44-44: Avoid specifying long messages outside the exception class

(TRY003)


51-51: Consider moving this statement to an else block

(TRY300)


115-115: Do not catch blind exception: Exception

(BLE001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: run-examples
  • GitHub Check: build-and-test (3.10)
  • GitHub Check: build-and-test (3.11)
  • GitHub Check: build-and-test (3.12)
  • GitHub Check: build-and-test (3.13)
  • GitHub Check: StepSecurity Harden-Runner
🔇 Additional comments (5)
CHANGELOG.md (1)

77-77: LGTM! Changelog entry accurately documents the transformation.

The entry clearly describes that the example was transformed from a static object demo to an end-to-end network-interacting example, which aligns with the PR objectives.

examples/tokens/custom_fee_fixed.py (4)

7-22: LGTM! Import style is now consistent.

All imports consistently use the full path pattern (from hiero_sdk_python.X import Y), which addresses previous feedback about mixing import styles.


27-56: Client setup is well-structured with clear error messages.

The function properly initializes the network and client, handles missing environment variables gracefully, and provides helpful error messages. The commented-out TLS configuration addresses previous concerns about hardcoded disabling.


58-91: Excellent end-to-end token creation workflow.

The example clearly demonstrates creating a token with a custom fixed fee, including proper fee definition, comprehensive token configuration, and correct transaction signing. The code is well-commented and follows the suggested structure from issue #1085.


121-122: LGTM! Standard main guard pattern.

The entry point is clean and follows Python conventions.

@exploreriii exploreriii marked this pull request as draft December 18, 2025 18:11
@Adityarya11 Adityarya11 marked this pull request as ready for review December 18, 2025 19:25
exploreriii
exploreriii previously approved these changes Dec 18, 2025
Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works very nicely well done !

@exploreriii
Copy link
Contributor

Please rebase and can merge this :)

@exploreriii
Copy link
Contributor

Please rebase and we can merge
I’ve also merged the ssl fix so all those comments can be removed, either you can or please help to create a good first issue for it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transform examples/tokens/custom_fee_fixed.py to be an end-to-end example

2 participants