From eaedf732268ea589c2d1d474fdb8449e991c4720 Mon Sep 17 00:00:00 2001 From: Mostafa Date: Sun, 23 Nov 2025 23:08:39 +0800 Subject: [PATCH 1/6] feat: define str for amount type --- examples/example_bls_multisig.py | 6 +-- examples/example_key_generation.py | 8 ++-- examples/example_transfer_transaction_bls.py | 10 ++-- .../example_transfer_transaction_ed25519.py | 10 ++-- pactus/crypto/__init__.py | 7 +++ pactus/crypto/bls/__init__.py | 6 +++ pactus/crypto/ed25519/__init__.py | 6 +++ pactus/crypto/hrp.py | 8 +++- pactus/transaction/__init__.py | 6 +++ pactus/transaction/_payload.py | 2 +- pactus/transaction/transaction.py | 2 +- pactus/types/__init__.py | 0 pactus/{ => types}/amount.py | 6 +++ tests/test_amount.py | 46 ++++++++++++++++++- tests/test_crypto_bls.py | 6 +-- tests/test_crypto_ed25519.py | 6 +-- tests/test_transaction.py | 6 +-- 17 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 pactus/types/__init__.py rename pactus/{ => types}/amount.py (93%) diff --git a/examples/example_bls_multisig.py b/examples/example_bls_multisig.py index 5dc96b8..436ab33 100644 --- a/examples/example_bls_multisig.py +++ b/examples/example_bls_multisig.py @@ -1,6 +1,6 @@ -from pactus.crypto.bls.private_key import PrivateKey -from pactus.crypto.bls.public_key import PublicKey -from pactus.crypto.bls.signature import Signature +from pactus.crypto.bls import PrivateKey +from pactus.crypto.bls import PublicKey +from pactus.crypto.bls import Signature def main() -> None: diff --git a/examples/example_key_generation.py b/examples/example_key_generation.py index 952176a..9f36146 100644 --- a/examples/example_key_generation.py +++ b/examples/example_key_generation.py @@ -2,10 +2,10 @@ from pactus.crypto.hrp import HRP from pactus.crypto.address import AddressType -from pactus.crypto.bls.private_key import PrivateKey as BLSPrivateKey -from pactus.crypto.ed25519.private_key import PrivateKey as Ed25519PrivateKey -from pactus.crypto.private_key import PrivateKey -from pactus.crypto.public_key import PublicKey +from pactus.crypto.bls import PrivateKey as BLSPrivateKey +from pactus.crypto.ed25519 import PrivateKey as Ed25519PrivateKey +from pactus.crypto import PrivateKey +from pactus.crypto import PublicKey from pactus.crypto.address import Address diff --git a/examples/example_transfer_transaction_bls.py b/examples/example_transfer_transaction_bls.py index 18f1b4c..57f9dea 100644 --- a/examples/example_transfer_transaction_bls.py +++ b/examples/example_transfer_transaction_bls.py @@ -1,8 +1,8 @@ -from pactus.crypto.hrp import HRP -from pactus.crypto.address import Address -from pactus.crypto.bls.private_key import PrivateKey -from pactus.transaction.transaction import Transaction -from pactus.amount import Amount +from pactus.crypto import HRP +from pactus.crypto import Address +from pactus.crypto.bls import PrivateKey +from pactus.transaction import Transaction +from pactus.types.amount import Amount def main() -> None: diff --git a/examples/example_transfer_transaction_ed25519.py b/examples/example_transfer_transaction_ed25519.py index 614797d..0d1f3c8 100644 --- a/examples/example_transfer_transaction_ed25519.py +++ b/examples/example_transfer_transaction_ed25519.py @@ -1,8 +1,8 @@ -from pactus.crypto.hrp import HRP -from pactus.crypto.address import Address -from pactus.crypto.ed25519.private_key import PrivateKey -from pactus.transaction.transaction import Transaction -from pactus.amount import Amount +from pactus.crypto import HRP +from pactus.crypto import Address +from pactus.crypto.ed25519 import PrivateKey +from pactus.transaction import Transaction +from pactus.types.amount import Amount def main() -> None: diff --git a/pactus/crypto/__init__.py b/pactus/crypto/__init__.py index e69de29..6b76b41 100644 --- a/pactus/crypto/__init__.py +++ b/pactus/crypto/__init__.py @@ -0,0 +1,7 @@ +from .address import Address, AddressType +from .hrp import HRP + +__all__ = ["Address", "AddressType", "HRP"] + + + diff --git a/pactus/crypto/bls/__init__.py b/pactus/crypto/bls/__init__.py index e69de29..0281170 100644 --- a/pactus/crypto/bls/__init__.py +++ b/pactus/crypto/bls/__init__.py @@ -0,0 +1,6 @@ +from .private_key import PrivateKey +from .public_key import PublicKey +from .signature import Signature, SIGNATURE_TYPE_BLS, DST + +__all__ = ["PrivateKey", "PublicKey", "Signature", "SIGNATURE_TYPE_BLS", "DST"] + diff --git a/pactus/crypto/ed25519/__init__.py b/pactus/crypto/ed25519/__init__.py index e69de29..7af56f0 100644 --- a/pactus/crypto/ed25519/__init__.py +++ b/pactus/crypto/ed25519/__init__.py @@ -0,0 +1,6 @@ +from .private_key import PrivateKey +from .public_key import PublicKey +from .signature import Signature, SIGNATURE_TYPE_ED25519 + +__all__ = ["PrivateKey", "PublicKey", "Signature", "SIGNATURE_TYPE_ED25519"] + diff --git a/pactus/crypto/hrp.py b/pactus/crypto/hrp.py index 877856a..7ee064f 100644 --- a/pactus/crypto/hrp.py +++ b/pactus/crypto/hrp.py @@ -3,8 +3,14 @@ class HRP: PUBLIC_KEY_HRP = "public" PRIVATE_KEY_HRP = "secret" + @classmethod + def use_mainnet(cls) -> None: + cls.ADDRESS_HRP = "pc" + cls.PUBLIC_KEY_HRP = "public" + cls.PRIVATE_KEY_HRP = "secret" + @classmethod def use_testnet(cls) -> None: cls.ADDRESS_HRP = "tpc" cls.PUBLIC_KEY_HRP = "tpublic" - cls.PRIVATE_KEY_HRP = "tsecret" + cls.PRIVATE_KEY_HRP = "tsecret" \ No newline at end of file diff --git a/pactus/transaction/__init__.py b/pactus/transaction/__init__.py index e69de29..cade590 100644 --- a/pactus/transaction/__init__.py +++ b/pactus/transaction/__init__.py @@ -0,0 +1,6 @@ +from .transaction import Transaction + +__all__ = ["Transaction"] + + + diff --git a/pactus/transaction/_payload.py b/pactus/transaction/_payload.py index b5e348d..58f231b 100644 --- a/pactus/transaction/_payload.py +++ b/pactus/transaction/_payload.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from enum import Enum -from pactus.amount import Amount +from pactus.types.amount import Amount from pactus.crypto.address import Address from pactus.encoding import encoding diff --git a/pactus/transaction/transaction.py b/pactus/transaction/transaction.py index fba2459..352637c 100644 --- a/pactus/transaction/transaction.py +++ b/pactus/transaction/transaction.py @@ -1,4 +1,4 @@ -from pactus.amount import Amount +from pactus.types.amount import Amount from pactus.crypto.address import Address from pactus.crypto.private_key import PrivateKey from pactus.crypto.public_key import PublicKey diff --git a/pactus/types/__init__.py b/pactus/types/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pactus/amount.py b/pactus/types/amount.py similarity index 93% rename from pactus/amount.py rename to pactus/types/amount.py index def8a40..011abd6 100644 --- a/pactus/amount.py +++ b/pactus/types/amount.py @@ -29,6 +29,11 @@ def __eq__(self, other: "Amount") -> bool: def __hash__(self) -> int: return hash(self.value) + def __str__(self) -> str: + """Return a string representation of the amount in PAC.""" + pac_value = self.value / NANO_PAC_PER_PAC + return f"{pac_value} PAC" + @classmethod def from_nano_pac(cls, a: int) -> "Amount": """Store the value as NanoPAC in the Amount instance.""" @@ -76,3 +81,4 @@ def round(self: float) -> float: return self - 0.5 return self + 0.5 + diff --git a/tests/test_amount.py b/tests/test_amount.py index 0bb8826..6333943 100644 --- a/tests/test_amount.py +++ b/tests/test_amount.py @@ -1,6 +1,6 @@ import unittest -from pactus.amount import NANO_PAC_PER_PAC, Amount +from pactus.types.amount import NANO_PAC_PER_PAC, Amount class TestAmount(unittest.TestCase): @@ -61,6 +61,50 @@ def test_from_string(self): amt = Amount.from_string(case["input"]) self.assertEqual(amt, case["expected"]) + def test_str(self): + test_cases = [ + { + "input": Amount(0), + "expected": "0.0 PAC", + }, + { + "input": Amount.from_pac(42.5), + "expected": "42.5 PAC", + }, + { + "input": Amount.from_pac(1.0), + "expected": "1.0 PAC", + }, + { + "input": Amount.from_pac(0.5), + "expected": "0.5 PAC", + }, + { + "input": Amount.from_pac(1000000.0), + "expected": "1000000.0 PAC", + }, + { + "input": Amount.from_pac(0.000000001), + "expected": "1e-09 PAC", + }, + { + "input": Amount.from_pac(-10.5), + "expected": "-10.5 PAC", + }, + { + "input": Amount.from_nano_pac(1000000000), + "expected": "1.0 PAC", + }, + { + "input": Amount.from_nano_pac(500000000), + "expected": "0.5 PAC", + }, + ] + + for case in test_cases: + result = str(case["input"]) + self.assertEqual(result, case["expected"]) + if __name__ == "__main__": unittest.main() diff --git a/tests/test_crypto_bls.py b/tests/test_crypto_bls.py index d1f74f5..3d0b59e 100644 --- a/tests/test_crypto_bls.py +++ b/tests/test_crypto_bls.py @@ -1,8 +1,8 @@ import unittest -from pactus.crypto.bls.private_key import PrivateKey as BLSPrivateKey -from pactus.crypto.bls.public_key import PublicKey as BLSPublicKey -from pactus.crypto.bls.signature import Signature as BLSSignature +from pactus.crypto.bls import PrivateKey as BLSPrivateKey +from pactus.crypto.bls import PublicKey as BLSPublicKey +from pactus.crypto.bls import Signature as BLSSignature class TestBLSCrypto(unittest.TestCase): diff --git a/tests/test_crypto_ed25519.py b/tests/test_crypto_ed25519.py index 253cb28..994090c 100644 --- a/tests/test_crypto_ed25519.py +++ b/tests/test_crypto_ed25519.py @@ -1,8 +1,8 @@ import unittest -from pactus.crypto.ed25519.private_key import PrivateKey as Ed25519PrivateKey -from pactus.crypto.ed25519.public_key import PublicKey as Ed25519PublicKey -from pactus.crypto.ed25519.signature import Signature as Ed25519Signature +from pactus.crypto.ed25519 import PrivateKey as Ed25519PrivateKey +from pactus.crypto.ed25519 import PublicKey as Ed25519PublicKey +from pactus.crypto.ed25519 import Signature as Ed25519Signature class TestEd25519Crypto(unittest.TestCase): diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 34bd113..3ed5bda 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -1,9 +1,9 @@ import unittest from pactus.crypto.address import Address -from pactus.crypto.bls.private_key import PrivateKey -from pactus.transaction.transaction import Transaction -from pactus.amount import Amount +from pactus.crypto.bls import PrivateKey +from pactus.transaction import Transaction +from pactus.types.amount import Amount class TestTransaction(unittest.TestCase): From 69f917de4001073756a23a7e6a2f584aaafac94a Mon Sep 17 00:00:00 2001 From: Mostafa Date: Sun, 23 Nov 2025 23:11:03 +0800 Subject: [PATCH 2/6] chore: fix linting issues --- pactus/crypto/__init__.py | 2 +- pactus/crypto/bls/__init__.py | 4 ++-- pactus/crypto/ed25519/__init__.py | 4 ++-- pactus/crypto/hrp.py | 2 +- pactus/transaction/_payload.py | 2 +- pactus/transaction/transaction.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pactus/crypto/__init__.py b/pactus/crypto/__init__.py index 6b76b41..b6faa06 100644 --- a/pactus/crypto/__init__.py +++ b/pactus/crypto/__init__.py @@ -1,7 +1,7 @@ from .address import Address, AddressType from .hrp import HRP -__all__ = ["Address", "AddressType", "HRP"] +__all__ = ["HRP", "Address", "AddressType"] diff --git a/pactus/crypto/bls/__init__.py b/pactus/crypto/bls/__init__.py index 0281170..4c1784c 100644 --- a/pactus/crypto/bls/__init__.py +++ b/pactus/crypto/bls/__init__.py @@ -1,6 +1,6 @@ from .private_key import PrivateKey from .public_key import PublicKey -from .signature import Signature, SIGNATURE_TYPE_BLS, DST +from .signature import DST, SIGNATURE_TYPE_BLS, Signature -__all__ = ["PrivateKey", "PublicKey", "Signature", "SIGNATURE_TYPE_BLS", "DST"] +__all__ = ["DST", "SIGNATURE_TYPE_BLS", "PrivateKey", "PublicKey", "Signature"] diff --git a/pactus/crypto/ed25519/__init__.py b/pactus/crypto/ed25519/__init__.py index 7af56f0..e6e249f 100644 --- a/pactus/crypto/ed25519/__init__.py +++ b/pactus/crypto/ed25519/__init__.py @@ -1,6 +1,6 @@ from .private_key import PrivateKey from .public_key import PublicKey -from .signature import Signature, SIGNATURE_TYPE_ED25519 +from .signature import SIGNATURE_TYPE_ED25519, Signature -__all__ = ["PrivateKey", "PublicKey", "Signature", "SIGNATURE_TYPE_ED25519"] +__all__ = ["SIGNATURE_TYPE_ED25519", "PrivateKey", "PublicKey", "Signature"] diff --git a/pactus/crypto/hrp.py b/pactus/crypto/hrp.py index 7ee064f..f399ebc 100644 --- a/pactus/crypto/hrp.py +++ b/pactus/crypto/hrp.py @@ -13,4 +13,4 @@ def use_mainnet(cls) -> None: def use_testnet(cls) -> None: cls.ADDRESS_HRP = "tpc" cls.PUBLIC_KEY_HRP = "tpublic" - cls.PRIVATE_KEY_HRP = "tsecret" \ No newline at end of file + cls.PRIVATE_KEY_HRP = "tsecret" diff --git a/pactus/transaction/_payload.py b/pactus/transaction/_payload.py index 58f231b..8d1c834 100644 --- a/pactus/transaction/_payload.py +++ b/pactus/transaction/_payload.py @@ -1,9 +1,9 @@ from abc import ABC, abstractmethod from enum import Enum -from pactus.types.amount import Amount from pactus.crypto.address import Address from pactus.encoding import encoding +from pactus.types.amount import Amount class PayloadType(Enum): diff --git a/pactus/transaction/transaction.py b/pactus/transaction/transaction.py index 352637c..d084d1a 100644 --- a/pactus/transaction/transaction.py +++ b/pactus/transaction/transaction.py @@ -1,9 +1,9 @@ -from pactus.types.amount import Amount from pactus.crypto.address import Address from pactus.crypto.private_key import PrivateKey from pactus.crypto.public_key import PublicKey from pactus.crypto.signature import Signature from pactus.encoding import encoding +from pactus.types.amount import Amount from ._payload import ( BondPayload, From 8bbcde7ba606ecb7e9de177006f169d287771b82 Mon Sep 17 00:00:00 2001 From: Mostafa Date: Sun, 23 Nov 2025 23:13:36 +0800 Subject: [PATCH 3/6] chore: fix linting issues --- pactus/crypto/__init__.py | 3 --- pactus/transaction/__init__.py | 3 --- 2 files changed, 6 deletions(-) diff --git a/pactus/crypto/__init__.py b/pactus/crypto/__init__.py index b6faa06..31a757b 100644 --- a/pactus/crypto/__init__.py +++ b/pactus/crypto/__init__.py @@ -2,6 +2,3 @@ from .hrp import HRP __all__ = ["HRP", "Address", "AddressType"] - - - diff --git a/pactus/transaction/__init__.py b/pactus/transaction/__init__.py index cade590..31c1c0a 100644 --- a/pactus/transaction/__init__.py +++ b/pactus/transaction/__init__.py @@ -1,6 +1,3 @@ from .transaction import Transaction __all__ = ["Transaction"] - - - From cc4d2e3117c690f5e14daf614af957ebf89b1ecb Mon Sep 17 00:00:00 2001 From: Mostafa Date: Sun, 23 Nov 2025 23:16:21 +0800 Subject: [PATCH 4/6] chore: fix linting issues --- examples/example_key_generation.py | 6 +----- pactus/crypto/__init__.py | 4 +++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/example_key_generation.py b/examples/example_key_generation.py index 9f36146..1467bf1 100644 --- a/examples/example_key_generation.py +++ b/examples/example_key_generation.py @@ -1,12 +1,8 @@ import argparse -from pactus.crypto.hrp import HRP -from pactus.crypto.address import AddressType +from pactus.crypto import Address, AddressType, HRP, PrivateKey, PublicKey from pactus.crypto.bls import PrivateKey as BLSPrivateKey from pactus.crypto.ed25519 import PrivateKey as Ed25519PrivateKey -from pactus.crypto import PrivateKey -from pactus.crypto import PublicKey -from pactus.crypto.address import Address def main() -> None: diff --git a/pactus/crypto/__init__.py b/pactus/crypto/__init__.py index 31a757b..7f448b8 100644 --- a/pactus/crypto/__init__.py +++ b/pactus/crypto/__init__.py @@ -1,4 +1,6 @@ from .address import Address, AddressType from .hrp import HRP +from .private_key import PrivateKey +from .public_key import PublicKey -__all__ = ["HRP", "Address", "AddressType"] +__all__ = ["HRP", "Address", "AddressType", "PrivateKey", "PublicKey"] From 74ffcb2c076c8018db8c290b0f268c357ccf99f7 Mon Sep 17 00:00:00 2001 From: Mostafa Date: Sun, 23 Nov 2025 23:22:58 +0800 Subject: [PATCH 5/6] chore: bump version --- pactus/types/__init__.py | 3 +++ setup.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pactus/types/__init__.py b/pactus/types/__init__.py index e69de29..5a338b5 100644 --- a/pactus/types/__init__.py +++ b/pactus/types/__init__.py @@ -0,0 +1,3 @@ +from .amount import Amount + +__all__ = ["Amount"] diff --git a/setup.py b/setup.py index 30404f2..5c3e1f4 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name="pactus-sdk", - version="1.2.4", + version="1.3.0", author="Pactus Development Team", author_email="info@pactus.org", description="Pactus Development Kit", From b50fbe407c76cec63ecf819457ce24a1d3bb5de1 Mon Sep 17 00:00:00 2001 From: Mostafa Date: Sun, 23 Nov 2025 23:29:46 +0800 Subject: [PATCH 6/6] chore: remove unit from Amount string --- pactus/types/amount.py | 2 +- tests/test_amount.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pactus/types/amount.py b/pactus/types/amount.py index 011abd6..23a36d2 100644 --- a/pactus/types/amount.py +++ b/pactus/types/amount.py @@ -32,7 +32,7 @@ def __hash__(self) -> int: def __str__(self) -> str: """Return a string representation of the amount in PAC.""" pac_value = self.value / NANO_PAC_PER_PAC - return f"{pac_value} PAC" + return f"{pac_value}" @classmethod def from_nano_pac(cls, a: int) -> "Amount": diff --git a/tests/test_amount.py b/tests/test_amount.py index 6333943..8653892 100644 --- a/tests/test_amount.py +++ b/tests/test_amount.py @@ -65,39 +65,39 @@ def test_str(self): test_cases = [ { "input": Amount(0), - "expected": "0.0 PAC", + "expected": "0.0", }, { "input": Amount.from_pac(42.5), - "expected": "42.5 PAC", + "expected": "42.5", }, { "input": Amount.from_pac(1.0), - "expected": "1.0 PAC", + "expected": "1.0", }, { "input": Amount.from_pac(0.5), - "expected": "0.5 PAC", + "expected": "0.5", }, { "input": Amount.from_pac(1000000.0), - "expected": "1000000.0 PAC", + "expected": "1000000.0", }, { "input": Amount.from_pac(0.000000001), - "expected": "1e-09 PAC", + "expected": "1e-09", }, { "input": Amount.from_pac(-10.5), - "expected": "-10.5 PAC", + "expected": "-10.5", }, { "input": Amount.from_nano_pac(1000000000), - "expected": "1.0 PAC", + "expected": "1.0", }, { "input": Amount.from_nano_pac(500000000), - "expected": "0.5 PAC", + "expected": "0.5", }, ]