Skip to content

Commit 52fce2f

Browse files
committed
Merge branch 'feat/tck-append-file' of fork into feat/tck-append-file
2 parents 9648e2a + c39d103 commit 52fce2f

8 files changed

Lines changed: 133 additions & 72 deletions

File tree

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ jobs:
115115
attestations: true
116116

117117
- name: Upload signed assets to GitHub Release
118-
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
118+
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
119119
with:
120120
body: |
121121
## Important notes

src/hiero_sdk_python/tokens/token_unpause_transaction.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def _from_proto(cls, proto: TokenUnpauseTransactionBody) -> TokenUnpauseTransact
8282
Returns:
8383
TokenUnpauseTransaction: A new instance of TokenUnpauseTransaction
8484
"""
85-
token_id = TokenId._from_proto(proto.token) if proto.token else None
85+
token_id = TokenId._from_proto(proto.token) if proto.HasField("token") else None
8686
return cls(token_id=token_id)
8787

8888
def _build_proto_body(self) -> TokenUnpauseTransactionBody:
@@ -91,14 +91,8 @@ def _build_proto_body(self) -> TokenUnpauseTransactionBody:
9191
9292
Returns:
9393
TokenUnpauseTransactionBody: The protobuf body for this transaction.
94-
95-
Raises:
96-
ValueError: If account ID or token ID is not set.
9794
"""
98-
if self.token_id is None:
99-
raise ValueError("Missing token ID")
100-
101-
return TokenUnpauseTransactionBody(token=self.token_id._to_proto())
95+
return TokenUnpauseTransactionBody(token=self.token_id._to_proto() if self.token_id is not None else None)
10296

10397
def build_transaction_body(self) -> TransactionBody:
10498
"""

tck/handlers/token.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from hiero_sdk_python.tokens.token_revoke_kyc_transaction import TokenRevokeKycTransaction
4040
from hiero_sdk_python.tokens.token_type import TokenType
4141
from hiero_sdk_python.tokens.token_unfreeze_transaction import TokenUnfreezeTransaction
42+
from hiero_sdk_python.tokens.token_unpause_transaction import TokenUnpauseTransaction
4243
from hiero_sdk_python.tokens.token_update_transaction import TokenUpdateTransaction
4344
from hiero_sdk_python.tokens.token_wipe_transaction import TokenWipeTransaction
4445
from hiero_sdk_python.transaction.transaction_receipt import TransactionReceipt
@@ -62,6 +63,7 @@
6263
RejectTokenParams,
6364
RevokeTokenKycParams,
6465
UnfreezeTokenParams,
66+
UnpauseTokenParams,
6567
UpdateTokenParams,
6668
WipeTokenParams,
6769
)
@@ -84,6 +86,7 @@
8486
RejectTokenResponse,
8587
RevokeTokenKycResponse,
8688
UnfreezeTokenResponse,
89+
UnpauseTokenResponse,
8790
UpdateTokenResponse,
8891
WipeTokenResponse,
8992
)
@@ -407,6 +410,16 @@ def _build_pause_token_transaction(params: PauseTokenParams) -> TokenPauseTransa
407410
return transaction
408411

409412

413+
def _build_unpause_token_transaction(params: UnpauseTokenParams) -> TokenUnpauseTransaction:
414+
"""Build a TokenUnpauseTransaction from TCK params."""
415+
transaction = TokenUnpauseTransaction().set_grpc_deadline(DEFAULT_GRPC_TIMEOUT)
416+
417+
if params.tokenId is not None:
418+
transaction.set_token_id(TokenId.from_string(params.tokenId))
419+
420+
return transaction
421+
422+
410423
def _build_grant_token_kyc_transaction(params: GrantTokenKycParams) -> TokenGrantKycTransaction:
411424
"""Build a TokenGrantKycTransaction from TCK params."""
412425
transaction = TokenGrantKycTransaction().set_grpc_deadline(DEFAULT_GRPC_TIMEOUT)
@@ -540,6 +553,22 @@ def pause_token(params: PauseTokenParams) -> PauseTokenResponse:
540553
return PauseTokenResponse(status=ResponseCode(receipt.status).name)
541554

542555

556+
@rpc_method("unpauseToken")
557+
def unpause_token(params: UnpauseTokenParams) -> UnpauseTokenResponse:
558+
"""Unpause a token using TCK unpauseToken parameters."""
559+
client = get_client(params.sessionId)
560+
561+
transaction = _build_unpause_token_transaction(params)
562+
563+
if params.commonTransactionParams is not None:
564+
params.commonTransactionParams.apply_common_params(transaction, client)
565+
566+
response = transaction.execute(client, wait_for_receipt=False)
567+
receipt: TransactionReceipt = response.get_receipt(client, validate_status=True)
568+
569+
return UnpauseTokenResponse(status=ResponseCode(receipt.status).name)
570+
571+
543572
@rpc_method("grantTokenKyc")
544573
def grant_token_kyc(params: GrantTokenKycParams) -> GrantTokenKycResponse:
545574
"""Grant KYC to an account for a token using TCK grantTokenKyc parameters."""

tck/param/token.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,22 @@ def parse_json_params(cls, params: dict) -> PauseTokenParams:
259259
)
260260

261261

262+
@dataclass
263+
class UnpauseTokenParams(BaseTransactionParams):
264+
"""Request parameters for the unpauseToken endpoint."""
265+
266+
tokenId: str | None = None
267+
268+
@classmethod
269+
def parse_json_params(cls, params: dict) -> UnpauseTokenParams:
270+
"""Parse JSON-RPC params into an UnpauseTokenParams instance."""
271+
return cls(
272+
tokenId=params.get("tokenId"),
273+
sessionId=parse_session_id(params),
274+
commonTransactionParams=parse_common_transaction_params(params),
275+
)
276+
277+
262278
@dataclass
263279
class AirdropTokenParams(BaseTransactionParams):
264280
"""Request parameters for the airdropToken endpoint."""

tck/response/token.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ class PauseTokenResponse(StatusOnlyResponse):
6969
"""Response payload for pauseToken."""
7070

7171

72+
@dataclass
73+
class UnpauseTokenResponse(StatusOnlyResponse):
74+
"""Response payload for unpauseToken."""
75+
76+
7277
@dataclass
7378
class AirdropTokenResponse(StatusOnlyResponse):
7479
"""Response payload for airdropToken."""

tests/integration/token_unpause_transaction_e2e_test.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from __future__ import annotations
22

33
import pytest
4-
from pytest import fixture
54

65
from hiero_sdk_python.crypto.private_key import PrivateKey
6+
from hiero_sdk_python.exceptions import PrecheckError
77
from hiero_sdk_python.query.token_info_query import TokenInfoQuery
88
from hiero_sdk_python.response_code import ResponseCode
99
from hiero_sdk_python.tokens.token_id import TokenId
@@ -15,17 +15,17 @@
1515
pause_key = PrivateKey.generate()
1616

1717

18-
@fixture
18+
@pytest.fixture
1919
def pausable_token(env):
20-
""" "Fixture to create a token that supports pausing."""
20+
"""Fixture to create a token that supports pausing."""
2121
return create_fungible_token(env, opts=[lambda tx: tx.set_pause_key(pause_key)])
2222

2323

2424
def pause_token(env, token_id: TokenId):
2525
"""Helper function to pause the token with the given token_id."""
26-
token_pasue_tx = TokenPauseTransaction().set_token_id(token_id).freeze_with(env.client).sign(pause_key)
26+
token_pause_tx = TokenPauseTransaction().set_token_id(token_id).freeze_with(env.client).sign(pause_key)
2727

28-
return token_pasue_tx.execute(env.client)
28+
return token_pause_tx.execute(env.client)
2929

3030

3131
def get_pause_status(env, token_id: TokenId):
@@ -34,6 +34,7 @@ def get_pause_status(env, token_id: TokenId):
3434
return token_info.pause_status.name
3535

3636

37+
@pytest.mark.integration
3738
def test_unpause_token(env, pausable_token):
3839
"""Test successful unpause of a paused token."""
3940
pause_receipt = pause_token(env, pausable_token)
@@ -48,6 +49,7 @@ def test_unpause_token(env, pausable_token):
4849
assert get_pause_status(env, pausable_token) == "UNPAUSED"
4950

5051

52+
@pytest.mark.integration
5153
def test_unpause_token_without_pause_key_signature(env, pausable_token):
5254
"""Test unpause transaction without pause key signature."""
5355
pause_receipt = pause_token(env, pausable_token)
@@ -61,7 +63,8 @@ def test_unpause_token_without_pause_key_signature(env, pausable_token):
6163
assert unpause_receipt.status == ResponseCode.INVALID_SIGNATURE
6264

6365

64-
def test_unpause_token_with_invalid_pasue_key(env, pausable_token):
66+
@pytest.mark.integration
67+
def test_unpause_token_with_invalid_pause_key(env, pausable_token):
6568
"""Test unpause transaction with invalid pause key."""
6669
pause_receipt = pause_token(env, pausable_token)
6770

@@ -76,16 +79,19 @@ def test_unpause_token_with_invalid_pasue_key(env, pausable_token):
7679
assert unpause_receipt.status == ResponseCode.INVALID_SIGNATURE
7780

7881

82+
@pytest.mark.integration
7983
def test_unpause_token_when_token_id_not_set(env):
8084
"""Test unpause transaction when token_id is not provided."""
8185
unpause_tx = TokenUnpauseTransaction()
82-
with pytest.raises(ValueError, match="Missing token ID"):
83-
unpause_tx.freeze_with(env.client)
86+
with pytest.raises(PrecheckError, match="failed precheck with status: INVALID_TOKEN_ID") as exc_info:
87+
unpause_tx.execute(env.client)
88+
assert exc_info.value.status == ResponseCode.INVALID_TOKEN_ID
8489

8590

91+
@pytest.mark.integration
8692
def test_unpause_token_with_invalid_token_id(env):
8793
"""Test unpause transaction using an invalid token ID."""
88-
token_id = TokenId(0, 0, 999)
94+
token_id = TokenId(0, 0, 0)
8995

9096
unpause_tx = TokenUnpauseTransaction().set_token_id(token_id).freeze_with(env.client).sign(pause_key)
9197

tests/unit/token_unpause_transaction_test.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ def test_build_transaction_body_when_token_id_not_set(mock_account_ids):
6262

6363
unpause_tx = TokenUnpauseTransaction()
6464
unpause_tx.set_node_account_ids([node_account_id])
65+
unpause_tx.operator_account_id = account_id
6566

66-
with pytest.raises(ValueError, match="Missing token ID"):
67-
unpause_tx.build_transaction_body()
67+
transaction_body = unpause_tx.build_transaction_body()
68+
assert not transaction_body.token_unpause.HasField("token"), "token field must be unset when token_id is None"
6869

6970

7071
def test_set_method(mock_account_ids):
@@ -169,6 +170,14 @@ def test_from_proto(mock_account_ids):
169170
assert unpause_tx.token_id.num == token_id.num
170171

171172

173+
def test_from_proto_without_token():
174+
"""Test creating a TokenUnpauseTransaction from protobuf representation without token."""
175+
proto = TokenUnpauseTransactionBody()
176+
unpause_tx = TokenUnpauseTransaction._from_proto(proto)
177+
178+
assert unpause_tx.token_id is None, "token_id must remain None when token is absent"
179+
180+
172181
def test_upause_transaction_can_execute(mock_account_ids):
173182
"""Test that a token upause transaction can be executed successfully."""
174183
_, _, _, token_id, _ = mock_account_ids

0 commit comments

Comments
 (0)