From e685da931a6bb61ba758d3eedf799f23956995b7 Mon Sep 17 00:00:00 2001
From: vtexier <vit@free.fr>
Date: Sun, 23 Sep 2018 11:50:30 +0200
Subject: [PATCH] issue #52 add type hinting and change some method signatures
 (break BC!)

Document sign, raw and signed_raw methods does not have arguments anymore
Certification sign, raw and signed_raw are renamed
Revocation sign, raw and signed_raw are renamed
verifying_key.py verify_document signature has changed
---
 duniterpy/documents/block.py          |  81 +++++++---
 duniterpy/documents/certification.py  | 212 ++++++++++++++++++--------
 duniterpy/documents/document.py       |  64 +++++---
 duniterpy/key/verifying_key.py        |   6 +-
 examples/save_revoke_document.py      |   4 +-
 examples/send_certification.py        |   4 +-
 tests/documents/test_certification.py |  10 +-
 tests/documents/test_membership.py    |   2 +-
 tests/documents/test_peer.py          |   6 +-
 tests/documents/test_transaction.py   |   6 +-
 10 files changed, 272 insertions(+), 123 deletions(-)

diff --git a/duniterpy/documents/block.py b/duniterpy/documents/block.py
index 229c343a..0822deb7 100644
--- a/duniterpy/documents/block.py
+++ b/duniterpy/documents/block.py
@@ -1,7 +1,7 @@
 import base64
 import hashlib
 import re
-from typing import Union, TypeVar, Type, Optional, List
+from typing import Union, TypeVar, Type, Optional, List, Sequence
 
 from .certification import Identity, Certification, Revocation
 from .document import Document, MalformedDocumentError
@@ -37,6 +37,8 @@ class BlockUID:
         :param blockid: The block id
         """
         data = BlockUID.re_block_uid.match(blockid)
+        if data is None:
+            raise MalformedDocumentError("BlockUID")
         try:
             number = int(data.group(1))
         except AttributeError:
@@ -52,19 +54,29 @@ class BlockUID:
     def __str__(self) -> str:
         return "{0}-{1}".format(self.number, self.sha_hash)
 
-    def __eq__(self, other: Type[BlockUIDType]) -> bool:
+    def __eq__(self, other: object) -> bool:
+        if not isinstance(other, BlockUID):
+            return False
         return self.number == other.number and self.sha_hash == other.sha_hash
 
-    def __lt__(self, other: Type[BlockUIDType]) -> bool:
+    def __lt__(self, other: object) -> bool:
+        if not isinstance(other, BlockUID):
+            return False
         return self.number < other.number
 
-    def __gt__(self, other: Type[BlockUIDType]) -> bool:
+    def __gt__(self, other: object) -> bool:
+        if not isinstance(other, BlockUID):
+            return False
         return self.number > other.number
 
-    def __le__(self, other: Type[BlockUIDType]) -> bool:
+    def __le__(self, other: object) -> bool:
+        if not isinstance(other, BlockUID):
+            return False
         return self.number <= other.number
 
-    def __ge__(self, other: Type[BlockUIDType]) -> bool:
+    def __ge__(self, other: object) -> bool:
+        if not isinstance(other, BlockUID):
+            return False
         return self.number >= other.number
 
     def __hash__(self) -> int:
@@ -215,9 +227,9 @@ The class Block handles Block documents.
                  issuers_frame: int,
                  issuers_frame_var: int,
                  different_issuers_count: int,
-                 prev_hash: str,
-                 prev_issuer: str,
-                 parameters: str,
+                 prev_hash: Optional[str],
+                 prev_issuer: Optional[str],
+                 parameters: Optional[Sequence[str]],
                  members_count: int,
                  identities: List[Identity],
                  joiners: List[Membership],
@@ -297,7 +309,7 @@ The class Block handles Block documents.
         self.noonce = noonce
 
     @property
-    def blockUID(self) -> BlockUIDType:
+    def blockUID(self) -> BlockUID:
         return BlockUID(self.number, self.proof_of_work())
 
     @classmethod
@@ -326,9 +338,10 @@ The class Block handles Block documents.
         mediantime = int(Block.parse_field("MedianTime", lines[n]))
         n += 1
 
-        ud = Block.re_universaldividend.match(lines[n])
-        unit_base = None
-        if ud is not None:
+        ud_match = Block.re_universaldividend.match(lines[n])
+        ud = None
+        unit_base = 0
+        if ud_match is not None:
             ud = int(Block.parse_field("UD", lines[n]))
             n += 1
 
@@ -354,19 +367,25 @@ The class Block handles Block documents.
         prev_hash = None
         prev_issuer = None
         if number > 0:
-            prev_hash = Block.parse_field("PreviousHash", lines[n])
+            prev_hash = str(Block.parse_field("PreviousHash", lines[n]))
             n += 1
 
-            prev_issuer = Block.parse_field("PreviousIssuer", lines[n])
+            prev_issuer = str(Block.parse_field("PreviousIssuer", lines[n]))
             n += 1
 
         parameters = None
         if number == 0:
             try:
                 if version >= 10:
-                    parameters = Block.re_parameters_v10.match(lines[n]).groups()
+                    params_match = Block.re_parameters_v10.match(lines[n])
+                    if params_match is None:
+                        raise MalformedDocumentError("Parameters")
+                    parameters = params_match.groups()
                 else:
-                    parameters = Block.re_parameters.match(lines[n]).groups()
+                    params_match = Block.re_parameters.match(lines[n])
+                    if params_match is None:
+                        raise MalformedDocumentError("Parameters")
+                    parameters = params_match.groups()
                 n += 1
             except AttributeError:
                 raise MalformedDocumentError("Parameters")
@@ -421,8 +440,10 @@ The class Block handles Block documents.
         if Block.re_excluded.match(lines[n]):
             n += 1
             while Block.re_certifications.match(lines[n]) is None:
-                exclusion = Block.re_exclusion.match(lines[n]).group(1)
-                excluded.append(exclusion)
+                exclusion_match = Block.re_exclusion.match(lines[n])
+                if exclusion_match is not None:
+                    exclusion = exclusion_match.group(1)
+                    excluded.append(exclusion)
                 n += 1
 
         if Block.re_certifications.match(lines[n]):
@@ -502,7 +523,7 @@ IssuersFrameVar: {1}
 DifferentIssuersCount: {2}
 """.format(self.issuers_frame, self.issuers_frame_var, self.different_issuers_count)
 
-        if self.number == 0:
+        if self.number == 0 and self.parameters is not None:
             str_params = ":".join([str(p) for p in self.parameters])
             doc += "Parameters: {0}\n".format(str_params)
         else:
@@ -571,17 +592,27 @@ Nonce: {nonce}
         signing = base64.b64encode(key.signature(bytes(signed, 'ascii')))
         self.signatures = [signing.decode("ascii")]
 
-    def __eq__(self, other: Type[BlockType]) -> bool:
+    def __eq__(self, other: object) -> bool:
+        if not isinstance(other, Block):
+            return False
         return self.blockUID == other.blockUID
 
-    def __lt__(self, other: Type[BlockType]) -> bool:
+    def __lt__(self, other: object) -> bool:
+        if not isinstance(other, Block):
+            return False
         return self.blockUID < other.blockUID
 
-    def __gt__(self, other: Type[BlockType]) -> bool:
+    def __gt__(self, other: object) -> bool:
+        if not isinstance(other, Block):
+            return False
         return self.blockUID > other.blockUID
 
-    def __le__(self, other: Type[BlockType]) -> bool:
+    def __le__(self, other: object) -> bool:
+        if not isinstance(other, Block):
+            return False
         return self.blockUID <= other.blockUID
 
-    def __ge__(self, other: Type[BlockType]) -> bool:
+    def __ge__(self, other: object) -> bool:
+        if not isinstance(other, Block):
+            return False
         return self.blockUID >= other.blockUID
diff --git a/duniterpy/documents/certification.py b/duniterpy/documents/certification.py
index 7e4fdc13..f32dc04b 100644
--- a/duniterpy/documents/certification.py
+++ b/duniterpy/documents/certification.py
@@ -1,10 +1,15 @@
 import base64
 import logging
 import re
+from typing import Optional, TypeVar, Type, List
 
+from duniterpy.documents import BlockUID
 from ..constants import PUBKEY_REGEX, SIGNATURE_REGEX, BLOCK_ID_REGEX, BLOCK_UID_REGEX, UID_REGEX
 from .document import Document, MalformedDocumentError
 
+# required to type hint cls in classmethod
+IdentityType = TypeVar('IdentityType', bound='Identity')
+
 
 class Identity(Document):
     """
@@ -29,16 +34,17 @@ class Identity(Document):
         "Timestamp": re_timestamp
     }}
 
-    def __init__(self, version, currency, pubkey, uid, ts, signature):
+    def __init__(self, version: int, currency: str, pubkey: str, uid: str, ts: BlockUID,
+                 signature: Optional[str]) -> None:
         """
         Create an identity document
 
-        :param int version: Version of the document
-        :param str currency: Name of the currency
-        :param str pubkey:  Public key of the account linked to the identity
-        :param str uid: Unique identifier
-        :param BlockUID ts: Block timestamp
-        :param str|None signature: Signature of the document
+        :param version: Version of the document
+        :param currency: Name of the currency
+        :param pubkey:  Public key of the account linked to the identity
+        :param uid: Unique identifier
+        :param ts: Block timestamp
+        :param signature: Signature of the document
         """
         if signature:
             super().__init__(version, currency, [signature])
@@ -49,7 +55,14 @@ class Identity(Document):
         self.uid = uid
 
     @classmethod
-    def from_inline(cls, version, currency, inline):
+    def from_inline(cls: Type[IdentityType], version: int, currency: str, inline: str) -> IdentityType:
+        """
+        Return Identity instance from inline Identity string
+        :param version: Document version number
+        :param currency: Name of the currency
+        :param inline: Inline string of the Identity
+        :return:
+        """
         from .block import BlockUID
 
         selfcert_data = Identity.re_inline.match(inline)
@@ -63,7 +76,12 @@ class Identity(Document):
         return cls(version, currency, pubkey, uid, ts, signature)
 
     @classmethod
-    def from_signed_raw(cls, signed_raw):
+    def from_signed_raw(cls: Type[IdentityType], signed_raw: str) -> IdentityType:
+        """
+        Return Identity instance from a signed_raw string
+        :param signed_raw: Signed raw document
+        :return:
+        """
         from .block import BlockUID
 
         n = 0
@@ -91,7 +109,11 @@ class Identity(Document):
 
         return cls(version, currency, pubkey, uid, ts, signature)
 
-    def raw(self):
+    def raw(self) -> str:
+        """
+        Return a raw document of the Identity
+        :return:
+        """
         return """Version: {version}
 Type: Identity
 Currency: {currency}
@@ -104,7 +126,11 @@ Timestamp: {timestamp}
            uid=self.uid,
            timestamp=self.timestamp)
 
-    def inline(self):
+    def inline(self) -> str:
+        """
+        Return an inline string of the Identity
+        :return:
+        """
         return "{pubkey}:{signature}:{timestamp}:{uid}".format(
             pubkey=self.pubkey,
             signature=self.signatures[0],
@@ -112,6 +138,10 @@ Timestamp: {timestamp}
             uid=self.uid)
 
 
+# required to type hint cls in classmethod
+CertificationType = TypeVar('CertificationType', bound='Certification')
+
+
 class Certification(Document):
     """
     A document describing a certification.
@@ -142,17 +172,17 @@ class Certification(Document):
         "IdtyTimestamp": re_idty_timestamp
     }}
 
-    def __init__(self, version, currency, pubkey_from, pubkey_to,
-                 timestamp, signature):
+    def __init__(self, version: int, currency: str, pubkey_from: str, pubkey_to: str,
+                 timestamp: BlockUID, signature: str) -> None:
         """
         Constructor
 
-        :param int version: the UCP version
-        :param str currency: the currency of the blockchain
-        :param str pubkey_from:
-        :param str pubkey_to:
-        :param BlockUID timestamp: the blockuid
-        :param str signature: the signature of the document
+        :param version: the UCP version
+        :param currency: the currency of the blockchain
+        :param pubkey_from: Pubkey of the certifier
+        :param pubkey_to: Pubkey of the certified
+        :param timestamp: the blockuid
+        :param signature: the signature of the document
         """
         super().__init__(version, currency, [signature])
         self.pubkey_from = pubkey_from
@@ -160,7 +190,13 @@ class Certification(Document):
         self.timestamp = timestamp
 
     @classmethod
-    def from_signed_raw(cls, signed_raw):
+    def from_signed_raw(cls: Type[CertificationType], signed_raw: str) -> CertificationType:
+        """
+        Return Certification instance from signed raw document
+
+        :param signed_raw: Signed raw document
+        :return:
+        """
         from .block import BlockUID
 
         n = 0
@@ -198,13 +234,15 @@ class Certification(Document):
         return cls(version, currency, pubkey_from, pubkey_to, timestamp, signature)
 
     @classmethod
-    def from_inline(cls, version, currency, blockhash, inline):
+    def from_inline(cls: Type[CertificationType], version: int, currency: str, blockhash: Optional[str],
+                    inline: str) -> CertificationType:
         """
-        From inline version in block
-        :param version:
-        :param currency:
-        :param blockhash:
-        :param inline:
+        Return Certification instance from inline document
+
+        :param version: Version of document
+        :param currency: Name of the currency
+        :param blockhash: Hash of the block
+        :param inline: Inline document
         :return:
         """
         from .block import BlockUID
@@ -214,7 +252,7 @@ class Certification(Document):
         pubkey_from = cert_data.group(1)
         pubkey_to = cert_data.group(2)
         blockid = int(cert_data.group(3))
-        if blockid == 0:
+        if blockid == 0 or blockhash is None:
             timestamp = BlockUID.empty()
         else:
             timestamp = BlockUID(blockid, blockhash)
@@ -222,10 +260,11 @@ class Certification(Document):
         signature = cert_data.group(4)
         return cls(version, currency, pubkey_from, pubkey_to, timestamp, signature)
 
-    def raw(self, selfcert):
+    def raw_for_certified(self, certified: Identity) -> str:
         """
+        Return a raw document of the self-certification of the Identity
 
-        :param Identity selfcert:
+        :param Identity certified: Identity document instance
         :return:
         """
         return """Version: {version}
@@ -240,34 +279,53 @@ CertTimestamp: {timestamp}
 """.format(version=self.version,
            currency=self.currency,
            issuer=self.pubkey_from,
-           certified_pubkey=selfcert.pubkey,
-           certified_uid=selfcert.uid,
-           certified_ts=selfcert.timestamp,
-           certified_signature=selfcert.signatures[0],
+           certified_pubkey=certified.pubkey,
+           certified_uid=certified.uid,
+           certified_ts=certified.timestamp,
+           certified_signature=certified.signatures[0],
            timestamp=self.timestamp)
 
-    def sign(self, selfcert, keys):
+    def sign_for_certified(self, certified: Identity, keys: list) -> None:
         """
-        Sign the current document.
+        Sign the current document with the keys for the certified Identity given
+
         Warning : current signatures will be replaced with the new ones.
+
+        :param certified: Identity instance certified
+        :param keys: List of libnacl key instances
         """
         self.signatures = []
         for key in keys:
-            signing = base64.b64encode(key.signature(bytes(self.raw(selfcert), 'ascii')))
+            signing = base64.b64encode(key.signature(bytes(self.raw_for_certified(certified), 'ascii')))
             logging.debug("Signature : \n{0}".format(signing.decode("ascii")))
             self.signatures.append(signing.decode("ascii"))
 
-    def signed_raw(self, selfcert):
-        raw = self.raw(selfcert)
+    def signed_raw_for_certified(self, certified: Identity) -> str:
+        """
+        Return signed raw document of the certification for the certified Identity instance
+
+        :param certified: Certified Identity instance
+        :return:
+        """
+        raw = self.raw_for_certified(certified)
         signed = "\n".join(self.signatures)
         signed_raw = raw + signed + "\n"
         return signed_raw
 
-    def inline(self):
+    def inline(self) -> str:
+        """
+        Return inline document string
+
+        :return:
+        """
         return "{0}:{1}:{2}:{3}".format(self.pubkey_from, self.pubkey_to,
                                         self.timestamp.number, self.signatures[0])
 
 
+# required to type hint cls in classmethod
+RevocationType = TypeVar('RevocationType', bound='Revocation')
+
+
 class Revocation(Document):
     """
     A document describing a self-revocation.
@@ -291,20 +349,27 @@ class Revocation(Document):
         "IdtySignature": re_idtysignature,
     }}
 
-    def __init__(self, version, currency, pubkey, signature):
+    def __init__(self, version: int, currency: str, pubkey: str, signature: str) -> None:
         """
-        Constructor
+        Init Revocation instance
+
+        :param version: Version number
+        :param currency: Name of the currency
+        :param pubkey: Public key of the issuer
+        :param signature: Signature
         """
         super().__init__(version, currency, [signature])
         self.pubkey = pubkey
 
     @classmethod
-    def from_inline(cls, version, currency, inline):
+    def from_inline(cls: Type[RevocationType], version: int, currency: str, inline: str) -> RevocationType:
         """
-        From inline version in block
-        :param int version:
-        :param str currency:
-        :param str inline:
+        Return Revocation document instance from inline string
+
+        :param version: Version number
+        :param currency: Name of the currency
+        :param inline: Inline document
+
         :return:
         """
         cert_data = Revocation.re_inline.match(inline)
@@ -315,11 +380,12 @@ class Revocation(Document):
         return cls(version, currency, pubkey, signature)
 
     @classmethod
-    def from_signed_raw(cls, signed_raw):
+    def from_signed_raw(cls: Type[RevocationType], signed_raw: str) -> RevocationType:
         """
-        Instanciates a revocation from a signed raw file
-        :param str signed_raw: raw document file in duniter format
-        :return: a revocation instance
+        Return Revocation document instance from a signed raw string
+
+        :param signed_raw: raw document file in duniter format
+        :return:
         """
         lines = signed_raw.splitlines(True)
         n = 0
@@ -342,7 +408,13 @@ class Revocation(Document):
         return cls(version, currency, issuer, signature)
 
     @staticmethod
-    def extract_self_cert(signed_raw):
+    def extract_self_cert(signed_raw: str) -> Identity:
+        """
+        Return self-certified Identity instance from the signed raw Revocation document
+
+        :param signed_raw: Signed raw document string
+        :return:
+        """
         lines = signed_raw.splitlines(True)
         n = 0
 
@@ -369,13 +441,19 @@ class Revocation(Document):
 
         return Identity(version, currency, issuer, unique_id, timestamp, signature)
 
-    def inline(self):
+    def inline(self) -> str:
+        """
+        Return inline document string
+
+        :return:
+        """
         return "{0}:{1}".format(self.pubkey, self.signatures[0])
 
-    def raw(self, selfcert):
+    def raw_for_revoked(self, revoked: Identity) -> str:
         """
+        Return Revocation raw document string from Identity instance
 
-        :param Identity selfcert:
+        :param Identity revoked: Identity instance
         :return:
         """
         return """Version: {version}
@@ -387,23 +465,33 @@ IdtyTimestamp: {timestamp}
 IdtySignature: {signature}
 """.format(version=self.version,
            currency=self.currency,
-           pubkey=selfcert.pubkey,
-           uid=selfcert.uid,
-           timestamp=selfcert.timestamp,
-           signature=selfcert.signatures[0])
+           pubkey=revoked.pubkey,
+           uid=revoked.uid,
+           timestamp=revoked.timestamp,
+           signature=revoked.signatures[0])
 
-    def sign(self, selfcert, keys):
+    def sign_for_revoked(self, revoked: Identity, keys: list) -> None:
         """
         Sign the current document.
         Warning : current signatures will be replaced with the new ones.
+
+        :param revoked: Identity instance
+        :param keys: List of libnacl key instances
+        :return:
         """
         self.signatures = []
         for key in keys:
-            signing = base64.b64encode(key.signature(bytes(self.raw(selfcert), 'ascii')))
+            signing = base64.b64encode(key.signature(bytes(self.raw_for_revoked(revoked), 'ascii')))
             self.signatures.append(signing.decode("ascii"))
 
-    def signed_raw(self, selfcert):
-        raw = self.raw(selfcert)
+    def signed_raw_for_revoked(self, revoked: Identity) -> str:
+        """
+        Return Revocation signed raw document string for revoked Identity instance
+
+        :param revoked: Identity instance
+        :return:
+        """
+        raw = self.raw_for_revoked(revoked)
         signed = "\n".join(self.signatures)
         signed_raw = raw + signed + "\n"
         return signed_raw
diff --git a/duniterpy/documents/document.py b/duniterpy/documents/document.py
index a2c21e47..55677bd8 100644
--- a/duniterpy/documents/document.py
+++ b/duniterpy/documents/document.py
@@ -2,6 +2,7 @@ import base64
 import hashlib
 import logging
 import re
+from typing import TypeVar, Type, Any, List
 
 from ..constants import SIGNATURE_REGEX
 
@@ -11,10 +12,19 @@ class MalformedDocumentError(Exception):
     Malformed document exception
     """
 
-    def __init__(self, field_name):
+    def __init__(self, field_name: str) -> None:
+        """
+        Init exception instance
+
+        :param field_name: Name of the wrong field
+        """
         super().__init__("Could not parse field {0}".format(field_name))
 
 
+# required to type hint cls in classmethod
+DocumentType = TypeVar('DocumentType', bound='Document')
+
+
 class Document:
     re_version = re.compile("Version: ([0-9]+)\n")
     re_currency = re.compile("Currency: ([^\n]+)\n")
@@ -26,21 +36,14 @@ class Document:
         "Signature": re_signature
     }
 
-    @classmethod
-    def parse_field(cls, field_name, line):
+    def __init__(self, version: int, currency: str, signatures: List[str]) -> None:
         """
+        Init Document instance
 
-        :param field_name:
-        :param line:
-        :return:
+        :param version: Version of the Document
+        :param currency: Name of the currency
+        :param signatures: List of signatures
         """
-        try:
-            value = cls.fields_parsers[field_name].match(line).group(1)
-        except AttributeError:
-            raise MalformedDocumentError(field_name)
-        return value
-
-    def __init__(self, version, currency, signatures):
         if version < 2:
             raise MalformedDocumentError("Version 1 documents are not handled by duniterpy>0.2")
         self.version = version
@@ -50,10 +53,31 @@ class Document:
         else:
             self.signatures = []
 
-    def sign(self, keys):
+    @classmethod
+    def parse_field(cls: Type[DocumentType], field_name: str, line: str) -> Any:
+        """
+        Parse a document field with regular expression and return the value
+
+        :param field_name: Name of the field
+        :param line: Line string to parse
+        :return:
+        """
+        try:
+            match = cls.fields_parsers[field_name].match(line)
+            if match is None:
+                raise AttributeError
+            value = match.group(1)
+        except AttributeError:
+            raise MalformedDocumentError(field_name)
+        return value
+
+    def sign(self, keys: list) -> None:
         """
         Sign the current document.
+
         Warning : current signatures will be replaced with the new ones.
+
+        :param keys: List of libnacl keys instance
         """
         self.signatures = []
         for key in keys:
@@ -61,16 +85,17 @@ class Document:
             logging.debug("Signature : \n{0}".format(signing.decode("ascii")))
             self.signatures.append(signing.decode("ascii"))
 
-    def raw(self, **kwargs):
+    def raw(self) -> str:
         """
         Returns the raw document in string format
         """
         raise NotImplementedError()
 
-    def signed_raw(self, *args):
+    def signed_raw(self) -> str:
         """
         If keys are None, returns the raw + current signatures
         If keys are present, returns the raw signed by these keys
+        :return:
         """
         raw = self.raw()
         signed = "\n".join(self.signatures)
@@ -78,5 +103,10 @@ class Document:
         return signed_raw
 
     @property
-    def sha_hash(self):
+    def sha_hash(self) -> str:
+        """
+        Return uppercase hex sha256 hash from signed raw document
+
+        :return:
+        """
         return hashlib.sha256(self.signed_raw().encode("ascii")).hexdigest().upper()
diff --git a/duniterpy/key/verifying_key.py b/duniterpy/key/verifying_key.py
index 5821bcc1..ba4652a6 100644
--- a/duniterpy/key/verifying_key.py
+++ b/duniterpy/key/verifying_key.py
@@ -17,6 +17,7 @@ class VerifyingKey(libnacl.sign.Verifier):
     """
     Class to verify documents
     """
+
     def __init__(self, pubkey: str) -> None:
         """
         Creates a Verify class from base58 pubkey
@@ -25,14 +26,14 @@ class VerifyingKey(libnacl.sign.Verifier):
         key = libnacl.encode.hex_encode(Base58Encoder.decode(pubkey))
         super().__init__(key)
 
-    def verify_document(self, document: Document, **kwargs) -> bool:
+    def verify_document(self, document: Document) -> bool:
         """
         Check specified document
         :param duniterpy.documents.Document document:
         :return:
         """
         signature = base64.b64decode(document.signatures[0])
-        prepended = signature + bytes(document.raw(**kwargs), 'ascii')
+        prepended = signature + bytes(document.raw(), 'ascii')
 
         try:
             self.verify(prepended)
@@ -66,4 +67,3 @@ class VerifyingKey(libnacl.sign.Verifier):
         :return str:
         """
         return self.verify(message).decode('utf-8')
-
diff --git a/examples/save_revoke_document.py b/examples/save_revoke_document.py
index e5fd24e1..8522cfb8 100644
--- a/examples/save_revoke_document.py
+++ b/examples/save_revoke_document.py
@@ -87,8 +87,8 @@ def get_signed_raw_revocation_document(identity: Identity, salt: str, password:
     revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity.pubkey, "")
 
     key = SigningKey(salt, password)
-    revocation.sign(identity, [key])
-    return revocation.signed_raw(identity)
+    revocation.sign_for_revoked(identity, [key])
+    return revocation.signed_raw_for_revoked(identity)
 
 
 async def main():
diff --git a/examples/send_certification.py b/examples/send_certification.py
index 0da9a8ee..59c96a24 100644
--- a/examples/send_certification.py
+++ b/examples/send_certification.py
@@ -80,7 +80,7 @@ def get_certification_document(current_block: dict, self_cert_document: Identity
     )
     # sign document
     key = SigningKey(salt, password)
-    certification.sign(self_cert_document, [key])
+    certification.sign_for_certified(self_cert_document, [key])
 
     return certification
 
@@ -118,7 +118,7 @@ async def main():
     certification = get_certification_document(current_block, identity, pubkey_from, salt, password)
 
     # Here we request for the path wot/certify
-    response = await client(bma.wot.certify, certification.signed_raw(identity))
+    response = await client(bma.wot.certify, certification.signed_raw_for_certified(identity))
 
     if response.status == 200:
         print(await response.text())
diff --git a/tests/documents/test_certification.py b/tests/documents/test_certification.py
index 2c86dde6..65d77284 100644
--- a/tests/documents/test_certification.py
+++ b/tests/documents/test_certification.py
@@ -107,10 +107,10 @@ IdtySignature: J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6B
 CertTimestamp: 36-1076F10A7397715D2BEE82579861999EA1F274AC
 SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneNYSMV3rk
 """
-        self.assertEqual(certification.signed_raw(selfcert), result)
+        self.assertEqual(certification.signed_raw_for_certified(selfcert), result)
 
-        from_raw = Certification.from_signed_raw(certification.signed_raw(selfcert))
-        self.assertEqual(from_raw.signed_raw(selfcert), result)
+        from_raw = Certification.from_signed_raw(certification.signed_raw_for_certified(selfcert))
+        self.assertEqual(from_raw.signed_raw_for_certified(selfcert), result)
 
     def test_revokation_from_inline(self):
         version = 2
@@ -139,7 +139,7 @@ IdtyTimestamp: 32-DB30D958EE5CB75186972286ED3F4686B8A1C2CD
 IdtySignature: J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci
 SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneNYSMV3rk
 """
-        self.assertEqual(revokation.signed_raw(selfcert), result)
+        self.assertEqual(revokation.signed_raw_for_revoked(selfcert), result)
 
     def test_revokation_from_signed_raw(self):
         signed_raw = """Version: 2
@@ -153,4 +153,4 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN
 """
         revocation = Revocation.from_signed_raw(signed_raw)
         selfcert = Revocation.extract_self_cert(signed_raw)
-        self.assertEqual(revocation.signed_raw(selfcert), signed_raw)
+        self.assertEqual(revocation.signed_raw_for_revoked(selfcert), signed_raw)
diff --git a/tests/documents/test_membership.py b/tests/documents/test_membership.py
index 4c2fe1f1..c5eefdaa 100644
--- a/tests/documents/test_membership.py
+++ b/tests/documents/test_membership.py
@@ -47,7 +47,7 @@ class Test_Membership(unittest.TestCase):
 
     def test_fromraw_toraw(self):
         membership = Membership.from_signed_raw(membership_raw)
-        rendered_membership = membership.signed_raw()
+        rendered_membership = membership.signed_raw_for_certified()
         from_rendered_membership = Membership.from_signed_raw(rendered_membership)
         self.assertEqual(from_rendered_membership.issuer, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
         self.assertEqual(from_rendered_membership.membership_ts.number, 0)
diff --git a/tests/documents/test_peer.py b/tests/documents/test_peer.py
index 192cb052..46a9e966 100644
--- a/tests/documents/test_peer.py
+++ b/tests/documents/test_peer.py
@@ -59,7 +59,7 @@ class TestPeer(unittest.TestCase):
 
     def test_fromraw_toraw(self):
         peer = Peer.from_signed_raw(rawpeer)
-        rendered_peer = peer.signed_raw()
+        rendered_peer = peer.signed_raw_for_certified()
         from_rendered_peer = Peer.from_signed_raw(rendered_peer)
 
         self.assertEqual(from_rendered_peer.currency, "beta_brousouf")
@@ -87,9 +87,9 @@ class TestPeer(unittest.TestCase):
 
         self.assertEqual(from_rendered_peer.signatures[0],
                          "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==")
-        self.assertEqual(rawpeer, from_rendered_peer.signed_raw())
+        self.assertEqual(rawpeer, from_rendered_peer.signed_raw_for_certified())
 
     def test_incorrect(self):
         peer = Peer.from_signed_raw(test_weird_ipv6_peer)
-        rendered_peer = peer.signed_raw()
+        rendered_peer = peer.signed_raw_for_certified()
         Peer.from_signed_raw(rendered_peer)
diff --git a/tests/documents/test_transaction.py b/tests/documents/test_transaction.py
index a14fe4e1..d872634b 100644
--- a/tests/documents/test_transaction.py
+++ b/tests/documents/test_transaction.py
@@ -299,7 +299,7 @@ class Test_Transaction(unittest.TestCase):
 
     def test_fromraw_toraw(self):
         tx = Transaction.from_signed_raw(tx_raw)
-        rendered_tx = tx.signed_raw()
+        rendered_tx = tx.signed_raw_for_certified()
         from_rendered_tx = Transaction.from_signed_raw(rendered_tx)
 
         self.assertEqual(tx.version, 2)
@@ -366,7 +366,7 @@ class Test_Transaction(unittest.TestCase):
 
     def test_fromraw_toraw_v3(self):
         tx = Transaction.from_signed_raw(tx_raw_v3)
-        rendered_tx = tx.signed_raw()
+        rendered_tx = tx.signed_raw_for_certified()
         from_rendered_tx = Transaction.from_signed_raw(rendered_tx)
 
         self.assertEqual(tx.version, 3)
@@ -435,7 +435,7 @@ class Test_Transaction(unittest.TestCase):
 
     def test_compact_change(self):
         tx = Transaction.from_compact("gtest", compact_change)
-        rendered_tx = tx.signed_raw()
+        rendered_tx = tx.signed_raw_for_certified()
         from_rendered_tx = Transaction.from_signed_raw(rendered_tx)
 
     def test_reduce_base(self):
-- 
GitLab