diff --git a/tck/handlers/token.py b/tck/handlers/token.py index 322ae5ea4..c20dbcc95 100644 --- a/tck/handlers/token.py +++ b/tck/handlers/token.py @@ -31,6 +31,7 @@ from hiero_sdk_python.tokens.token_mint_transaction import TokenMintTransaction from hiero_sdk_python.tokens.token_pause_status import TokenPauseStatus from hiero_sdk_python.tokens.token_pause_transaction import TokenPauseTransaction +from hiero_sdk_python.tokens.token_reject_transaction import TokenRejectTransaction from hiero_sdk_python.tokens.token_revoke_kyc_transaction import TokenRevokeKycTransaction from hiero_sdk_python.tokens.token_type import TokenType from hiero_sdk_python.transaction.transaction_receipt import TransactionReceipt @@ -48,6 +49,7 @@ GrantTokenKycParams, MintTokenParams, PauseTokenParams, + RejectTokenParams, RevokeTokenKycParams, ) from tck.response.token import ( @@ -63,6 +65,7 @@ GrantTokenKycResponse, MintTokenResponse, PauseTokenResponse, + RejectTokenResponse, RevokeTokenKycResponse, ) from tck.util.client_utils import get_client @@ -732,3 +735,44 @@ def get_token_info(params: GetTokenInfoParams) -> GetTokenInfoResponse: info = query.execute(client) return _build_token_info_response(info) + + +def _build_reject_token_transaction( + params: RejectTokenParams, +) -> TokenRejectTransaction: + transaction = TokenRejectTransaction().set_grpc_deadline(DEFAULT_GRPC_TIMEOUT) + + if params.ownerId is not None: + transaction.set_owner_id(AccountId.from_string(params.ownerId)) + + if params.serialNumbers is not None and params.tokenIds is not None: + nft_ids = [] + + for token_id in params.tokenIds: + nft_ids.extend( + NftId(TokenId.from_string(token_id), int(serial_number)) for serial_number in params.serialNumbers + ) + + transaction.set_nft_ids(nft_ids) + + elif params.tokenIds is not None: + transaction.set_token_ids([TokenId.from_string(token) for token in params.tokenIds]) + + return transaction + + +@rpc_method("rejectToken") +def reject_token(params: RejectTokenParams) -> RejectTokenResponse: + client = get_client(params.sessionId) + + transaction = _build_reject_token_transaction(params) + + if params.commonTransactionParams is not None: + params.commonTransactionParams.apply_common_params(transaction, client) + + response = transaction.execute(client, wait_for_receipt=False) + receipt = response.get_receipt(client, validate_status=True) + + return RejectTokenResponse( + status=ResponseCode(receipt.status).name, + ) diff --git a/tck/param/token.py b/tck/param/token.py index ad5cdee88..05667716a 100644 --- a/tck/param/token.py +++ b/tck/param/token.py @@ -311,3 +311,33 @@ def parse_json_params(cls, params: dict) -> GetTokenInfoParams: maxQueryPayment=params.get("maxQueryPayment"), sessionId=parse_session_id(params), ) + + +@dataclass +class RejectTokenParams(BaseTransactionParams): + ownerId: str | None = None + tokenIds: list[str] | None = None + serialNumbers: list[str] | None = None + + @classmethod + def parse_json_params(cls, params: dict) -> RejectTokenParams: + token_ids = params.get("tokenIds") + if token_ids is not None and ( + not isinstance(token_ids, list) or not all(isinstance(token_id, str) for token_id in token_ids) + ): + raise ValueError("tokenIds must be a list of strings") + + serial_numbers = params.get("serialNumbers") + if serial_numbers is not None and ( + not isinstance(serial_numbers, list) + or not all(isinstance(serial_number, str) for serial_number in serial_numbers) + ): + raise ValueError("serialNumbers must be a list of strings") + + return cls( + ownerId=params.get("ownerId"), + tokenIds=token_ids, + serialNumbers=serial_numbers, + sessionId=parse_session_id(params), + commonTransactionParams=parse_common_transaction_params(params), + ) diff --git a/tck/response/token.py b/tck/response/token.py index ba08efbbc..36188fe49 100644 --- a/tck/response/token.py +++ b/tck/response/token.py @@ -54,6 +54,11 @@ class RevokeTokenKycResponse(StatusOnlyResponse): """Response payload for revokeTokenKyc.""" +@dataclass +class RejectTokenResponse(StatusOnlyResponse): + """Response payload for rejectToken.""" + + @dataclass class PauseTokenResponse(StatusOnlyResponse): """Response payload for pauseToken."""