From ce59413bbea7c4990e723bf852a31463ae733e87 Mon Sep 17 00:00:00 2001
From: Vincent Texier <vit@free.fr>
Date: Sun, 13 Jun 2021 10:47:08 +0200
Subject: [PATCH] [enh] #95 remove useless signature argument from
 Document.__init__

Rename Identity(ts: BlockUID) by Identity(timestamp: BlockUID)
Break backward compatibility !
---
 duniterpy/documents/block.py          |  20 ++--
 duniterpy/documents/certification.py  |  73 ++++-----------
 duniterpy/documents/document.py       |   8 +-
 duniterpy/documents/identity.py       | 126 ++++++++++++++++++++++----
 duniterpy/documents/membership.py     |  44 +++++----
 duniterpy/documents/peer.py           |  16 +++-
 duniterpy/documents/revocation.py     |  76 ++++------------
 duniterpy/documents/transaction.py    |  21 +++--
 duniterpy/documents/ws2p/messages.py  |   8 +-
 examples/save_revoke_document.py      |   6 +-
 examples/send_certification.py        |   5 +-
 examples/send_identity.py             |   3 +-
 examples/send_transaction.py          |   1 -
 tests/api/ws2p/test_ws2p.py           |   1 -
 tests/documents/test_certification.py |  18 +++-
 tests/documents/test_transaction.py   |   1 -
 16 files changed, 220 insertions(+), 207 deletions(-)

diff --git a/duniterpy/documents/block.py b/duniterpy/documents/block.py
index 70061828..a465c4ff 100644
--- a/duniterpy/documents/block.py
+++ b/duniterpy/documents/block.py
@@ -174,7 +174,6 @@ class Block(Document):
         transactions: List[Transaction],
         inner_hash: str,
         nonce: int,
-        signature: str,
     ) -> None:
         """
         Constructor
@@ -205,9 +204,8 @@ class Block(Document):
         :param transactions: transactions documents
         :param inner_hash: the block hash
         :param nonce: the nonce value of the block
-        :param signature: the block signature
         """
-        super().__init__(version, currency, [signature])
+        super().__init__(version, currency)
         documents_versions = max(
             max([1] + [i.version for i in identities]),
             max([1] + [m.version for m in actives + leavers + joiners]),
@@ -245,6 +243,7 @@ class Block(Document):
         self.transactions = transactions
         self.inner_hash = inner_hash
         self.nonce = nonce
+        self.signatures = list()
 
     @property
     def blockUID(self) -> BlockUID:
@@ -283,7 +282,6 @@ class Block(Document):
             "transactions": b["transactions"],
             "inner_hash": b["inner_hash"],
             "nonce": b["nonce"],
-            "signature": b["signature"],
         }
         # parameters: Optional[Sequence[str]]
         if arguments["parameters"]:
@@ -325,8 +323,11 @@ class Block(Document):
             Transaction.from_bma_history(currency, i) for i in arguments["transactions"]
         ]
 
-        # now that the arguments are ready, return the block
-        return cls(**arguments)
+        block = cls(**arguments)
+
+        # return the block with signature
+        block.signatures = [b["signature"]]
+        return block
 
     @classmethod
     def from_signed_raw(cls: Type[BlockType], signed_raw: str) -> BlockType:
@@ -497,7 +498,7 @@ class Block(Document):
 
         signature = Block.parse_field("Signature", lines[n])
 
-        return cls(
+        block = cls(
             version,
             currency,
             number,
@@ -524,9 +525,12 @@ class Block(Document):
             transactions,
             inner_hash,
             nonce,
-            signature,
         )
 
+        # return block with signature
+        block.signatures = [signature]
+        return block
+
     def raw(self) -> str:
         doc = """Version: {version}
 Type: Block
diff --git a/duniterpy/documents/certification.py b/duniterpy/documents/certification.py
index ede06b54..dd087d42 100644
--- a/duniterpy/documents/certification.py
+++ b/duniterpy/documents/certification.py
@@ -18,13 +18,7 @@ import logging
 import re
 from typing import Optional, Type, TypeVar, Union
 
-from ..constants import (
-    BLOCK_ID_REGEX,
-    BLOCK_UID_REGEX,
-    PUBKEY_REGEX,
-    SIGNATURE_REGEX,
-    UID_REGEX,
-)
+from ..constants import BLOCK_ID_REGEX, BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX
 from .block_uid import BlockUID
 from .document import Document, MalformedDocumentError
 from .identity import Identity
@@ -53,33 +47,13 @@ class Certification(Document):
     re_issuer = re.compile(
         "Issuer: ({pubkey_regex})\n".format(pubkey_regex=PUBKEY_REGEX)
     )
-    re_idty_issuer = re.compile(
-        "IdtyIssuer: ({pubkey_regex})\n".format(pubkey_regex=PUBKEY_REGEX)
-    )
-    re_idty_unique_id = re.compile(
-        "IdtyUniqueID: ({uid_regex})\n".format(uid_regex=UID_REGEX)
-    )
-    re_idty_timestamp = re.compile(
-        "IdtyTimestamp: ({block_uid_regex})\n".format(block_uid_regex=BLOCK_UID_REGEX)
-    )
-    re_idty_signature = re.compile(
-        "IdtySignature: ({signature_regex})\n".format(signature_regex=SIGNATURE_REGEX)
-    )
     re_cert_timestamp = re.compile(
         "CertTimestamp: ({block_uid_regex})\n".format(block_uid_regex=BLOCK_UID_REGEX)
     )
 
     fields_parsers = {
         **Document.fields_parsers,
-        **{
-            "Type": re_type,
-            "Issuer": re_issuer,
-            "CertTimestamp": re_cert_timestamp,
-            "IdtyIssuer": re_idty_issuer,
-            "IdtyUniqueID": re_idty_unique_id,
-            "IdtySignature": re_idty_signature,
-            "IdtyTimestamp": re_idty_timestamp,
-        },
+        **{"Type": re_type, "Issuer": re_issuer, "CertTimestamp": re_cert_timestamp},
     }
 
     def __init__(
@@ -89,7 +63,6 @@ class Certification(Document):
         pubkey_from: str,
         identity: Union[Identity, str],
         timestamp: BlockUID,
-        signature: str,
     ) -> None:
         """
         Constructor
@@ -99,9 +72,8 @@ class Certification(Document):
         :param pubkey_from: Pubkey of the certifier
         :param identity: Document instance of the certified identity or identity pubkey string
         :param timestamp: the blockuid
-        :param signature: the signature of the document
         """
-        super().__init__(version, currency, [signature])
+        super().__init__(version, currency)
         self.pubkey_from = pubkey_from
         self.identity = identity if isinstance(identity, Identity) else None
         self.pubkey_to = identity.pubkey if isinstance(identity, Identity) else identity
@@ -120,7 +92,7 @@ class Certification(Document):
         n = 0
         lines = signed_raw.splitlines(True)
 
-        version = int(Identity.parse_field("Version", lines[n]))
+        version = int(Certification.parse_field("Version", lines[n]))
         n += 1
 
         Certification.parse_field("Type", lines[n])
@@ -130,21 +102,7 @@ class Certification(Document):
         n += 1
 
         pubkey_from = Certification.parse_field("Issuer", lines[n])
-        n += 1
-
-        identity_pubkey = Certification.parse_field("IdtyIssuer", lines[n])
-        n += 1
-
-        identity_uid = Certification.parse_field("IdtyUniqueID", lines[n])
-        n += 1
-
-        identity_timestamp = BlockUID.from_str(
-            Certification.parse_field("IdtyTimestamp", lines[n])
-        )
-        n += 1
-
-        identity_signature = Certification.parse_field("IdtySignature", lines[n])
-        n += 1
+        n += 5
 
         timestamp = BlockUID.from_str(
             Certification.parse_field("CertTimestamp", lines[n])
@@ -153,16 +111,13 @@ class Certification(Document):
 
         signature = Certification.parse_field("Signature", lines[n])
 
-        identity = Identity(
-            version,
-            currency,
-            identity_pubkey,
-            identity_uid,
-            identity_timestamp,
-            identity_signature,
-        )
+        identity = Identity.from_certification_raw(signed_raw)
 
-        return cls(version, currency, pubkey_from, identity, timestamp, signature)
+        certification = cls(version, currency, pubkey_from, identity, timestamp)
+
+        # return certification with signature
+        certification.signatures = [signature]
+        return certification
 
     @classmethod
     def from_inline(
@@ -196,7 +151,11 @@ class Certification(Document):
             timestamp = BlockUID(blockid, blockhash)
 
         signature = cert_data.group(4)
-        return cls(version, currency, pubkey_from, pubkey_to, timestamp, signature)
+        certification = cls(version, currency, pubkey_from, pubkey_to, timestamp)
+
+        # return certification with signature
+        certification.signatures = [signature]
+        return certification
 
     def raw(self) -> str:
         """
diff --git a/duniterpy/documents/document.py b/duniterpy/documents/document.py
index f0890328..1d9f5536 100644
--- a/duniterpy/documents/document.py
+++ b/duniterpy/documents/document.py
@@ -53,20 +53,16 @@ class Document:
         "Signature": re_signature,
     }
 
-    def __init__(self, version: int, currency: str, signatures: List[str]) -> None:
+    def __init__(self, version: int, currency: str) -> None:
         """
         Init Document instance
 
         :param version: Version of the Document
         :param currency: Name of the currency
-        :param signatures: List of signatures
         """
         self.version = version
         self.currency = currency
-        if signatures:
-            self.signatures = [s for s in signatures if s is not None]
-        else:
-            self.signatures = []
+        self.signatures: List[str] = list()
 
     @classmethod
     def parse_field(cls: Type[DocumentType], field_name: str, line: str) -> Any:
diff --git a/duniterpy/documents/identity.py b/duniterpy/documents/identity.py
index 3bc878b3..d952a527 100644
--- a/duniterpy/documents/identity.py
+++ b/duniterpy/documents/identity.py
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
-from typing import Optional, Type, TypeVar
+from typing import Type, TypeVar
 
 from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX, UID_REGEX
 from .block_uid import BlockUID
@@ -49,6 +49,19 @@ class Identity(Document):
         "Timestamp: ({block_uid_regex})\n".format(block_uid_regex=BLOCK_UID_REGEX)
     )
 
+    re_idty_issuer = re.compile(
+        "IdtyIssuer: ({pubkey_regex})\n".format(pubkey_regex=PUBKEY_REGEX)
+    )
+    re_idty_unique_id = re.compile(
+        "IdtyUniqueID: ({uid_regex})\n".format(uid_regex=UID_REGEX)
+    )
+    re_idty_timestamp = re.compile(
+        "IdtyTimestamp: ({block_uid_regex})\n".format(block_uid_regex=BLOCK_UID_REGEX)
+    )
+    re_idty_signature = re.compile(
+        "IdtySignature: ({signature_regex})\n".format(signature_regex=SIGNATURE_REGEX)
+    )
+
     fields_parsers = {
         **Document.fields_parsers,
         **{
@@ -56,17 +69,15 @@ class Identity(Document):
             "UniqueID": re_unique_id,
             "Issuer": re_issuer,
             "Timestamp": re_timestamp,
+            "IdtyIssuer": re_idty_issuer,
+            "IdtyUniqueID": re_idty_unique_id,
+            "IdtyTimestamp": re_idty_timestamp,
+            "IdtySignature": re_idty_signature,
         },
     }
 
     def __init__(
-        self,
-        version: int,
-        currency: str,
-        pubkey: str,
-        uid: str,
-        ts: BlockUID,
-        signature: Optional[str],
+        self, version: int, currency: str, pubkey: str, uid: str, timestamp: BlockUID
     ) -> None:
         """
         Create an identity document
@@ -75,15 +86,12 @@ class Identity(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
+        :param timestamp: BlockUID instance
         """
-        if signature:
-            super().__init__(version, currency, [signature])
-        else:
-            super().__init__(version, currency, [])
+        super().__init__(version, currency)
+
         self.pubkey = pubkey
-        self.timestamp = ts
+        self.timestamp = timestamp
         self.uid = uid
 
     @classmethod
@@ -92,6 +100,7 @@ class Identity(Document):
     ) -> 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
@@ -102,15 +111,20 @@ class Identity(Document):
             raise MalformedDocumentError("Inline self certification")
         pubkey = selfcert_data.group(1)
         signature = selfcert_data.group(2)
-        ts = BlockUID.from_str(selfcert_data.group(3))
+        blockstamp = BlockUID.from_str(selfcert_data.group(3))
         uid = selfcert_data.group(4)
 
-        return cls(version, currency, pubkey, uid, ts, signature)
+        identity = cls(version, currency, pubkey, uid, blockstamp)
+
+        # return identity with signature
+        identity.signatures = [signature]
+        return identity
 
     @classmethod
     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:
         """
@@ -132,16 +146,21 @@ class Identity(Document):
         uid = Identity.parse_field("UniqueID", lines[n])
         n += 1
 
-        ts = BlockUID.from_str(Identity.parse_field("Timestamp", lines[n]))
+        blockstamp = BlockUID.from_str(Identity.parse_field("Timestamp", lines[n]))
         n += 1
 
         signature = Identity.parse_field("Signature", lines[n])
 
-        return cls(version, currency, pubkey, uid, ts, signature)
+        identity = cls(version, currency, pubkey, uid, blockstamp)
+
+        # return identity with signature
+        identity.signatures = [signature]
+        return identity
 
     def raw(self) -> str:
         """
         Return a raw document of the Identity
+
         :return:
         """
         return """Version: {version}
@@ -161,6 +180,7 @@ Timestamp: {timestamp}
     def inline(self) -> str:
         """
         Return an inline string of the Identity
+
         :return:
         """
         return "{pubkey}:{signature}:{timestamp}:{uid}".format(
@@ -169,3 +189,71 @@ Timestamp: {timestamp}
             timestamp=self.timestamp,
             uid=self.uid,
         )
+
+    @classmethod
+    def from_certification_raw(
+        cls: Type[IdentityType], certification_raw: str
+    ) -> IdentityType:
+        """
+        Return Identity instance from certification_raw
+
+        :param certification_raw: Certification raw format
+        :return:
+        """
+        lines = certification_raw.splitlines(True)
+        n = 0
+        version = int(Identity.parse_field("Version", lines[n]))
+
+        n += 2
+        currency = Identity.parse_field("Currency", lines[n])
+
+        n += 2
+        issuer = Identity.parse_field("IdtyIssuer", lines[n])
+
+        n += 1
+        uid = Identity.parse_field("IdtyUniqueID", lines[n])
+
+        n += 1
+        timestamp = BlockUID.from_str(Identity.parse_field("IdtyTimestamp", lines[n]))
+
+        n += 1
+        signature = Identity.parse_field("IdtySignature", lines[n])
+
+        identity = cls(version, currency, issuer, uid, timestamp)
+        identity.signatures = [signature]
+
+        return identity
+
+    @classmethod
+    def from_revocation_raw(
+        cls: Type[IdentityType], revocation_raw: str
+    ) -> IdentityType:
+        """
+        Return Identity instance from revocation_raw
+
+        :param revocation_raw: Revocation raw format
+        :return:
+        """
+        lines = revocation_raw.splitlines(True)
+        n = 0
+        version = int(Identity.parse_field("Version", lines[n]))
+
+        n += 2
+        currency = Identity.parse_field("Currency", lines[n])
+
+        n += 1
+        issuer = Identity.parse_field("Issuer", lines[n])
+
+        n += 1
+        uid = Identity.parse_field("IdtyUniqueID", lines[n])
+
+        n += 1
+        timestamp = BlockUID.from_str(Identity.parse_field("IdtyTimestamp", lines[n]))
+
+        n += 1
+        signature = Identity.parse_field("IdtySignature", lines[n])
+
+        identity = cls(version, currency, issuer, uid, timestamp)
+        identity.signatures = [signature]
+
+        return identity
diff --git a/duniterpy/documents/membership.py b/duniterpy/documents/membership.py
index d79c79d5..2b80ec5b 100644
--- a/duniterpy/documents/membership.py
+++ b/duniterpy/documents/membership.py
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
-from typing import Optional, Type, TypeVar
+from typing import Type, TypeVar
 
 from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX
 from .block_uid import BlockUID
@@ -82,7 +82,6 @@ class Membership(Document):
         membership_type: str,
         uid: str,
         identity_ts: BlockUID,
-        signature: Optional[str] = None,
     ) -> None:
         """
         Create a membership document
@@ -94,13 +93,8 @@ class Membership(Document):
         :param membership_type: "IN" or "OUT" to enter or quit the community
         :param uid: Unique identifier of the identity
         :param identity_ts:  BlockUID of the identity
-        :param signature: Signature of the document
         """
-        if signature:
-            signatures = [signature]
-        else:
-            signatures = []
-        super().__init__(version, currency, signatures)
+        super().__init__(version, currency)
 
         self.issuer = issuer
         self.membership_ts = membership_ts
@@ -130,20 +124,23 @@ class Membership(Document):
             raise MalformedDocumentError("Inline membership ({0})".format(inline))
         issuer = data.group(1)
         signature = data.group(2)
-        membership_ts = BlockUID.from_str(data.group(3))
-        identity_ts = BlockUID.from_str(data.group(4))
+        membership_blockstamp = BlockUID.from_str(data.group(3))
+        identity_blockstamp = BlockUID.from_str(data.group(4))
         uid = data.group(5)
-        return cls(
+        membership = cls(
             version,
             currency,
             issuer,
-            membership_ts,
+            membership_blockstamp,
             membership_type,
             uid,
-            identity_ts,
-            signature,
+            identity_blockstamp,
         )
 
+        # return membership with signature
+        membership.signatures = [signature]
+        return membership
+
     @classmethod
     def from_signed_raw(cls: Type[MembershipType], signed_raw: str) -> MembershipType:
         """
@@ -167,7 +164,9 @@ class Membership(Document):
         issuer = Membership.parse_field("Issuer", lines[n])
         n += 1
 
-        membership_ts = BlockUID.from_str(Membership.parse_field("Block", lines[n]))
+        membership_blockstamp = BlockUID.from_str(
+            Membership.parse_field("Block", lines[n])
+        )
         n += 1
 
         membership_type = Membership.parse_field("Membership", lines[n])
@@ -176,23 +175,28 @@ class Membership(Document):
         uid = Membership.parse_field("UserID", lines[n])
         n += 1
 
-        identity_ts = BlockUID.from_str(Membership.parse_field("CertTS", lines[n]))
+        identity_blockstamp = BlockUID.from_str(
+            Membership.parse_field("CertTS", lines[n])
+        )
         n += 1
 
         signature = Membership.parse_field("Signature", lines[n])
         n += 1
 
-        return cls(
+        membership = cls(
             version,
             currency,
             issuer,
-            membership_ts,
+            membership_blockstamp,
             membership_type,
             uid,
-            identity_ts,
-            signature,
+            identity_blockstamp,
         )
 
+        # return membership with signature
+        membership.signatures = [signature]
+        return membership
+
     def raw(self) -> str:
         """
         Return signed raw format string of the Membership instance
diff --git a/duniterpy/documents/peer.py b/duniterpy/documents/peer.py
index b5bb076f..b995c650 100644
--- a/duniterpy/documents/peer.py
+++ b/duniterpy/documents/peer.py
@@ -69,7 +69,6 @@ class Peer(Document):
         pubkey: str,
         block_uid: BlockUID,
         endpoints: List[Endpoint],
-        signature: str,
     ) -> None:
         """
         Init Peer instance
@@ -79,9 +78,8 @@ class Peer(Document):
         :param pubkey: Public key of the issuer
         :param block_uid: BlockUID instance timestamp
         :param endpoints: List of endpoints string
-        :param signature: Signature of the document
         """
-        super().__init__(version, currency, [signature])
+        super().__init__(version, currency)
 
         self.pubkey = pubkey
         self.blockUID = block_uid
@@ -126,7 +124,11 @@ class Peer(Document):
             raise MalformedDocumentError("Peer")
         signature = data.group(1)
 
-        return cls(version, currency, pubkey, block_uid, endpoints, signature)
+        peer = cls(version, currency, pubkey, block_uid, endpoints)
+
+        # return peer with signature
+        peer.signatures = [signature]
+        return peer
 
     def raw(self) -> str:
         """
@@ -163,4 +165,8 @@ Endpoints:
 
         signature = str(Peer.re_signature.match(data["signature"]))
 
-        return cls(version, currency, pubkey, block_uid, endpoints, signature)
+        peer = cls(version, currency, pubkey, block_uid, endpoints)
+
+        # return peer with signature
+        peer.signatures = [signature]
+        return peer
diff --git a/duniterpy/documents/revocation.py b/duniterpy/documents/revocation.py
index 4efeb423..2f7ba949 100644
--- a/duniterpy/documents/revocation.py
+++ b/duniterpy/documents/revocation.py
@@ -18,7 +18,6 @@ import re
 from typing import Type, TypeVar, Union
 
 from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX
-from .block_uid import BlockUID
 from .document import Document, MalformedDocumentError
 from .identity import Identity
 
@@ -61,11 +60,7 @@ class Revocation(Document):
     }
 
     def __init__(
-        self,
-        version: int,
-        currency: str,
-        identity: Union[Identity, str],
-        signature: str,
+        self, version: int, currency: str, identity: Union[Identity, str]
     ) -> None:
         """
         Init Revocation instance
@@ -73,9 +68,8 @@ class Revocation(Document):
         :param version: Version number
         :param currency: Name of the currency
         :param identity: Identity instance or identity pubkey
-        :param signature: Signature
         """
-        super().__init__(version, currency, [signature])
+        super().__init__(version, currency)
 
         self.identity = identity if isinstance(identity, Identity) else None
         self.pubkey = identity.pubkey if isinstance(identity, Identity) else identity
@@ -101,7 +95,11 @@ class Revocation(Document):
             raise MalformedDocumentError("Revokation")
         pubkey = cert_data.group(1)
         signature = cert_data.group(2)
-        return cls(version, currency, pubkey, signature)
+        revocation = cls(version, currency, pubkey)
+
+        # return revocation with signature
+        revocation.signatures = [signature]
+        return revocation
 
     @classmethod
     def from_signed_raw(cls: Type[RevocationType], signed_raw: str) -> RevocationType:
@@ -121,69 +119,27 @@ class Revocation(Document):
         n += 1
 
         currency = Revocation.parse_field("Currency", lines[n])
-        n += 1
-
-        issuer = Revocation.parse_field("Issuer", lines[n])
-        n += 1
-
-        identity_uid = Revocation.parse_field("IdtyUniqueID", lines[n])
-        n += 1
-
-        identity_timestamp = BlockUID.from_str(
-            Revocation.parse_field("IdtyTimestamp", lines[n])
-        )
-        n += 1
-
-        identity_signature = Revocation.parse_field("IdtySignature", lines[n])
-        n += 1
 
+        n += 5
         signature = Revocation.parse_field("Signature", lines[n])
-        n += 1
 
-        identity = Identity(
-            version,
-            currency,
-            issuer,
-            identity_uid,
-            identity_timestamp,
-            identity_signature,
-        )
+        identity = Identity.from_revocation_raw(signed_raw)
 
-        return cls(version, currency, identity, signature)
+        revocation = cls(version, currency, identity)
+
+        # return revocation with signature
+        revocation.signatures = [signature]
+        return revocation
 
     @staticmethod
     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
+        :param signed_raw: Signed raw revocation document string
         :return:
         """
-        lines = signed_raw.splitlines(True)
-        n = 0
-
-        version = int(Revocation.parse_field("Version", lines[n]))
-        n += 1
-
-        Revocation.parse_field("Type", lines[n])
-        n += 1
-
-        currency = Revocation.parse_field("Currency", lines[n])
-        n += 1
-
-        issuer = Revocation.parse_field("Issuer", lines[n])
-        n += 1
-
-        unique_id = Revocation.parse_field("IdtyUniqueID", lines[n])
-        n += 1
-
-        timestamp = Revocation.parse_field("IdtyTimestamp", lines[n])
-        n += 1
-
-        signature = Revocation.parse_field("IdtySignature", lines[n])
-        n += 1
-
-        return Identity(version, currency, issuer, unique_id, timestamp, signature)
+        return Identity.from_revocation_raw(signed_raw)
 
     def inline(self) -> str:
         """
diff --git a/duniterpy/documents/transaction.py b/duniterpy/documents/transaction.py
index 21a4b3eb..05434761 100644
--- a/duniterpy/documents/transaction.py
+++ b/duniterpy/documents/transaction.py
@@ -545,7 +545,6 @@ class Transaction(Document):
         unlocks: List[Unlock],
         outputs: List[OutputSource],
         comment: str,
-        signatures: List[str],
         time: Optional[int] = None,
     ) -> None:
         """
@@ -561,9 +560,8 @@ class Transaction(Document):
         :param outputs: List of OutputSource instances
         :param comment: Comment field
         :param time: time when the transaction enters the blockchain
-        :param signatures: List of signatures
         """
-        super().__init__(version, currency, signatures)
+        super().__init__(version, currency)
         self.blockstamp = blockstamp
         self.locktime = locktime
         self.issuers = issuers
@@ -721,7 +719,7 @@ Comment: {comment}
             else:
                 raise MalformedDocumentError("Compact TX Signatures")
 
-        return cls(
+        transaction = cls(
             version,
             currency,
             blockstamp,
@@ -731,9 +729,12 @@ Comment: {comment}
             unlocks,
             outputs,
             comment,
-            signatures,
         )
 
+        # return transaction with signatures
+        transaction.signatures = signatures
+        return transaction
+
     @classmethod
     def from_signed_raw(
         cls: Type[TransactionType], raw: str, time: int = 0
@@ -807,7 +808,7 @@ Comment: {comment}
                 signatures.append(sign)
                 n += 1
 
-        return cls(
+        transaction = cls(
             version,
             currency,
             blockstamp,
@@ -817,10 +818,13 @@ Comment: {comment}
             unlocks,
             outputs,
             comment,
-            signatures,
             time,
         )
 
+        # return transaction with signatures
+        transaction.signatures = signatures
+        return transaction
+
     def raw(self) -> str:
         """
         Return raw string format from the instance
@@ -917,7 +921,6 @@ class SimpleTransaction(Transaction):
         unlocks: List[Unlock],
         outputs: List[OutputSource],
         comment: str,
-        signature: str,
         time: int,
     ) -> None:
         """
@@ -933,7 +936,6 @@ class SimpleTransaction(Transaction):
         :param outputs: List of OutputSource instances
         :param comment: Comment field
         :param time: time when the transaction enters the blockchain
-        :param signature: Signature
         """
         super().__init__(
             version,
@@ -945,7 +947,6 @@ class SimpleTransaction(Transaction):
             unlocks,
             outputs,
             comment,
-            [signature],
             time,
         )
 
diff --git a/duniterpy/documents/ws2p/messages.py b/duniterpy/documents/ws2p/messages.py
index a5f7a904..a42803aa 100644
--- a/duniterpy/documents/ws2p/messages.py
+++ b/duniterpy/documents/ws2p/messages.py
@@ -40,12 +40,7 @@ class HandshakeMessage(Document):
         :param challenge: [Optional, default=None] Big random string, typically an uuid
         :param signature: [Optional, default=None] Base64 encoded signature of raw formated document
         """
-        if signature is not None:
-            signatures = [signature]
-        else:
-            signatures = []
-
-        super().__init__(self.version, currency, signatures)
+        super().__init__(self.version, currency)
 
         self.pubkey = pubkey
 
@@ -56,6 +51,7 @@ class HandshakeMessage(Document):
             self.challenge = challenge
 
         if signature is not None:
+            self.signatures = [signature]
             # verify signature
             verifying_key = VerifyingKey(self.pubkey)
             verifying_key.verify_document(self)
diff --git a/examples/save_revoke_document.py b/examples/save_revoke_document.py
index 8f1ba26a..9c4596ad 100644
--- a/examples/save_revoke_document.py
+++ b/examples/save_revoke_document.py
@@ -84,9 +84,9 @@ def get_identity_document(
                 currency=current_block["currency"],
                 pubkey=pubkey,
                 uid=uid,
-                ts=timestamp,
-                signature=signature,
+                timestamp=timestamp,
             )
+            identity.signatures = [signature]
             break
 
     return identity
@@ -104,7 +104,7 @@ def get_signed_raw_revocation_document(
 
     :rtype: str
     """
-    revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity, "")
+    revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity)
 
     key = SigningKey.from_credentials(salt, password)
     revocation.sign([key])
diff --git a/examples/send_certification.py b/examples/send_certification.py
index b9bc7c0f..a14db4c9 100644
--- a/examples/send_certification.py
+++ b/examples/send_certification.py
@@ -65,9 +65,9 @@ def get_identity_document(
                 currency=current_block["currency"],
                 pubkey=pubkey,
                 uid=uid,
-                ts=timestamp,
-                signature=signature,
+                timestamp=timestamp,
             )
+            identity.signatures = [signature]
             break
 
     return identity
@@ -92,7 +92,6 @@ def get_certification_document(
         pubkey_from=from_pubkey,
         identity=self_cert_document,
         timestamp=BlockUID(current_block["number"], current_block["hash"]),
-        signature="",
     )
 
 
diff --git a/examples/send_identity.py b/examples/send_identity.py
index aa59e829..c777a75e 100644
--- a/examples/send_identity.py
+++ b/examples/send_identity.py
@@ -56,8 +56,7 @@ def get_identity_document(
         currency=current_block["currency"],
         pubkey=key.pubkey,
         uid=uid,
-        ts=timestamp,
-        signature=None,
+        timestamp=timestamp,
     )
 
     # sign document
diff --git a/examples/send_transaction.py b/examples/send_transaction.py
index 77462fe7..983c17a2 100644
--- a/examples/send_transaction.py
+++ b/examples/send_transaction.py
@@ -97,7 +97,6 @@ def get_transaction_document(
         unlocks=unlocks,
         outputs=outputs,
         comment="",
-        signatures=[],
     )
 
     return transaction
diff --git a/tests/api/ws2p/test_ws2p.py b/tests/api/ws2p/test_ws2p.py
index 209fa1f5..9461c78f 100644
--- a/tests/api/ws2p/test_ws2p.py
+++ b/tests/api/ws2p/test_ws2p.py
@@ -193,7 +193,6 @@ class TestWs2p(unittest.TestCase):
             "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd",
             "lolcat",
             BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"),
-            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci",
         )
         # get json string message
         json_document_message = document_message.get_json(
diff --git a/tests/documents/test_certification.py b/tests/documents/test_certification.py
index 510f832a..315be00a 100644
--- a/tests/documents/test_certification.py
+++ b/tests/documents/test_certification.py
@@ -77,7 +77,8 @@ class TestCertification(unittest.TestCase):
         timestamp = BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD")
         signature = "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci"
 
-        selfcert = Identity(version, currency, issuer, uid, timestamp, signature)
+        selfcert = Identity(version, currency, issuer, uid, timestamp)
+        selfcert.signatures = [signature]
 
         result = """Version: 2
 Type: Identity
@@ -139,12 +140,15 @@ J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBf
             pubkey_to,
             "lolcat",
             BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"),
-            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci",
         )
+        identity.signatures = [
+            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci"
+        ]
 
         certification = Certification(
-            version, currency, pubkey_from, identity, timestamp, signature
+            version, currency, pubkey_from, identity, timestamp
         )
+        certification.signatures = [signature]
 
         result = """Version: 2
 Type: Certification
@@ -185,9 +189,13 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN
             pubkey,
             "lolcat",
             BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"),
-            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci",
         )
-        revokation = Revocation(version, currency, identity, signature)
+        identity.signatures = [
+            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci"
+        ]
+
+        revokation = Revocation(version, currency, identity)
+        revokation.signatures = [signature]
 
         result = """Version: 2
 Type: Revocation
diff --git a/tests/documents/test_transaction.py b/tests/documents/test_transaction.py
index 6f0a598c..78367187 100644
--- a/tests/documents/test_transaction.py
+++ b/tests/documents/test_transaction.py
@@ -443,7 +443,6 @@ class TestTransaction(unittest.TestCase):
             unlocks=[Unlock(index=0, parameters=[SIGParameter(0)])],
             outputs=[OutputSource.from_inline(output_source_str)],
             comment="",
-            signatures=[],
         )
         self.assertTrue(transaction.time is None)
         self.assertTrue(transaction.currency == "gtest")
-- 
GitLab