diff --git a/pyrogram/api/core/__init__.py b/pyrogram/api/core/__init__.py
index b9ee0a98..078374f3 100644
--- a/pyrogram/api/core/__init__.py
+++ b/pyrogram/api/core/__init__.py
@@ -15,3 +15,11 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see .
+
+from .future_salt import FutureSalt
+from .future_salts import FutureSalts
+from .gzip_packed import GzipPacked
+from .message import Message
+from .msg_container import MsgContainer
+from .object import Object
+from .primitives import *
diff --git a/pyrogram/api/core/future_salt.py b/pyrogram/api/core/future_salt.py
new file mode 100644
index 00000000..e9697458
--- /dev/null
+++ b/pyrogram/api/core/future_salt.py
@@ -0,0 +1,40 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from datetime import datetime
+from io import BytesIO
+
+from .object import Object
+from .primitives import Int, Long
+
+
+class FutureSalt(Object):
+ ID = 0x0949d9dc
+
+ def __init__(self, valid_since: int or datetime, valid_until: int or datetime, salt: int):
+ self.valid_since = valid_since
+ self.valid_until = valid_until
+ self.salt = salt
+
+ @staticmethod
+ def read(b: BytesIO) -> "FutureSalt":
+ valid_since = datetime.fromtimestamp(Int.read(b))
+ valid_until = datetime.fromtimestamp(Int.read(b))
+ salt = Long.read(b)
+
+ return FutureSalt(valid_since, valid_until, salt)
diff --git a/pyrogram/api/core/future_salts.py b/pyrogram/api/core/future_salts.py
new file mode 100644
index 00000000..d1a62d95
--- /dev/null
+++ b/pyrogram/api/core/future_salts.py
@@ -0,0 +1,43 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from datetime import datetime
+from io import BytesIO
+
+from . import FutureSalt
+from .object import Object
+from .primitives import Int, Long
+
+
+class FutureSalts(Object):
+ ID = 0xae500895
+
+ def __init__(self, req_msg_id: int, now: int or datetime, salts: list):
+ self.req_msg_id = req_msg_id
+ self.now = now
+ self.salts = salts
+
+ @staticmethod
+ def read(b: BytesIO) -> "FutureSalts":
+ req_msg_id = Long.read(b)
+ now = datetime.fromtimestamp(Int.read(b))
+
+ count = Int.read(b)
+ salts = [FutureSalt.read(b) for _ in range(count)]
+
+ return FutureSalts(req_msg_id, now, salts)
diff --git a/pyrogram/api/core/gzip_packed.py b/pyrogram/api/core/gzip_packed.py
new file mode 100644
index 00000000..58d22760
--- /dev/null
+++ b/pyrogram/api/core/gzip_packed.py
@@ -0,0 +1,56 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from gzip import compress, decompress
+from io import BytesIO
+
+from .object import Object
+from .primitives import Int, Bytes
+
+
+class GzipPacked(Object):
+ ID = 0x3072cfa1
+
+ def __init__(self, packed_data: Object):
+ self.packed_data = packed_data
+
+ @staticmethod
+ def read(b: BytesIO) -> "GzipPacked":
+ # Return the Object itself instead of a GzipPacked wrapping it
+ return Object.read(
+ BytesIO(
+ decompress(
+ Bytes.read(b)
+ )
+ )
+ )
+
+ def write(self) -> bytes:
+ b = BytesIO()
+
+ b.write(Int(self.ID, False))
+
+ b.write(
+ Bytes(
+ compress(
+ self.packed_data.write()
+ )
+ )
+ )
+
+ return b.getvalue()
diff --git a/pyrogram/api/core/message.py b/pyrogram/api/core/message.py
new file mode 100644
index 00000000..045c51bb
--- /dev/null
+++ b/pyrogram/api/core/message.py
@@ -0,0 +1,51 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from io import BytesIO
+
+from .object import Object
+from .primitives import Int, Long
+
+
+class Message(Object):
+ ID = 0x5bb8e511 # hex(crc32(b"message msg_id:long seqno:int bytes:int body:Object = Message"))
+
+ def __init__(self, body: Object, msg_id: int, seq_no: int, length: int):
+ self.msg_id = msg_id
+ self.seq_no = seq_no
+ self.length = length
+ self.body = body
+
+ @staticmethod
+ def read(b: BytesIO) -> "Message":
+ msg_id = Long.read(b)
+ seq_no = Int.read(b)
+ length = Int.read(b)
+ body = b.read(length)
+
+ return Message(Object.read(BytesIO(body)), msg_id, seq_no, length)
+
+ def write(self) -> bytes:
+ b = BytesIO()
+
+ b.write(Long(self.msg_id))
+ b.write(Int(self.seq_no))
+ b.write(Int(self.length))
+ b.write(self.body.write())
+
+ return b.getvalue()
diff --git a/pyrogram/api/core/msg_container.py b/pyrogram/api/core/msg_container.py
new file mode 100644
index 00000000..57286cd6
--- /dev/null
+++ b/pyrogram/api/core/msg_container.py
@@ -0,0 +1,48 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from io import BytesIO
+
+from .message import Message
+from .object import Object
+from .primitives import Int
+
+
+class MsgContainer(Object):
+ ID = 0x73f1f8dc
+
+ def __init__(self, messages: list):
+ self.messages = messages
+
+ @staticmethod
+ def read(b: BytesIO) -> "MsgContainer":
+ count = Int.read(b)
+ return MsgContainer([Message.read(b) for _ in range(count)])
+
+ def write(self) -> bytes:
+ b = BytesIO()
+
+ b.write(Int(self.ID, False))
+
+ count = len(self.messages)
+ b.write(Int(count))
+
+ for message in self.messages:
+ b.write(message.write())
+
+ return b.getvalue()
diff --git a/pyrogram/api/core/object.py b/pyrogram/api/core/object.py
new file mode 100644
index 00000000..72452c46
--- /dev/null
+++ b/pyrogram/api/core/object.py
@@ -0,0 +1,69 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from collections import OrderedDict
+from datetime import datetime
+from importlib import import_module
+from io import BytesIO
+from json import JSONEncoder, dumps
+
+from ..all import objects
+
+
+class Object:
+ @staticmethod
+ def read(b: BytesIO, *args):
+ id = int.from_bytes(b.read(4), "little")
+ name = objects.get(id)
+ path, name = name.rsplit(".", 1)
+
+ return getattr(
+ import_module("pyrogram.api." + path),
+ name
+ ).read(b, *args)
+
+ def write(self, *args) -> bytes:
+ pass
+
+ def __str__(self) -> str:
+ return dumps(self, cls=Encoder, indent=4)
+
+ def __eq__(self, other) -> bool:
+ return self.__dict__ == other.__dict__
+
+ def __len__(self) -> int:
+ return len(self.write())
+
+ def __call__(self):
+ pass
+
+
+class Encoder(JSONEncoder):
+ def default(self, o: Object):
+ try:
+ content = o.__dict__
+ except AttributeError:
+ if isinstance(o, datetime):
+ return o.strftime("%d-%b-%Y %H:%M:%S")
+ else:
+ return repr(o)
+
+ return OrderedDict(
+ [("_", objects.get(getattr(o, "ID", None), None))]
+ + [i for i in content.items()]
+ )