@@ -61,6 +61,65 @@ def generate_transaction_id(account_id_proto):
6161
6262########### Basic Tests for Building Transactions ###########
6363
64+ def test_set_key_with_public_key (mock_client ):
65+ """
66+ Tests the NEW path: setting a key using a PublicKey.
67+ This proves the non-custodial path works.
68+ """
69+ # 1. Create a real key pair
70+ real_private_key = PrivateKey .generate_ed25519 ()
71+ real_public_key = real_private_key .public_key ()
72+
73+ # 2. Build the transaction
74+ token_tx = TokenCreateTransaction (
75+ TokenParams (
76+ token_name = "MyToken" ,
77+ token_symbol = "MTK" ,
78+ treasury_account_id = AccountId (0 , 0 , 123 ),
79+ initial_supply = 100 , # Must be > 0 for fungible
80+ token_type = TokenType .FUNGIBLE_COMMON ,
81+ )
82+ )
83+
84+ # 3. Use the NEW feature: set a key using a PublicKey
85+ token_tx .set_admin_key (real_public_key )
86+
87+ # 4. Spy on the _to_proto_key method
88+ token_tx ._to_proto_key = MagicMock (return_value = real_public_key ._to_proto ())
89+
90+ # 5. Freeze (this calls _build_proto_body)
91+ token_tx .freeze_with (mock_client )
92+
93+ # 6. THE PROOF: Assert that _to_proto_key was called
94+ # with the PublicKey object at least once.
95+ token_tx ._to_proto_key .assert_any_call (real_public_key )
96+
97+ def test_set_key_with_invalid_type_raises_error (mock_client ):
98+ """
99+ Tests the SAFETY NET: proves that passing a non-key type fails
100+ when the transaction is built.
101+ """
102+ token_tx = TokenCreateTransaction (
103+ TokenParams (
104+ token_name = "MyToken" ,
105+ token_symbol = "MTK" ,
106+ treasury_account_id = AccountId (0 , 0 , 123 ),
107+ initial_supply = 100 ,
108+ token_type = TokenType .FUNGIBLE_COMMON
109+ )
110+ )
111+
112+ # Try to set an invalid key type
113+ token_tx .set_admin_key ("this is just a string" )
114+
115+ # Prove that the transaction build fails
116+ # with the exact error we want
117+ with pytest .raises (TypeError ) as e :
118+ token_tx .freeze_with (mock_client ) # This calls _build_proto_body
119+
120+ # Check that our specific error was raised
121+ assert "Key must be of type PrivateKey or PublicKey" in str (e .value )
122+
64123# This test uses fixture mock_account_ids as parameter
65124def test_build_transaction_body_without_key (mock_account_ids ):
66125 """Test building a token creation transaction body without an admin, supply or freeze key."""
@@ -260,36 +319,36 @@ def test_sign_transaction(mock_account_ids, mock_client):
260319 private_key .sign .return_value = b"signature"
261320 private_key .public_key ().to_bytes_raw .return_value = b"public_key"
262321
263- private_key_admin = MagicMock ()
322+ private_key_admin = MagicMock (spec = PrivateKey )
264323 private_key_admin .sign .return_value = b"admin_signature"
265324 private_key_admin .public_key ().to_bytes_raw .return_value = b"admin_public_key"
266325 private_key_admin .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"admin_public_key" )
267326
268- private_key_supply = MagicMock ()
327+ private_key_supply = MagicMock (spec = PrivateKey )
269328 private_key_supply .sign .return_value = b"supply_signature"
270329 private_key_supply .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"supply_public_key" )
271330
272- private_key_freeze = MagicMock ()
331+ private_key_freeze = MagicMock (spec = PrivateKey )
273332 private_key_freeze .sign .return_value = b"freeze_signature"
274333 private_key_freeze .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"freeze_public_key" )
275334
276- private_key_wipe = MagicMock ()
335+ private_key_wipe = MagicMock (spec = PrivateKey )
277336 private_key_wipe .sign .return_value = b"wipe_signature"
278337 private_key_wipe .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"wipe_public_key" )
279338
280- private_key_metadata = MagicMock ()
339+ private_key_metadata = MagicMock (spec = PrivateKey )
281340 private_key_metadata .sign .return_value = b"metadata_signature"
282341 private_key_metadata .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"metadata_public_key" )
283342
284- private_key_pause = MagicMock ()
343+ private_key_pause = MagicMock (spec = PrivateKey )
285344 private_key_pause .sign .return_value = b"pause_signature"
286345 private_key_pause .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"pause_public_key" )
287346
288- private_key_kyc = MagicMock ()
347+ private_key_kyc = MagicMock (spec = PrivateKey )
289348 private_key_kyc .sign .return_value = b"kyc_signature"
290349 private_key_kyc .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"kyc_public_key" )
291350
292- private_key_fee_schedule = MagicMock ()
351+ private_key_fee_schedule = MagicMock (spec = PrivateKey )
293352 private_key_fee_schedule .sign .return_value = b"fee_schedule_signature"
294353 private_key_fee_schedule .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"fee_schedule_public_key" )
295354
@@ -722,36 +781,36 @@ def test_build_and_sign_nft_transaction_to_proto(mock_account_ids, mock_client):
722781 private_key_private .sign .return_value = b"private_signature"
723782 private_key_private .public_key ().to_bytes_raw .return_value = b"private_public_key"
724783
725- private_key_admin = MagicMock ()
784+ private_key_admin = MagicMock (spec = PrivateKey )
726785 private_key_admin .sign .return_value = b"admin_signature"
727786 private_key_admin .public_key ().to_bytes_raw .return_value = b"admin_public_key"
728787 private_key_admin .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"admin_public_key" )
729788
730- private_key_supply = MagicMock ()
789+ private_key_supply = MagicMock (spec = PrivateKey )
731790 private_key_supply .sign .return_value = b"supply_signature"
732791 private_key_supply .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"supply_public_key" )
733792
734- private_key_freeze = MagicMock ()
793+ private_key_freeze = MagicMock (spec = PrivateKey )
735794 private_key_freeze .sign .return_value = b"freeze_signature"
736795 private_key_freeze .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"freeze_public_key" )
737796
738- private_key_wipe = MagicMock ()
797+ private_key_wipe = MagicMock (spec = PrivateKey )
739798 private_key_wipe .sign .return_value = b"wipe_signature"
740799 private_key_wipe .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"wipe_public_key" )
741800
742- private_key_metadata = MagicMock ()
801+ private_key_metadata = MagicMock (spec = PrivateKey )
743802 private_key_metadata .sign .return_value = b"metadata_signature"
744803 private_key_metadata .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"metadata_public_key" )
745804
746- private_key_pause = MagicMock ()
805+ private_key_pause = MagicMock (spec = PrivateKey )
747806 private_key_pause .sign .return_value = b"pause_signature"
748807 private_key_pause .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"pause_public_key" )
749808
750- private_key_kyc = MagicMock ()
809+ private_key_kyc = MagicMock (spec = PrivateKey )
751810 private_key_kyc .sign .return_value = b"kyc_signature"
752811 private_key_kyc .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"kyc_public_key" )
753812
754- private_key_fee_schedule = MagicMock ()
813+ private_key_fee_schedule = MagicMock (spec = PrivateKey )
755814 private_key_fee_schedule .sign .return_value = b"fee_schedule_signature"
756815 private_key_fee_schedule .public_key ()._to_proto .return_value = basic_types_pb2 .Key (ed25519 = b"fee_schedule_public_key" )
757816
0 commit comments