1313from typing import TYPE_CHECKING
1414
1515if TYPE_CHECKING :
16- from typing import Tuple
16+ from typing import Tuple , List , Union , Any
1717
1818import re
1919import struct
2020import hashlib
2121from abc import ABC , abstractmethod
2222from base64 import b64encode , b64decode
23- from typing import Optional
23+ from typing import Optional , List , Tuple , Union , cast
2424from base58check import b58encode , b58decode # type: ignore
2525from ecdsa import ( # type: ignore
2626 SigningKey ,
@@ -138,26 +138,26 @@ def to_bytes(self) -> bytes:
138138 return self .key .to_string ()
139139
140140 @classmethod
141- def from_wif (cls , wif : str ):
141+ def from_wif (cls , wif : str ) -> 'PrivateKey' :
142142 """Creates key from WIFC or WIF format key"""
143143
144144 return cls (wif = wif )
145145
146146 @classmethod
147- def from_bytes (cls , b : bytes ):
147+ def from_bytes (cls , b : bytes ) -> 'PrivateKey' :
148148 """Creates a key directly from 32 raw bytes"""
149149
150150 return cls (b = b )
151151
152- def _from_bytes (self , b : bytes ):
152+ def _from_bytes (self , b : bytes ) -> None :
153153 """Creates a key directly from 32 raw bytes"""
154154
155155 if len (b ) != 32 :
156156 raise ValueError ("Invalid key length: must be exactly 32 bytes." )
157157 self .key = SigningKey .from_string (b , curve = SECP256k1 )
158158
159159 # expects wif in hex string
160- def _from_wif (self , wif : str ):
160+ def _from_wif (self , wif : str ) -> None :
161161 """Creates key from WIFC or WIF format key
162162
163163 Check to_wif for the detailed process. From WIF is the reverse.
@@ -196,7 +196,7 @@ def _from_wif(self, wif: str):
196196 else :
197197 self .key = SigningKey .from_string (key_bytes , curve = SECP256k1 )
198198
199- def to_wif (self , compressed : bool = True ):
199+ def to_wif (self , compressed : bool = True ) -> str :
200200 """Returns key in WIFC or WIF string
201201
202202 | Pseudocode:
@@ -276,8 +276,8 @@ def sign_message(self, message: str, compressed: bool = True) -> Optional[str]:
276276 return None
277277
278278 def sign_input (
279- self , tx : Transaction , txin_index : int , script : Script , sighash = SIGHASH_ALL
280- ):
279+ self , tx : Transaction , txin_index : int , script : Script , sighash : int = SIGHASH_ALL
280+ ) -> str :
281281 # get the digest from the transaction object and sign
282282 tx_digest = tx .get_transaction_digest (txin_index , script , sighash )
283283 return self ._sign_input (tx_digest , sighash )
@@ -289,7 +289,7 @@ def sign_segwit_input(
289289 script : Script ,
290290 amount : int ,
291291 sighash : int = SIGHASH_ALL ,
292- ):
292+ ) -> str :
293293 # get the digest from the transaction object and sign
294294 tx_digest = tx .get_transaction_segwit_digest (
295295 txin_index , script , amount , sighash
@@ -304,10 +304,10 @@ def sign_taproot_input(
304304 amounts : list [int ],
305305 script_path : bool = False ,
306306 tapleaf_script : Script = Script ([]),
307- tapleaf_scripts : Optional [Script | list [Script ] | list [ list [Script ]]] | bytes = None ,
307+ tapleaf_scripts : Optional [Union [ Script , List [Script ], List [ List [Script ]], bytes ]] = None ,
308308 sighash : int = TAPROOT_SIGHASH_ALL ,
309309 tweak : bool = True ,
310- ):
310+ ) -> str :
311311 # get the digest from the transaction object and sign
312312 # note that when signing a tapleaf we typically won't use tweaked
313313 # keys - so tweak should be set to False
@@ -439,7 +439,7 @@ def _sign_taproot_input(
439439 self ,
440440 tx_digest : bytes ,
441441 sighash : int = SIGHASH_ALL ,
442- scripts : Optional [Script | list [Script ] | list [ list [Script ]]] = None ,
442+ scripts : Optional [Union [ Script , List [Script ], List [ List [Script ]], bytes ]] = None ,
443443 tweak : bool = True ,
444444 ) -> str :
445445 """Signs a taproot transaction input with the private key
@@ -483,7 +483,7 @@ def _sign_taproot_input(
483483
484484 return b_to_h (sig )
485485
486- def get_public_key (self ) -> PublicKey :
486+ def get_public_key (self ) -> ' PublicKey' :
487487 """Returns the corresponding PublicKey"""
488488
489489 verifying_key = b_to_h (self .key .get_verifying_key ().to_string ())
@@ -530,7 +530,7 @@ class PublicKey:
530530 returns the corresponding P2trAddress object
531531 """
532532
533- def __init__ (self , hex_str : str = None , message : str = None , signature : bytes = None ) -> None :
533+ def __init__ (self , hex_str : Optional [ str ] = None , message : Optional [ str ] = None , signature : Optional [ bytes ] = None ) -> None :
534534 """
535535 Parameters
536536 ----------
@@ -614,7 +614,7 @@ def __init__(self, hex_str: str = None, message: str = None, signature: bytes =
614614 if not message :
615615 raise ValueError ("Empty message provided for public key recovery." )
616616
617- if ( len (signature ) != 65 ) :
617+ if not signature or len (signature ) != 65 :
618618 raise ValueError ("Invalid signature length, must be exactly 65 bytes" )
619619
620620 # The compressed signature is of the format: recovery_id (1 byte) | r (32 bytes) | s (32 bytes)
@@ -639,7 +639,7 @@ def __init__(self, hex_str: str = None, message: str = None, signature: bytes =
639639 raise TypeError ("Either 'hex_str' or ('message', 'signature') must be provided." )
640640
641641 @classmethod
642- def from_hex (cls , hex_str : str ) -> PublicKey :
642+ def from_hex (cls , hex_str : str ) -> ' PublicKey' :
643643 """Creates a public key from a hex string (SEC format)"""
644644
645645 return cls (hex_str )
@@ -674,7 +674,7 @@ def to_x_only_hex(self) -> str:
674674 return key_hex [:64 ]
675675
676676 def to_taproot_hex (
677- self , scripts : Optional [Script | list [Script ] | list [ list [Script ]]] = None
677+ self , scripts : Optional [Union [ Script , List [Script ], List [ List [Script ] ]]] = None
678678 ) -> Tuple [str , bool ]:
679679 """Returns the tweaked x coordinate of the public key as a hex string.
680680
@@ -706,7 +706,7 @@ def is_y_even(self) -> bool:
706706 return y % 2 == 0
707707
708708 @classmethod
709- def from_message_signature (cls , message , signature ) :
709+ def from_message_signature (cls , message : str , signature : bytes ) -> 'PublicKey' :
710710 """Recovers a public key from a Bitcoin-signed message and a 65-byte compressed signature.
711711 """
712712 #Note: Only works for compressed signatures because DER encoding does not contain the recovery id
@@ -831,14 +831,14 @@ def to_hash160(self, compressed: bool = True) -> str:
831831
832832 return b_to_h (self ._to_hash160 (compressed ))
833833
834- def get_address (self , compressed : bool = True ) -> P2pkhAddress :
834+ def get_address (self , compressed : bool = True ) -> ' P2pkhAddress' :
835835 """Returns the corresponding P2PKH Address (default compressed)"""
836836
837837 hash160 = self ._to_hash160 (compressed )
838838 addr_string_hex = b_to_h (hash160 )
839839 return P2pkhAddress (hash160 = addr_string_hex )
840840
841- def get_segwit_address (self ) -> P2wpkhAddress :
841+ def get_segwit_address (self ) -> ' P2wpkhAddress' :
842842 """Returns the corresponding P2WPKH address
843843
844844 Only compressed is allowed. It is otherwise identical to normal P2PKH
@@ -849,8 +849,8 @@ def get_segwit_address(self) -> P2wpkhAddress:
849849 return P2wpkhAddress (witness_program = addr_string_hex )
850850
851851 def get_taproot_address (
852- self , scripts : Optional [Script | list [Script ] | list [ list [Script ]]] | bytes = None
853- ) -> P2trAddress :
852+ self , scripts : Optional [Union [ Script , List [Script ], List [ List [Script ]], bytes ]] = None
853+ ) -> ' P2trAddress' :
854854 """Returns the corresponding P2TR address
855855
856856 Only compressed is allowed. Taproot uses x-only public key with
@@ -943,19 +943,19 @@ def __init__(
943943 raise TypeError ("A valid address or hash160 is required." )
944944
945945 @classmethod
946- def from_address (cls , address : str ) -> Address :
946+ def from_address (cls , address : str ) -> ' Address' :
947947 """Creates an address object from an address string"""
948948
949949 return cls (address = address )
950950
951951 @classmethod
952- def from_hash160 (cls , hash160 : str ) -> Address :
952+ def from_hash160 (cls , hash160 : str ) -> ' Address' :
953953 """Creates an address object from a hash160 string"""
954954
955955 return cls (hash160 = hash160 )
956956
957957 @classmethod
958- def from_script (cls , script : Script ) -> Address :
958+ def from_script (cls , script : Script ) -> ' Address' :
959959 """Creates an address object from a Script object"""
960960
961961 return cls (script = script )
@@ -1121,7 +1121,7 @@ def __init__(
11211121 address : Optional [str ] = None ,
11221122 hash160 : Optional [str ] = None ,
11231123 script : Optional [Script ] = None ,
1124- ):
1124+ ) -> None :
11251125 super ().__init__ (address = address , hash160 = hash160 , script = script )
11261126
11271127 def to_script_pub_key (self ) -> Script :
@@ -1219,19 +1219,19 @@ def __init__(
12191219 raise TypeError ("A valid address or witness program is required." )
12201220
12211221 @classmethod
1222- def from_address (cls , address : str ) -> SegwitAddress :
1222+ def from_address (cls , address : str ) -> ' SegwitAddress' :
12231223 """Creates an address object from an address string"""
12241224
12251225 return cls (address = address )
12261226
12271227 @classmethod
1228- def from_witness_program (cls , witness_program : str ) -> SegwitAddress :
1228+ def from_witness_program (cls , witness_program : str ) -> ' SegwitAddress' :
12291229 """Creates an address object from a hash string"""
12301230
12311231 return cls (witness_program = witness_program )
12321232
12331233 @classmethod
1234- def from_script (cls , script : Script ) -> SegwitAddress :
1234+ def from_script (cls , script : Script ) -> ' SegwitAddress' :
12351235 """Creates an address object from a Script object"""
12361236
12371237 return cls (script = script )
@@ -1411,4 +1411,4 @@ def main():
14111411
14121412
14131413if __name__ == "__main__" :
1414- main ()
1414+ main ()
0 commit comments