diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Sergey Bushnyak (c) 2019
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Sergey Bushnyak nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# api-factom
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/api-rpc-factom.cabal b/api-rpc-factom.cabal
new file mode 100644
--- /dev/null
+++ b/api-rpc-factom.cabal
@@ -0,0 +1,89 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.31.2.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 4a03e226d4cdc196784e6ca4a4cc652c2cf2c1812d85ff21c8c672e23581cfb5
+
+name:           api-rpc-factom
+version:        0.1.3.0
+synopsis:       RPC API client for Factom
+description:    RPC API client for Factom blockchain
+category:       Web
+homepage:       https://github.com/sigrlami/api-monobank#readme
+bug-reports:    https://github.com/sigrlami/api-monobank/issues
+author:         Sergey Bushnyak
+maintainer:     sergey.bushnyak@sigrlami.eu
+copyright:      Copyright: (c) 2019 Sergey Bushnyak
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+
+source-repository head
+  type: git
+  location: https://github.com/sigrlami/api-monobank
+
+library
+  exposed-modules:
+      Factom.RPC.Api
+      Factom.RPC.Wallet.Api
+      Factom.RPC.Types
+  other-modules:
+      Factom.RPC.JsonRpc
+      Factom.RPC.Utils
+      Paths_api_rpc_factom
+  hs-source-dirs:
+      src
+  build-depends:
+      aeson
+    , aeson-casing
+    , base >=4.7 && <5
+    , bytestring
+    , http-client
+    , http-client-tls
+    , http-conduit
+    , network
+    , servant
+    , servant-client
+    , servant-jsonrpc
+    , servant-jsonrpc-client
+    , text
+    , time
+    , transformers
+  default-language: Haskell2010
+
+executable factom-app
+  main-is: Main.hs
+  other-modules:
+      Paths_api_rpc_factom
+  hs-source-dirs:
+      app
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      aeson
+    , api-rpc-factom
+    , base
+    , bytestring
+    , http-client
+    , http-conduit
+    , stm
+    , text
+    , time
+  default-language: Haskell2010
+
+test-suite factom-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_api_rpc_factom
+  hs-source-dirs:
+      tests
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      api-rpc-factom
+    , base
+    , bytestring
+  default-language: Haskell2010
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import           Control.Concurrent          (forkIO, threadDelay)
+import           Control.Concurrent.STM.TVar
+import           Control.Monad               (forever)
+import qualified Data.Text                   as T
+import           Data.Time.Clock
+import           System.Environment
+
+import qualified Factom.RPC.Api              as FCTApi
+import qualified Factom.RPC.Types            as FCTApi
+
+--------------------------------------------------------------------------------
+
+main :: IO ()
+main =
+  do
+    let delay = 60000  -- 1 request per minute available
+    a       <- getArgs
+    timeVar <- newTVarIO (delay*1000)
+    case a of
+      ["-t"]    -> do
+        -- read token from file
+        return ()
+      otherwise -> do
+        putStrLn $ "Factom | Establishing connection"
+        putStrLn $ "Factom | Getting last entries\n"
+        --mentries <- MBApi.getEntries
+        --putStrLn $ show $ mcurrs
+        -- mapM_ FCTApi.showEntryBlock mentries
+        return ()
diff --git a/src/Factom/RPC/Api.hs b/src/Factom/RPC/Api.hs
new file mode 100644
--- /dev/null
+++ b/src/Factom/RPC/Api.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE DataKinds                  #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE TypeOperators              #-}
+
+module Factom.RPC.Api
+    ( runTCPClient
+    ) where
+
+import           Control.Exception  (bracket)
+import           Network.Socket     (HostName, ServiceName, SocketType (Stream),
+                                     addrAddress, addrFamily, addrProtocol,
+                                     addrSocketType, close, connect,
+                                     defaultHints, getAddrInfo, socket)
+
+import           Factom.RPC.JsonRpc (JsonRpcT, runJsonRpcT)
+
+
+--------------------------------------------------------------------------------
+
+endpoint = "http://localhost:8088/v2"
+
+runTCPClient :: HostName -> ServiceName -> JsonRpcT IO a -> IO a
+runTCPClient host port f = do
+  addr <- resolve host port
+  bracket (open addr) close talk
+    where
+      resolve host' port' = do
+          let hints = defaultHints { addrSocketType = Stream }
+          addr:_ <- getAddrInfo (Just hints) (Just host') (Just port')
+          return addr
+
+      open addr = do
+          sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
+          connect sock $ addrAddress addr
+          return sock
+
+      talk sock = runJsonRpcT sock f
diff --git a/src/Factom/RPC/JsonRpc.hs b/src/Factom/RPC/JsonRpc.hs
new file mode 100644
--- /dev/null
+++ b/src/Factom/RPC/JsonRpc.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TemplateHaskell            #-}
+
+module Factom.RPC.JsonRpc
+    ( JsonRpcT (..)
+    , Method (..)
+    , Request (..)
+    , Response (..)
+    , Error
+    , version
+    , runJsonRpcT
+    , request
+    , mkDefaultRequest
+    ) where
+
+import           Control.Monad.IO.Class         (MonadIO, liftIO)
+import           Control.Monad.Trans.Class      (lift)
+import           Control.Monad.Trans.Reader     (ReaderT, ask, runReaderT)
+import           Control.Monad.Trans.State.Lazy (StateT (..), evalStateT, get,
+                                                 modify')
+import           Data.Aeson                     (FromJSON (..), ToJSON (..),
+                                                 eitherDecode', encode,
+                                                 withObject, (.:), (.:?))
+import           Data.Aeson.Casing              (snakeCase)
+import           Data.Aeson.TH                  (defaultOptions, deriveJSON,
+                                                 fieldLabelModifier,
+                                                 omitNothingFields)
+import           Data.ByteString.Lazy           (fromStrict, toStrict)
+import           Data.Either                    (Either)
+import           Data.Text                      (Text)
+import           Network.Socket                 (Socket)
+import           Network.Socket.ByteString      (recv, sendAll)
+
+--------------------------------------------------------------------------------
+
+newtype Version =
+  Version Text
+    deriving (Eq, Show, ToJSON, FromJSON)
+
+version :: Version
+version = Version "2.0"
+
+newtype Method =
+  Method Text
+    deriving (Eq, Show, ToJSON, FromJSON)
+
+data Request a = Request
+    { reqJsonrpc :: Version
+    , reqMethod  :: Method
+    , reqParams  :: a
+    , reqId      :: Int
+    } deriving (Show, Eq)
+
+deriveJSON defaultOptions
+  { omitNothingFields  = True
+  , fieldLabelModifier = snakeCase . drop 3
+  } ''Request
+
+mkDefaultRequest :: ToJSON a => Method -> a -> Request a
+mkDefaultRequest method req = Request version method req 0
+
+data Error =
+  Error
+    { code    :: Int
+    , message :: Text
+    , errData :: Maybe Text
+    } deriving (Eq, Show)
+
+deriveJSON defaultOptions ''Error
+
+
+-- | TODO: handle jsonrpc errors
+data Response a =
+  Response
+    { resJsonrpc :: Version
+    , resResult  :: Either Error a
+    , resId      :: Int
+    } deriving (Show, Eq)
+
+
+instance FromJSON a => FromJSON (Response a) where
+  parseJSON = withObject "response" $ \o -> do
+    v      <- o .: "jsonrpc"
+    jid    <- o .: "id"
+    result <- o .:? "result"
+    e      <- o .:? "error"
+    let r = maybe (maybe (fail "invalid response") Left e) Right result
+    return $ Response v r jid
+
+
+unwrapJson :: (Show a, FromJSON a) => Response a -> Either Error a
+unwrapJson (Response _ r _) = r
+
+
+newtype JsonRpcT m a =
+  JsonRpcT
+    { unJsonRpcT :: StateT Int (ReaderT Socket m) a
+    } deriving ( Functor, Applicative, Monad, MonadIO )
+
+runJsonRpcT :: MonadIO m => Socket -> JsonRpcT m a -> m a
+runJsonRpcT s jm = flip runReaderT s . flip evalStateT 0 $ unJsonRpcT jm
+
+request :: (MonadIO m, Show b, ToJSON a, FromJSON b) => Method -> a -> JsonRpcT m (Either Error b)
+request method params = do
+    s   <- JsonRpcT $ lift ask
+    req <- toStrict . encode . Request version method params <$> JsonRpcT get
+    liftIO $ sendAll s req
+    JsonRpcT $ modify' (+1)
+    response <- fromStrict <$> liftIO (recv s 262144)
+    either fail (return . unwrapJson) $ eitherDecode' response
diff --git a/src/Factom/RPC/Types.hs b/src/Factom/RPC/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Factom/RPC/Types.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE DeriveAnyClass        #-}
+{-# LANGUAGE DeriveGeneric         #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE GADTs                 #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE TypeSynonymInstances  #-}
+
+module Factom.RPC.Types where
+
+import           Data.Aeson
+import           Data.Aeson.TH
+import           Data.Maybe
+import qualified Data.Text        as T
+import           Data.Time
+import           GHC.Generics
+
+import           Factom.RPC.Utils
+
+--------------------------------------------------------------------------------
+
+   -- { "jsonrpc": "2.0"
+   -- , "id": 0
+   -- , "method":"entry"
+   -- , "params": {
+   --     "hash":"24674e6bc3094eb773297de955ee095a05830e431da13a37382dcdc89d73c7d7"
+   --    }
+   -- }
+data ApiRequest =
+  ApiRequest
+    { jsonRpc :: T.Text
+    , id      :: Int
+    , method  :: T.Text
+    , params  :: Maybe Object
+    } deriving (Eq, Show, Generic, ToJSON)
+
+data ApiResponse a =
+  ApiResponse
+   { jsonRpc :: T.Text
+   , id      :: Int
+   , result  :: a
+   } deriving (Eq, Show, Generic, FromJSON)
+
+-- "chainid":"df3ade9eec4b08d5379cc64270c30ea7315d8a8a1a69efe2b98a60ecdd69e604",
+-- "content":"...",
+-- "extids":[ "466163746f6d416e63686f72436861696e"]
+data Entry =
+  Entry
+    { enChainId :: T.Text
+    , enContent :: T.Text
+    , enExtIds  :: [T.Text]
+    } deriving (Eq, Show, Generic, FromJSON)
+
+data EntryBlock =
+  EntryBlock
+   { blockSequenceNumber :: Int
+   } deriving (Eq, Show, Generic, FromJSON)
+
+data EntryCreditBalance =
+  EntryCreditBalance
+    { ecBalance :: Int
+    } deriving (Eq, Show, Generic, FromJSON)
diff --git a/src/Factom/RPC/Utils.hs b/src/Factom/RPC/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Factom/RPC/Utils.hs
@@ -0,0 +1,1 @@
+module Factom.RPC.Utils where
diff --git a/src/Factom/RPC/Wallet/Api.hs b/src/Factom/RPC/Wallet/Api.hs
new file mode 100644
--- /dev/null
+++ b/src/Factom/RPC/Wallet/Api.hs
@@ -0,0 +1,1 @@
+module Factom.RPC.Wallet.Api where
diff --git a/tests/Spec.hs b/tests/Spec.hs
new file mode 100644
--- /dev/null
+++ b/tests/Spec.hs
