From c1555c4512f57ef8e61f31c6ded90d4d86a57431 Mon Sep 17 00:00:00 2001
From: kmochocki <kmochocki@syncad.com>
Date: Thu, 19 Dec 2024 12:24:01 +0000
Subject: [PATCH] Add transaction factory method

---
 python/wax/_private/base_api.py | 19 ++++++++++++++++---
 python/wax/interfaces.py        | 17 ++++++++++++++++-
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/python/wax/_private/base_api.py b/python/wax/_private/base_api.py
index 686bce805..9b21cc116 100644
--- a/python/wax/_private/base_api.py
+++ b/python/wax/_private/base_api.py
@@ -1,9 +1,13 @@
 from __future__ import annotations
 
-from datetime import datetime, timezone
+from datetime import datetime, timedelta, timezone
 from typing import TYPE_CHECKING
 
-from wax._private.core.constants import HIVE_PERCENT_PRECISION_DOT_PLACES, PUBLIC_KEY_ADDRESS_PREFIX
+from wax._private.core.constants import (
+    DEFAULT_TRANSACTION_EXPIRATION_TIME,
+    HIVE_PERCENT_PRECISION_DOT_PLACES,
+    PUBLIC_KEY_ADDRESS_PREFIX,
+)
 from wax._private.core.decimal_converter import DecimalConverter
 from wax._private.core.python_price_converter import convert_to_python_price
 from wax._private.models.asset import (
@@ -30,6 +34,7 @@ from wax._private.result_tools import (
     to_python_string,
     validate_wax_result,
 )
+from wax._private.transaction import Transaction
 from wax.cpp_python_bridge import (  # type: ignore[attr-defined]
     calculate_account_hp,
     calculate_current_manabar_value,
@@ -47,12 +52,13 @@ from wax.cpp_python_bridge import (  # type: ignore[attr-defined]
     suggest_brain_key,
     validate_operation,
 )
-from wax.interfaces import ChainConfig, IWaxBaseInterface
+from wax.interfaces import ChainConfig, IWaxBaseInterface, TTimestamp
 
 if TYPE_CHECKING:
     from decimal import Decimal
 
     from wax._private.models.basic import AccountName, ChainId, PublicKey, SigDigest, Signature
+    from wax.interfaces import ITransaction
 
 
 class WaxBaseApi(IWaxBaseInterface):
@@ -268,3 +274,10 @@ class WaxBaseApi(IWaxBaseInterface):
         return DecimalConverter.convert(
             expose_result_as_python_string(result), precision=HIVE_PERCENT_PRECISION_DOT_PLACES
         )
+
+    def create_transaction_with_tapos(self, tapos_block_id: str, expiration: TTimestamp | None = None) -> ITransaction:
+        expiration = expiration or DEFAULT_TRANSACTION_EXPIRATION_TIME
+        if isinstance(expiration, datetime):
+            expiration = expiration.replace(microsecond=0) - datetime.now(timezone.utc).replace(microsecond=0)
+        assert isinstance(expiration, timedelta), "Expiration has to be timedelta type"
+        return Transaction(api=self, tapos_block_id=tapos_block_id, expiration_time=expiration)
diff --git a/python/wax/interfaces.py b/python/wax/interfaces.py
index 9f95aa7a6..5afc582c6 100644
--- a/python/wax/interfaces.py
+++ b/python/wax/interfaces.py
@@ -2,6 +2,7 @@ from __future__ import annotations
 
 from abc import ABC, abstractmethod
 from dataclasses import dataclass
+from datetime import datetime, timedelta
 from typing import TYPE_CHECKING, TypeAlias
 
 from typing_extensions import Self
@@ -9,7 +10,6 @@ from typing_extensions import Self
 from wax.proto.transaction_pb2 import transaction as proto_transaction
 
 if TYPE_CHECKING:
-    from datetime import datetime
     from decimal import Decimal
 
     from beekeepy._interface.abc.asynchronous.wallet import UnlockedWallet as AsyncUnlockedWallet
@@ -31,6 +31,8 @@ if TYPE_CHECKING:
 ProtoTransaction: TypeAlias = proto_transaction
 JsonTransaction: TypeAlias = str
 
+TTimestamp: TypeAlias = datetime | timedelta
+
 ChainConfig: TypeAlias = dict[str, str]
 
 
@@ -574,3 +576,16 @@ class IWaxBaseInterface(ABC):
         Raises:
             WaxValidationFailedError: When passed parameters are wrong.
         """
+
+    @abstractmethod
+    def create_transaction_with_tapos(self, tapos_block_id: str, expiration: TTimestamp | None = None) -> ITransaction:
+        """
+        Creates transaction object using basic information from chain.
+
+        Args:
+            tapos_block_id: Block id (mostly head) that transaction should refer to
+            expiration: time (UTC) till transaction is valid. Default to +1 minute.
+
+        Returns:
+            Transaction object
+        """
-- 
GitLab