diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@
 [![Build Status](https://travis-ci.org/airalab/hs-web3.svg?branch=master)](https://travis-ci.org/airalab/hs-web3)
 [![Build status](https://ci.appveyor.com/api/projects/status/8ljq93nar8kobk75?svg=true)](https://ci.appveyor.com/project/akru/hs-web3)
 [![Hackage](https://img.shields.io/hackage/v/web3.svg)](http://hackage.haskell.org/package/web3)
-![Hackage Dependencies](https://img.shields.io/hackage-deps/v/web3.svg)
 ![Haskell Programming Language](https://img.shields.io/badge/language-Haskell-blue.svg)
 ![BSD3 License](http://img.shields.io/badge/license-BSD3-brightgreen.svg)
+[![Code Triagers Badge](https://www.codetriage.com/airalab/hs-web3/badges/users.svg)](https://www.codetriage.com/airalab/hs-web3)
 
 ### Installation
 
diff --git a/src/Network/Ethereum/Unit.hs b/src/Network/Ethereum/Unit.hs
--- a/src/Network/Ethereum/Unit.hs
+++ b/src/Network/Ethereum/Unit.hs
@@ -1,5 +1,6 @@
-{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE DeriveGeneric        #-}
 {-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE TypeSynonymInstances #-}
 -- |
 -- Module      :  Network.Ethereum.Unit
 -- Copyright   :  Alexander Krupenkin 2016
@@ -54,12 +55,13 @@
   , KEther
   ) where
 
-import Text.ParserCombinators.ReadPrec
-import Data.Text.Lazy (Text, unpack)
-import qualified Text.Read.Lex as L
-import Data.Monoid ((<>))
-import Text.Printf
-import GHC.Read
+import           Data.Monoid                     ((<>))
+import           Data.Text.Lazy                  (Text, unpack)
+import           GHC.Generics                    (Generic)
+import           GHC.Read
+import           Text.ParserCombinators.ReadPrec
+import           Text.Printf
+import qualified Text.Read.Lex                   as L
 
 -- | Ethereum value unit
 class (Read a, Show a, UnitSpec a, Fractional a) => Unit a where
@@ -79,7 +81,7 @@
 
 -- | Value abstraction
 data Value a = MkValue { unValue :: Integer }
-  deriving (Eq, Ord)
+  deriving (Eq, Ord, Generic)
 
 mkValue :: (UnitSpec a, RealFrac b) => b -> Value a
 mkValue = modify res . round . (divider res *)
diff --git a/src/Network/Ethereum/Web3.hs b/src/Network/Ethereum/Web3.hs
--- a/src/Network/Ethereum/Web3.hs
+++ b/src/Network/Ethereum/Web3.hs
@@ -39,11 +39,11 @@
   , module Network.Ethereum.Unit
   ) where
 
-import Network.Ethereum.Web3.Encoding.Bytes
-import Network.Ethereum.Web3.Encoding.Tuple
-import Network.Ethereum.Web3.Contract
-import Network.Ethereum.Web3.Encoding
-import Network.Ethereum.Web3.Provider
-import Network.Ethereum.Web3.Address
-import Network.Ethereum.Web3.Types
-import Network.Ethereum.Unit
+import           Network.Ethereum.Unit
+import           Network.Ethereum.Web3.Address
+import           Network.Ethereum.Web3.Contract
+import           Network.Ethereum.Web3.Encoding
+import           Network.Ethereum.Web3.Encoding.Bytes
+import           Network.Ethereum.Web3.Encoding.Tuple
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
diff --git a/src/Network/Ethereum/Web3/Address.hs b/src/Network/Ethereum/Web3/Address.hs
--- a/src/Network/Ethereum/Web3/Address.hs
+++ b/src/Network/Ethereum/Web3/Address.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveGeneric #-}
 -- |
 -- Module      :  Network.Ethereum.Web3.Address
 -- Copyright   :  Alexander Krupenkin 2016
@@ -16,20 +17,24 @@
   , zero
   ) where
 
-import Data.Aeson (FromJSON(..), ToJSON(..), Value(..))
-import Data.Text.Lazy.Builder.Int as B (hexadecimal)
-import Data.Text.Lazy.Builder (toLazyText)
-import Data.Text.Read as R (hexadecimal)
-import Data.Text (Text, unpack, pack)
-import Data.String (IsString(..))
-import Data.Text.Lazy (toStrict)
-import qualified Data.Text as T
-import Control.Monad ((<=<))
-import Data.Monoid ((<>))
+import           Control.Monad              ((<=<))
+import           Data.Aeson                 (FromJSON (..), ToJSON (..),
+                                             Value (..))
+import qualified Data.Char                  as C
+import           Data.Monoid                ((<>))
+import           Data.String                (IsString (..))
+import           Data.Text                  (Text, pack, unpack)
+import qualified Data.Text                  as T
+import           Data.Text.Lazy             (toStrict)
+import           Data.Text.Lazy.Builder     (toLazyText)
+import           Data.Text.Lazy.Builder.Int as B (hexadecimal)
+import           Data.Text.Read             as R (hexadecimal)
 
+import           GHC.Generics               (Generic)
+
 -- | Ethereum account address
 newtype Address = Address { unAddress :: Integer }
-  deriving (Eq, Ord)
+  deriving (Eq, Ord, Generic)
 
 instance Show Address where
     show = unpack . toText
@@ -37,11 +42,11 @@
 instance IsString Address where
     fromString a = case fromText (pack a) of
         Right address -> address
-        Left e -> error e
+        Left e        -> error e
 
 instance FromJSON Address where
     parseJSON (String a) = either fail return (fromText a)
-    parseJSON _ = fail "Address should be a string"
+    parseJSON _          = fail "Address should be a string"
 
 instance ToJSON Address where
     toJSON = toJSON . ("0x" <>) . toText
@@ -50,10 +55,11 @@
 fromText :: Text -> Either String Address
 fromText = fmap (Address . fst) . R.hexadecimal <=< check
   where check t | T.take 2 t == "0x" = check (T.drop 2 t)
-                | otherwise = if T.length t == 40 && T.all (`elem` valid) t
-                              then Right t
-                              else Left "This is not seems like address."
-        valid = ['0'..'9'] ++ ['a'..'f'] ++ ['A'..'F']
+                | otherwise = do if T.length t == 40 then pure () else lengthError
+                                 if T.all C.isHexDigit t then pure () else invalidCharError
+                                 pure t
+        lengthError = Left "Invalid Address: text length not equal to 20"
+        invalidCharError = Left "Invalid Address: contains non-hex character"
 
 -- | Render 'Address' to text string
 toText :: Address -> Text
diff --git a/src/Network/Ethereum/Web3/Api.hs b/src/Network/Ethereum/Web3/Api.hs
deleted file mode 100644
--- a/src/Network/Ethereum/Web3/Api.hs
+++ /dev/null
@@ -1,84 +0,0 @@
--- |
--- Module      :  Network.Ethereum.Web3.Api
--- Copyright   :  Alexander Krupenkin 2016
--- License     :  BSD3
---
--- Maintainer  :  mail@akru.me
--- Stability   :  experimental
--- Portability :  unknown
---
--- Ethereum node JSON-RPC API methods.
---
-module Network.Ethereum.Web3.Api where
-
-import Network.Ethereum.Web3.Provider
-import Network.Ethereum.Web3.Address
-import Network.Ethereum.Web3.JsonRpc
-import Network.Ethereum.Web3.Types
-import Data.Text (Text)
-
--- | Returns current node version string.
-web3_clientVersion :: Provider a => Web3 a Text
-{-# INLINE web3_clientVersion #-}
-web3_clientVersion = remote "web3_clientVersion"
-
--- | Returns Keccak-256 (not the standardized SHA3-256) of the given data.
-web3_sha3 :: Provider a => Text -> Web3 a Text
-{-# INLINE web3_sha3 #-}
-web3_sha3 = remote "web3_sha3"
-
--- | Returns the balance of the account of given address.
-eth_getBalance :: Provider a => Address -> CallMode -> Web3 a Text
-{-# INLINE eth_getBalance #-}
-eth_getBalance = remote "eth_getBalance"
-
--- | Creates a filter object, based on filter options, to notify when the
--- state changes (logs). To check if the state has changed, call
--- 'getFilterChanges'.
-eth_newFilter :: Provider a => Filter -> Web3 a FilterId
-{-# INLINE eth_newFilter #-}
-eth_newFilter = remote "eth_newFilter"
-
--- | Polling method for a filter, which returns an array of logs which
--- occurred since last poll.
-eth_getFilterChanges :: Provider a => FilterId -> Web3 a [Change]
-{-# INLINE eth_getFilterChanges #-}
-eth_getFilterChanges = remote "eth_getFilterChanges"
-
--- | Uninstalls a filter with given id.
--- Should always be called when watch is no longer needed.
-eth_uninstallFilter :: Provider a => FilterId -> Web3 a Bool
-{-# INLINE eth_uninstallFilter #-}
-eth_uninstallFilter = remote "eth_uninstallFilter"
-
--- | Executes a new message call immediately without creating a
--- transaction on the block chain.
-eth_call :: Provider a => Call -> CallMode -> Web3 a Text
-{-# INLINE eth_call #-}
-eth_call = remote "eth_call"
-
--- | Creates new message call transaction or a contract creation,
--- if the data field contains code.
-eth_sendTransaction :: Provider a => Call -> Web3 a Text
-{-# INLINE eth_sendTransaction #-}
-eth_sendTransaction = remote "eth_sendTransaction"
-
--- | Returns a list of addresses owned by client.
-eth_accounts :: Provider a => Web3 a [Address]
-{-# INLINE eth_accounts #-}
-eth_accounts = remote "eth_accounts"
-
-eth_newBlockFilter :: Provider a => Web3 a Text
-{-# INLINE eth_newBlockFilter #-}
-eth_newBlockFilter = remote "eth_newBlockFilter"
-
--- | Polling method for a block filter, which returns an array of block hashes
--- occurred since last poll.
-eth_getBlockFilterChanges :: Provider a => Text -> Web3 a [Text]
-{-# INLINE eth_getBlockFilterChanges #-}
-eth_getBlockFilterChanges = remote "eth_getFilterChanges"
-
--- | Returns information about a block by hash.
-eth_getBlockByHash :: Provider a => Text -> Web3 a Block
-{-# INLINE eth_getBlockByHash #-}
-eth_getBlockByHash = flip (remote "eth_getBlockByHash") True
diff --git a/src/Network/Ethereum/Web3/Contract.hs b/src/Network/Ethereum/Web3/Contract.hs
--- a/src/Network/Ethereum/Web3/Contract.hs
+++ b/src/Network/Ethereum/Web3/Contract.hs
@@ -35,24 +35,24 @@
   , nopay
   ) where
 
-import qualified Data.Text.Lazy.Builder.Int as B
-import qualified Data.Text.Lazy.Builder     as B
-import Control.Concurrent (ThreadId, threadDelay)
-import Data.Maybe (mapMaybe, listToMaybe)
-import Control.Monad.IO.Class (liftIO)
-import Control.Exception (throwIO)
-import Data.Text.Lazy (toStrict)
-import qualified Data.Text as T
-import Control.Monad (when, forM)
-import Control.Monad.Trans.Reader (ReaderT(..))
-import Data.Monoid ((<>))
+import           Control.Concurrent             (ThreadId, threadDelay)
+import           Control.Exception              (throwIO)
+import           Control.Monad                  (forM, when)
+import           Control.Monad.IO.Class         (liftIO)
+import           Control.Monad.Trans.Reader     (ReaderT (..))
+import           Data.Maybe                     (listToMaybe, mapMaybe)
+import           Data.Monoid                    ((<>))
+import qualified Data.Text                      as T
+import           Data.Text.Lazy                 (toStrict)
+import qualified Data.Text.Lazy.Builder         as B
+import qualified Data.Text.Lazy.Builder.Int     as B
 
-import Network.Ethereum.Web3.Provider
-import Network.Ethereum.Web3.Encoding
-import Network.Ethereum.Web3.Address
-import Network.Ethereum.Web3.Types
-import Network.Ethereum.Web3.Api
-import Network.Ethereum.Unit
+import           Network.Ethereum.Unit
+import           Network.Ethereum.Web3.Address
+import           Network.Ethereum.Web3.Encoding
+import qualified Network.Ethereum.Web3.Eth      as Eth
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
 
 -- | Event callback control response
 data EventAction = ContinueEvent
@@ -83,16 +83,16 @@
 _event a f = do
     fid <- let ftyp = snd $ let x = undefined :: Event a => a
                             in  (f x, x)
-           in  eth_newFilter (eventFilter ftyp a)
+           in  Eth.newFilter (eventFilter ftyp a)
 
     forkWeb3 $
         let loop = do liftIO (threadDelay 1000000)
-                      changes <- eth_getFilterChanges fid
+                      changes <- Eth.getFilterChanges fid
                       acts <- forM (mapMaybe pairChange changes) $ \(changeEvent, changeWithMeta) ->
                         runReaderT (f changeEvent) changeWithMeta
                       when (TerminateEvent `notElem` acts) loop
         in do loop
-              eth_uninstallFilter fid
+              Eth.uninstallFilter fid
               return ()
   where
     prepareTopics = fmap (T.drop 2) . drop 1
@@ -120,7 +120,7 @@
     call :: (Provider p, ABIEncoding b)
          => Address
          -- ^ Contract address
-         -> CallMode
+         -> DefaultBlock
          -- ^ State mode for constant call (latest or pending)
          -> a
          -- ^ Method data
@@ -131,17 +131,17 @@
 _sendTransaction :: (Provider p, Method a, Unit b)
                  => Address -> b -> a -> Web3 p TxHash
 _sendTransaction to value dat = do
-    primeAddress <- listToMaybe <$> eth_accounts
-    eth_sendTransaction (txdata primeAddress $ Just $ toData dat)
+    primeAddress <- listToMaybe <$> Eth.accounts
+    Eth.sendTransaction (txdata primeAddress $ Just $ toData dat)
   where txdata from = Call from to (Just defaultGas) Nothing (Just $ toWeiText value)
         toWeiText   = ("0x" <>) . toStrict . B.toLazyText . B.hexadecimal . toWei
         defaultGas  = "0x2DC2DC"
 
 _call :: (Provider p, Method a, ABIEncoding b)
-      => Address -> CallMode -> a -> Web3 p b
+      => Address -> DefaultBlock -> a -> Web3 p b
 _call to mode dat = do
-    primeAddress <- listToMaybe <$> eth_accounts
-    res <- eth_call (txdata primeAddress) mode
+    primeAddress <- listToMaybe <$> Eth.accounts
+    res <- Eth.call (txdata primeAddress) mode
     case fromData (T.drop 2 res) of
         Nothing -> liftIO $ throwIO $ ParserFail $
             "Unable to parse result on `" ++ T.unpack res
diff --git a/src/Network/Ethereum/Web3/Encoding.hs b/src/Network/Ethereum/Web3/Encoding.hs
--- a/src/Network/Ethereum/Web3/Encoding.hs
+++ b/src/Network/Ethereum/Web3/Encoding.hs
@@ -11,16 +11,18 @@
 --
 module Network.Ethereum.Web3.Encoding (ABIEncoding(..)) where
 
-import Data.Text.Lazy.Builder (Builder, toLazyText, fromText, fromLazyText)
-import Data.Attoparsec.Text.Lazy (parse, maybeResult, Parser)
-import qualified Network.Ethereum.Web3.Address as A
-import qualified Data.Attoparsec.Text          as P
-import qualified Data.Text.Lazy                as LT
-import qualified Data.Text                     as T
-import Network.Ethereum.Web3.Encoding.Internal
-import Network.Ethereum.Web3.Address (Address)
-import Data.Monoid ((<>))
-import Data.Text (Text)
+import qualified Data.Attoparsec.Text                    as P
+import           Data.Attoparsec.Text.Lazy               (Parser, maybeResult,
+                                                          parse)
+import           Data.Monoid                             ((<>))
+import           Data.Text                               (Text)
+import qualified Data.Text                               as T
+import qualified Data.Text.Lazy                          as LT
+import           Data.Text.Lazy.Builder                  (Builder, fromLazyText,
+                                                          fromText, toLazyText)
+import           Network.Ethereum.Web3.Address           (Address)
+import qualified Network.Ethereum.Web3.Address           as A
+import           Network.Ethereum.Web3.Encoding.Internal
 
 -- | Contract ABI data codec
 class ABIEncoding a where
diff --git a/src/Network/Ethereum/Web3/Encoding/Bytes.hs b/src/Network/Ethereum/Web3/Encoding/Bytes.hs
--- a/src/Network/Ethereum/Web3/Encoding/Bytes.hs
+++ b/src/Network/Ethereum/Web3/Encoding/Bytes.hs
@@ -1,5 +1,7 @@
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE DataKinds      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE PolyKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 -- |
 -- Module      :  Network.Ethereum.Web3.Encoding.Bytes
 -- Copyright   :  Alexander Krupenkin 2016
@@ -16,19 +18,21 @@
   , BytesD(..)
   ) where
 
-import qualified Data.ByteString.Base16 as BS16 (decode, encode)
-import qualified Data.Attoparsec.Text   as P
-import qualified Data.Text.Lazy.Builder as B
-import qualified Data.Text.Encoding     as T
-import qualified Data.Text              as T
-import qualified Data.ByteArray         as BA
-import Network.Ethereum.Web3.Encoding.Internal
-import Network.Ethereum.Web3.Encoding
-import GHC.TypeLits (KnownNat, Nat, natVal)
-import Data.Monoid (Monoid(..), (<>))
-import Data.ByteArray (Bytes)
+import qualified Data.Attoparsec.Text                    as P
+import           Data.ByteArray                          (Bytes)
+import qualified Data.ByteArray                          as BA
+import qualified Data.ByteString.Base16                  as BS16 (decode,
+                                                                  encode)
+import           Data.Monoid                             (Monoid (..), (<>))
+import           Data.Proxy
+import qualified Data.Text                               as T
+import qualified Data.Text.Encoding                      as T
+import qualified Data.Text.Lazy.Builder                  as B
+import           GHC.TypeLits                            (KnownNat, Nat, natVal)
+import           Network.Ethereum.Web3.Encoding
+import           Network.Ethereum.Web3.Encoding.Internal
 
-import Debug.Trace
+import           Debug.Trace
 
 -- | Fixed length byte array
 newtype BytesN (n :: Nat) = BytesN { unBytesN :: Bytes }
@@ -39,7 +43,7 @@
 update _ = BytesN
 
 instance KnownNat n => EncodingType (BytesN n) where
-    typeName  = const "bytes[N]"
+    typeName  = const $ "bytes" <> (show . natVal $ (Proxy :: Proxy n))
     isDynamic = const False
 
 instance KnownNat n => ABIEncoding (BytesN n) where
diff --git a/src/Network/Ethereum/Web3/Encoding/Internal.hs b/src/Network/Ethereum/Web3/Encoding/Internal.hs
--- a/src/Network/Ethereum/Web3/Encoding/Internal.hs
+++ b/src/Network/Ethereum/Web3/Encoding/Internal.hs
@@ -11,20 +11,21 @@
 --
 module Network.Ethereum.Web3.Encoding.Internal where
 
-import Data.Text.Lazy.Builder (Builder, toLazyText, fromText, fromLazyText)
-import qualified Data.ByteString.Base16        as BS16 (decode, encode)
 import qualified Data.Attoparsec.Text          as P
-import qualified Data.Text.Lazy                as LT
+import           Data.Attoparsec.Text.Lazy     (Parser)
+import           Data.Bits                     (Bits)
+import qualified Data.ByteString.Base16        as BS16 (decode, encode)
+import           Data.Monoid                   ((<>))
+import           Data.Text                     (Text)
 import qualified Data.Text                     as T
+import           Data.Text.Encoding            (decodeUtf8, encodeUtf8)
+import qualified Data.Text.Lazy                as LT
+import           Data.Text.Lazy.Builder        (Builder, fromLazyText, fromText,
+                                                toLazyText)
+import           Data.Text.Lazy.Builder.Int    as B
 import qualified Data.Text.Read                as R
-import Data.Text.Encoding (encodeUtf8, decodeUtf8)
-import Network.Ethereum.Web3.Address (Address)
-import Data.Attoparsec.Text.Lazy (Parser)
-import Data.Text.Lazy.Builder.Int as B
-import Language.Haskell.TH
-import Data.Monoid ((<>))
-import Data.Text (Text)
-import Data.Bits (Bits)
+import           Language.Haskell.TH
+import           Network.Ethereum.Web3.Address (Address)
 
 class EncodingType a where
     typeName :: a -> String
diff --git a/src/Network/Ethereum/Web3/Encoding/Tuple.hs b/src/Network/Ethereum/Web3/Encoding/Tuple.hs
--- a/src/Network/Ethereum/Web3/Encoding/Tuple.hs
+++ b/src/Network/Ethereum/Web3/Encoding/Tuple.hs
@@ -12,9 +12,9 @@
 --
 module Network.Ethereum.Web3.Encoding.Tuple (Singleton(..)) where
 
-import Network.Ethereum.Web3.Encoding.Internal
-import Network.Ethereum.Web3.Encoding.TupleTH
-import Network.Ethereum.Web3.Encoding
+import           Network.Ethereum.Web3.Encoding
+import           Network.Ethereum.Web3.Encoding.Internal
+import           Network.Ethereum.Web3.Encoding.TupleTH
 
 -- | Singleton parameter instance
 newtype Singleton a = Singleton { unSingleton :: a }
diff --git a/src/Network/Ethereum/Web3/Encoding/TupleTH.hs b/src/Network/Ethereum/Web3/Encoding/TupleTH.hs
--- a/src/Network/Ethereum/Web3/Encoding/TupleTH.hs
+++ b/src/Network/Ethereum/Web3/Encoding/TupleTH.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE TemplateHaskell #-}
 -- |
 -- Module      :  Network.Ethereum.Web3.Encoding.TupleTH
 -- Copyright   :  Alexander Krupenkin 2016
@@ -18,14 +18,14 @@
   , dParser
   ) where
 
-import Data.Text.Lazy.Builder (toLazyText, Builder)
-import Network.Ethereum.Web3.Encoding.Internal
-import qualified Data.Attoparsec.Text as P
-import qualified Data.Text.Lazy       as LT
-import Network.Ethereum.Web3.Encoding
-import Data.Attoparsec.Text (Parser)
-import Control.Monad (replicateM)
-import Language.Haskell.TH
+import           Control.Monad                           (replicateM)
+import           Data.Attoparsec.Text                    (Parser)
+import qualified Data.Attoparsec.Text                    as P
+import qualified Data.Text.Lazy                          as LT
+import           Data.Text.Lazy.Builder                  (Builder, toLazyText)
+import           Language.Haskell.TH
+import           Network.Ethereum.Web3.Encoding
+import           Network.Ethereum.Web3.Encoding.Internal
 
 -- | Argument offset calculator
 offset :: Int
@@ -105,11 +105,11 @@
 
 mkAppSeq :: [ExpQ] -> ExpQ
 mkAppSeq = infixApps . dollarFirst . sparse
-  where sparse [x] = [x]
+  where sparse [x]      = [x]
         sparse (x : xs) = x : [|(<*>)|] : sparse xs
         dollarFirst (x : _ : xs) = x : [|(<$>)|] : xs
         infixApps (x : xs) = go x xs
-        go acc [] = acc
+        go acc []           = acc
         go acc (f : x : xs) = go (infixApp acc f x) xs
 
 eTupleE :: Int -> ExpQ
@@ -127,7 +127,7 @@
 eTupleE 13 = [|(,,,,,,,,,,,,)|]
 eTupleE 14 = [|(,,,,,,,,,,,,,)|]
 eTupleE 15 = [|(,,,,,,,,,,,,,,)|]
-eTupleE _ = error "Unsupported tuple size"
+eTupleE _  = error "Unsupported tuple size"
 
 mkEncodingInst :: Int -> DecQ
 mkEncodingInst n = do
diff --git a/src/Network/Ethereum/Web3/Eth.hs b/src/Network/Ethereum/Web3/Eth.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Ethereum/Web3/Eth.hs
@@ -0,0 +1,240 @@
+-- |
+-- Module      :  Network.Ethereum.Web3.Eth
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unknown
+--
+-- Ethereum node JSON-RPC API methods with `eth_` prefix.
+--
+module Network.Ethereum.Web3.Eth where
+
+import           Data.Text                      (Text)
+import           Network.Ethereum.Web3.Address
+import           Network.Ethereum.Web3.JsonRpc
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
+
+-- | Returns the current ethereum protocol version.
+protocolVersion :: Provider a => Web3 a Text
+{-# INLINE protocolVersion #-}
+protocolVersion = remote "eth_protocolVersion"
+
+-- TODO The return type of this function requires a new type to be created
+-- | Returns an object with data about the sync status or false.
+-- syncing :: Proviver a => Web3 a Text
+
+-- | Returns the client coinbase address.
+coinbase :: Provider a => Web3 a Address
+{-# INLINE coinbase #-}
+coinbase = remote "eth_coinbase"
+
+-- | Returns true if client is actively mining new blocks.
+mining :: Provider a => Web3 a Bool
+{-# INLINE mining #-}
+mining = remote "eth_mining"
+
+-- | Returns the number of hashes per second that the node is mining with.
+hashrate :: Provider a => Web3 a Text
+{-# INLINE hashrate #-}
+hashrate = remote "eth_hashrate"
+
+-- | Returns the value from a storage position at a given address.
+getStorageAt :: Provider a => Address -> Text -> DefaultBlock -> Web3 a Text
+{-# INLINE getStorageAt #-}
+getStorageAt = remote "eth_getStorageAt"
+
+-- | Returns the number of transactions sent from an address.
+getTransactionCount :: Provider a => Address -> DefaultBlock -> Web3 a Text
+{-# INLINE getTransactionCount #-}
+getTransactionCount = remote "eth_getTransactionCount"
+
+-- | Returns the number of transactions in a block from a block matching the given block hash.
+getBlockTransactionCountByHash :: Provider a => Text -> Web3 a Text
+{-# INLINE getBlockTransactionCountByHash #-}
+getBlockTransactionCountByHash = remote "eth_getBlockTransactionCountByHash"
+
+-- | Returns the number of transactions in a block matching the
+-- given block number.
+getBlockTransactionCountByNumber :: Provider a => Text -> Web3 a Text
+{-# INLINE getBlockTransactionCountByNumber #-}
+getBlockTransactionCountByNumber = remote "eth_getBlockTransactionCountByNumber"
+
+-- | Returns the number of uncles in a block from a block matching the given
+-- block hash.
+getUncleCountByBlockHash :: Provider a => Text -> Web3 a Text
+{-# INLINE getUncleCountByBlockHash #-}
+getUncleCountByBlockHash = remote "eth_getUncleCountByBlockHash"
+
+-- | Returns the number of uncles in a block from a block matching the given
+-- block number.
+getUncleCountByBlockNumber :: Provider a => Text -> Web3 a Text
+{-# INLINE getUncleCountByBlockNumber #-}
+getUncleCountByBlockNumber = remote "eth_getUncleCountByBlockNumber"
+
+-- | Returns code at a given address.
+getCode :: Provider a => Address -> DefaultBlock -> Web3 a Text
+{-# INLINE getCode #-}
+getCode = remote "eth_getCode"
+
+-- | Returns an Ethereum specific signature with:
+-- sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))).
+sign :: Provider a => Address -> Text -> Web3 a Text
+{-# INLINE sign #-}
+sign = remote "eth_sign"
+
+-- | Creates new message call transaction or a contract creation,
+-- if the data field contains code.
+sendTransaction :: Provider a => Call -> Web3 a Text
+{-# INLINE sendTransaction #-}
+sendTransaction = remote "eth_sendTransaction"
+
+-- | Creates new message call transaction or a contract creation for signed
+-- transactions.
+sendRawTransaction :: Provider a => Text -> Web3 a Text
+{-# INLINE sendRawTransaction #-}
+sendRawTransaction = remote "eth_sendRawTransaction"
+
+-- | Returns the balance of the account of given address.
+getBalance :: Provider a => Address -> DefaultBlock -> Web3 a Text
+{-# INLINE getBalance #-}
+getBalance = remote "eth_getBalance"
+
+-- | Creates a filter object, based on filter options, to notify when the
+-- state changes (logs). To check if the state has changed, call
+-- 'getFilterChanges'.
+newFilter :: Provider a => Filter -> Web3 a FilterId
+{-# INLINE newFilter #-}
+newFilter = remote "eth_newFilter"
+
+-- | Polling method for a filter, which returns an array of logs which
+-- occurred since last poll.
+getFilterChanges :: Provider a => FilterId -> Web3 a [Change]
+{-# INLINE getFilterChanges #-}
+getFilterChanges = remote "eth_getFilterChanges"
+
+-- | Uninstalls a filter with given id.
+-- Should always be called when watch is no longer needed.
+uninstallFilter :: Provider a => FilterId -> Web3 a Bool
+{-# INLINE uninstallFilter #-}
+uninstallFilter = remote "eth_uninstallFilter"
+
+-- | Returns an array of all logs matching a given filter object.
+getLogs :: Provider a => Filter -> Web3 a [Change]
+{-# INLINE getLogs #-}
+getLogs = remote "eth_getLogs"
+
+-- | Executes a new message call immediately without creating a
+-- transaction on the block chain.
+call :: Provider a => Call -> DefaultBlock -> Web3 a Text
+{-# INLINE call #-}
+call = remote "eth_call"
+
+-- | Makes a call or transaction, which won't be added to the blockchain and
+-- returns the used gas, which can be used for estimating the used gas.
+estimateGas :: Provider a => Call -> Web3 a Text
+{-# INLINE estimateGas #-}
+estimateGas = remote "eth_estimateGas"
+
+-- | Returns information about a block by hash.
+getBlockByHash :: Provider a => Text -> Web3 a Block
+{-# INLINE getBlockByHash #-}
+getBlockByHash = flip (remote "eth_getBlockByHash") True
+
+-- | Returns information about a block by block number.
+getBlockByNumber :: Provider a => Text -> Web3 a Block
+{-# INLINE getBlockByNumber #-}
+getBlockByNumber = flip (remote "eth_getBlockByNumber") True
+
+-- | Returns the information about a transaction requested by transaction hash.
+getTransactionByHash :: Provider a => Text -> Web3 a (Maybe Transaction)
+{-# INLINE getTransactionByHash #-}
+getTransactionByHash = remote "eth_getTransactionByHash"
+
+-- | Returns information about a transaction by block hash and transaction index position.
+getTransactionByBlockHashAndIndex :: Provider a => Text -> Text -> Web3 a (Maybe Transaction)
+{-# INLINE getTransactionByBlockHashAndIndex #-}
+getTransactionByBlockHashAndIndex = remote "eth_getTransactionByBlockHashAndIndex"
+
+-- | Returns information about a transaction by block number and transaction
+-- index position.
+getTransactionByBlockNumberAndIndex :: Provider a => DefaultBlock -> Text -> Web3 a (Maybe Transaction)
+{-# INLINE getTransactionByBlockNumberAndIndex #-}
+getTransactionByBlockNumberAndIndex = remote "eth_getTransactionByBlockNumberAndIndex"
+
+-- | Returns the receipt of a transaction by transaction hash.
+-- TODO must create new type, TxReceipt
+-- getTransactionReceipt :: Provider a => Text -> Web3 a TxReceipt
+-- getTransactionReceipt = remote "getTransactionReceipt"
+
+-- | Returns a list of addresses owned by client.
+accounts :: Provider a => Web3 a [Address]
+{-# INLINE accounts #-}
+accounts = remote "eth_accounts"
+
+newBlockFilter :: Provider a => Web3 a Text
+{-# INLINE newBlockFilter #-}
+newBlockFilter = remote "eth_newBlockFilter"
+
+-- | Polling method for a block filter, which returns an array of block hashes
+-- occurred since last poll.
+getBlockFilterChanges :: Provider a => Text -> Web3 a [Text]
+{-# INLINE getBlockFilterChanges #-}
+getBlockFilterChanges = remote "eth_getBlockFilterChanges"
+
+-- | Returns the number of most recent block.
+blockNumber :: Provider a => Web3 a Text
+{-# INLINE blockNumber #-}
+blockNumber = remote "eth_blockNumber"
+
+-- | Returns the current price per gas in wei.
+gasPrice :: Provider a => Web3 a Text
+{-# INLINE gasPrice #-}
+gasPrice = remote "eth_gasPrice"
+
+-- | Returns information about a uncle of a block by hash and uncle index
+-- position.
+getUncleByBlockHashAndIndex :: Provider a => Text -> Text -> Web3 a Block
+{-# INLINE getUncleByBlockHashAndIndex #-}
+getUncleByBlockHashAndIndex = remote "eth_getUncleByBlockHashAndIndex"
+
+-- | Returns information about a uncle of a block by number and uncle index
+-- position.
+getUncleByBlockNumberAndIndex :: Provider a => DefaultBlock -> Text -> Web3 a Block
+{-# INLINE getUncleByBlockNumberAndIndex #-}
+getUncleByBlockNumberAndIndex = remote "eth_getUncleByBlockNumberAndIndex"
+
+-- | Creates a filter in the node, to notify when new pending transactions arrive. To check if the state has changed, call getFilterChanges. Returns a FilterId.
+newPendingTransactionFilter :: Provider a => Web3 a Text
+{-# INLINE newPendingTransactionFilter #-}
+newPendingTransactionFilter = remote "eth_newPendingTransactionFilter"
+
+-- | Returns an array of all logs matching filter with given id.
+getFilterLogs :: Provider a => Text -> Web3 a [Change]
+{-# INLINE getFilterLogs #-}
+getFilterLogs = remote "eth_getFilterLogs"
+
+-- | Returns the hash of the current block, the seedHash, and the boundary
+-- condition to be met ("target").
+getWork :: Provider a => Web3 a [Text]
+{-# INLINE getWork #-}
+getWork = remote "eth_getWork"
+
+-- | Used for submitting a proof-of-work solution.
+-- Parameters:
+-- 1. DATA, 8 Bytes - The nonce found (64 bits)
+-- 2. DATA, 32 Bytes - The header's pow-hash (256 bits)
+-- 3. DATA, 32 Bytes - The mix digest (256 bits)
+submitWork :: Provider a => Text -> Text -> Text -> Web3 a Bool
+{-# INLINE submitWork #-}
+submitWork = remote "eth_submitWork"
+
+-- | Used for submitting mining hashrate.
+-- Parameters:
+-- 1. Hashrate, a hexadecimal string representation (32 bytes) of the hash rate
+-- 2. ID, String - A random hexadecimal(32 bytes) ID identifying the client
+submitHashrate :: Provider a => Text -> Text -> Web3 a Bool
+{-# INLINE submitHashrate #-}
+submitHashrate = remote "eth_submitHashrate"
diff --git a/src/Network/Ethereum/Web3/Internal.hs b/src/Network/Ethereum/Web3/Internal.hs
--- a/src/Network/Ethereum/Web3/Internal.hs
+++ b/src/Network/Ethereum/Web3/Internal.hs
@@ -11,14 +11,14 @@
 --
 module Network.Ethereum.Web3.Internal where
 
-import Data.Char (toLower, toUpper)
+import           Data.Char (toLower, toUpper)
 
 -- | Lower first char of string
 toLowerFirst :: String -> String
-toLowerFirst [] = []
+toLowerFirst []       = []
 toLowerFirst (x : xs) = toLower x : xs
 
 -- | Upper first char of string
 toUpperFirst :: String -> String
-toUpperFirst [] = []
+toUpperFirst []       = []
 toUpperFirst (x : xs) = toUpper x : xs
diff --git a/src/Network/Ethereum/Web3/JsonAbi.hs b/src/Network/Ethereum/Web3/JsonAbi.hs
--- a/src/Network/Ethereum/Web3/JsonAbi.hs
+++ b/src/Network/Ethereum/Web3/JsonAbi.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE OverloadedStrings    #-}
-{-# LANGUAGE TemplateHaskell      #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
 -- |
 -- Module      :  Network.Ethereum.Web3.JsonAbi
 -- Copyright   :  Alexander Krupenkin 2016
@@ -21,14 +21,14 @@
   , eventId
   ) where
 
-import Crypto.Hash (Digest, Keccak_256, hash)
-import qualified Data.Text.Encoding as T
-import qualified Data.Text          as T
-import Network.Ethereum.Web3.Internal
-import Data.Monoid ((<>))
-import Data.Text (Text)
-import Data.Aeson.TH
-import Data.Aeson
+import           Crypto.Hash                    (Digest, Keccak_256, hash)
+import           Data.Aeson
+import           Data.Aeson.TH
+import           Data.Monoid                    ((<>))
+import           Data.Text                      (Text)
+import qualified Data.Text                      as T
+import qualified Data.Text.Encoding             as T
+import           Network.Ethereum.Web3.Internal
 
 -- | Method argument
 data FunctionArg = FunctionArg
@@ -60,10 +60,10 @@
 data Declaration
   = DConstructor { conInputs :: [FunctionArg] }
   -- ^ Contract constructor
-  | DFunction { funName      :: Text
-              , funConstant  :: Bool
-              , funInputs    :: [FunctionArg]
-              , funOutputs   :: Maybe [FunctionArg] }
+  | DFunction { funName     :: Text
+              , funConstant :: Bool
+              , funInputs   :: [FunctionArg]
+              , funOutputs  :: Maybe [FunctionArg] }
   -- ^ Method
   | DEvent { eveName      :: Text
            , eveInputs    :: [EventArg]
@@ -101,12 +101,12 @@
 showConstructor :: Declaration -> [Text]
 showConstructor x = case x of
     DConstructor{} -> ["\tConstructor " <> signature x]
-    _ -> []
+    _              -> []
 
 showEvent :: Declaration -> [Text]
 showEvent x = case x of
     DEvent{} -> ["\t\t" <> signature x]
-    _ -> []
+    _        -> []
 
 showMethod :: Declaration -> [Text]
 showMethod x = case x of
diff --git a/src/Network/Ethereum/Web3/JsonRpc.hs b/src/Network/Ethereum/Web3/JsonRpc.hs
--- a/src/Network/Ethereum/Web3/JsonRpc.hs
+++ b/src/Network/Ethereum/Web3/JsonRpc.hs
@@ -18,20 +18,21 @@
   , ServerUri
   ) where
 
-import Network.Ethereum.Web3.Provider
-import Network.Ethereum.Web3.Types
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
 
-import Network.HTTP.Client (httpLbs, newManager, requestBody,
-                            responseBody, method, requestHeaders,
-                            parseRequest, RequestBody(RequestBodyLBS))
-import Network.HTTP.Client.TLS (tlsManagerSettings)
-import Data.ByteString.Lazy (ByteString)
-import Control.Applicative ((<|>))
-import Control.Exception (throwIO)
-import Data.Vector (fromList)
-import Control.Monad ((>=>))
-import Data.Text (Text)
-import Data.Aeson
+import           Control.Applicative            ((<|>))
+import           Control.Exception              (throwIO)
+import           Control.Monad                  ((>=>))
+import           Data.Aeson
+import           Data.ByteString.Lazy           (ByteString)
+import           Data.Text                      (Text)
+import           Data.Vector                    (fromList)
+import           Network.HTTP.Client            (RequestBody (RequestBodyLBS),
+                                                 httpLbs, method, newManager,
+                                                 parseRequest, requestBody,
+                                                 requestHeaders, responseBody)
+import           Network.HTTP.Client.TLS        (tlsManagerSettings)
 
 -- | Name of called method.
 type MethodName = Text
diff --git a/src/Network/Ethereum/Web3/Net.hs b/src/Network/Ethereum/Web3/Net.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Ethereum/Web3/Net.hs
@@ -0,0 +1,32 @@
+-- |
+-- Module      :  Network.Ethereum.Web3.Net
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unknown
+--
+-- Ethereum node JSON-RPC API methods with `net_` prefix.
+--
+module Network.Ethereum.Web3.Net where
+
+import           Data.Text                      (Text)
+import           Network.Ethereum.Web3.JsonRpc
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
+
+-- | Returns the current network id.
+version :: Provider a => Web3 a Text
+{-# INLINE version #-}
+version = remote "net_version"
+
+-- | Returns true if client is actively listening for network connections.
+listening :: Provider a => Web3 a Bool
+{-# INLINE listening #-}
+listening = remote "net_listening"
+
+-- | Returns number of peers currently connected to the client.
+peerCount :: Provider a => Web3 a Text
+{-# INLINE peerCount #-}
+peerCount = remote "net_peerCount"
diff --git a/src/Network/Ethereum/Web3/Provider.hs b/src/Network/Ethereum/Web3/Provider.hs
--- a/src/Network/Ethereum/Web3/Provider.hs
+++ b/src/Network/Ethereum/Web3/Provider.hs
@@ -11,10 +11,10 @@
 --
 module Network.Ethereum.Web3.Provider where
 
-import Control.Concurrent (forkIO, ThreadId)
-import Control.Monad.IO.Class (MonadIO(..))
-import Network.Ethereum.Web3.Types
-import Control.Exception (try)
+import           Control.Concurrent          (ThreadId, forkIO)
+import           Control.Exception           (try)
+import           Control.Monad.IO.Class      (MonadIO (..))
+import           Network.Ethereum.Web3.Types
 
 -- | Ethereum node service provider
 class Provider a where
diff --git a/src/Network/Ethereum/Web3/TH.hs b/src/Network/Ethereum/Web3/TH.hs
--- a/src/Network/Ethereum/Web3/TH.hs
+++ b/src/Network/Ethereum/Web3/TH.hs
@@ -1,6 +1,9 @@
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE QuasiQuotes     #-}
-{-# LANGUAGE CPP             #-}
+{-# LANGUAGE CPP              #-}
+{-# LANGUAGE DeriveGeneric    #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TemplateHaskell  #-}
+
 -- |
 -- Module      :  Network.Ethereum.Web3.TH
 -- Copyright   :  Alexander Krupenkin 2016
@@ -35,34 +38,36 @@
   , ABIEncoding(..)
   ) where
 
-import qualified Data.Text.Lazy.Encoding as LT
-import qualified Data.Text.Lazy.Builder  as B
-import qualified Data.Text.Lazy          as LT
-import qualified Data.Attoparsec.Text    as P
-import qualified Data.Text               as T
+import qualified Data.Attoparsec.Text                 as P
+import qualified Data.Text                            as T
+import qualified Data.Text.Lazy                       as LT
+import qualified Data.Text.Lazy.Builder               as B
+import qualified Data.Text.Lazy.Encoding              as LT
 
-import Network.Ethereum.Web3.Address (Address)
-import Network.Ethereum.Web3.Encoding.Tuple
-import Network.Ethereum.Web3.Encoding
-import Network.Ethereum.Web3.Provider
-import Network.Ethereum.Web3.Internal
-import Network.Ethereum.Web3.Contract
-import Network.Ethereum.Web3.JsonAbi
-import Network.Ethereum.Web3.Types
-import Network.Ethereum.Unit
+import           Network.Ethereum.Unit
+import           Network.Ethereum.Web3.Address        (Address)
+import           Network.Ethereum.Web3.Contract
+import           Network.Ethereum.Web3.Encoding
+import           Network.Ethereum.Web3.Encoding.Tuple
+import           Network.Ethereum.Web3.Internal
+import           Network.Ethereum.Web3.JsonAbi
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
 
-import Control.Monad (replicateM)
+import           Control.Monad                        (replicateM)
 
-import Data.Text (Text, isPrefixOf)
-import Data.List (groupBy, sortBy)
-import Data.Monoid (mconcat, (<>))
-import Data.ByteArray (Bytes)
-import Data.Aeson
+import           Data.Aeson
+import           Data.ByteArray                       (Bytes)
+import           Data.List                            (groupBy, sortBy)
+import           Data.Monoid                          (mconcat, (<>))
+import           Data.Text                            (Text, isPrefixOf)
 
-import Language.Haskell.TH.Quote
-import Language.Haskell.TH.Lib
-import Language.Haskell.TH
+import           GHC.Generics
 
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Lib
+import           Language.Haskell.TH.Quote
+
 -- | Read contract ABI from file
 abiFrom :: QuasiQuoter
 abiFrom = quoteFile abi
@@ -215,7 +220,7 @@
                 [|sendTx $(varE a) $(varE b) $(params)|] ]
   where
     p = varT (mkName "p")
-    arrowing [x] = x
+    arrowing [x]      = x
     arrowing (x : xs) = [t|$x -> $(arrowing xs)|]
     inputT  = fmap (typeQ . funArgType) args
     outputT = case result of
@@ -232,7 +237,7 @@
     , instanceD' eventName eventT    (eventFilterD (T.unpack $ eventId eve) indexedFieldsCount)
     ]
   where eventName   = mkName (toUpperFirst (T.unpack name))
-        derivingD   = [mkName "Show", mkName "Eq", mkName "Ord"]
+        derivingD   = [mkName "Show", mkName "Eq", mkName "Ord", ''Generic]
         eventFields = normalC eventName (eventBangType <$> inputs)
         encodingT   = conT (mkName "ABIEncoding")
         eventT      = conT (mkName "Event")
@@ -251,16 +256,16 @@
         dataName  = mkName (toUpperFirst (T.unpack $ name <> "Data"))
         funName   = mkName (toLowerFirst (T.unpack name))
         bangInput = fmap funBangType inputs
-        derivingD = [mkName "Show", mkName "Eq", mkName "Ord"]
+        derivingD = [mkName "Show", mkName "Eq", mkName "Ord", ''Generic]
         encodingT = conT (mkName "ABIEncoding")
         methodT   = conT (mkName "Method")
 
 escape :: [Declaration] -> [Declaration]
 escape = concat . escapeNames . groupBy fnEq . sortBy fnCompare
   where fnEq (DFunction n1 _ _ _) (DFunction n2 _ _ _) = n1 == n2
-        fnEq _ _ = False
+        fnEq _ _                                       = False
         fnCompare (DFunction n1 _ _ _) (DFunction n2 _ _ _) = compare n1 n2
-        fnCompare _ _ = GT
+        fnCompare _ _                                       = GT
 
 escapeNames :: [[Declaration]] -> [[Declaration]]
 escapeNames = fmap go
@@ -272,14 +277,14 @@
 mkDecl :: Declaration -> Q [Dec]
 mkDecl x@DFunction{} = mkFun x
 mkDecl x@DEvent{}    = mkEvent x
-mkDecl _ = return []
+mkDecl _             = return []
 
 -- | ABI to declarations converter
 quoteAbiDec :: String -> Q [Dec]
 quoteAbiDec abi_string =
     case decode abi_lbs of
         Just (ContractABI abi) -> concat <$> mapM mkDecl (escape abi)
-        _ -> fail "Unable to parse ABI!"
+        _                      -> fail "Unable to parse ABI!"
   where abi_lbs = LT.encodeUtf8 (LT.pack abi_string)
 
 -- | ABI information string
diff --git a/src/Network/Ethereum/Web3/Types.hs b/src/Network/Ethereum/Web3/Types.hs
--- a/src/Network/Ethereum/Web3/Types.hs
+++ b/src/Network/Ethereum/Web3/Types.hs
@@ -1,5 +1,6 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE TemplateHaskell            #-}
 -- |
 -- Module      :  Network.Ethereum.Web3.Types
@@ -10,22 +11,23 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- Common used types and instances.
+-- Commonly used types and instances.
 --
 module Network.Ethereum.Web3.Types where
 
-import Network.Ethereum.Web3.Internal (toLowerFirst)
-import qualified Data.Text.Lazy.Builder.Int as B
-import qualified Data.Text.Lazy.Builder     as B
-import qualified Data.Text.Read             as R
-import Network.Ethereum.Web3.Address (Address)
-import Control.Monad.IO.Class (MonadIO)
-import Control.Exception (Exception)
-import Data.Typeable (Typeable)
-import Data.Monoid ((<>))
-import Data.Text (Text)
-import Data.Aeson.TH
-import Data.Aeson
+import           Control.Exception              (Exception)
+import           Control.Monad.IO.Class         (MonadIO)
+import           Data.Aeson
+import           Data.Aeson.TH
+import           Data.Monoid                    ((<>))
+import           Data.Text                      (Text)
+import qualified Data.Text.Lazy.Builder         as B
+import qualified Data.Text.Lazy.Builder.Int     as B
+import qualified Data.Text.Read                 as R
+import           Data.Typeable                  (Typeable)
+import           GHC.Generics
+import           Network.Ethereum.Web3.Address  (Address)
+import           Network.Ethereum.Web3.Internal (toLowerFirst)
 
 -- | Any communication with Ethereum node wrapped with 'Web3' monad
 newtype Web3 a b = Web3 { unWeb3 :: IO b }
@@ -39,16 +41,16 @@
   -- ^ Error in parser state
   | UserFail    !String
   -- ^ Common head for user errors
-  deriving (Typeable, Show, Eq)
+  deriving (Typeable, Show, Eq, Generic)
 
 instance Exception Web3Error
 
 -- | JSON-RPC error message
 data RpcError = RpcError
-  { errCode     :: !Int
-  , errMessage  :: !Text
-  , errData     :: !(Maybe Value)
-  } deriving (Show, Eq)
+  { errCode    :: !Int
+  , errMessage :: !Text
+  , errData    :: !(Maybe Value)
+  } deriving (Show, Eq, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 3 }) ''RpcError)
@@ -59,20 +61,20 @@
   , filterTopics    :: !(Maybe [Maybe Text])
   , filterFromBlock :: !(Maybe Text)
   , filterToBlock   :: !(Maybe Text)
-  } deriving Show
+  } deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 6 }) ''Filter)
 
--- | Event filder ident
+-- | Event filter identifier
 newtype FilterId = FilterId Integer
-  deriving (Show, Eq, Ord)
+  deriving (Show, Eq, Ord, Generic)
 
 instance FromJSON FilterId where
     parseJSON (String v) =
         case R.hexadecimal v of
             Right (x, "") -> return (FilterId x)
-            _ -> fail "Unable to parse FilterId!"
+            _             -> fail "Unable to parse FilterId!"
     parseJSON _ = fail "The string is required!"
 
 instance ToJSON FilterId where
@@ -80,7 +82,8 @@
         let hexValue = B.toLazyText (B.hexadecimal x)
         in  toJSON ("0x" <> hexValue)
 
--- | Changes pulled by low-level call 'eth_getFilterChanges'
+-- | Changes pulled by low-level call 'eth_getFilterChanges', 'eth_getLogs',
+-- and 'eth_getFilterLogs'
 data Change = Change
   { changeLogIndex         :: !Text
   , changeTransactionIndex :: !Text
@@ -90,30 +93,32 @@
   , changeAddress          :: !Address
   , changeData             :: !Text
   , changeTopics           :: ![Text]
-  } deriving Show
+  } deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 6 }) ''Change)
 
 -- | The contract call params
 data Call = Call
-  { callFrom    :: !(Maybe Address)
-  , callTo      :: !Address
-  , callGas     :: !(Maybe Text)
+  { callFrom     :: !(Maybe Address)
+  , callTo       :: !Address
+  , callGas      :: !(Maybe Text)
   , callGasPrice:: !(Maybe Text)
-  , callValue   :: !(Maybe Text)
-  , callData    :: !(Maybe Text)
-  } deriving Show
+  , callValue    :: !(Maybe Text)
+  , callData     :: !(Maybe Text)
+  } deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
-    { fieldLabelModifier = toLowerFirst . drop 4 }) ''Call)
+    { fieldLabelModifier = toLowerFirst . drop 4
+    , omitNothingFields = True }) ''Call)
 
 -- | The contract call mode describe used state: latest or pending
-data CallMode = Latest | Pending
+data DefaultBlock = BlockNumberHex Text | Earliest | Latest | Pending
   deriving (Show, Eq)
 
-instance ToJSON CallMode where
-    toJSON = toJSON . toLowerFirst . show
+instance ToJSON DefaultBlock where
+    toJSON (BlockNumberHex hex) = toJSON hex
+    toJSON parameter            = toJSON . toLowerFirst . show $ parameter
 
 -- TODO: Wrap
 -- | Transaction hash text string
@@ -121,29 +126,29 @@
 
 -- | Transaction information
 data Transaction = Transaction
-  { txHash              :: !TxHash
+  { txHash             :: !TxHash
   -- ^ DATA, 32 Bytes - hash of the transaction.
-  , txNonce             :: !Text
+  , txNonce            :: !Text
   -- ^ QUANTITY - the number of transactions made by the sender prior to this one.
-  , txBlockHash         :: !Text
+  , txBlockHash        :: !Text
   -- ^ DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
-  , txBlockNumber       :: !Text
+  , txBlockNumber      :: !Text
   -- ^ QUANTITY - block number where this transaction was in. null when its pending.
-  , txTransactionIndex  :: !Text
+  , txTransactionIndex :: !Text
   -- ^ QUANTITY - integer of the transactions index position in the block. null when its pending.
-  , txFrom              :: !Address
+  , txFrom             :: !Address
   -- ^ DATA, 20 Bytes - address of the sender.
-  , txTo                :: !(Maybe Address)
+  , txTo               :: !(Maybe Address)
   -- ^ DATA, 20 Bytes - address of the receiver. null when its a contract creation transaction.
-  , txValue             :: !Text
+  , txValue            :: !Text
   -- ^ QUANTITY - value transferred in Wei.
-  , txGasPrice          :: !Text
+  , txGasPrice         :: !Text
   -- ^ QUANTITY - gas price provided by the sender in Wei.
-  , txGas               :: !Text
+  , txGas              :: !Text
   -- ^ QUANTITY - gas provided by the sender.
-  , txInput             :: !Text
+  , txInput            :: !Text
   -- ^ DATA - the data send along with the transaction.
-  } deriving Show
+  } deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 2 }) ''Transaction)
@@ -188,7 +193,7 @@
   -- ^ Array of transaction objects.
   , blockUncles           :: ![Text]
   -- ^ Array - Array of uncle hashes.
-  } deriving Show
+  } deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 5 }) ''Block)
diff --git a/src/Network/Ethereum/Web3/Web3.hs b/src/Network/Ethereum/Web3/Web3.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Ethereum/Web3/Web3.hs
@@ -0,0 +1,27 @@
+-- |
+-- Module      :  Network.Ethereum.Web3.Web3
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unknown
+--
+-- Ethereum node JSON-RPC API methods with `web3_` prefix.
+--
+module Network.Ethereum.Web3.Web3 where
+
+import           Data.Text                      (Text)
+import           Network.Ethereum.Web3.JsonRpc
+import           Network.Ethereum.Web3.Provider
+import           Network.Ethereum.Web3.Types
+
+-- | Returns current node version string.
+clientVersion :: Provider a => Web3 a Text
+{-# INLINE clientVersion #-}
+clientVersion = remote "web3_clientVersion"
+
+-- | Returns Keccak-256 (not the standardized SHA3-256) of the given data.
+sha3 :: Provider a => Text -> Web3 a Text
+{-# INLINE sha3 #-}
+sha3 = remote "web3_sha3"
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,12 +1,13 @@
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE QuasiQuotes       #-}
-{-# LANGUAGE DataKinds         #-}
 module Main where
 
-import Network.Ethereum.Web3.TH
-import Network.Ethereum.Web3
-import Data.Text (unpack)
-import Text.Printf
+import           Data.Text                (unpack)
+import           Network.Ethereum.Web3
+import           Network.Ethereum.Web3.TH
+import           Text.Printf
 
 [abiFrom|data/ERC20.json|]
 
diff --git a/web3.cabal b/web3.cabal
--- a/web3.cabal
+++ b/web3.cabal
@@ -1,5 +1,5 @@
 name: web3
-version: 0.5.5.0
+version: 0.6.0.0
 cabal-version: >=1.10
 build-type: Simple
 license: BSD3
@@ -25,7 +25,9 @@
         Network.Ethereum.Web3
         Network.Ethereum.Unit
         Network.Ethereum.Web3.TH
-        Network.Ethereum.Web3.Api
+        Network.Ethereum.Web3.Web3
+        Network.Ethereum.Web3.Eth
+        Network.Ethereum.Web3.Net
         Network.Ethereum.Web3.Types
         Network.Ethereum.Web3.Address
         Network.Ethereum.Web3.JsonAbi
@@ -45,7 +47,7 @@
         bytestring >=0.10.8.1 && <0.11,
         cryptonite ==0.23.*,
         vector >=0.12.0.1 && <0.13,
-        memory >=0.14.6 && <0.15,
+        memory >=0.14.8 && <0.15,
         aeson >=1.1.2.0 && <1.2,
         text >=1.2.2.2 && <1.3
     default-language: Haskell2010
@@ -62,7 +64,7 @@
     main-is: Spec.hs
     build-depends:
         base >=4.9.1.0 && <4.10,
-        memory >=0.14.6 && <0.15,
+        memory >=0.14.8 && <0.15,
         text >=1.2.2.2 && <1.3,
         web3
     default-language: Haskell2010
