web3 0.5.5.0 → 0.6.0.0
raw patch · 22 files changed
+565/−321 lines, 22 filesdep ~memory
Dependency ranges changed: memory
Files
- README.md +1/−1
- src/Network/Ethereum/Unit.hs +10/−8
- src/Network/Ethereum/Web3.hs +8/−8
- src/Network/Ethereum/Web3/Address.hs +23/−17
- src/Network/Ethereum/Web3/Api.hs +0/−84
- src/Network/Ethereum/Web3/Contract.hs +26/−26
- src/Network/Ethereum/Web3/Encoding.hs +12/−10
- src/Network/Ethereum/Web3/Encoding/Bytes.hs +19/−15
- src/Network/Ethereum/Web3/Encoding/Internal.hs +12/−11
- src/Network/Ethereum/Web3/Encoding/Tuple.hs +3/−3
- src/Network/Ethereum/Web3/Encoding/TupleTH.hs +12/−12
- src/Network/Ethereum/Web3/Eth.hs +240/−0
- src/Network/Ethereum/Web3/Internal.hs +3/−3
- src/Network/Ethereum/Web3/JsonAbi.hs +16/−16
- src/Network/Ethereum/Web3/JsonRpc.hs +14/−13
- src/Network/Ethereum/Web3/Net.hs +32/−0
- src/Network/Ethereum/Web3/Provider.hs +4/−4
- src/Network/Ethereum/Web3/TH.hs +38/−33
- src/Network/Ethereum/Web3/Types.hs +53/−48
- src/Network/Ethereum/Web3/Web3.hs +27/−0
- test/Spec.hs +6/−5
- web3.cabal +6/−4
README.md view
@@ -5,9 +5,9 @@ [](https://travis-ci.org/airalab/hs-web3) [](https://ci.appveyor.com/project/akru/hs-web3) [](http://hackage.haskell.org/package/web3)-  +[](https://www.codetriage.com/airalab/hs-web3) ### Installation
src/Network/Ethereum/Unit.hs view
@@ -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 *)
src/Network/Ethereum/Web3.hs view
@@ -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
src/Network/Ethereum/Web3/Address.hs view
@@ -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
− src/Network/Ethereum/Web3/Api.hs
@@ -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
src/Network/Ethereum/Web3/Contract.hs view
@@ -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
src/Network/Ethereum/Web3/Encoding.hs view
@@ -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
src/Network/Ethereum/Web3/Encoding/Bytes.hs view
@@ -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
src/Network/Ethereum/Web3/Encoding/Internal.hs view
@@ -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
src/Network/Ethereum/Web3/Encoding/Tuple.hs view
@@ -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 }
src/Network/Ethereum/Web3/Encoding/TupleTH.hs view
@@ -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
+ src/Network/Ethereum/Web3/Eth.hs view
@@ -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"
src/Network/Ethereum/Web3/Internal.hs view
@@ -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
src/Network/Ethereum/Web3/JsonAbi.hs view
@@ -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
src/Network/Ethereum/Web3/JsonRpc.hs view
@@ -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
+ src/Network/Ethereum/Web3/Net.hs view
@@ -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"
src/Network/Ethereum/Web3/Provider.hs view
@@ -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
src/Network/Ethereum/Web3/TH.hs view
@@ -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
src/Network/Ethereum/Web3/Types.hs view
@@ -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)
+ src/Network/Ethereum/Web3/Web3.hs view
@@ -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"
test/Spec.hs view
@@ -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|]
web3.cabal view
@@ -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