Skip to content

Commit 767913e

Browse files
authored
Merge branch 'main' into hbar
Signed-off-by: prajeeta <96904203+prajeeta15@users.noreply.github.com>
2 parents ca729cb + acf4d26 commit 767913e

35 files changed

+1956
-459
lines changed

.github/workflows/examples.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
egress-policy: audit
2020

2121
- name: Checkout repository
22-
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
22+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
2323
with:
2424
fetch-depth: 0
2525

.github/workflows/pr-check-changelog.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
changelog-check:
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
15+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
1616
with:
1717
fetch-depth: 0
1818

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
egress-policy: audit
2424

2525
- name: Checkout repository
26-
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
26+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2727

2828
- name: Set up Python
2929
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
egress-policy: audit
2828

2929
- name: Checkout repository
30-
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
30+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
3131

3232
- name: Set up Python ${{ matrix.python-version }}
3333
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,22 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
77
## [Unreleased]
88

99
### Added
10+
- Add examples/tokens/token_create_transaction_pause_key.py example demonstrating token pause/unpause behavior and pause key usage (#833)
11+
- Added `docs/sdk_developers/training/transaction_lifecycle.md` to explain the typical lifecycle of executing a transaction using the Hedera Python SDK.
12+
### Changed
13+
-
14+
15+
### Fixed
16+
-
17+
18+
### Breaking Change
19+
-
1020

21+
## [0.1.10] - 2025-12-03
22+
23+
### Added
24+
- Added docs/sdk_developers/training/workflow: a training for developers to learn the workflow to contribute to the python SDK.
25+
- Added Improved NFT allowance deletion flow with receipt-based status checks and strict `SPENDER_DOES_NOT_HAVE_ALLOWANCE` verification.
1126
- Add `max_automatic_token_associations`, `staked_account_id`, `staked_node_id` and `decline_staking_reward` fields to `AccountUpdateTransaction` (#801)
1227
- Added docs/sdk_developers/training/setup: a training to set up as a developer to the python sdk
1328
- Add example demonstrating usage of `CustomFeeLimit` in `examples/transaction/custom_fee_limit.py`
@@ -21,7 +36,10 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
2136

2237
- bot workflows to include new changelog entry
2338
- Removed duplicate import of transaction_pb2 in transaction.py
39+
- Refactor `TokenInfo` into an immutable dataclass, remove all setters, and rewrite `_from_proto` as a pure factory for consistent parsing [#800]
2440
- feat: Add string representation method for `CustomFractionalFee` class and update `custom_fractional_fee.py` example.
41+
- Moved query examples to their respective domain folders to improve structure matching.
42+
2543

2644
### Fixed
2745

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Transaction Lifecycle in the Python SDK
2+
3+
This guide explains the typical lifecycle of executing a transaction using the Hedera Python SDK. Transactions are requests to change the state of the Hedera network, such as creating accounts, transferring HBAR, or minting tokens. Understanding the lifecycle helps you avoid common pitfalls and ensures your transactions succeed.
4+
5+
## Overview
6+
7+
A typical transaction follows this flow:
8+
9+
1. **Construct** the transaction
10+
2. **Freeze** the transaction
11+
3. **Sign** the transaction
12+
4. **Execute** the transaction
13+
5. **Check the receipt**
14+
15+
The order matters because each step builds on the previous one. Skipping or reordering steps can cause errors.
16+
17+
## 1. Construct the Transaction
18+
19+
Start by creating a transaction object and populating it with the necessary data. You can use either Pythonic syntax (constructor arguments) or method chaining (fluent API).
20+
21+
### Pythonic Syntax
22+
```python
23+
from hiero_sdk_python import TokenAssociateTransaction
24+
25+
transaction = TokenAssociateTransaction(
26+
account_id=account_id,
27+
token_ids=[token_id]
28+
)
29+
```
30+
31+
### Method Chaining
32+
```python
33+
transaction = (
34+
TokenAssociateTransaction()
35+
.set_account_id(account_id)
36+
.add_token_id(token_id)
37+
)
38+
```
39+
40+
This step collects all information for the transaction body. Fields can still be modified at this point.
41+
42+
## 2. Freeze the Transaction
43+
44+
Freezing finalizes the transaction payload and makes it immutable. It sets the transaction ID, node ID, and builds the protobuf body.
45+
46+
```python
47+
transaction.freeze_with(client)
48+
```
49+
50+
- **Why freeze?** Hedera requires a consistent payload for signing and execution. Freezing prevents accidental changes.
51+
- **When to freeze?** Always before signing. Some transactions auto-freeze during execution, but manual freezing is recommended for clarity.
52+
- **What happens if you don't freeze?** Signing or executing may fail or behave unexpectedly.
53+
54+
## 3. Sign the Transaction
55+
56+
Hedera uses cryptographic signatures for authorization. Sign with the required keys (e.g., operator key, admin keys).
57+
58+
```python
59+
transaction.sign(account_private_key)
60+
```
61+
62+
- **Who signs?** The operator (client account) often signs automatically, but additional keys may be needed (e.g., supply key for minting).
63+
- **Multiple signatures?** Call `.sign()` multiple times if required.
64+
- **Order?** Sign after freezing, as the payload must be finalized.
65+
66+
## 4. Execute the Transaction
67+
68+
Submit the transaction to the Hedera network. This returns a `TransactionReceipt` indicating the network has processed it.
69+
70+
```python
71+
receipt = transaction.execute(client)
72+
```
73+
74+
- **Does this guarantee success?** No! It only confirms receipt. The network processes it asynchronously.
75+
- **What if you skip signing?** Execution will fail with an authorization error.
76+
77+
## 5. Check the Receipt
78+
79+
Fetch and verify the transaction receipt to confirm processing.
80+
81+
```python
82+
# In this SDK `execute(client)` returns the receipt directly:
83+
receipt = transaction.execute(client)
84+
85+
if receipt.status != ResponseCode.SUCCESS:
86+
print(f"Transaction failed: {ResponseCode(receipt.status).name}")
87+
else:
88+
print("Transaction successful!")
89+
```
90+
91+
- **Why check?** Always inspect `receipt.status` returned by `execute(client)`. The `execute` call confirms the network received your transaction; the receipt contains the final processing result. Your Python code will not automatically raise for Hedera-level failures — you must check the receipt to detect them.
92+
93+
- **Common failure examples (from `src/hiero_sdk_python/response_code.py`):**
94+
- `INSUFFICIENT_ACCOUNT_BALANCE` — payer/account lacks sufficient funds
95+
- `INSUFFICIENT_TX_FEE` — submitted fee was too low to cover processing
96+
- `INVALID_SIGNATURE` — missing or incorrect cryptographic signature
97+
- `INVALID_PAYER_SIGNATURE` — payer's signature is invalid
98+
- `TRANSACTION_EXPIRED` — transaction timestamp/duration expired
99+
- `INVALID_TOKEN_ID` — supplied token ID does not exist
100+
- `TOKEN_NOT_ASSOCIATED_TO_ACCOUNT` — attempted token operation on an unassociated account
101+
- `TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT` — duplicate association attempt
102+
- `FAIL_BALANCE`, `FAIL_FEE` — generic failure categories
103+
104+
- **Important:** These are examples only — many other ResponseCodes exist. Always consult `src/hiero_sdk_python/response_code.py` for the full list and handle codes relevant to your workflow.
105+
106+
```python
107+
# Example: check and handle failure explicitly
108+
receipt = transaction.execute(client)
109+
110+
if receipt.status != ResponseCode.SUCCESS:
111+
# react to failure: log, retry, or surface to caller
112+
print(f"Transaction processed with failure: {ResponseCode(receipt.status).name}")
113+
# e.g. inspect receipt fields for more info, then handle appropriately
114+
else:
115+
print("Transaction successful!")
116+
```
117+
118+
## Complete Example
119+
120+
Here's a clean example associating a token with an account:
121+
122+
```python
123+
import sys
124+
from hiero_sdk_python import TokenAssociateTransaction, ResponseCode
125+
126+
def associate_token_with_account(client, account_id, account_private_key, token_id):
127+
"""Associate a token with an account."""
128+
129+
receipt = (
130+
TokenAssociateTransaction()
131+
.set_account_id(account_id)
132+
.add_token_id(token_id)
133+
.freeze_with(client) # Lock fields
134+
.sign(account_private_key) # Authorize
135+
.execute(client) # Submit to Hedera
136+
)
137+
138+
if receipt.status != ResponseCode.SUCCESS:
139+
print(f"Token association failed: {ResponseCode(receipt.status).name}")
140+
sys.exit(1)
141+
142+
print("Token associated successfully!")
143+
```
144+
145+
For more examples, see `examples/tokens/token_grant_kyc.py` or `examples/tokens/token_associate.py`.
146+
147+
## Correct vs. Incorrect Order
148+
149+
### Correct
150+
```python
151+
transaction = TokenAssociateTransaction().set_account_id(account_id).freeze_with(client).sign(key).execute(client)
152+
```
153+
154+
### Incorrect (Signing before freezing)
155+
```python
156+
transaction = TokenAssociateTransaction().set_account_id(account_id).sign(key).freeze_with(client) # Error: Cannot sign unfrozen transaction
157+
```
158+
159+
### Incorrect (Modifying after freezing)
160+
```python
161+
transaction = TokenAssociateTransaction().set_account_id(account_id).freeze_with(client)
162+
transaction.set_account_id(new_id) # Error: Transaction is immutable
163+
```
164+
165+
## Flow Diagram
166+
167+
```
168+
[Construct] → [Freeze] → [Sign] → [Execute] → [Check Receipt]
169+
↓ ↓ ↓ ↓ ↓
170+
Build data Finalize Authorize Submit Verify status
171+
```
172+
173+
## Common Pitfalls
174+
175+
- **Forgetting to freeze:** Leads to runtime errors during signing.
176+
- **Wrong signer:** Use the correct key (e.g., supply key for minting).
177+
- **Ignoring receipt:** Always check status; don't assume success.
178+
- **Auto-freeze/sign:** Works for simple transactions but can hide issues in complex ones.
179+
- **Order dependency:** Construct → Freeze → Sign → Execute → Receipt.
180+
181+
For more details, refer to the SDK documentation or community calls on [Discord](https://github.com/hiero-ledger/hiero-sdk-python/blob/main/docs/discord.md).
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## Supporting Infrastructure When Developing for the Python SDK
2+
3+
For the best development experience and smoother support, we strongly recommend installing the following tools when developing for the Python SDK:
4+
5+
Recommended Tools
6+
- [ ] GitHub Desktop
7+
- [ ] Visual Studio Code
8+
- [ ] Pylance
9+
- [ ] GitHub Copilot
10+
11+
However, what may work best for you might be different.
12+
13+
### Github Desktop
14+
GitHub Desktop is a free, user-friendly application that provides a visual interface for Git and GitHub. Instead of running Git commands in a terminal, GitHub Desktop lets you perform common tasks through an intuitive UI.
15+
16+
It allows you to:
17+
- Clone, fork, and manage repositories without using the command line
18+
- Easily create and switch branches
19+
- Visualize commit history and branches in a clear, interactive timeline
20+
- Stage and push local changes with a click
21+
- Resolve merge conflicts with guided prompts
22+
23+
Overall, GitHub Desktop makes Git simpler, safer, and more visual, which is great for maintaining clean, branched pull requests and staying aligned with the rest of the Python SDK team.
24+
25+
### VS Studio Code
26+
VS Code is a workpace that enables:
27+
28+
- Easy project navigation
29+
- Easy file organisation
30+
- Access to a large ecosystem of extensions that plug-in, including Pylance and Github Copilot
31+
32+
It’s the recommended editor for working within this SDK.
33+
34+
#### Pylance
35+
Pylance is a high-performance language server for Python that:
36+
37+
- Improves code quality
38+
- Identifies errors early
39+
- Helps you resolve issues faster
40+
41+
For example, Pylance will underline this in red indicating it is incorrect with a reason:
42+
```python
43+
from hiero_sdk_python.account.token_id import TokenId
44+
```
45+
This is incorrect because token_id.py does not live in /account! Instead, it lives in /tokens
46+
47+
Read our [Pylance Installation Guide](../../pylance.md)
48+
49+
#### Github Copilot
50+
Github Copilot is an AI coding-assistant tool.
51+
52+
GitHub Copilot supports your workflow by:
53+
- Suggesting code snippets and patterns
54+
- Helping predict correct imports
55+
- Maintaining consistent naming and formatting
56+
- Speeding up development
57+
58+
Additionally, since we have Copilot enabled as an automatic reviewer, once you enable Copilot as a reviewer, it will review your pull requests submitted to the Python SDK. This helps maintainers merge changes more quickly and is a great benefit to the project.
59+
60+
61+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Forking the Python SDK
2+
3+
To begin contributing to the Python SDK, you’ll first need your own copy of the repository.
4+
5+
Forking creates a personal, editable version of the SDK under your own GitHub account, where you can safely experiment and prepare pull requests without impacting the Python SDK.
6+
7+
### Steps to Fork the Python SDK
8+
9+
1. Navigate to the Python SDK Repository
10+
11+
Open the [Official Python SDK repository on GitHub](https://github.com/hiero-ledger/hiero-sdk-python)
12+
13+
2. Create Your Fork
14+
Make sure you are logged in to Github. Then, in the top-right of the repository page, click Fork.
15+
16+
GitHub will prompt you to confirm:
17+
- The destination account (your profile)
18+
- The name you want to give your fork (you can keep the default)
19+
20+
Click Create fork.
21+
22+
Your new fork will appear at:
23+
`https://github.com/<your-username>/<repository-name>`
24+
This is your copy of the Python SDK. You can also access it from your repository section on github online.
25+
26+
27+
3. Clone Your Fork Locally
28+
29+
You now have an online copy of the Python SDK but you also need a local copy to work on the code.
30+
31+
Using GitHub Desktop (recommended):
32+
1. Open GitHub Desktop.
33+
2. Go to File → Clone Repository
34+
3. Select the fork you just created under the “Your Repositories” tab.
35+
4. Choose a folder location on your machine and click Clone.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## Syncing Your Repo with the Upstream Python SDK
2+
3+
Development at the Python SDK can be fast meaning new changes are added frequently.
4+
5+
It is important to frequently pull new changes at the Python SDK to your local repository to ensure you are working on the most updated code and avoid merge_conflicts.
6+
7+
To do this:
8+
9+
1. Link the Upstream Python SDK Remote with yours
10+
Link your fork to the upstream original Python SDK repository so you can easily bring in new updates from main.
11+
12+
```bash
13+
git remote add upstream https://github.com/hiero-ledger/hiero-sdk-python.git
14+
```
15+
16+
Then verify it is correctly set:
17+
```bash
18+
git remote -v
19+
```
20+
21+
You should now see:
22+
origin → your fork
23+
upstream → the official Python SDK repo
24+
25+
2. Before starting work and during a pull request, always fetch new changes:
26+
git checkout main
27+
git fetch upstream
28+
git pull upstream main
29+
30+
Then rebase on your working branch to apply the new changes:
31+
git checkout mybranch
32+
git rebase main -S
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## Getting Assigned to an Issue
2+
3+
It is important to be assigned an issue before starting work on it or creating a pull request.
4+
5+
We recommend Good First Issues for developers new to the Python SDK. These are easier and better documented tasks.
6+
7+
To do that,
8+
1. Select a `Good First Issue` that interests you and is not yet assigned at [Python SDK Issues](https://github.com/hiero-ledger/hiero-sdk-python/issues)
9+
2. Write a comment at the bottom of the issue page asking "I want to be assigned to this issue"
10+
3. A maintainer will shortly assign you to the issue
11+
12+
Congratulations! You are assigned and can now get started on the work.

0 commit comments

Comments
 (0)