diff --git a/duniterpy/documents/crc_pubkey.py b/duniterpy/documents/crc_pubkey.py
index c8a63391a0637b7acf3423dae78dac7b3c6417a8..9d387708fa290e089be87733bc6de260f893e394 100644
--- a/duniterpy/documents/crc_pubkey.py
+++ b/duniterpy/documents/crc_pubkey.py
@@ -1,9 +1,14 @@
+from typing import TypeVar, Type
+
 import base58
 import re
 import hashlib
 from ..constants import PUBKEY_REGEX
 from ..helpers import ensure_str
 
+# required to type hint cls in classmethod
+CRCPubkeyType = TypeVar('CRCPubkeyType', bound='CRCPubkey')
+
 
 class CRCPubkey:
     """
@@ -11,23 +16,39 @@ class CRCPubkey:
     """
     re_crc_pubkey = re.compile("({pubkey_regex}):([A-Za-z0-9]{{3}})".format(pubkey_regex=PUBKEY_REGEX))
 
-    def __init__(self, pubkey, crc):
+    def __init__(self, pubkey: str, crc: str) -> None:
         """
         Creates a pubkey with a crc
-        :param pubkey:
+
+        :param pubkey: Public key
+        :param crc: CRC
         """
         self.pubkey = pubkey
         self.crc = crc
 
     @classmethod
-    def from_str(cls, crc_pubkey):
+    def from_str(cls: Type[CRCPubkeyType], crc_pubkey: str) -> CRCPubkeyType:
+        """
+        Return CRCPubkey instance from CRC public key string
+
+        :param crc_pubkey: CRC public key
+        :return:
+        """
         data = CRCPubkey.re_crc_pubkey.match(crc_pubkey)
+        if data is None:
+            raise Exception("Could not parse CRC public key {0}".format(crc_pubkey))
         pubkey = data.group(1)
         crc = data.group(2)
         return cls(pubkey, crc)
 
     @classmethod
-    def from_pubkey(cls, pubkey):
+    def from_pubkey(cls: Type[CRCPubkeyType], pubkey: str) -> CRCPubkeyType:
+        """
+        Return CRCPubkey instance from public key string
+
+        :param pubkey: Public key
+        :return:
+        """
         hash_root = hashlib.sha256()
         hash_root.update(base58.b58decode(pubkey))
         hash_squared = hashlib.sha256()
@@ -37,8 +58,16 @@ class CRCPubkey:
         crc = b58_checksum[:3]
         return cls(pubkey, crc)
 
-    def is_valid(self):
+    def is_valid(self) -> bool:
+        """
+        Return True if CRC is valid
+        :return:
+        """
         return CRCPubkey.from_pubkey(self.pubkey).crc == self.crc
 
-    def __str__(self):
+    def __str__(self) -> str:
+        """
+        Return string representation of instance
+        :return:
+        """
         return "{:}:{:}".format(self.pubkey, self.crc)