From 61ac9e41bcedcf7d10fa3ecc325bde6849499529 Mon Sep 17 00:00:00 2001 From: Philip Mataras Date: Mon, 13 Apr 2026 11:36:19 -0400 Subject: [PATCH] fix: add missing receipt fields to TurboUploadResponse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upload API returns timestamp, signature, public, version, and deadlineHeight as part of the signed receipt, but these fields were silently discarded during response parsing in both single and chunked upload paths. - Add receipt fields to TurboUploadResponse and TurboUploadStatus - Extract fields in _upload_single() from API response JSON - Extract fields in get_status() from chunked receipt dict - Carry fields through status→response conversion in upload() - Update tests with new fields and assertions Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/test_chunked.py | 8 ++++++++ tests/test_turbo.py | 10 ++++++++++ turbo_sdk/chunked.py | 9 +++++++++ turbo_sdk/client.py | 5 +++++ turbo_sdk/types.py | 9 +++++++++ 5 files changed, 41 insertions(+) diff --git a/tests/test_chunked.py b/tests/test_chunked.py index d57d01b..5bee9c6 100644 --- a/tests/test_chunked.py +++ b/tests/test_chunked.py @@ -254,6 +254,10 @@ def test_get_status_finalized(self, mock_session_class): "dataCaches": ["arweave.net"], "fastFinalityIndexes": ["arweave.net"], "winc": "1000", + "signature": "receipt_sig", + "public": "receipt_pub", + "version": "1.0.0", + "deadlineHeight": 999999, }, } @@ -274,6 +278,10 @@ def test_get_status_finalized(self, mock_session_class): assert status.id == "tx-id" assert status.owner == "owner-address" assert status.data_caches == ["arweave.net"] + assert status.signature == "receipt_sig" + assert status.public == "receipt_pub" + assert status.version == "1.0.0" + assert status.deadline_height == 999999 @patch("turbo_sdk.chunked.requests.Session") def test_get_status_validating(self, mock_session_class): diff --git a/tests/test_turbo.py b/tests/test_turbo.py index 7af315a..facf014 100644 --- a/tests/test_turbo.py +++ b/tests/test_turbo.py @@ -289,6 +289,11 @@ def test_upload_with_bytes(self, mock_post, turbo): "dataCaches": ["cache1"], "fastFinalityIndexes": ["index1"], "winc": "1000", + "timestamp": 1776068746997, + "signature": "test_sig", + "public": "test_pub", + "version": "1.0.0", + "deadlineHeight": 1234567, } mock_post.return_value = mock_response @@ -296,6 +301,11 @@ def test_upload_with_bytes(self, mock_post, turbo): assert result.id == "test_tx_id" assert result.owner == "test_owner" + assert result.timestamp == 1776068746997 + assert result.signature == "test_sig" + assert result.public == "test_pub" + assert result.version == "1.0.0" + assert result.deadline_height == 1234567 mock_post.assert_called_once() @patch("turbo_sdk.client.requests.post") diff --git a/turbo_sdk/chunked.py b/turbo_sdk/chunked.py index 330f0a4..e876e33 100644 --- a/turbo_sdk/chunked.py +++ b/turbo_sdk/chunked.py @@ -154,6 +154,10 @@ def get_status(self, upload_id: str) -> TurboUploadStatus: data_caches=receipt.get("dataCaches", []), fast_finality_indexes=receipt.get("fastFinalityIndexes", []), winc=receipt.get("winc"), + signature=receipt.get("signature"), + public=receipt.get("public"), + version=receipt.get("version"), + deadline_height=receipt.get("deadlineHeight"), ) elif response.status_code == 404: raise ChunkedUploadError("Upload session not found") @@ -300,6 +304,11 @@ def upload( data_caches=status.data_caches, fast_finality_indexes=status.fast_finality_indexes, winc=status.winc or "0", + timestamp=status.timestamp, + signature=status.signature, + public=status.public, + version=status.version, + deadline_height=status.deadline_height, ) except Exception: # Could implement cleanup here in future diff --git a/turbo_sdk/client.py b/turbo_sdk/client.py index bdfb630..9bc8377 100644 --- a/turbo_sdk/client.py +++ b/turbo_sdk/client.py @@ -192,6 +192,11 @@ def _upload_single( data_caches=result.get("dataCaches", []), fast_finality_indexes=result.get("fastFinalityIndexes", []), winc=result.get("winc", "0"), + timestamp=result.get("timestamp"), + signature=result.get("signature"), + public=result.get("public"), + version=result.get("version"), + deadline_height=result.get("deadlineHeight"), ) else: raise Exception(f"Upload failed: {response.status_code} - {response.text}") diff --git a/turbo_sdk/types.py b/turbo_sdk/types.py index 78c8ab9..c13d43d 100644 --- a/turbo_sdk/types.py +++ b/turbo_sdk/types.py @@ -45,6 +45,10 @@ class TurboUploadStatus: data_caches: List[str] = field(default_factory=list) fast_finality_indexes: List[str] = field(default_factory=list) winc: Optional[str] = None + signature: Optional[str] = None + public: Optional[str] = None + version: Optional[str] = None + deadline_height: Optional[int] = None @dataclass @@ -56,6 +60,11 @@ class TurboUploadResponse: data_caches: List[str] # Cache endpoints fast_finality_indexes: List[str] # Fast finality winc: str # Winston credits cost + timestamp: Optional[int] = None # Receipt creation time (ms) + signature: Optional[str] = None # Base64URL receipt signature + public: Optional[str] = None # Signer's public key + version: Optional[str] = None # Receipt schema version + deadline_height: Optional[int] = None # Block height context @dataclass