Skip to content

Commit 753fae7

Browse files
authored
feat: Add convenient factory methods for Hbar units (#1277)
Signed-off-by: Adityarya11 <arya050411@gmail.com> Signed-off-by: notsogod <149138960+Adityarya11@users.noreply.github.com>
1 parent dbb49d4 commit 753fae7

File tree

4 files changed

+121
-2
lines changed

4 files changed

+121
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
7272
- Added `transfer_transaction_tinybar.py` example demonstrating tinybar transfers with both integer and Hbar object approaches. ([#1249](https://github.com/hiero-ledger/hiero-sdk-python/issues/1249))
7373
- Added `transfer_transaction_gigabar.py` example demonstrating `GIGABAR` unit usage for large-value transfers. ([#1249](https://github.com/hiero-ledger/hiero-sdk-python/issues/1249))
7474
- Coderabbit prompt for .github
75+
- Added convenient factory methods to `Hbar` class for easier instantiation: `from_microbars()`, `from_millibars()`, `from_hbars()`, `from_kilobars()`, `from_megabars()`, and `from_gigabars()`. [#1272](https://github.com/hiero-ledger/hiero-sdk-python/issues/1272)
7576
- Added merge conflict bot workflow (`.github/workflows/bot-merge-conflict.yml`) and helper script (`.github/scripts/bot-merge-conflict.js`) to detect and notify about PR merge conflicts, with retry logic for unknown mergeable states, idempotent commenting, and push-to-main recheck logic (#1247)
7677
- Added workflow to prevent assigning intermediate issues to contributors without prior Good First Issue completion (#1143).
7778

examples/hbar.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@
66
from hiero_sdk_python.hbar import Hbar
77
from hiero_sdk_python.hbar_unit import HbarUnit
88

9+
def demonstrate_factory_methods():
10+
"""
11+
Demonstrates creating Hbar values using the convenient factory methods.
12+
"""
13+
print("\n=== Creating Hbar Using Factory Methods ===")
14+
15+
# Creates an Hbar object representing 1 Gigabar (1,000,000,000 ℏ)
16+
h_giga = Hbar.from_gigabars(1)
17+
18+
# Creates an Hbar object representing 500 Millibars (0.5 ℏ)
19+
h_milli = Hbar.from_millibars(500)
20+
21+
# Creates an Hbar object representing 10.5 Hbars (10.5 ℏ)
22+
h_standard = Hbar.from_hbars(10.5)
23+
24+
print(f"Hbar.from_gigabars(1): {h_giga}")
25+
print(f"Hbar.from_millibars(500): {h_milli}")
26+
print(f"Hbar.from_hbars(10.5): {h_standard}")
27+
928
def create_hbar_using_constructor():
1029
"""
1130
Demonstrates creating Hbar values using the constructor.
@@ -144,7 +163,7 @@ def run_example():
144163
demonstrate_conversion_methods()
145164
demonstrate_negation()
146165
demonstrate_constants()
147-
166+
demonstrate_factory_methods()
148167

149168
if __name__ == "__main__":
150169
run_example()

src/hiero_sdk_python/hbar.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,54 @@ def from_tinybars(cls, tinybars: int) -> "Hbar":
107107
if not isinstance(tinybars, int):
108108
raise TypeError("tinybars must be an int.")
109109
return cls(tinybars, unit=HbarUnit.TINYBAR)
110+
111+
@classmethod
112+
def from_microbars(cls, amount: Union[int, float, Decimal]) -> "Hbar":
113+
"""
114+
Create an Hbar object representing the specified amount of microbars.
115+
Example: Hbar.from_microbars(100) -> 100 μℏ
116+
"""
117+
return cls(amount, unit=HbarUnit.MICROBAR)
118+
119+
@classmethod
120+
def from_millibars(cls, amount: Union[int, float, Decimal]) -> "Hbar":
121+
"""
122+
Create an Hbar object representing the specified amount of millibars.
123+
Example: Hbar.from_millibars(500) -> 500 mℏ
124+
"""
125+
return cls(amount, unit=HbarUnit.MILLIBAR)
126+
127+
@classmethod
128+
def from_hbars(cls, amount: Union[int, float, Decimal]) -> "Hbar":
129+
"""
130+
Create an Hbar object representing the specified amount of hbars.
131+
Example: Hbar.from_hbars(10) -> 10 ℏ
132+
"""
133+
return cls(amount, unit=HbarUnit.HBAR)
134+
135+
@classmethod
136+
def from_kilobars(cls, amount: Union[int, float, Decimal]) -> "Hbar":
137+
"""
138+
Create an Hbar object representing the specified amount of kilobars.
139+
Example: Hbar.from_kilobars(1) -> 1 kℏ
140+
"""
141+
return cls(amount, unit=HbarUnit.KILOBAR)
142+
143+
@classmethod
144+
def from_megabars(cls, amount: Union[int, float, Decimal]) -> "Hbar":
145+
"""
146+
Create an Hbar object representing the specified amount of megabars.
147+
Example: Hbar.from_megabars(1) -> 1 Mℏ
148+
"""
149+
return cls(amount, unit=HbarUnit.MEGABAR)
150+
151+
@classmethod
152+
def from_gigabars(cls, amount: Union[int, float, Decimal]) -> "Hbar":
153+
"""
154+
Create an Hbar object representing the specified amount of gigabars.
155+
Example: Hbar.from_gigabars(1) -> 1 Gℏ
156+
"""
157+
return cls(amount, unit=HbarUnit.GIGABAR)
110158

111159
@classmethod
112160
def from_string(cls, amount: str, unit: HbarUnit = HbarUnit.HBAR) -> "Hbar":

tests/unit/hbar_test.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,55 @@ def test_comparison():
149149
# Comparison without Hbar returns NotImplemented
150150
assert (h1 == 5) is False
151151
with pytest.raises(TypeError):
152-
_ = h1 < 5
152+
_ = h1 < 5
153+
154+
def test_factory_methods():
155+
"""Test the convenient from_X factory methods."""
156+
157+
# from_microbars
158+
# 1 microbar = 100 tinybars
159+
result = Hbar.from_microbars(1)
160+
assert isinstance(result, Hbar)
161+
assert result.to_tinybars() == 100
162+
assert Hbar.from_microbars(1.5).to_tinybars() == 150
163+
assert Hbar.from_microbars(Decimal("2.5")).to_tinybars() == 250
164+
assert Hbar.from_microbars(0).to_tinybars() == 0
165+
assert Hbar.from_microbars(-10).to_tinybars() == -1_000
166+
# Verify equivalence with constructor
167+
assert Hbar.from_microbars(5) == Hbar(5, unit=HbarUnit.MICROBAR)
168+
169+
# from_millibars
170+
# 1 millibar = 100,000 tinybars
171+
assert Hbar.from_millibars(1).to_tinybars() == 100_000
172+
assert Hbar.from_millibars(0).to_tinybars() == 0
173+
assert Hbar.from_millibars(-5).to_tinybars() == -500_000
174+
assert Hbar.from_millibars(Decimal("1.5")).to_tinybars() == 150_000
175+
176+
# from_hbars
177+
# 1 hbar = 100,000,000 tinybars
178+
assert Hbar.from_hbars(1).to_tinybars() == 100_000_000
179+
assert Hbar.from_hbars(0.00000001).to_tinybars() == 1
180+
assert Hbar.from_hbars(0).to_tinybars() == 0
181+
assert Hbar.from_hbars(-10).to_tinybars() == -1_000_000_000
182+
assert Hbar.from_hbars(Decimal("5.5")).to_tinybars() == 550_000_000
183+
184+
# from_kilobars
185+
# 1 kilobar = 1,000 hbars
186+
assert Hbar.from_kilobars(1).to_hbars() == 1_000
187+
assert Hbar.from_kilobars(0).to_hbars() == 0
188+
assert Hbar.from_kilobars(-2).to_hbars() == -2_000
189+
assert Hbar.from_kilobars(1).to_tinybars() == 100_000_000_000
190+
191+
# from_megabars
192+
# 1 megabar = 1,000,000 hbars
193+
assert Hbar.from_megabars(1).to_hbars() == 1_000_000
194+
assert Hbar.from_megabars(0).to_hbars() == 0
195+
assert Hbar.from_megabars(-1).to_hbars() == -1_000_000
196+
assert Hbar.from_megabars(1).to_tinybars() == 100_000_000_000_000
197+
198+
# from_gigabars
199+
# 1 gigabar = 1,000,000,000 hbars
200+
assert Hbar.from_gigabars(1).to_hbars() == 1_000_000_000
201+
assert Hbar.from_gigabars(0).to_hbars() == 0
202+
assert Hbar.from_gigabars(-1).to_hbars() == -1_000_000_000
203+
assert Hbar.from_gigabars(1).to_tinybars() == 100_000_000_000_000_000

0 commit comments

Comments
 (0)