Skip to content

Commit b4d41cc

Browse files
authored
Merge branch 'main' into pr970-signed
2 parents 1361ff9 + 524f0d0 commit b4d41cc

File tree

7 files changed

+557
-53
lines changed

7 files changed

+557
-53
lines changed

.github/scripts/linked_issue_enforce.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const isAuthorAssigned = (issue, login) => {
1717

1818
const baseMessage = `Hi there! I'm the LinkedIssueBot.\nThis pull request has been automatically closed due to the following reason(s):
1919
`;
20-
const messageSuffix = `Please read - [Creating Issues](docs/sdk_developers/creating_issues.md) - [How To Link Issues](docs/sdk_developers/how_to_link_issues.md)\n\nThank you,
20+
const messageSuffix = `Please read - [Creating Issues](docs/sdk_developers/creating_issues.md) - [How To Link Issues Workflow](docs/sdk_developers/training/workflow/how_to_link_issues.md)\n\nThank you,
2121
From Python SDK team`
2222

2323
const messages = {

.github/scripts/pr_missing_linked_issue.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ module.exports = async ({ github, context }) => {
3232
`- Fixes #123`,
3333
``,
3434
`📖 Guide:`,
35-
`docs/sdk_developers/how_to_link_issues.md`,
35+
`docs/sdk_developers/training/workflow/how_to_link_issues.md`,
3636
``,
3737
`If no issue exists yet, please create one:`,
3838
`docs/sdk_developers/creating_issues.md`,

CHANGELOG.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
66

77
## [Unreleased]
88

9-
10-
119
### Added
10+
11+
- Added Hbar object support for TransferTransaction HBAR transfers:
12+
- Methods now accept `Union[int, Hbar]` for amount parameters with immediate normalization to tinybars
13+
- Includes comprehensive unit tests covering various Hbar units (HBAR, MICROBAR, NANOBAR, TINYBAR) and accumulation behavior with mixed `int` and `Hbar` inputs
1214
- Added a module-level docstring to the HBAR allowance approval example to clarify
1315
delegated spending behavior and key concepts. [#1202](https://github.com/hiero-ledger/hiero-sdk-python/issues/1202)
1416
- Added a GitHub Actions workflow to validate broken Markdown links in pull requests.
@@ -28,7 +30,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
2830
- Added unit tests for `SubscriptionHandle` class covering cancellation state, thread management, and join operations.
2931
- Refactored `account_create_transaction_create_with_alias.py` example by splitting monolithic function into modular functions: `generate_main_and_alias_keys()`, `create_account_with_ecdsa_alias()`, `fetch_account_info()`, `print_account_summary()` (#1016)
3032
- Added `.github/workflows/bot-pr-auto-draft-on-changes.yml` to automatically convert PRs to draft and notify authors when reviewers request changes.
31-
-
33+
-
3234
- Modularized `transfer_transaction_fungible` example by introducing `account_balance_query()` & `transfer_transaction()`.Renamed `transfer_tokens()``main()`
3335
- Phase 2 of the inactivity-unassign bot: Automatically detects stale open pull requests (no commit activity for 21+ days), comments with a helpful InactivityBot message, closes the stale PR, and unassigns the contributor from the linked issue.
3436
- Added `__str__()` to CustomFixedFee and updated examples and tests accordingly.
@@ -48,7 +50,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
4850
- Support selecting specific node account ID(s) for queries and transactions and added `Network._get_node()` with updated execution flow (#362)
4951
- Add TLS support with two-stage control (`set_transport_security()` and `set_verify_certificates()`) for encrypted connections to Hedera networks. TLS is enabled by default for hosted networks (mainnet, testnet, previewnet) and disabled for local networks (solo, localhost) (#855)
5052
- Add PR inactivity reminder bot for stale pull requests `.github/workflows/pr-inactivity-reminder-bot.yml`
51-
- Add comprehensive training documentation for _Executable class `docs/sdk_developers/training/executable.md`
53+
- Add comprehensive training documentation for \_Executable class `docs/sdk_developers/training/executable.md`
5254
- Added empty `docs/maintainers/good_first_issues.md` file for maintainers to write Good First Issue guidelines (#1034)
5355
- Added new `.github/ISSUE_TEMPLATE/04_good_first_issue_candidate.yml` file (1068)(https://github.com/hiero-ledger/hiero-sdk-python/issues/1068)
5456
- Enhanced `.github/ISSUE_TEMPLATE/01_good_first_issue.yml` with welcoming message and acceptance criteria sections to guide contributors in creating quality GFIs (#1052)
@@ -57,17 +59,18 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
5759
- Add support for include_children in TransactionGetReceiptQuery (#1100)(https://github.com/hiero-ledger/hiero-sdk-python/issues/1100)
5860
- Add new `.github/ISSUE_TEMPLATE/05_intermediate_issue.yml` file (1072)(https://github.com/hiero-ledger/hiero-sdk-python/issues/1072)
5961
- Add a workflow to notify the team when issues are labeled as “good first issues” or identified as candidates for that label: `bot-gfi-notify-team.yml`(#1115)
60-
- Added __str__ and __repr__ to AccountBalance
62+
- Added **str** and **repr** to AccountBalance
6163
- Added GitHub workflow that makes sure newly added test files follow pytest test files naming conventions (#1054)
6264
- Added advanced issue template for contributors `.github/ISSUE_TEMPLATE/06_advanced_issue.yml`.
6365
- Add new tests to `tests/unit/topic_info_query_test.py` (#1124)
6466
- Added `coding_token_transactions.md` for a high level overview training on how token transactions are created in the python sdk.
65-
- Added prompt for codeRabbit on how to review /examples ([#1180](https://github.com/hiero-ledger/hiero-sdk-python/issues/1180))
67+
- Added prompt for codeRabbit on how to review /examples ([#1180](https://github.com/hiero-ledger/hiero-sdk-python/issues/1180))
6668
- Add Linked Issue Enforcer to automatically close PRs without linked issues `.github/workflows/bot-linked-issue-enforcer.yml`.
6769
- Added support for include duplicates in get transaction receipt query (#1166)
6870
- Added `.github/workflows/cron-check-broken-links.yml` workflow to perform scheduled monthly Markdown link validation across the entire repository with automatic issue creation for broken links ([#1210](https://github.com/hiero-ledger/hiero-sdk-python/issues/1210))
6971

7072
### Changed
73+
- Moved `docs/sdk_developers/how_to_link_issues.md` to `docs/sdk_developers/training/workflow/how_to_link_issues.md` and updated all references (#1222)
7174
- Moved docs/sdk_developers/project_structure.md to docs/sdk_developers/training/setup/project_structure.md and ensured all previous references are updated [#1223](https://github.com/hiero-ledger/hiero-sdk-python/issues/1223)
7275
- Renamed workflow scripts in `.github/scripts/` to match their corresponding workflow file names for improved consistency and maintainability (#1198)
7376
- Refactored `account_create_transaction_evm_alias.py` to improve readability by splitting the monolithic function into smaller helper functions. [#1017](https://github.com/hiero-ledger/hiero-sdk-python/issues/1017)
@@ -92,21 +95,20 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
9295
- Cleaned up `token_airdrop_claim_auto` example for pylint compliance (no functional changes). (#1079)
9396
- Formatted `examples/query` using black (#1082)(https://github.com/hiero-ledger/hiero-sdk-python/issues/1082)
9497
- Update team notification script and workflow for P0 issues 'p0_issues_notify_team.js'
95-
- Rename test files across the repository to ensure they consistently end with _test.py (#1055)
98+
- Rename test files across the repository to ensure they consistently end with \_test.py (#1055)
9699
- Cleaned up `token_airdrop_claim_signature_required` example for pylint compliance (no functional changes). (#1080)
97-
- Rename the file 'test_token_fee_schedule_update_transaction_e2e.py' to make it ends with _test.py as all other test files.(#1117)
100+
- Rename the file 'test_token_fee_schedule_update_transaction_e2e.py' to make it ends with \_test.py as all other test files.(#1117)
98101
- Format token examples with Black for consistent code style and improved readability (#1119)
99102
- Transformed `examples/tokens/custom_fee_fixed.py` to be an end-to-end example, that interacts with the Hedera network, rather than a static object demo.
100-
- Format token examples with Black for consistent code style and improved readability (#1119)
101-
- Replaced `ResponseCode.get_name(receipt.status)` with the `ResponseCode(receipt.status).name` across examples and integration tests for consistency. (#1136)
103+
- Format token examples with Black for consistent code style and improved readability (#1119)
104+
- Replaced `ResponseCode.get_name(receipt.status)` with the `ResponseCode(receipt.status).name` across examples and integration tests for consistency. (#1136)
102105
- Moved helpful references to Additional Context section and added clickable links.
103106
- Transformed `examples\tokens\custom_royalty_fee.py` to be an end-to-end example, that interacts with the Hedera network, rather than a static object demo.
104107
- Refactored `examples/tokens/custom_royalty_fee.py` by splitting monolithic function custom_royalty_fee_example() into modular functions create_royalty_fee_object(), create_token_with_fee(), verify_token_fee(), and main() to improve readability, cleaned up setup_client() (#1169)
105108
- Added comprehensive unit tests for Timestamp class (#1158)
106109
- Enhance unit and integration test review instructions for clarity and coverage `.coderabbit.yaml`.
107110
- Issue reminder bot now explicitly mentions assignees (e.g., `@user`) in comments. ([#1232](https://github.com/hiero-ledger/hiero-sdk-python/issues/1232))
108111

109-
110112
### Fixed
111113

112114
- Fix token association verification in `token_airdrop_transaction.py` to correctly check if tokens are associated by using `token_id in token_balances` instead of incorrectly displaying zero balances which was misleading (#[815])
@@ -120,7 +122,6 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
120122
- Fixed `cron-check-broken-links.yml` string parsing issue in context input `dry_run` (#1235)
121123
- Flaky tests by disabling TLS in mock Hedera nodes in `mock_server.py`
122124

123-
124125
### Breaking Change
125126

126127
- Remove deprecated 'in_tinybars' parameter and update related tests `/src/hiero_sdk_python/hbar.py`, `/tests/unit/hbar_test.py` and `/src/hiero_sdk_python/tokens/custom_fixed_fee.py`.
@@ -686,4 +687,3 @@ contract_call_local_pb2.ContractLoginfo -> contract_types_pb2.ContractLoginfo
686687
### Removed
687688

688689
- N/A
689-
File renamed without changes.

src/hiero_sdk_python/transaction/transfer_transaction.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
Defines TransferTransaction for transferring HBAR or tokens between accounts.
33
"""
44

5-
from typing import Dict, List, Optional, Tuple
5+
from typing import Dict, List, Optional, Tuple, Union
66

77
from hiero_sdk_python.account.account_id import AccountId
88
from hiero_sdk_python.channels import _Channel
99
from hiero_sdk_python.executable import _Method
10+
from hiero_sdk_python.hbar import Hbar
1011
from hiero_sdk_python.hapi.services import basic_types_pb2, crypto_transfer_pb2, transaction_pb2
1112
from hiero_sdk_python.hapi.services.schedulable_transaction_body_pb2 import (
1213
SchedulableTransactionBody,
@@ -29,7 +30,8 @@ def __init__(
2930
self,
3031
hbar_transfers: Optional[Dict[AccountId, int]] = None,
3132
token_transfers: Optional[Dict[TokenId, Dict[AccountId, int]]] = None,
32-
nft_transfers: Optional[Dict[TokenId, List[Tuple[AccountId, AccountId, int, bool]]]] = None,
33+
nft_transfers: Optional[Dict[TokenId,
34+
List[Tuple[AccountId, AccountId, int, bool]]]] = None,
3335
) -> None:
3436
"""
3537
Initializes a new TransferTransaction instance.
@@ -59,14 +61,14 @@ def _init_hbar_transfers(self, hbar_transfers: Dict[AccountId, int]) -> None:
5961
self.add_hbar_transfer(account_id, amount)
6062

6163
def _add_hbar_transfer(
62-
self, account_id: AccountId, amount: int, is_approved: bool = False
64+
self, account_id: AccountId, amount: Union[int, Hbar], is_approved: bool = False
6365
) -> "TransferTransaction":
6466
"""
6567
Internal method to add a HBAR transfer to the transaction.
6668
6769
Args:
6870
account_id (AccountId): The account ID of the sender or receiver.
69-
amount (int): The amount of the HBAR to transfer.
71+
amount (Union[int, Hbar]): The amount of the HBAR to transfer.
7072
is_approved (bool, optional): Whether the transfer is approved. Defaults to False.
7173
7274
Returns:
@@ -75,8 +77,12 @@ def _add_hbar_transfer(
7577
self._require_not_frozen()
7678
if not isinstance(account_id, AccountId):
7779
raise TypeError("account_id must be an AccountId instance.")
78-
if not isinstance(amount, int) or amount == 0:
79-
raise ValueError("Amount must be a non-zero integer.")
80+
if isinstance(amount, Hbar):
81+
amount = amount.to_tinybars()
82+
elif not isinstance(amount, int):
83+
raise TypeError("amount must be an int or Hbar instance.")
84+
if amount == 0:
85+
raise ValueError("Amount must be a non-zero value.")
8086
if not isinstance(is_approved, bool):
8187
raise TypeError("is_approved must be a boolean.")
8288

@@ -85,16 +91,17 @@ def _add_hbar_transfer(
8591
transfer.amount += amount
8692
return self
8793

88-
self.hbar_transfers.append(HbarTransfer(account_id, amount, is_approved))
94+
self.hbar_transfers.append(
95+
HbarTransfer(account_id, amount, is_approved))
8996
return self
9097

91-
def add_hbar_transfer(self, account_id: AccountId, amount: int) -> "TransferTransaction":
98+
def add_hbar_transfer(self, account_id: AccountId, amount: Union[int, Hbar]) -> "TransferTransaction":
9299
"""
93100
Adds a HBAR transfer to the transaction.
94101
95102
Args:
96103
account_id (AccountId): The account ID of the sender or receiver.
97-
amount (int): The amount of the HBAR to transfer.
104+
amount (Union[int, Hbar]): The amount of the HBAR to transfer.
98105
99106
Returns:
100107
TransferTransaction: The current instance of the transaction for chaining.
@@ -103,14 +110,14 @@ def add_hbar_transfer(self, account_id: AccountId, amount: int) -> "TransferTran
103110
return self
104111

105112
def add_approved_hbar_transfer(
106-
self, account_id: AccountId, amount: int
113+
self, account_id: AccountId, amount: Union[int, Hbar]
107114
) -> "TransferTransaction":
108115
"""
109116
Adds a HBAR transfer with approval to the transaction.
110117
111118
Args:
112119
account_id (AccountId): The account ID of the sender or receiver.
113-
amount (int): The amount of the HBAR to transfer.
120+
amount (Union[int, Hbar]): The amount of the HBAR to transfer.
114121
115122
Returns:
116123
TransferTransaction: The current instance of the transaction for chaining.
@@ -190,7 +197,8 @@ def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
190197

191198
if crypto_transfer.HasField("transfers"):
192199
for account_amount in crypto_transfer.transfers.accountAmounts:
193-
account_id = AccountId._from_proto(account_amount.accountID)
200+
account_id = AccountId._from_proto(
201+
account_amount.accountID)
194202
amount = account_amount.amount
195203
is_approved = account_amount.is_approval
196204
transaction.hbar_transfers.append(
@@ -210,17 +218,21 @@ def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
210218
expected_decimals = token_transfer_list.expected_decimals.value
211219

212220
transaction.token_transfers[token_id].append(
213-
TokenTransfer(token_id, account_id, amount, expected_decimals, is_approved)
221+
TokenTransfer(token_id, account_id, amount,
222+
expected_decimals, is_approved)
214223
)
215224

216225
for nft_transfer in token_transfer_list.nftTransfers:
217-
sender_id = AccountId._from_proto(nft_transfer.senderAccountID)
218-
receiver_id = AccountId._from_proto(nft_transfer.receiverAccountID)
226+
sender_id = AccountId._from_proto(
227+
nft_transfer.senderAccountID)
228+
receiver_id = AccountId._from_proto(
229+
nft_transfer.receiverAccountID)
219230
serial_number = nft_transfer.serialNumber
220231
is_approved = nft_transfer.is_approval
221232

222233
transaction.nft_transfers[token_id].append(
223-
TokenNftTransfer(token_id, sender_id, receiver_id, serial_number, is_approved)
234+
TokenNftTransfer(
235+
token_id, sender_id, receiver_id, serial_number, is_approved)
224236
)
225237

226238
return transaction

0 commit comments

Comments
 (0)