From 8eaf4730d211ddfc350661ba6f5e62acb131bdb1 Mon Sep 17 00:00:00 2001
From: "alexey.stratulat" <alexey.stratulat@demlabs.net>
Date: Fri, 4 Feb 2022 16:57:47 +0000
Subject: [PATCH] Features-5386

---
 CMakeLists.txt                                |   2 +
 CellFrame/python-cellframe.c                  |   6 +
 include/python-cellframe.h                    |   4 +
 modules/cellframe-sdk/chain/CMakeLists.txt    |  11 +-
 .../chain/include/libdap-chain-python.h       |   3 +
 .../chain/src/libdap-chain-python.c           |   8 +
 .../include/wrapping_dap_chain_common.h       |  10 +-
 .../common/include/wrapping_dap_chain_datum.h |  20 +-
 .../include/wrapping_dap_chain_datum_token.h  |  52 ++++-
 .../common/src/wrapping_dap_chain_common.c    |  32 +++
 .../common/src/wrapping_dap_chain_datum.c     |  76 ++++++-
 .../src/wrapping_dap_chain_datum_token.c      | 166 ++++++++++++++
 .../net/include/libdap_chain_net_python.h     |  12 +-
 .../net/src/libdap_chain_net_python.c         |   8 +
 modules/cellframe-sdk/type/dag/CMakeLists.txt | 208 ++++++++++++++++++
 .../dag/include/wrapping_dap_chain_cs_dag.h   |  70 ++++++
 .../include/wrapping_dap_chain_cs_dag_event.h |  85 +++++++
 .../type/dag/src/wrapping_dap_chain_cs_dag.c  |  29 +++
 .../dag/src/wrapping_dap_chain_cs_dag_event.c |  81 +++++++
 setup.py                                      |   2 +-
 20 files changed, 865 insertions(+), 20 deletions(-)
 create mode 100644 modules/cellframe-sdk/common/src/wrapping_dap_chain_datum_token.c
 create mode 100644 modules/cellframe-sdk/type/dag/CMakeLists.txt
 create mode 100644 modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag.h
 create mode 100644 modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag_event.h
 create mode 100644 modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag.c
 create mode 100644 modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag_event.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b4634c8..c08d21b3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,6 +44,7 @@ add_subdirectory(modules/cellframe-sdk/gdb)
 add_subdirectory(modules/cellframe-sdk/chain)
 add_subdirectory(modules/cellframe-sdk/app-cli)
 add_subdirectory(modules/cellframe-sdk/wallet)
+add_subdirectory(modules/cellframe-sdk/type/dag)
 
     target_compile_options(dap_chain_common_python_module PRIVATE "-fpic")
     target_compile_options(dap_python_module PRIVATE "-fpic" )
@@ -182,6 +183,7 @@ target_link_libraries(${PROJECT_NAME} cellframe-sdk dap_python_module
                       dap_app_cli_python_module
                       dap_chain_wallet_python_module
                       dap_server_json_rpc_python_module
+                      dap_chain_cs_dag_python_module
                       ${PYTHON_LIBRARIES}
                      )
 
diff --git a/CellFrame/python-cellframe.c b/CellFrame/python-cellframe.c
index 78d7bccd..34860b9a 100644
--- a/CellFrame/python-cellframe.c
+++ b/CellFrame/python-cellframe.c
@@ -437,6 +437,8 @@ PyMODINIT_FUNC PyInit_libCellFrame(void){
             PyType_Ready(&HTTPCode_HTTPCodeType) < 0 ||
             PyType_Ready(&DapJSONRPCRequest_DapJSONRPCRequestType) < 0 ||
             PyType_Ready(&DapJSONRPCResponse_DapJSONRPCResponseType) < 0 ||
+            PyType_Ready(&DapChainCsDag_DapChainCsDagType) < 0 ||
+            PyType_Ready(&DapChainCsDagEvent_DapChainCsDagEventType) < 0 ||
             #ifdef DAP_SUPPORT_PYTHON_PLUGINS
                 PyType_Ready(&DapHTTPSimple_DapHTTPSimpleType) < 0 ||
                 PyType_Ready(&dapAppContext_dapAppContextType) < 0
@@ -524,6 +526,10 @@ PyMODINIT_FUNC PyInit_libCellFrame(void){
     PyModule_AddObject(module, "ChainNetNode", (PyObject*)&DapChainNetNodeObject_DapChainNetNodeObjectType);
     PyModule_AddObject(module, "ChainNetState", (PyObject*)&DapChainNetStateObject_DapChainNetStateObjectType);
     // =============
+    // === Chain type dag ===
+    PyModule_AddObject(module, "ChainCsDag", (PyObject*)&DapChainCsDag_DapChainCsDagType);
+    PyModule_AddObject(module, "ChainCsDagEvent", (PyObject*)&DapChainCsDagEvent_DapChainCsDagEventType);
+    // =============
 
     PyModule_AddObject(module, "ChainGDB", (PyObject*)&DapChainGDBObject_DapChainGDBType);
     PyModule_AddObject(module, "ChainWallet", (PyObject*)&DapChainWallet_dapChainWalletType);
diff --git a/include/python-cellframe.h b/include/python-cellframe.h
index 499c15b4..a5042ee6 100644
--- a/include/python-cellframe.h
+++ b/include/python-cellframe.h
@@ -37,6 +37,10 @@
 #include "wrapping_dap_chain_net_node_info.h"
 #include "wrapping_dap_chain_net_state.h"
 // ============
+// === type DAG ===
+#include "wrapping_dap_chain_cs_dag.h"
+#include "wrapping_dap_chain_cs_dag_event.h"
+// ============
 
 
 #include "wrapping_http.h"
diff --git a/modules/cellframe-sdk/chain/CMakeLists.txt b/modules/cellframe-sdk/chain/CMakeLists.txt
index 4debf128..4532c23a 100644
--- a/modules/cellframe-sdk/chain/CMakeLists.txt
+++ b/modules/cellframe-sdk/chain/CMakeLists.txt
@@ -202,7 +202,16 @@ add_library(${PROJECT_NAME} STATIC ${CHAIN_PYTHON_SRCS} ${CHAIN_PYTHON_HEADERS})
 
 target_link_libraries(${PROJECT_NAME})
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_server_core dap_chain_net dap_crypto_python_module dap_python_module dap_chain_common_python_module)
+target_link_libraries(${PROJECT_NAME}
+        dap_core
+        dap_crypto
+        dap_chain
+        dap_server_core
+        dap_chain_net
+        dap_crypto_python_module
+        dap_python_module
+        dap_chain_common_python_module
+        dap_chain_cs_dag_python_module)
 
 target_include_directories(${PROJECT_NAME} PUBLIC include/ )
 
diff --git a/modules/cellframe-sdk/chain/include/libdap-chain-python.h b/modules/cellframe-sdk/chain/include/libdap-chain-python.h
index 407be7df..400850ad 100644
--- a/modules/cellframe-sdk/chain/include/libdap-chain-python.h
+++ b/modules/cellframe-sdk/chain/include/libdap-chain-python.h
@@ -11,6 +11,7 @@
 #include "libdap_chain_atom_iter_python.h"
 #include "wrapping_dap_chain_atom_ptr.h"
 #include "wrapping_dap_chain_datum.h"
+#include "wrapping_dap_chain_cs_dag.h"
 
 
 typedef struct PyDapChain{
@@ -38,6 +39,7 @@ PyObject *dap_chain_python_create_atom_iter(PyObject *self, PyObject *args);
 PyObject *dap_chain_python_atom_iter_get_first(PyObject *self, PyObject *args);
 PyObject *dap_chain_python_atom_get_datums(PyObject *self, PyObject *args);
 PyObject *dap_chain_python_atom_iter_get_next(PyObject *self, PyObject *args);
+PyObject *dap_chain_python_atom_iter_get_dag(PyObject *self, PyObject *args);
 
 static PyMethodDef DapChainMethods[] = {
     {"findById", (PyCFunction)dap_chain_find_by_id_py, METH_VARARGS|METH_STATIC, ""},
@@ -49,6 +51,7 @@ static PyMethodDef DapChainMethods[] = {
     {"atomIterGetFirst", (PyCFunction) dap_chain_python_atom_iter_get_first, METH_VARARGS, ""},
     {"atomGetDatums", (PyCFunction) dap_chain_python_atom_get_datums, METH_VARARGS, ""},
     {"atomIterGetNext", (PyCFunction)dap_chain_python_atom_iter_get_next, METH_VARARGS, ""},
+    {"getDag", (PyCFunction)dap_chain_python_atom_iter_get_dag, METH_NOARGS},
     //{"close", (PyCFunction)dap_chain_close_py, METH_NOARGS, ""},
     {NULL, NULL, 0, NULL}
 };
diff --git a/modules/cellframe-sdk/chain/src/libdap-chain-python.c b/modules/cellframe-sdk/chain/src/libdap-chain-python.c
index 1b3961e3..4d638c7d 100644
--- a/modules/cellframe-sdk/chain/src/libdap-chain-python.c
+++ b/modules/cellframe-sdk/chain/src/libdap-chain-python.c
@@ -154,3 +154,11 @@ PyObject *dap_chain_python_atom_iter_get_next(PyObject *self, PyObject *args){
     }
     return Py_BuildValue("On", obj_atom_ptr, atom_size);
 }
+
+PyObject *dap_chain_python_atom_iter_get_dag(PyObject *self, PyObject *args){
+    (void)args;
+    PyDapChainCsDagObject *obj_dag = PyObject_New(PyDapChainCsDagObject, &DapChainCsDag_DapChainCsDagType);
+    PyObject_Dir((PyObject*)obj_dag);
+    obj_dag->dag = DAP_CHAIN_CS_DAG(((PyDapChainObject*)self)->chain_t);
+    return (PyObject*)obj_dag;
+}
diff --git a/modules/cellframe-sdk/common/include/wrapping_dap_chain_common.h b/modules/cellframe-sdk/common/include/wrapping_dap_chain_common.h
index 5a4fe690..dec022f3 100644
--- a/modules/cellframe-sdk/common/include/wrapping_dap_chain_common.h
+++ b/modules/cellframe-sdk/common/include/wrapping_dap_chain_common.h
@@ -102,6 +102,7 @@ typedef struct PyDapChainAddr{
 PyObject *dap_chain_addr_to_str_py(PyObject *self, PyObject *args);
 PyObject *dap_chain_addr_from_str_py(PyObject *self, PyObject *args);
 PyObject *dap_chain_addr_fill_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_addr_fill_from_key_py(PyObject *self, PyObject *args);
 PyObject *dap_chain_addr_check_sum_py(PyObject *self, PyObject *args);
 
 PyObject *dap_chain_addr_get_net_id_py(PyObject *self, PyObject *args);
@@ -111,7 +112,8 @@ PyObject *obj_addr_str(PyObject *self);
 static PyMethodDef DapChainAddrMethods[] = {
     {"toStr", (PyCFunction)dap_chain_addr_to_str_py, METH_VARARGS, ""},
     {"fromStr", (PyCFunction)dap_chain_addr_from_str_py, METH_VARARGS | METH_STATIC, ""},
-    {"fill", (PyCFunction)dap_chain_addr_fill_py, METH_VARARGS, ""},
+    {"fill", (PyCFunction)dap_chain_addr_fill_py, METH_VARARGS | METH_STATIC, ""},
+    {"fillFromKey", (PyCFunction)dap_chain_addr_fill_from_key_py, METH_VARARGS, ""},
     {"checkSum", (PyCFunction)dap_chain_addr_check_sum_py, METH_VARARGS, ""},
     {"getNetId", (PyCFunction)dap_chain_addr_get_net_id_py, METH_NOARGS, ""},
     {NULL, NULL, 0, NULL}
@@ -351,7 +353,7 @@ static PyTypeObject DapChainIDObject_DapChainIDType = {
     0,                               /* tp_as_mapping */
     0,                               /* tp_hash  */
     0,                               /* tp_call */
-    DapChainIdObject_str,                               /* tp_str */
+    DapChainIdObject_str,            /* tp_str */
     0,                               /* tp_getattro */
     0,                               /* tp_setattro */
     0,                               /* tp_as_buffer */
@@ -386,6 +388,8 @@ typedef struct PyDapChainCellID{
     dap_chain_cell_id_t cell_id;
 }PyDapChainCellIDObject;
 
+PyObject *PyDapChainCellIdObject_str(PyObject *self);
+
 static PyTypeObject DapChainCellIDObject_DapChainCellIDType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "CellFrame.ChainCellID"  ,       /* tp_name */
@@ -402,7 +406,7 @@ static PyTypeObject DapChainCellIDObject_DapChainCellIDType = {
     0,                               /* tp_as_mapping */
     0,                               /* tp_hash  */
     0,                               /* tp_call */
-    0,                               /* tp_str */
+    PyDapChainCellIdObject_str,      /* tp_str */
     0,                               /* tp_getattro */
     0,                               /* tp_setattro */
     0,                               /* tp_as_buffer */
diff --git a/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum.h b/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum.h
index 148bbed1..9cffb846 100644
--- a/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum.h
+++ b/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum.h
@@ -27,8 +27,10 @@
 #define _WRAPPING_DAP_CHAIN_DATUM_
 #include "Python.h"
 #include "dap_chain_datum.h"
+#include "dap_chain_datum_token.h"
 #include "datetime.h"
 #include "wrapping_dap_chain_datum_tx.h"
+#include "dap_common.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -91,19 +93,31 @@ typedef struct PyDapChainDatum{
 //void PyDapChainDatumObject_dealloc(PyDapChainDatumObject* object);
 PyObject *PyDapChainDatumObject_new(PyTypeObject *type_object, PyObject *args, PyObject *kwds);
 PyObject *dap_chain_datum_size_py(PyObject *self, PyObject *args);
-PyObject *dap_chain_datum_get_ts_created(PyObject *self, void* closure);
+PyObject *dap_chain_datum_get_ts_created_py(PyObject *self, void* closure);
 PyObject *dap_chain_datum_is_type_tx(PyObject *self, PyObject *args);
 PyObject *wrapping_dap_chain_datum_get_datum_tx(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_is_type_token(PyObject *self, PyObject *args);
+PyObject *wrapping_dap_chain_datum_get_datum_token(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_is_type_emission(PyObject *self, PyObject *args);
+PyObject *wrapping_dap_chain_datum_get_datum_token_emission(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_get_type_str_py(PyObject *self, PyObject *args);
+PyObject *wrapping_dap_chain_datum_get_version_str_py(PyObject *self, void* closure);
 
 static PyMethodDef DapChainDatumMethods[] = {
-    {"size", dap_chain_datum_size_py, METH_VARARGS, ""},
+    {"getSize", dap_chain_datum_size_py, METH_VARARGS, ""},
     {"isDatumTX", dap_chain_datum_is_type_tx, METH_NOARGS, ""},
     {"getDatumTX", wrapping_dap_chain_datum_get_datum_tx, METH_NOARGS, ""},
+    {"isDatumToken", dap_chain_datum_is_type_token, METH_NOARGS, ""},
+    {"getDatumToken", wrapping_dap_chain_datum_get_datum_token, METH_NOARGS, ""},
+    {"isDatumTokenEmission", dap_chain_datum_is_type_emission, METH_NOARGS, ""},
+    {"getDatumTokenEmission", wrapping_dap_chain_datum_get_datum_token_emission, METH_NOARGS, ""},
+    {"getTypeStr", dap_chain_datum_get_type_str_py, METH_NOARGS, ""},
     {NULL, NULL, 0, NULL}
 };
 
 static PyGetSetDef  DapChainDatumGetSet[] = {
-        {"tsCreated", (getter)dap_chain_datum_get_ts_created, NULL, NULL, NULL},
+        {"versionStr", (getter)wrapping_dap_chain_datum_get_version_str_py, NULL, NULL},
+        {"tsCreated", (getter)dap_chain_datum_get_ts_created_py, NULL, NULL},
         {NULL}
 };
 
diff --git a/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum_token.h b/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum_token.h
index 1da688e3..fbb6c959 100644
--- a/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum_token.h
+++ b/modules/cellframe-sdk/common/include/wrapping_dap_chain_datum_token.h
@@ -28,6 +28,7 @@
 
 #include "Python.h"
 #include "dap_chain_datum_token.h"
+#include "wrapping_dap_chain_common.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -40,9 +41,26 @@ typedef struct PyDapChainDatumToken{
     dap_chain_datum_token_t *token;
 }PyDapChainDatumTokenObject;
 
+PyObject *wrapping_dap_chain_datum_token_get_ticker(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_get_type_str(PyObject *self, void *closure);
+//PyObject *wrapping_dap_chain_datum_token_get_size(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_get_data(PyObject *self, void *closure);
+
+static PyGetSetDef  PyDapChainDatumTokenGetsSetsDef[]={
+        {"ticker", (getter)wrapping_dap_chain_datum_token_get_ticker, NULL, NULL, NULL},
+        {"typeStr", (getter)wrapping_dap_chain_datum_token_get_type_str, NULL, NULL, NULL},
+        {"data", (getter)wrapping_dap_chain_datum_token_get_data, NULL, NULL, NULL},
+        {NULL}
+};
+
+static PyMethodDef  PyDapChainDatumTokenMethods[] = {
+        {NULL, NULL, 0, NULL}
+};
+
+
 static PyTypeObject DapChainDatumToken_DapChainDatumTokenObjectType = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "CellFrame.Chain.DatumTokenObject",       /* tp_name */
+    "CellFrame.ChainDatumToken",       /* tp_name */
     sizeof(PyDapChainDatumTokenObject),      /* tp_basicsize */
     0,                                       /* tp_itemsize */
     0,                                       /* tp_dealloc */
@@ -69,9 +87,9 @@ static PyTypeObject DapChainDatumToken_DapChainDatumTokenObjectType = {
     0,                                       /* tp_weaklistoffset */
     0,		                                 /* tp_iter */
     0,		                                 /* tp_iternext */
-    0,                                       /* tp_methods */
+    PyDapChainDatumTokenMethods,              /* tp_methods */
     0,                                       /* tp_members */
-    0,                                       /* tp_getset */
+    PyDapChainDatumTokenGetsSetsDef,           /* tp_getset */
     0,                                       /* tp_base */
     0,                                       /* tp_dict */
     0,                                       /* tp_descr_get */
@@ -89,11 +107,33 @@ static PyTypeObject DapChainDatumToken_DapChainDatumTokenObjectType = {
 typedef struct PyDapChainDatumTokenEmission{
     PyObject_HEAD
     dap_chain_datum_token_emission_t *token_emission;
+    size_t token_size;
 }PyDapChainDatumTokenEmissionObject;
 
+PyObject *wrapping_dap_chain_datum_token_emission_get_version(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_emission_get_type_str(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_emission_get_ticker(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_emission_get_addr(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_emission_get_value(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_datum_token_emission_get_data(PyObject *self, void *closure);
+
+static PyGetSetDef PyDapChainDatumTokenEmissionGetsSetsDef[]={
+        {"version", (getter)wrapping_dap_chain_datum_token_emission_get_version, NULL, NULL},
+        {"typeStr", (getter)wrapping_dap_chain_datum_token_emission_get_type_str, NULL, NULL},
+        {"ticker", (getter)wrapping_dap_chain_datum_token_emission_get_ticker, NULL, NULL},
+        {"addr", (getter)wrapping_dap_chain_datum_token_emission_get_addr, NULL, NULL},
+        {"value", (getter)wrapping_dap_chain_datum_token_emission_get_value, NULL, NULL},
+        {"data", (getter)wrapping_dap_chain_datum_token_emission_get_data, NULL, NULL},
+        {NULL}
+};
+
+static PyMethodDef PyDapChainDatumTokenEmissionMethods[]={
+        {NULL, NULL, 0, NULL}
+};
+
 static PyTypeObject DapChainDatumTokenEmission_DapChainDatumTokenEmissionObjectType = {
     PyVarObject_HEAD_INIT(NULL, 0)
-    "CellFrame.Chain.DatumTokenEmission",             /* tp_name */
+    "CellFrame.ChainDatumTokenEmission",             /* tp_name */
     sizeof(PyDapChainDatumTokenEmissionObject),      /* tp_basicsize */
     0,                                               /* tp_itemsize */
     0,                                               /* tp_dealloc */
@@ -120,9 +160,9 @@ static PyTypeObject DapChainDatumTokenEmission_DapChainDatumTokenEmissionObjectT
     0,                                               /* tp_weaklistoffset */
     0,		                                         /* tp_iter */
     0,		                                         /* tp_iternext */
-    0,  	                                         /* tp_methods */
+    PyDapChainDatumTokenEmissionMethods,  	         /* tp_methods */
     0,                                               /* tp_members */
-    0,                                               /* tp_getset */
+    PyDapChainDatumTokenEmissionGetsSetsDef,           /* tp_getset */
     0,                                               /* tp_base */
     0,                                               /* tp_dict */
     0,                                               /* tp_descr_get */
diff --git a/modules/cellframe-sdk/common/src/wrapping_dap_chain_common.c b/modules/cellframe-sdk/common/src/wrapping_dap_chain_common.c
index 6aaec83d..3fee84f5 100644
--- a/modules/cellframe-sdk/common/src/wrapping_dap_chain_common.c
+++ b/modules/cellframe-sdk/common/src/wrapping_dap_chain_common.c
@@ -4,6 +4,10 @@ PyObject *DapChainIdObject_str(PyObject *self){
     return Py_BuildValue("s", dap_strdup_printf("0x%016"DAP_UINT64_FORMAT_x, ((PyDapChainIDObject*)self)->chain_id->uint64));
 }
 
+PyObject *PyDapChainCellIdObject_str(PyObject *self){
+    return Py_BuildValue("s", dap_strdup_printf("0x%016"DAP_UINT64_FORMAT_x, ((PyDapChainCellIDObject*)self)->cell_id.uint64));
+}
+
 PyObject *dap_chain_hash_slow_to_str_py(PyObject *self, PyObject *args){
     PyObject *obj_hash_slow;
     char *str;
@@ -35,6 +39,34 @@ PyObject *dap_chain_addr_from_str_py(PyObject *self, PyObject *args){
 }
 
 PyObject *dap_chain_addr_fill_py(PyObject *self, PyObject *args){
+    PyObject *obj_sign_type;
+    PyObject *obj_pkey_hash;
+    PyObject *obj_chain_net_id;
+    if (!PyArg_ParseTuple(args, "OOO", &obj_sign_type, &obj_pkey_hash, &obj_chain_net_id)){
+        PyErr_SetString(PyExc_AttributeError, "This function takes three arguments, signature type, public key hash, chain network ID.");
+        return NULL;
+    }
+    if (self == NULL){
+        PyDapChainAddrObject *obj_addr = PyObject_New(PyDapChainAddrObject, &DapChainAddrObject_DapChainAddrObjectType);
+        PyObject_Dir((PyObject*)obj_addr);
+        obj_addr->addr = DAP_NEW(dap_chain_addr_t);
+        dap_chain_addr_fill(
+                obj_addr->addr,
+                *((PyDapSignTypeObject*)obj_sign_type)->sign_type,
+                ((PyDapHashFastObject*)obj_pkey_hash)->hash_fast,
+                ((PyDapChainNetIdObject*)obj_chain_net_id)->net_id);
+        return (PyObject*)obj_addr;
+    }else{
+        dap_chain_addr_fill(
+                ((PyDapChainAddrObject*)self)->addr,
+                *((PyDapSignTypeObject*)obj_sign_type)->sign_type,
+                ((PyDapHashFastObject*)obj_pkey_hash)->hash_fast,
+                ((PyDapChainNetIdObject*)obj_chain_net_id)->net_id);
+        return Py_None;
+    }
+}
+
+PyObject *dap_chain_addr_fill_from_key_py(PyObject *self, PyObject *args){
     PyObject *key;
     PyObject *net_id;
     if (!PyArg_ParseTuple(args, "O|O", &key, &net_id))
diff --git a/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum.c b/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum.c
index ed2ed52b..a39c1aad 100644
--- a/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum.c
+++ b/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum.c
@@ -20,10 +20,12 @@ PyObject *dap_chain_datum_size_py(PyObject *self, PyObject *args){
     return PyLong_FromSize_t(size);
 }
 
-PyObject *dap_chain_datum_get_ts_created(PyObject *self, void* closure){
+PyObject *dap_chain_datum_get_ts_created_py(PyObject *self, void* closure){
     (void)closure;
-    PyObject *timestamp = Py_BuildValue("k", ((PyDapChainDatumObject*)self)->datum->header.ts_create);
-    return PyDateTime_FromTimestamp(timestamp);
+    PyDateTime_IMPORT;
+    PyObject *obj_ts_long =  Py_BuildValue("(k)",((PyDapChainDatumObject*)self)->datum->header.ts_create);
+    PyObject *obj_ts = PyDateTime_FromTimestamp(obj_ts_long);
+    return obj_ts;
 }
 
 PyObject *dap_chain_datum_is_type_tx(PyObject *self, PyObject *args){
@@ -35,6 +37,60 @@ PyObject *dap_chain_datum_is_type_tx(PyObject *self, PyObject *args){
     }
 }
 
+PyObject *dap_chain_datum_is_type_token(PyObject *self, PyObject *args){
+    (void)args;
+    if (((PyDapChainDatumObject*)self)->datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_DECL ){
+        return Py_BuildValue("O", Py_True);
+    } else {
+        return Py_BuildValue("O", Py_False);
+    }
+}
+
+PyObject *wrapping_dap_chain_datum_get_datum_token(PyObject *self, PyObject *args){
+    (void)args;
+    if (((PyDapChainDatumObject*)self)->datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_DECL ){
+        PyDapChainDatumTokenObject *obj_token = PyObject_New(PyDapChainDatumTokenObject,
+                                                             &DapChainDatumToken_DapChainDatumTokenObjectType);
+        PyObject_Dir((PyObject*)obj_token);
+        size_t l_size_token = ((PyDapChainDatumObject*)self)->datum->header.data_size;
+        obj_token->token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_size_token);
+        memcpy(obj_token->token, ((PyDapChainDatumObject*)self)->datum->data, l_size_token);
+        return (PyObject*)obj_token;
+    }else{
+        PyErr_SetString(PyExc_Exception, "Due to the type of this datum, it is not possible to get the token datum.");
+        return NULL;
+    }
+}
+
+PyObject *dap_chain_datum_is_type_emission(PyObject *self, PyObject *args){
+    (void)args;
+    if (((PyDapChainDatumObject*)self)->datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_EMISSION){
+        return Py_BuildValue("O", Py_True);
+    }else{
+        return Py_BuildValue("O", Py_False);
+    }
+}
+
+PyObject *wrapping_dap_chain_datum_get_datum_token_emission(PyObject *self, PyObject *args){
+    (void)args;
+    if (((PyDapChainDatumObject*)self)->datum->header.type_id == DAP_CHAIN_DATUM_TOKEN_EMISSION ){
+        PyDapChainDatumTokenEmissionObject *obj_emission = PyObject_New(
+                PyDapChainDatumTokenEmissionObject,
+                &DapChainDatumTokenEmission_DapChainDatumTokenEmissionObjectType
+        );
+        PyObject_Dir((PyObject*)obj_emission);
+        size_t l_token_emission_size = ((PyDapChainDatumObject*)self)->datum->header.data_size;
+        obj_emission->token_emission = dap_chain_datum_emission_read(((PyDapChainDatumObject*)self)->datum->data,
+                                                                     &l_token_emission_size);
+        obj_emission->token_size = l_token_emission_size;
+        return (PyObject*)obj_emission;
+
+    }else{
+        PyErr_SetString(PyExc_Exception, "Due to the type of this datum, it is not possible to get the token datum.");
+        return NULL;
+    }
+}
+
 PyObject *wrapping_dap_chain_datum_get_datum_tx(PyObject *self, PyObject *args){
     (void)args;
     if(((PyDapChainDatumObject *)self)->datum->header.type_id == DAP_CHAIN_DATUM_TX){
@@ -48,3 +104,17 @@ PyObject *wrapping_dap_chain_datum_get_datum_tx(PyObject *self, PyObject *args){
         return NULL;
     }
 }
+
+PyObject *dap_chain_datum_get_type_str_py(PyObject *self, PyObject *args){
+    (void)args;
+    const char *l_ret;
+    DAP_DATUM_TYPE_STR(((PyDapChainDatumObject*)self)->datum->header.type_id, l_ret);
+    if (l_ret == NULL)
+        return Py_None;
+    return Py_BuildValue("s", l_ret);
+}
+
+PyObject *wrapping_dap_chain_datum_get_version_str_py(PyObject *self, void* closure){
+    (void)closure;
+    return Py_BuildValue("s", dap_strdup_printf("0x%02X",((PyDapChainDatumObject*)self)->datum->header.version_id));
+}
diff --git a/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum_token.c b/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum_token.c
new file mode 100644
index 00000000..6982943c
--- /dev/null
+++ b/modules/cellframe-sdk/common/src/wrapping_dap_chain_datum_token.c
@@ -0,0 +1,166 @@
+#include "wrapping_dap_chain_datum_token.h"
+
+/* Token */
+PyObject *wrapping_dap_chain_datum_token_get_ticker(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("s", ((PyDapChainDatumTokenObject*)self)->token->ticker);
+}
+PyObject *wrapping_dap_chain_datum_token_get_type_str(PyObject *self, void *closure){
+    (void)closure;
+    switch (((PyDapChainDatumTokenObject*)self)->token->type) {
+        case DAP_CHAIN_DATUM_TOKEN_TYPE_SIMPLE:
+            return Py_BuildValue("s", "SIMPLE");
+        case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_UPDATE:
+            return Py_BuildValue("s", "PRIVATE_UPDATE");
+        case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL:
+            return Py_BuildValue("s", "PRIVATE_DECL");
+        case DAP_CHAIN_DATUM_TOKEN_TYPE_PUBLIC:
+            return Py_BuildValue("s", "PUBLIC");
+        default:
+            return Py_BuildValue("s", "UNKNOWN");
+    }
+//    dap_chain_datum_token_flags_dump()
+}
+//PyObject *wrapping_dap_chain_datum_token_get_size(PyObject *self, void *closure){
+//    (void)closure;
+//    return Py_BuildValue("", ((PyDapChainDatumTokenObject*)self)->token->)
+//}
+PyObject *wrapping_dap_chain_datum_token_get_data(PyObject *self, void *closure){
+    (void)closure;
+    dap_chain_datum_token_t  *l_token = ((PyDapChainDatumTokenObject*)self)->token;
+//    ((PyDapChainDatumTokenObject*)self)->token
+    PyObject *obj_dict = PyDict_New();
+    PyObject *obj_dict_header_private = NULL;
+    PyObject *obj = Py_None;
+    switch(l_token->type){
+        case DAP_CHAIN_DATUM_TOKEN_TYPE_SIMPLE:
+            obj = Py_BuildValue("H", l_token->header_private.signs_total);
+            PyDict_SetItemString(obj_dict, "signs_total", obj);
+            obj = Py_BuildValue("H", l_token->header_private.signs_valid);
+            PyDict_SetItemString(obj_dict, "signs_valid", obj);
+            obj = Py_BuildValue("k", l_token->header_private.total_supply);
+            PyDict_SetItemString(obj_dict, "total_supply", obj);
+            break;
+//        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE:
+//        case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_UPDATE:
+////            dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(l_token, ((PyDapChainDatumTokenObject*)self)->token_size);
+//            break;
+//        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL:
+//        case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL:
+//            break;
+        default:
+            return Py_None;
+    }
+    return obj_dict;
+}
+
+/* Token Emission */
+PyObject *wrapping_dap_chain_datum_token_emission_get_version(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("I", ((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.version);
+}
+PyObject *wrapping_dap_chain_datum_token_emission_get_type_str(PyObject *self, void *closure){
+    (void)closure;
+    const char *str;
+    switch (((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.type) {
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED:
+            str = "TOKEN_EMISSION_TYPE_UNDEFINED";
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:
+            str = "TOKEN_EMISSION_TYPE_AUTH";
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO:
+            str = "TOKEN_EMISSION_TYPE_ALGO";
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER:
+            str = "TOKEN_EMISSION_TYPE_ATOM_OWNER";
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT:
+            str = "TOKEN_EMISSION_TYPE_SMART_CONTRACT";
+            break;
+        default:
+            str = "UNDEFINED";
+    }
+    return Py_BuildValue("s", str);
+//    const char *str = "UNDEFINED";
+//#define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED         0x00
+//#define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH              0x01
+//#define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO              0x02
+//#define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER        0x03
+//#define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT    0x04
+//    const char *str = c_dap_chain_datum_token_emission_type_str(((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.type);
+//    return Py_BuildValue("s", str);
+}
+PyObject *wrapping_dap_chain_datum_token_emission_get_ticker(PyObject *self, void *closure){
+    (void)closure;
+//    log_it(L_NOTICE, "ticker in token: %s", ((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.ticker);
+    return Py_BuildValue("s", ((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.ticker);
+}
+PyObject *wrapping_dap_chain_datum_token_emission_get_addr(PyObject *self, void *closure){
+    (void)closure;
+    PyDapChainAddrObject *obj_addr = PyObject_New(PyDapChainAddrObject, &DapChainAddrObject_DapChainAddrObjectType);
+    PyObject_Dir((PyObject*)obj_addr);
+    obj_addr->addr = &((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.address;
+    return (PyObject*)obj_addr;
+}
+PyObject *wrapping_dap_chain_datum_token_emission_get_value(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("k", ((PyDapChainDatumTokenEmissionObject*)self)->token_emission->hdr.value);
+}
+//PyObject *wrapping_dap_chain_datum_token_emission_get_nonce(PyObject *self, void *closure){
+//    (void)closure;
+//}
+PyObject *wrapping_dap_chain_datum_token_emission_get_data(PyObject *self, void *closure){
+    (void)closure;
+    PyObject *obj_dict = NULL;
+    PyObject *obj_tmp = Py_None;
+    dap_chain_datum_token_emission_t *token_emi = ((PyDapChainDatumTokenEmissionObject*)self)->token_emission;
+    size_t token_emi_size = ((PyDapChainDatumTokenEmissionObject*)self)->token_size;
+    PyDapSignObject *obj_tmp_sign = (PyDapSignObject*)Py_None;
+    dap_sign_t *l_sign_ptr = NULL;
+    size_t l_offset = 0;
+    switch(token_emi->hdr.type){
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:
+            l_sign_ptr = (dap_sign_t*)token_emi->data.type_auth.signs;
+            l_offset = (byte_t*)l_sign_ptr - (byte_t*)token_emi;
+            obj_tmp = PyList_New(0);
+            for (size_t i = 0; i < token_emi->data.type_auth.signs_count && l_offset < token_emi_size; i++){
+                if(dap_sign_verify_size(l_sign_ptr, ((PyDapChainDatumTokenEmissionObject*)self)->token_size - l_offset)){
+                    obj_tmp_sign = PyObject_New(PyDapSignObject, &DapSignObject_DapSignObjectType);
+                    PyObject_Dir((PyObject*)obj_tmp_sign);
+                    obj_tmp_sign->sign = DAP_NEW_Z_SIZE(dap_sign_t, dap_sign_get_size(l_sign_ptr));
+                    memcpy(obj_tmp_sign->sign, l_sign_ptr, dap_sign_get_size(l_sign_ptr));
+                    if (PyList_Append(obj_tmp, (PyObject*)obj_tmp_sign) == -1){
+                        return NULL;
+                    }
+                    l_offset += dap_sign_get_size(l_sign_ptr);
+                    l_sign_ptr = (dap_sign_t*)(byte_t*)token_emi + l_offset;
+                } else {
+                    break;
+                }
+            }
+            return obj_tmp;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO:
+            obj_dict = PyDict_New();
+            obj_tmp = Py_BuildValue("s", token_emi->data.type_algo.codename);
+            PyDict_SetItemString(obj_dict, "codename", obj_tmp);
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER:
+            obj_dict = PyDict_New();
+            obj_tmp = Py_BuildValue("k", token_emi->data.type_atom_owner.value_start);
+            PyDict_SetItemString(obj_dict, "value_start", obj_tmp);
+            obj_tmp = Py_BuildValue("s", token_emi->data.type_atom_owner.value_change_algo_codename);
+            PyDict_SetItemString(obj_dict, "value_change_algo_codename", obj_tmp);
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT:
+//            obj_dict = PyDict_New();
+            return Py_None;
+            break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED:
+            return Py_None;
+            break;
+        default:
+            return Py_None;
+    }
+    return obj_dict;
+}
\ No newline at end of file
diff --git a/modules/cellframe-sdk/net/include/libdap_chain_net_python.h b/modules/cellframe-sdk/net/include/libdap_chain_net_python.h
index d6bf30b2..36c62ceb 100644
--- a/modules/cellframe-sdk/net/include/libdap_chain_net_python.h
+++ b/modules/cellframe-sdk/net/include/libdap_chain_net_python.h
@@ -77,6 +77,7 @@ PyObject *dap_chain_net_get_chain_by_chain_type_py(PyObject *self, PyObject *arg
 PyObject *dap_chain_net_get_ledger_py(PyObject *self, PyObject *args);
 PyObject *dap_chain_net_get_name_py(PyObject *self, PyObject *args);
 PyObject *dap_chain_net_get_tx_by_hash_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_net_python_get_id(PyObject *self, void *closure);
 
 static PyMethodDef DapChainNetMethods[] = {
     {"loadAll", dap_chain_net_load_all_py, METH_NOARGS | METH_STATIC, ""},
@@ -105,6 +106,11 @@ static PyMethodDef DapChainNetMethods[] = {
     {NULL, NULL, 0, NULL}
 };
 
+static PyGetSetDef DapChainNetGetsSetsDef[] = {
+    {"id", (getter)dap_chain_net_python_get_id, NULL, NULL, NULL},
+    {NULL}
+};
+
 static PyTypeObject DapChainNetObject_DapChainNetObjectType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "CellFrame.ChainNet",            /* tp_name */
@@ -134,9 +140,9 @@ static PyTypeObject DapChainNetObject_DapChainNetObjectType = {
     0,                               /* tp_weaklistoffset */
     0,		                         /* tp_iter */
     0,		                         /* tp_iternext */
-    DapChainNetMethods,              /* tp_methods */
-    0,                               /* tp_members */
-    0,                               /* tp_getset */
+    DapChainNetMethods,             /* tp_methods */
+    0,                              /* tp_members */
+    DapChainNetGetsSetsDef,           /* tp_getset */
     0,                               /* tp_base */
     0,                               /* tp_dict */
     0,                               /* tp_descr_get */
diff --git a/modules/cellframe-sdk/net/src/libdap_chain_net_python.c b/modules/cellframe-sdk/net/src/libdap_chain_net_python.c
index 3f81f3f6..5d1a0c8d 100644
--- a/modules/cellframe-sdk/net/src/libdap_chain_net_python.c
+++ b/modules/cellframe-sdk/net/src/libdap_chain_net_python.c
@@ -183,3 +183,11 @@ PyObject *dap_chain_net_get_tx_by_hash_py(PyObject *self, PyObject *args){
     }
     return (PyObject*)obj_tx;
 }
+
+PyObject *dap_chain_net_python_get_id(PyObject *self, void *closure){
+    (void)closure;
+    PyDapChainNetIdObject *obj_net_id = PyObject_New(PyDapChainNetObject, &DapChainNetIdObject_DapChainNetIdObjectType);
+    PyObject_Dir((PyObject*)obj_net_id);
+    obj_net_id->net_id = ((PyDapChainNetObject*)self)->chain_net->pub.id;
+    return (PyObject*)obj_net_id;
+}
diff --git a/modules/cellframe-sdk/type/dag/CMakeLists.txt b/modules/cellframe-sdk/type/dag/CMakeLists.txt
new file mode 100644
index 00000000..b4f1649e
--- /dev/null
+++ b/modules/cellframe-sdk/type/dag/CMakeLists.txt
@@ -0,0 +1,208 @@
+project(dap_chain_cs_dag_python_module C)
+cmake_minimum_required(VERSION 3.0)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+set(CMAKE_COLOR_MAKEFILE   ON)
+set(CMAKE_C_STANDARD 11)
+add_definitions("-fpic")
+add_definitions("-DDAP_LOG_MT")
+
+if(UNIX)
+    add_definitions("-DDAP_OS_UNIX")
+endif()
+
+if (NOT (${SUBMODULES_NO_BUILD} MATCHES ON))
+    set (SUBMODULES_NO_BUILD ON)
+    if (NOT (TARGET dap_core))
+        add_subdirectory(libdap)
+        target_compile_options(
+                dap_core PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_crypto))
+        add_subdirectory(libdap-crypto)
+        target_compile_options(
+                dap_crypto PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain))
+        add_subdirectory(libdap-chain)
+        target_compile_options(
+                dap_chain PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_crypto))
+        add_subdirectory(libdap-chain-crypto)
+        target_compile_options(
+                dap_chain_crypto PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_common))
+        add_subdirectory(libdap-chain-common)
+        target_compile_options(
+                dap_chain_common PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_mempool))
+        add_subdirectory(libdap-chain-mempool)
+        target_compile_options(
+                dap_chain_mempool PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_net))
+        add_subdirectory(libdap-chain-net)
+        target_compile_options(
+                dap_chain_net PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_server_core))
+        add_subdirectory(libdap-server-core)
+        target_compile_options(
+                dap_server_core PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_global_db))
+        add_subdirectory(libdap-chain-global-db)
+        target_compile_options(
+                dap_chain_global_db PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_client))
+        add_subdirectory(libdap-client)
+        target_compile_options(
+                dap_client PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET libdap-server))
+        add_subdirectory(libdap-server)
+        #       target_compile_options(
+        #            libdap-server PRIVATE
+        #            "-fpic"
+        #       )
+    endif()
+    if (NOT (TARGET dap_stream))
+        add_subdirectory(libdap-stream)
+        target_compile_options(
+                dap_stream PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_stream_ch))
+        add_subdirectory(libdap-stream-ch)
+        target_compile_options(
+                dap_stream_ch PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_stream_ch_chain))
+        add_subdirectory(libdap-stream-ch-chain)
+        target_compile_options(
+                dap_stream_ch_chain PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_stream_ch_chain_net))
+        add_subdirectory(libdap-stream-ch-chain-net)
+        target_compile_options(
+                dap_stream_ch_chain_net PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_udp_server))
+        add_subdirectory(libdap-server-udp)
+        target_compile_options(
+                dap_udp_server PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_wallet))
+        add_subdirectory(libdap-chain-wallet)
+        target_compile_options(
+                dap_chain_wallet PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_net_srv))
+        add_subdirectory(libdap-chain-net-srv)
+        target_compile_options(
+                dap_chain_net_srv PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_server_http_db_auth))
+        add_subdirectory(libdap-server-http-db-auth)
+        target_compile_options(
+                dap_server_http_db_auth PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_gdb))
+        add_subdirectory(libdap-chain-gdb)
+        target_compile_options(
+                dap_chain_gdb PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_python_module))
+        add_subdirectory(libdap-python)
+        target_compile_options(
+                dap_python_module PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_crypto_python_module))
+        add_subdirectory(libdap-crypto-python)
+        target_compile_options(
+                dap_crypto_python_module PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_net_srv_vpn))
+        add_subdirectory(libdap-chain-net-srv-vpn)
+        target_compile_options(
+                dap_chain_net_srv_vpn PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_server_http_db))
+        add_subdirectory(libdap-server-http-db)
+        target_compile_options(
+                dap_server_http_db PRIVATE
+                "-fpic"
+        )
+    endif()
+    if (NOT (TARGET dap_chain_common_python_module))
+        add_subdirectory(libdap-chain-common-python)
+        target_compile_options(
+                dap_chain_common_python_module PRIVATE
+                "-fpic"
+        )
+    endif()
+endif()
+#add_definitions("-DDAP_APP_NAME=\"TestPRJ\" -DSYSTEM_CONFIGS_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\"")
+
+file(GLOB CHAIN_CS_DAG_PYTHON_SRCS src/*.c)
+file(GLOB CHAIN_CS_DAG_PYTHON_HEADERS include/*.h)
+
+set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
+find_package (PythonLibs REQUIRED)
+include_directories(${PYTHON_INCLUDE_DIR} include/)
+
+add_library(${PROJECT_NAME} STATIC ${CHAIN_CS_DAG_PYTHON_SRCS} ${CHAIN_CS_DAG_PYTHON_HEADERS})
+
+target_link_libraries(${PROJECT_NAME})
+
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_cs_dag dap_server_core dap_chain_net dap_crypto_python_module dap_python_module dap_chain_common_python_module)
+
+target_include_directories(${PROJECT_NAME} PUBLIC include/ )
+
diff --git a/modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag.h b/modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag.h
new file mode 100644
index 00000000..c978669c
--- /dev/null
+++ b/modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag.h
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <Python.h>
+#include "dap_chain_cs_dag.h"
+#include "wrapping_dap_chain_cs_dag_event.h"
+#include "wrapping_dap_hash.h"
+#include "wrapping_dap_chain_atom_ptr.h"
+#include "libdap_chain_atom_iter_python.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+typedef struct PyDapChainCsDag {
+    PyObject_HEAD
+    dap_chain_cs_dag_t *dag;
+} PyDapChainCsDagObject;
+
+PyObject *dap_chain_cs_dag_find_event_by_hash_py(PyObject *self, PyObject *args);
+
+static PyMethodDef DapChainCsDagMethods[] = {
+        {"findByHash", (PyCFunction)dap_chain_cs_dag_find_event_by_hash_py, METH_VARARGS, ""},
+        {NULL, NULL, 0, NULL}
+};
+
+static PyTypeObject DapChainCsDag_DapChainCsDagType = {
+        PyVarObject_HEAD_INIT(NULL, 0)
+        "CellFrame.ChainCsDag",                                            /* tp_name */
+        sizeof(PyDapChainCsDagObject),                                     /* tp_basicsize */
+        0,                                                            /* tp_itemsize */
+        0,                         /* tp_dealloc */
+        0,                                                            /* tp_print */
+        0,                                                            /* tp_getattr */
+        0,                                                            /* tp_setattr */
+        0,                                                            /* tp_reserved */
+        0,                                                            /* tp_repr */
+        0,                                                            /* tp_as_number */
+        0,                                                            /* tp_as_sequence */
+        0,                                                            /* tp_as_mapping */
+        0,                                                            /* tp_hash  */
+        0,                                                            /* tp_call */
+        0,                                                            /* tp_str */
+        0,                                                            /* tp_getattro */
+        0,                                                            /* tp_setattro */
+        0,                                                            /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT |
+        Py_TPFLAGS_BASETYPE,                                      /* tp_flags */
+        "Chain cs dag objects",                                              /* tp_doc */
+        0,                                                              /* tp_traverse */
+        0,                                                              /* tp_clear */
+        0,                                                              /* tp_richcompare */
+        0,                                                              /* tp_weaklistoffset */
+        0,                                                              /* tp_iter */
+        0,                                                            /* tp_iternext */
+        DapChainCsDagMethods,                                        /* tp_methods */
+        0,                                                          /* tp_members */
+        0,                                                           /* tp_getset */
+        0,                                                            /* tp_base */
+        0,                                                            /* tp_dict */
+        0,                                                            /* tp_descr_get */
+        0,                                                            /* tp_descr_set */
+        0,                                                            /* tp_dictoffset */
+        0,                                                            /* tp_init */
+        0,                                                            /* tp_alloc */
+        PyType_GenericNew,                                            /* tp_new */
+};
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag_event.h b/modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag_event.h
new file mode 100644
index 00000000..e4c1dfb5
--- /dev/null
+++ b/modules/cellframe-sdk/type/dag/include/wrapping_dap_chain_cs_dag_event.h
@@ -0,0 +1,85 @@
+#pragma once
+
+#include <Python.h>
+#include <datetime.h>
+#include "dap_chain_cs_dag_event.h"
+#include "wrapping_dap_chain_common.h"
+#include "wrapping_dap_hash.h"
+#include "wrapping_dap_chain_datum.h"
+
+typedef struct PyDapChainCsDagEvent{
+    PyObject_HEAD
+    dap_chain_cs_dag_event_t *event;
+    size_t event_size;
+}PyDapChainCsDagEventObject;
+
+PyObject *wrapping_dap_chain_cs_dag_event_get_version(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_round_id(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_ts_created(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_chain_id(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_cell_id(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_hash_count(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_signs_count(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_links(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_datum(PyObject *self, void *closure);
+PyObject *wrapping_dap_chain_cs_dag_event_get_signs(PyObject *self, void *closure);
+
+static PyMethodDef PyDapChainCsDagEventMethodsDef[] = {
+        {NULL, NULL, 0, NULL}
+};
+
+static PyGetSetDef PyDapChainCsDagEventGetsSetsDef[] = {
+        {"version", (getter)wrapping_dap_chain_cs_dag_event_get_version, NULL, NULL, NULL},
+        {"roundId", (getter)wrapping_dap_chain_cs_dag_event_get_round_id, NULL, NULL, NULL},
+        {"created", (getter)wrapping_dap_chain_cs_dag_event_get_ts_created, NULL, NULL, NULL},
+        {"chainId", (getter)wrapping_dap_chain_cs_dag_event_get_chain_id, NULL, NULL, NULL},
+        {"cellId", (getter)wrapping_dap_chain_cs_dag_event_get_cell_id, NULL, NULL, NULL},
+        {"hashCount", (getter)wrapping_dap_chain_cs_dag_event_get_hash_count, NULL, NULL, NULL},
+        {"signsCount", (getter)wrapping_dap_chain_cs_dag_event_get_signs_count, NULL, NULL, NULL},
+        {"links", (getter)wrapping_dap_chain_cs_dag_event_get_links, NULL, NULL, NULL},
+        {"datum", (getter)wrapping_dap_chain_cs_dag_event_get_datum, NULL, NULL, NULL},
+        {"signs", (getter)wrapping_dap_chain_cs_dag_event_get_signs, NULL, NULL, NULL},
+        {NULL}
+};
+
+static PyTypeObject DapChainCsDagEvent_DapChainCsDagEventType = {
+        PyVarObject_HEAD_INIT(NULL, 0)
+        "CellFrame.ChainCsDagEvent",                                            /* tp_name */
+        sizeof(PyDapChainCsDagEventObject),                                     /* tp_basicsize */
+        0,                                                            /* tp_itemsize */
+        0,                         /* tp_dealloc */
+        0,                                                            /* tp_print */
+        0,                                                            /* tp_getattr */
+        0,                                                            /* tp_setattr */
+        0,                                                            /* tp_reserved */
+        0,                                                            /* tp_repr */
+        0,                                                            /* tp_as_number */
+        0,                                                            /* tp_as_sequence */
+        0,                                                            /* tp_as_mapping */
+        0,                                                            /* tp_hash  */
+        0,                                                            /* tp_call */
+        0,                                                            /* tp_str */
+        0,                                                            /* tp_getattro */
+        0,                                                            /* tp_setattro */
+        0,                                                            /* tp_as_buffer */
+        Py_TPFLAGS_DEFAULT |
+        Py_TPFLAGS_BASETYPE,                                      /* tp_flags */
+        "Chain cs dag event objects",                                              /* tp_doc */
+        0,		                                                      /* tp_traverse */
+        0,		                                                      /* tp_clear */
+        0,		                                                      /* tp_richcompare */
+        0,		                                                      /* tp_weaklistoffset */
+        0,		                                                      /* tp_iter */
+        0,		                                                      /* tp_iternext */
+        PyDapChainCsDagEventMethodsDef,                             /* tp_methods */
+        0,                                                            /* tp_members */
+        PyDapChainCsDagEventGetsSetsDef,                             /* tp_getset */
+        0,                                                            /* tp_base */
+        0,                                                            /* tp_dict */
+        0,                                                            /* tp_descr_get */
+        0,                                                            /* tp_descr_set */
+        0,                                                            /* tp_dictoffset */
+        0,                                                            /* tp_init */
+        0,                                                            /* tp_alloc */
+        PyType_GenericNew,                                            /* tp_new */
+};
diff --git a/modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag.c b/modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag.c
new file mode 100644
index 00000000..e9a756a6
--- /dev/null
+++ b/modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag.c
@@ -0,0 +1,29 @@
+#include "wrapping_dap_chain_cs_dag.h"
+#include "dap_chain_cell.h"
+
+PyObject *dap_chain_cs_dag_find_event_by_hash_py(PyObject *self, PyObject *args){
+    PyObject *obj_hash;
+    PyObject *obj_atom_iter;
+    if (!PyArg_ParseTuple(args, "O", &obj_hash)){
+        PyErr_SetString(PyExc_AttributeError, "This function must take two arguments. ");
+        return NULL;
+    }
+    bool isCheck = PyObject_TypeCheck(obj_hash, &DapHashFastObject_DapHashFastObjectType);
+    dap_chain_cell_t *l_cell = ((PyDapChainCsDagObject*)self)->dag->chain->cells;
+    size_t size_atom = 0;
+    dap_chain_atom_iter_t *l_iter = ((PyDapChainCsDagObject*)self)->dag->chain->callback_atom_iter_create(
+            ((PyDapChainCsDagObject*)self)->dag->chain);
+    dap_chain_atom_ptr_t l_ptr = ((PyDapChainCsDagObject*)self)->dag->chain->callback_atom_find_by_hash(
+            l_iter,
+            ((PyDapHashFastObject*)obj_hash)->hash_fast,
+            &size_atom);
+    if (l_ptr == NULL){
+        return Py_None;
+    }
+    PyDapChainCsDagEventObject *obj_event = PyObject_New(PyDapChainCsDagEventObject,
+                                                         &DapChainCsDagEvent_DapChainCsDagEventType);
+    PyObject_Dir((PyObject*)obj_event);
+    obj_event->event = l_iter->cur;
+    obj_event->event_size = l_iter->cur_size;
+    return (PyObject*)obj_event;
+}
\ No newline at end of file
diff --git a/modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag_event.c b/modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag_event.c
new file mode 100644
index 00000000..049cc4f3
--- /dev/null
+++ b/modules/cellframe-sdk/type/dag/src/wrapping_dap_chain_cs_dag_event.c
@@ -0,0 +1,81 @@
+#include "wrapping_dap_chain_cs_dag_event.h"
+
+PyObject *wrapping_dap_chain_cs_dag_event_get_version(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("H", ((PyDapChainCsDagEventObject*)self)->event->header.version);
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_round_id(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("k", ((PyDapChainCsDagEventObject*)self)->event->header.round_id);
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_ts_created(PyObject *self, void *closure){
+    (void)closure;
+    PyDateTime_IMPORT;
+    PyObject *obj_ts_float = PyLong_FromLong(((PyDapChainCsDagEventObject*)self)->event->header.ts_created);
+    PyObject *obj_ts = Py_BuildValue("(O)", obj_ts_float);
+    PyDateTime_IMPORT;
+    PyObject *obj_dt = PyDateTime_FromTimestamp(obj_ts);
+    return obj_dt;
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_chain_id(PyObject *self, void *closure){
+    (void)closure;
+    PyDapChainIDObject *obj_chain_id = PyObject_New(PyDapChainIDObject, &DapChainIDObject_DapChainIDType);
+    PyObject_Dir((PyObject*)obj_chain_id);
+    obj_chain_id->chain_id = &((PyDapChainCsDagEventObject*)self)->event->header.chain_id;
+    return (PyObject*)obj_chain_id;
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_cell_id(PyObject *self, void *closure){
+    (void)closure;
+    PyDapChainCellIDObject *obj_cell_id = PyObject_New(PyDapChainCellIDObject, &DapChainCellIDObject_DapChainCellIDType);
+    PyObject_Dir((PyObject*)obj_cell_id);
+    obj_cell_id->cell_id = ((PyDapChainCsDagEventObject*)self)->event->header.cell_id;
+    return (PyObject*)obj_cell_id;
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_hash_count(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("H", ((PyDapChainCsDagEventObject*)self)->event->header.hash_count);
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_signs_count(PyObject *self, void *closure){
+    (void)closure;
+    return Py_BuildValue("H", ((PyDapChainCsDagEventObject*)self)->event->header.signs_count);
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_links(PyObject *self, void *closure){
+    (void)closure;
+    PyObject *obj_list = PyList_New(((PyDapChainCsDagEventObject*)self)->event->header.hash_count);
+    for (uint16_t i=0; i < ((PyDapChainCsDagEventObject*)self)->event->header.hash_count; i++){
+        PyDapHashFastObject  *obj_hf = PyObject_New(PyDapHashFastObject, &DapHashFastObject_DapHashFastObjectType);
+        PyObject_Dir((PyObject*)obj_hf);
+        obj_hf->hash_fast =
+                (dap_chain_hash_fast_t *) (((PyDapChainCsDagEventObject*)self)->event->hashes_n_datum_n_signs +
+                                                                    i*sizeof (dap_chain_hash_fast_t));
+        PyList_SetItem(obj_list, i, obj_hf);
+    }
+    return obj_list;
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_datum(PyObject *self, void *closure){
+    (void)closure;
+    size_t l_offset =  ((PyDapChainCsDagEventObject*)self)->event->header.hash_count*sizeof (dap_chain_hash_fast_t);
+    PyDapChainDatumObject *datum = PyObject_New(PyDapChainDatumObject, &DapChainDatumObject_DapChainDatumObjectType);
+    PyObject_Dir((PyObject*)datum);
+    datum->datum = (dap_chain_datum_t*) (((PyDapChainCsDagEventObject*)self)->event->hashes_n_datum_n_signs + l_offset);
+    return (PyObject*)datum;
+}
+PyObject *wrapping_dap_chain_cs_dag_event_get_signs(PyObject *self, void *closure){
+    size_t l_offset =  ((PyDapChainCsDagEventObject*)self)->event->header.hash_count*sizeof (dap_chain_hash_fast_t);
+    dap_chain_datum_t  *l_datum = (dap_chain_datum_t*) (((PyDapChainCsDagEventObject*)self)->event->hashes_n_datum_n_signs + l_offset);
+    l_offset += dap_chain_datum_size(l_datum);
+    PyObject *obj_list = PyList_New(0);
+    while (l_offset + sizeof(((PyDapChainCsDagEventObject*)self)->event->header) < ((PyDapChainCsDagEventObject*)self)->event_size){
+        dap_sign_t * l_sign =(dap_sign_t *) (((PyDapChainCsDagEventObject*)self)->event->hashes_n_datum_n_signs +l_offset);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        if (l_sign_size == 0){
+            break;
+        }
+        PyDapSignObject *obj_sign = PyObject_New(PyDapSignObject, &DapSignObject_DapSignObjectType);
+        PyObject_Dir((PyObject*)obj_sign);
+        obj_sign->sign = l_sign;
+        PyList_Append(obj_list, (PyObject*)obj_sign);
+        l_offset += l_sign_size;
+    }
+    return obj_list;
+}
diff --git a/setup.py b/setup.py
index 28b02649..898f14b6 100755
--- a/setup.py
+++ b/setup.py
@@ -70,7 +70,7 @@ class CMakeBuild(build_ext):
 
 setup(
     name="CellFrame",
-    version="2.9-34",
+    version="2.9-35",
     description="CellFrame SDK",
     author='Demlabs (2007-2022)',
     license="GNU GPLv3",
-- 
GitLab