diff --git a/stream/ch/chain/net/srv/DapStreamChChainNetSrv.cpp b/stream/ch/chain/net/srv/DapStreamChChainNetSrv.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..92bb5c63f59c21e2bc24f57f39fc191de839b7c6
--- /dev/null
+++ b/stream/ch/chain/net/srv/DapStreamChChainNetSrv.cpp
@@ -0,0 +1,160 @@
+/*
+* Authors:
+* Dmitriy Gerasimov <naeper@demlabs.net>
+* Cellframe       https://cellframe.net
+* DeM Labs Inc.   https://demlabs.net
+* Copyright  (c) 2017-2019
+* All rights reserved.
+
+This file is part of CellFrame SDK the open source project
+
+CellFrame SDK is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+CellFrame SDK 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QtDebug>
+#include "dap_common.h"
+#include "DapStreamChChainNetSrv.h"
+
+
+// TYPE_REQUEST
+typedef struct dap_stream_ch_chain_net_srv_pkt_request_hdr{
+    dap_chain_net_id_t net_id;// Network id wheither to request
+    dap_chain_hash_fast_t tx_cond; // Conditioned transaction with paymemt for
+    dap_chain_net_srv_uid_t srv_uid;
+    char token[DAP_CHAIN_TICKER_SIZE_MAX];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_hdr_t;
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_request{
+    dap_stream_ch_chain_net_srv_pkt_request_hdr_t hdr;
+    uint8_t data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_t;
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_success_hdr{
+    uint32_t usage_id;
+    dap_chain_net_id_t net_id;
+    dap_chain_net_srv_uid_t srv_uid;
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_hdr_t;
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_success{
+    dap_stream_ch_chain_net_srv_pkt_success_hdr_t hdr;
+    uint8_t custom_data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_t;
+
+// TYPE_RESPONSE_ERROR
+typedef struct dap_stream_ch_chain_net_srv_pkt_error{
+    dap_chain_net_id_t net_id;
+    dap_chain_net_srv_uid_t srv_uid;
+    uint32_t usage_id;
+    uint32_t code; // error code
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_error_t;
+
+using namespace Dap;
+using namespace Dap::Stream;
+using namespace Dap::Chain;
+using namespace Dap::Crypto;
+
+/**
+ * @brief ChChainNetSrv::ChChainNetSrv
+ * @param a_streamer
+ * @param a_mainDapSession
+ */
+ChChainNetSrv::ChChainNetSrv(DapStreamer * a_streamer, DapSession * a_mainDapSession)
+                : DapChBase(nullptr, 'R'), m_streamer(a_streamer), m_mainDapSession(a_mainDapSession)
+{
+
+}
+
+/**
+ * @brief ChChainNetSrv::sendReceipt
+ * @param receipt
+ */
+void ChChainNetSrv::sendReceipt(Chain::Receipt * receipt )
+{
+    sendPacket( get_id(),ChChainNetSrvPktType::SIGN_RESPONSE,receipt->value() ,receipt->size() );
+
+    // To prevent double free
+    receipt->release();
+    delete receipt;
+}
+
+/**
+ * @brief ChChainNetSrv::onPktIn
+ * @param a_pkt
+ */
+void ChChainNetSrv::onPktIn(DapChannelPacket* a_pkt)
+{
+    switch (static_cast<ChChainNetSrvPktType>(a_pkt->hdr()->type) ) {
+        case REQUEST:{
+            qWarning() << "We don't serve any service so nothing todo with REQUEST. TODO: add service provide for this realization as well";
+        } break;
+        case SIGN_REQUEST:{
+            Chain::Receipt * receipt = nullptr;
+            try {
+                receipt = new Chain::Receipt(a_pkt->data(), a_pkt->hdr()->size);
+                emit sigReceiptToSign(receipt);
+            } catch (Chain::Receipt::ThrowClass err) {
+                switch (err) {
+                    case Chain::Receipt::DataNull:
+                        qWarning() << "Packet with receipt has NULL data";
+                    break;
+                    case Chain::Receipt::DataSizeWrong:
+                    qWarning() << "Packet with receipt has wrong data size "<< a_pkt->hdr()->size;
+                    break;
+                }
+            }
+
+        } break;
+        case SIGN_RESPONSE:{
+            qWarning() << "We don't serve any service so nothing todo with SIG_RESPONSE. TODO: add service provide for this realization as well";
+        } break;
+        case RESPONSE_SUCCESS:{
+            if( a_pkt->hdr()->size < sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t) ){
+                qWarning() << "Wrong error packet data size, expected to be at least " << sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t);
+                break;
+            }
+            const dap_stream_ch_chain_net_srv_pkt_success_t * l_success =
+                    reinterpret_cast<const dap_stream_ch_chain_net_srv_pkt_success_t* >(a_pkt->data());
+            emit sigProvideSuccess( l_success->hdr.net_id, l_success->hdr.srv_uid, l_success->hdr.usage_id );
+        } break;
+        case RESPONSE_ERROR:{
+            const dap_stream_ch_chain_net_srv_pkt_error_t *l_err;
+            if( a_pkt->hdr()->size != sizeof(*l_err) ){
+                qWarning() << "Wrong error packet data size, expected to be "<<sizeof (*l_err);
+                break;
+            }
+            l_err =reinterpret_cast<const dap_stream_ch_chain_net_srv_pkt_error_t*>(a_pkt->data());
+            emit sigProvideError(l_err->net_id, l_err->srv_uid, l_err->usage_id,  l_err->code );
+        } break;
+        case NOTIFY_STOPPED: {
+            /// TODO add usage id, net id and service id to identify what exactly was stopped
+            emit sigNotifyStopped();
+        } break;
+        //default: qWarning() << "Unknown packet type " << a_pkt->hdr()->type;
+    }
+}
+
+void ChChainNetSrv::sendRequest(Chain::NetId a_netId,// Network id wheither to request
+    Crypto::HashFast a_txCond, // Conditioned transaction with paymemt for
+    Chain::NetSrv::Uid a_srvUid, const QString& a_token ) // Service ID
+{
+    dap_stream_ch_chain_net_srv_pkt_request_t * l_request =static_cast<dap_stream_ch_chain_net_srv_pkt_request_t *>(
+                calloc(1,sizeof(dap_stream_ch_chain_net_srv_pkt_request_t) ) );
+    l_request->hdr.net_id = a_netId.value();
+    l_request->hdr.tx_cond = a_txCond.value();
+    qDebug() << "2791: Service req: net_id = " << a_netId.value().uint64 << "tx_cond = " << a_txCond.value().raw;
+    l_request->hdr.srv_uid = a_srvUid;
+    strncpy(l_request->hdr.token, a_token.toLatin1().constData(),sizeof (l_request->hdr.token)-1);
+    sendPacket( get_id(),ChChainNetSrvPktType::REQUEST,l_request,sizeof(*l_request));
+    qInfo() << "Sent request for service "<<a_srvUid.toString();
+}
diff --git a/stream/ch/chain/net/srv/DapStreamChChainNetSrv.h b/stream/ch/chain/net/srv/DapStreamChChainNetSrv.h
new file mode 100755
index 0000000000000000000000000000000000000000..4cbbc723204b4308cae22c5843e5743ef18a0d06
--- /dev/null
+++ b/stream/ch/chain/net/srv/DapStreamChChainNetSrv.h
@@ -0,0 +1,227 @@
+/*
+* Authors:
+* Dmitriy Gerasimov <naeper@demlabs.net>
+* Cellframe       https://cellframe.net
+* DeM Labs Inc.   https://demlabs.net
+* Copyright  (c) 2017-2019
+* All rights reserved.
+
+This file is part of CellFrame SDK the open source project
+
+CellFrame SDK is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+CellFrame SDK 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#include "dap_common.h"
+#include "dap_chain_common.h"
+#include "dap_chain_datum_tx_receipt.h"
+#include "DapChBase.h"
+#include "DapCrypto.h"
+
+
+
+class DapStreamer;
+class DapSession;
+namespace Dap {
+
+    // TODO move to its own module
+    namespace Chain {
+
+        class NetId
+        {
+        private:
+            dap_chain_net_id_t m_value;
+        public:
+            const dap_chain_net_id_t& value () const { return  m_value;}
+            NetId(){ m_value.uint64 = 0ull; }
+            NetId( const dap_chain_net_id_t& a_value){ m_value.uint64 = a_value.uint64; }
+            NetId( const NetId& a_netId){ m_value.uint64 = a_netId.m_value.uint64; }
+            NetId( const QString& a_str){
+                m_value.uint64 = a_str.isNull() ? 0 : dap_chain_net_id_from_str(a_str.toLatin1().constData()).uint64;
+            }
+            QString toString(){ return QString().sprintf("0x%016lX",m_value.uint64); }
+            operator dap_chain_net_id_t& (){ return  m_value; }
+            dap_chain_net_id_t& operator=(const NetId& a_netId) {  m_value.uint64 = a_netId.m_value.uint64; return m_value; }
+            dap_chain_net_id_t& operator=(QString& a_netId_str) {
+                m_value.uint64 = a_netId_str.toInt(nullptr, 16);
+                return m_value;
+            }
+            bool operator==(const NetId& a_netId){ return a_netId.m_value.uint64 == m_value.uint64; }
+        };
+
+
+        namespace NetSrv {
+            class Uid
+            {
+            private:
+                dap_chain_net_srv_uid_t m_value;
+            public:
+                Uid(quint64 a_value) { m_value.uint64 = a_value ;}
+                Uid(){ m_value.uint64 = 0ull; }
+                Uid( const dap_chain_net_srv_uid_t& a_value){ m_value.uint64 = a_value.uint64; }
+                Uid( const Uid& a_netSrvUid){ m_value.uint64 = a_netSrvUid.m_value.uint64; }
+                Uid( const QString& a_str){
+                    m_value.uint64 = dap_chain_net_srv_uid_from_str(a_str.toLatin1().constData()).uint64;
+                }
+                operator dap_chain_net_srv_uid_t& (){ return  m_value; }
+
+                QString toString(){ return QString().sprintf("0x%016lX",m_value.uint64); }
+
+                dap_chain_net_srv_uid_t& operator=(const Uid& a_netSrvUid) {
+                    m_value.uint64 = a_netSrvUid.m_value.uint64;
+                    return m_value;
+                }
+                dap_chain_net_srv_uid_t& operator=(quint64 a_value) {
+                    m_value.uint64 = a_value;
+                    return m_value;
+                }
+
+                bool operator==(const Uid& a_netSrvUid){ return a_netSrvUid.m_value.uint64 == m_value.uint64; }
+            };
+            static const Uid UidNull=Uid();
+            enum UnitType{
+                UNIT_TYPE_UNDEFINED = 0 ,
+                UNIT_TYPE_MB = 0x00000001, // megabytes
+                UNIT_TYPE_SEC = 0x00000002, // seconds
+                UNIT_TYPE_DAY = 0x00000003,  // days
+                UNIT_TYPE_KB = 0x00000010,  // kilobytes
+                UNIT_TYPE_B = 0x00000011,   // bytes
+            };
+
+
+        }
+        class Receipt {
+        private:
+            dap_chain_datum_tx_receipt_t * m_value;
+        public:
+            enum ThrowClass{DataNull, DataSizeWrong};
+            Receipt() { m_value = nullptr; }
+            Receipt(const Receipt& a_receipt){ m_value = a_receipt.m_value; }
+            Receipt(const Receipt* a_receipt){ m_value = a_receipt->m_value; }
+            Receipt(const void * a_data, size_t a_dataSize){
+                if( a_data == nullptr)
+                    throw DataNull;
+                if( a_dataSize < ( 1 +sizeof (m_value->receipt_info)+sizeof (m_value->size)))
+                    throw DataSizeWrong;
+                m_value = DAP_NEW_Z_SIZE(dap_chain_datum_tx_receipt_t, a_dataSize);
+                ::memcpy(m_value,a_data,a_dataSize);
+            }
+            ~Receipt(){
+                if (m_value)
+                    DAP_DELETE(m_value);
+            }
+
+            void release(){ m_value = nullptr; } // Release wrapper from m_value to prevent doulbe free
+            operator dap_chain_datum_tx_receipt_t& () { return  *m_value;}
+            operator dap_chain_datum_tx_receipt_t* () { return  m_value;}
+            operator const void* () { return  m_value;}
+            operator void* () { return  m_value;}
+            quint16 size() { return m_value?m_value->size : 0; }
+
+            dap_chain_datum_tx_receipt_t * value() { return m_value; }
+            NetSrv::Uid getNetSrvUid() { return m_value ? m_value->receipt_info.srv_uid : NetSrv::UidNull; }
+            NetSrv::UnitType getUnitType() { return m_value ?static_cast<NetSrv::UnitType>(m_value->receipt_info.units_type.uint32):
+                                                             NetSrv::UNIT_TYPE_UNDEFINED ; }
+            quint64 getUnits() { return  m_value? m_value->receipt_info.units : 0; }
+            quint64 getValueDatoshi() { return  m_value ? m_value->receipt_info.value_datoshi: 0; }
+
+            void signAdd(Crypto::Key& a_key){
+                dap_chain_datum_tx_receipt_sign_add( &m_value, m_value->size, a_key );
+            }
+            void signAdd(Crypto::Cert& a_cert){
+                dap_chain_datum_tx_receipt_sign_add( &m_value, m_value->size, a_cert.key() );
+            }
+
+            Receipt* deepCopy(){
+                Receipt* ret = new Receipt;
+                ret->m_value = DAP_NEW_Z_SIZE(dap_chain_datum_tx_receipt_t, m_value->size);
+                ::memcpy(ret->m_value, m_value, m_value->size);
+                return  ret;
+            }
+        };
+
+    }
+    namespace Stream{
+        enum ChChainNetSrvPktType {
+            REQUEST             = 0x01,
+            SIGN_REQUEST        = 0x10,
+            SIGN_RESPONSE       = 0x11,
+            NOTIFY_STOPPED      = 0x20,
+            RESPONSE_SUCCESS    = 0xf0,
+            RESPONSE_ERROR      = 0xff
+        };
+        enum ChChainNetSrvPktResponseErrorCode{
+            UNDEFINED                 = 0x00000000,
+            SERVICE_NOT_FOUND         = 0x00000100,
+            NETWORK_NOT_FOUND         = 0x00000200,
+            NETWORK_NO_LEDGER         = 0x00000201,
+            USAGE_CANT_ADD            = 0x00000300,
+            TX_COND_NOT_FOUND         = 0x00000400,
+            TX_COND_NO_COND_OUT       = 0x00000401,
+            TX_COND_NOT_ENOUGH        = 0x00000402,
+            TX_COND_NOT_ACCEPT_TOKEN  = 0x00000403,
+            TX_COND_WRONG_SRV_UID     = 0x00000404,
+            TX_COND_WRONG_SIZE        = 0x00000405,
+            RECEIPT_CANT_FIND         = 0x00000500,
+            RECEIPT_NO_SIGN           = 0x00000501,
+            PRICE_NOT_FOUND           = 0x00000600,
+            RECEIPT_WRONG_PKEY_HASH   = 0x00000502,
+            UNKNOWN                   = 0xffffffff
+        };
+        static inline const QString chChainNetSrvPktResponseErrorCodeToString(quint32 a){
+            switch (static_cast<ChChainNetSrvPktResponseErrorCode>(a)) {
+                case UNDEFINED: return "UNDEFINED";
+                case SERVICE_NOT_FOUND: return "SERVICE_NOT_FOUND";
+                case NETWORK_NOT_FOUND: return "NETWORK_NOT_FOUND";
+                case NETWORK_NO_LEDGER: return "NETWORK_NO_LEDGER";
+                case USAGE_CANT_ADD: return "USAGE_CANT_ADD";
+                case TX_COND_NOT_FOUND: return "TX_COND_NOT_FOUND";
+                case TX_COND_NO_COND_OUT: return "TX_COND_NO_COND_OUT";
+                case TX_COND_NOT_ENOUGH: return "TX_COND_NOT_ENOUGH";
+                case TX_COND_NOT_ACCEPT_TOKEN: return "TX_COND_NOT_ACCEPT_TOKEN";
+                case TX_COND_WRONG_SRV_UID: return "TX_COND_WRONG_SRV_UID";
+                case TX_COND_WRONG_SIZE: return "TX_COND_WRONG_SIZE";
+                case RECEIPT_CANT_FIND: return "RECEIPT_CANT_FIND";
+                case RECEIPT_NO_SIGN: return "RECEIPT_NO_SIGN";
+                case PRICE_NOT_FOUND: return "PRICE_NOT_FOUND";
+                case RECEIPT_WRONG_PKEY_HASH: return "RECEIPT_WRONG_PKEY_HASH";
+                default: return "UNKNOWN";
+            }
+        };
+
+        class ChChainNetSrv : public DapChBase
+        {
+            Q_OBJECT
+        private:
+            DapStreamer * m_streamer;
+            DapSession * m_mainDapSession;
+        public:
+            ChChainNetSrv(DapStreamer * a_streamer, DapSession * a_mainDapSession);
+        signals:
+            void sigReceiptToSign(Chain::Receipt * receipt );
+            void sigProvideSuccess (Chain::NetId a_netId, Chain::NetSrv::Uid a_srvUid, quint32 a_usageId );
+            void sigProvideError(Chain::NetId a_netId, Chain::NetSrv::Uid a_srvUid, quint32 a_usageId,quint32 a_errorCode);
+            void sigNotifyStopped(); // Service stopped
+        public slots:
+            void onPktIn(DapChannelPacket* a_pkt) override;
+
+            void sendReceipt(Chain::Receipt * receipt );
+            void sendRequest(Chain::NetId a_netId,// Network id wheither to request
+                Crypto::HashFast a_txCond, // Conditioned transaction with paymemt for
+                Chain::NetSrv::Uid a_srvUid ,// Service ID
+                const QString& a_token        // Token to pay
+            );
+        };
+    }
+}
diff --git a/stream/ch/chain/net/srv/README.md b/stream/ch/chain/net/srv/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c9b4f1aa9868d47e0740b8970641a2096dcefc47
--- /dev/null
+++ b/stream/ch/chain/net/srv/README.md
@@ -0,0 +1,2 @@
+# libdap-qt-stream-ch-chain-net-srv
+
diff --git a/stream/ch/chain/net/srv/libdap-qt-stream-ch-chain-net-srv.pri b/stream/ch/chain/net/srv/libdap-qt-stream-ch-chain-net-srv.pri
new file mode 100755
index 0000000000000000000000000000000000000000..9aadb1e5b5024d4dd4aa9de7238ec6febd62a3b7
--- /dev/null
+++ b/stream/ch/chain/net/srv/libdap-qt-stream-ch-chain-net-srv.pri
@@ -0,0 +1,7 @@
+SOURCES += \
+    $$PWD/DapStreamChChainNetSrv.cpp
+
+HEADERS += \
+    $$PWD/DapStreamChChainNetSrv.h
+
+INCLUDEPATH += $$PWD