packages feed

web3 0.8.4.0 → 0.9.0.0

raw patch · 80 files changed

+4593/−1236 lines, 80 filesdep +attoparsecdep +base58stringdep +errorsdep ~hspecPVP ok

version bump matches the API change (PVP)

Dependencies added: attoparsec, base58string, errors, http-media, http-types, network, servant, servant-client, tar, unordered-containers, websockets

Dependency ranges changed: hspec

API changes (from Hackage documentation)

- Crypto.Ethereum: sha3 :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout
- Crypto.Ethereum.Signature: pack :: ByteArray rsv => (Integer, Integer, Word8) -> rsv
- Crypto.Ethereum.Signature: unpack :: ByteArrayAccess rsv => rsv -> (Integer, Integer, Word8)
- Crypto.Ethereum.Utils: derivePubKey :: PrivateKey -> PublicKey
- Crypto.Ethereum.Utils: exportKey :: ByteArray privateKey => PrivateKey -> privateKey
- Crypto.Ethereum.Utils: exportPubKey :: ByteArray publicKey => PublicKey -> publicKey
- Crypto.Ethereum.Utils: importKey :: ByteArrayAccess privateKey => privateKey -> PrivateKey
- Crypto.Ethereum.Utils: sha3 :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout
- Network.Ethereum.Api.Provider: HttpProvider :: String -> Provider
- Network.Ethereum.Api.Provider: JsonRpcFail :: !String -> Web3Error
- Network.Ethereum.Api.Provider: ParserFail :: !String -> Web3Error
- Network.Ethereum.Api.Provider: UserFail :: !String -> Web3Error
- Network.Ethereum.Api.Provider: Web3 :: StateT JsonRpcClient IO a -> Web3 a
- Network.Ethereum.Api.Provider: [unWeb3] :: Web3 a -> StateT JsonRpcClient IO a
- Network.Ethereum.Api.Provider: data Provider
- Network.Ethereum.Api.Provider: data Web3Error
- Network.Ethereum.Api.Provider: forkWeb3 :: Web3 a -> Web3 (Async a)
- Network.Ethereum.Api.Provider: instance Control.Monad.Catch.MonadThrow Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: instance Control.Monad.IO.Class.MonadIO Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: instance Control.Monad.State.Class.MonadState Network.JsonRpc.TinyClient.JsonRpcClient Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: instance Data.Default.Class.Default Network.Ethereum.Api.Provider.Provider
- Network.Ethereum.Api.Provider: instance GHC.Base.Applicative Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: instance GHC.Base.Functor Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: instance GHC.Base.Monad Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: instance GHC.Classes.Eq Network.Ethereum.Api.Provider.Provider
- Network.Ethereum.Api.Provider: instance GHC.Classes.Eq Network.Ethereum.Api.Provider.Web3Error
- Network.Ethereum.Api.Provider: instance GHC.Exception.Type.Exception Network.Ethereum.Api.Provider.Web3Error
- Network.Ethereum.Api.Provider: instance GHC.Generics.Generic Network.Ethereum.Api.Provider.Provider
- Network.Ethereum.Api.Provider: instance GHC.Generics.Generic Network.Ethereum.Api.Provider.Web3Error
- Network.Ethereum.Api.Provider: instance GHC.Show.Show Network.Ethereum.Api.Provider.Provider
- Network.Ethereum.Api.Provider: instance GHC.Show.Show Network.Ethereum.Api.Provider.Web3Error
- Network.Ethereum.Api.Provider: instance Network.JsonRpc.TinyClient.JsonRpc Network.Ethereum.Api.Provider.Web3
- Network.Ethereum.Api.Provider: newtype Web3 a
- Network.Ethereum.Api.Provider: runWeb3 :: MonadIO m => Web3 a -> m (Either Web3Error a)
- Network.Ethereum.Api.Provider: runWeb3' :: MonadIO m => Provider -> Web3 a -> m (Either Web3Error a)
- Network.Ethereum.Api.Provider: runWeb3With :: MonadIO m => Manager -> Provider -> Web3 a -> m (Either Web3Error a)
- Network.Ethereum.Contract.Event.MultiFilter: multiEvent' :: (PollFilters es, QueryAllLogs es, MapHandlers Web3 es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es)) => MultiFilter es -> Handlers es (ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.MultiFilter: multiEventMany' :: (PollFilters es, QueryAllLogs es, MapHandlers Web3 es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es)) => MultiFilter es -> Integer -> Handlers es (ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.MultiFilter: multiEventManyNoFilter' :: (QueryAllLogs es, MapHandlers Web3 es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es)) => MultiFilter es -> Integer -> Handlers es (ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.MultiFilter: multiEventNoFilter' :: (QueryAllLogs es, MapHandlers Web3 es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es)) => MultiFilter es -> Handlers es (ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.SingleFilter: event' :: DecodeEvent i ni e => Filter e -> (e -> ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.SingleFilter: eventMany' :: DecodeEvent i ni e => Filter e -> Integer -> (e -> ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.SingleFilter: eventManyNoFilter' :: DecodeEvent i ni e => Filter e -> Integer -> (e -> ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Contract.Event.SingleFilter: eventNoFilter' :: DecodeEvent i ni e => Filter e -> (e -> ReaderT Change Web3 EventAction) -> Web3 ()
- Network.Ethereum.Web3: ContinueEvent :: EventAction
- Network.Ethereum.Web3: TerminateEvent :: EventAction
- Network.Ethereum.Web3: data EventAction
- Network.Ethereum.Web3: data Web3 a
- Network.Ethereum.Web3: event :: DecodeEvent i ni e => Filter e -> (e -> ReaderT Change Web3 EventAction) -> Web3 (Async ())
- Network.Ethereum.Web3: runWeb3 :: MonadIO m => Web3 a -> m (Either Web3Error a)
- Network.JsonRpc.TinyClient: jsonRpcManager :: Lens' JsonRpcClient Manager
- Network.JsonRpc.TinyClient: jsonRpcServer :: Lens' JsonRpcClient String
+ Crypto.Ecdsa.Signature: pack :: ByteArray rsv => (Integer, Integer, Word8) -> rsv
+ Crypto.Ecdsa.Signature: sign :: ByteArrayAccess bin => PrivateKey -> bin -> (Integer, Integer, Word8)
+ Crypto.Ecdsa.Signature: unpack :: ByteArrayAccess rsv => rsv -> (Integer, Integer, Word8)
+ Crypto.Ecdsa.Utils: derivePubKey :: PrivateKey -> PublicKey
+ Crypto.Ecdsa.Utils: exportKey :: ByteArray privateKey => PrivateKey -> privateKey
+ Crypto.Ecdsa.Utils: exportPubKey :: ByteArray publicKey => PublicKey -> publicKey
+ Crypto.Ecdsa.Utils: importKey :: ByteArrayAccess privateKey => privateKey -> PrivateKey
+ Crypto.Ethereum: keccak256 :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout
+ Crypto.Ethereum.Utils: keccak256 :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout
+ Network.Ethereum: ContinueEvent :: EventAction
+ Network.Ethereum: TerminateEvent :: EventAction
+ Network.Ethereum: data EventAction
+ Network.Ethereum: event :: (DecodeEvent i ni e, JsonRpc m) => Filter e -> (e -> ReaderT Change m EventAction) -> m ()
+ Network.Ethereum.Contract.Event.MultiFilter: multiEventMany :: (PollFilters es, QueryAllLogs es, MapHandlers m es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es), JsonRpc m) => MultiFilter es -> Integer -> Handlers es (ReaderT Change m EventAction) -> m ()
+ Network.Ethereum.Contract.Event.MultiFilter: multiEventManyNoFilter :: (QueryAllLogs es, MapHandlers m es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es), JsonRpc m) => MultiFilter es -> Integer -> Handlers es (ReaderT Change m EventAction) -> m ()
+ Network.Ethereum.Contract.Event.SingleFilter: eventMany :: (DecodeEvent i ni e, JsonRpc m) => Filter e -> Integer -> (e -> ReaderT Change m EventAction) -> m ()
+ Network.Ethereum.Contract.Event.SingleFilter: eventManyNoFilter :: (DecodeEvent i ni e, JsonRpc m) => Filter e -> Integer -> (e -> ReaderT Change m EventAction) -> m ()
+ Network.Ipfs.Api.Bitswap: ledger :: MonadIO m => Text -> IpfsT m BitswapLedgerObj
+ Network.Ipfs.Api.Bitswap: reprovide :: MonadIO m => IpfsT m ReprovideReturnType
+ Network.Ipfs.Api.Bitswap: stat :: MonadIO m => IpfsT m BitswapStatObj
+ Network.Ipfs.Api.Bitswap: wl :: MonadIO m => IpfsT m BitswapWLObj
+ Network.Ipfs.Api.Block: get :: MonadIO m => Text -> IpfsT m BlockReturnType
+ Network.Ipfs.Api.Block: put :: MonadIO m => Text -> IpfsT m (Maybe BlockObj)
+ Network.Ipfs.Api.Block: stat :: MonadIO m => Text -> IpfsT m BlockObj
+ Network.Ipfs.Api.Bootstrap: add :: MonadIO m => Text -> IpfsT m BootstrapObj
+ Network.Ipfs.Api.Bootstrap: list :: MonadIO m => IpfsT m BootstrapObj
+ Network.Ipfs.Api.Bootstrap: rm :: MonadIO m => Text -> IpfsT m BootstrapObj
+ Network.Ipfs.Api.Cid: base32 :: MonadIO m => Text -> IpfsT m CidObj
+ Network.Ipfs.Api.Cid: bases :: MonadIO m => IpfsT m [CidBasesObj]
+ Network.Ipfs.Api.Cid: codecs :: MonadIO m => IpfsT m [CidCodecsObj]
+ Network.Ipfs.Api.Cid: format :: MonadIO m => Text -> IpfsT m CidObj
+ Network.Ipfs.Api.Cid: hashes :: MonadIO m => IpfsT m [CidHashesObj]
+ Network.Ipfs.Api.Config: get :: MonadIO m => Text -> IpfsT m ConfigObj
+ Network.Ipfs.Api.Config: replace :: MonadIO m => Text -> IpfsT m Bool
+ Network.Ipfs.Api.Config: set :: MonadIO m => Text -> Maybe Text -> IpfsT m ConfigObj
+ Network.Ipfs.Api.Core: add :: MonadIO m => Text -> IpfsT m (Maybe AddObj)
+ Network.Ipfs.Api.Core: cat :: MonadIO m => Text -> IpfsT m CatReturnType
+ Network.Ipfs.Api.Core: dns :: MonadIO m => Text -> IpfsT m DnsObj
+ Network.Ipfs.Api.Core: get :: MonadIO m => Text -> IpfsT m Text
+ Network.Ipfs.Api.Core: id :: MonadIO m => IpfsT m IdObj
+ Network.Ipfs.Api.Core: idPeer :: MonadIO m => Text -> IpfsT m IdObj
+ Network.Ipfs.Api.Core: ls :: MonadIO m => Text -> IpfsT m LsObj
+ Network.Ipfs.Api.Core: ping :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Core: refs :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Core: refsLocal :: MonadIO m => m ()
+ Network.Ipfs.Api.Core: shutdown :: MonadIO m => IpfsT m NoContent
+ Network.Ipfs.Api.Core: version :: MonadIO m => IpfsT m VersionObj
+ Network.Ipfs.Api.Dag: get :: MonadIO m => Text -> IpfsT m DagReturnType
+ Network.Ipfs.Api.Dag: put :: MonadIO m => Text -> IpfsT m (Maybe DagPutObj)
+ Network.Ipfs.Api.Dag: resolve :: MonadIO m => Text -> IpfsT m DagResolveObj
+ Network.Ipfs.Api.Dht: findPeer :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Dht: findProvs :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Dht: get :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Dht: provide :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Dht: query :: MonadIO m => Text -> m ()
+ Network.Ipfs.Api.Files: chcidVer :: MonadIO m => Text -> Int -> IpfsT m NoContent
+ Network.Ipfs.Api.Files: cp :: MonadIO m => Text -> Text -> IpfsT m NoContent
+ Network.Ipfs.Api.Files: filesRm :: MonadIO m => Text -> IpfsT m NoContent
+ Network.Ipfs.Api.Files: flush :: MonadIO m => Text -> IpfsT m FilesFlushObj
+ Network.Ipfs.Api.Files: ls :: MonadIO m => Text -> IpfsT m FilesLsObj
+ Network.Ipfs.Api.Files: mkdir :: MonadIO m => Text -> IpfsT m NoContent
+ Network.Ipfs.Api.Files: mv :: MonadIO m => Text -> Text -> IpfsT m NoContent
+ Network.Ipfs.Api.Files: read :: MonadIO m => Text -> IpfsT m FilesReadType
+ Network.Ipfs.Api.Files: stat :: MonadIO m => Text -> IpfsT m FilesStatObj
+ Network.Ipfs.Api.Files: write :: MonadIO m => Text -> Text -> Bool -> IpfsT m Bool
+ Network.Ipfs.Api.Internal: _bitswapLedger :: Text -> ClientM BitswapLedgerObj
+ Network.Ipfs.Api.Internal: _bitswapReprovide :: ClientM ReprovideReturnType
+ Network.Ipfs.Api.Internal: _bitswapStat :: ClientM BitswapStatObj
+ Network.Ipfs.Api.Internal: _bitswapWL :: ClientM BitswapWLObj
+ Network.Ipfs.Api.Internal: _blockGet :: Text -> ClientM BlockReturnType
+ Network.Ipfs.Api.Internal: _blockStat :: Text -> ClientM BlockObj
+ Network.Ipfs.Api.Internal: _bootstrapAdd :: Maybe Text -> ClientM BootstrapObj
+ Network.Ipfs.Api.Internal: _bootstrapList :: ClientM BootstrapObj
+ Network.Ipfs.Api.Internal: _bootstrapRM :: Maybe Text -> ClientM BootstrapObj
+ Network.Ipfs.Api.Internal: _cat :: Text -> ClientM CatReturnType
+ Network.Ipfs.Api.Internal: _cidBase32 :: Text -> ClientM CidObj
+ Network.Ipfs.Api.Internal: _cidBases :: ClientM [CidBasesObj]
+ Network.Ipfs.Api.Internal: _cidCodecs :: ClientM [CidCodecsObj]
+ Network.Ipfs.Api.Internal: _cidFormat :: Text -> ClientM CidObj
+ Network.Ipfs.Api.Internal: _cidHashes :: ClientM [CidHashesObj]
+ Network.Ipfs.Api.Internal: _configGet :: Text -> ClientM ConfigObj
+ Network.Ipfs.Api.Internal: _configSet :: Text -> Maybe Text -> ClientM ConfigObj
+ Network.Ipfs.Api.Internal: _dagGet :: Text -> ClientM DagReturnType
+ Network.Ipfs.Api.Internal: _dagResolve :: Text -> ClientM DagResolveObj
+ Network.Ipfs.Api.Internal: _dns :: Text -> ClientM DnsObj
+ Network.Ipfs.Api.Internal: _filesChcid :: Maybe Text -> Maybe Int -> ClientM NoContent
+ Network.Ipfs.Api.Internal: _filesCp :: Maybe Text -> Maybe Text -> ClientM NoContent
+ Network.Ipfs.Api.Internal: _filesFlush :: Maybe Text -> ClientM FilesFlushObj
+ Network.Ipfs.Api.Internal: _filesLs :: Maybe Text -> ClientM FilesLsObj
+ Network.Ipfs.Api.Internal: _filesMkdir :: Maybe Text -> ClientM NoContent
+ Network.Ipfs.Api.Internal: _filesMv :: Maybe Text -> Maybe Text -> ClientM NoContent
+ Network.Ipfs.Api.Internal: _filesRead :: Maybe Text -> ClientM FilesReadType
+ Network.Ipfs.Api.Internal: _filesRm :: Maybe Text -> Maybe Bool -> ClientM NoContent
+ Network.Ipfs.Api.Internal: _filesStat :: Maybe Text -> ClientM FilesStatObj
+ Network.Ipfs.Api.Internal: _get :: Text -> ClientM GetReturnType
+ Network.Ipfs.Api.Internal: _id :: ClientM IdObj
+ Network.Ipfs.Api.Internal: _idPeer :: Text -> ClientM IdObj
+ Network.Ipfs.Api.Internal: _ipfsApi :: Proxy IpfsApi
+ Network.Ipfs.Api.Internal: _keyGen :: Text -> Maybe Text -> ClientM KeyDetailsObj
+ Network.Ipfs.Api.Internal: _keyList :: ClientM KeyObj
+ Network.Ipfs.Api.Internal: _keyRename :: Text -> Maybe Text -> ClientM KeyRenameObj
+ Network.Ipfs.Api.Internal: _keyRm :: Text -> ClientM KeyObj
+ Network.Ipfs.Api.Internal: _logLevel :: Text -> Maybe Text -> ClientM LogLevelObj
+ Network.Ipfs.Api.Internal: _logLs :: ClientM LogLsObj
+ Network.Ipfs.Api.Internal: _ls :: Text -> ClientM LsObj
+ Network.Ipfs.Api.Internal: _objectAddLink :: Text -> Maybe Text -> Maybe Text -> ClientM ObjectLinksObj
+ Network.Ipfs.Api.Internal: _objectData :: Text -> ClientM ObjectReturnType
+ Network.Ipfs.Api.Internal: _objectDiff :: Text -> Maybe Text -> ClientM ObjectDiffObj
+ Network.Ipfs.Api.Internal: _objectGet :: Text -> ClientM ObjectGetObj
+ Network.Ipfs.Api.Internal: _objectGetLinks :: Text -> ClientM ObjectLinksObj
+ Network.Ipfs.Api.Internal: _objectNew :: ClientM ObjectObj
+ Network.Ipfs.Api.Internal: _objectRmLink :: Text -> Maybe Text -> ClientM ObjectLinksObj
+ Network.Ipfs.Api.Internal: _objectStat :: Text -> ClientM ObjectStatObj
+ Network.Ipfs.Api.Internal: _pinAdd :: Text -> ClientM PinObj
+ Network.Ipfs.Api.Internal: _pinRemove :: Text -> ClientM PinObj
+ Network.Ipfs.Api.Internal: _pubsubLs :: ClientM PubsubObj
+ Network.Ipfs.Api.Internal: _pubsubPeers :: ClientM PubsubObj
+ Network.Ipfs.Api.Internal: _pubsubPublish :: Text -> Maybe Text -> ClientM NoContent
+ Network.Ipfs.Api.Internal: _repoFsck :: ClientM RepoFsckObj
+ Network.Ipfs.Api.Internal: _repoVersion :: ClientM RepoVersionObj
+ Network.Ipfs.Api.Internal: _shutdown :: ClientM NoContent
+ Network.Ipfs.Api.Internal: _statsBw :: ClientM StatsBwObj
+ Network.Ipfs.Api.Internal: _statsRepo :: ClientM StatsRepoObj
+ Network.Ipfs.Api.Internal: _swarmConnect :: Maybe Text -> ClientM SwarmObj
+ Network.Ipfs.Api.Internal: _swarmDisconnect :: Maybe Text -> ClientM SwarmObj
+ Network.Ipfs.Api.Internal: _swarmFilterAdd :: Maybe Text -> ClientM SwarmObj
+ Network.Ipfs.Api.Internal: _swarmFilterRm :: Maybe Text -> ClientM SwarmObj
+ Network.Ipfs.Api.Internal: _swarmFilters :: ClientM SwarmObj
+ Network.Ipfs.Api.Internal: _swarmPeers :: ClientM SwarmPeersObj
+ Network.Ipfs.Api.Internal: _version :: ClientM VersionObj
+ Network.Ipfs.Api.Internal.Call: call :: MonadIO m => ClientM a -> IpfsT m a
+ Network.Ipfs.Api.Internal.Call: multipartCall :: MonadIO m => Text -> Text -> IpfsT m (Response ByteString)
+ Network.Ipfs.Api.Internal.Call: streamCall :: (MonadIO m, Show a) => ClientM (SourceT IO a) -> m ()
+ Network.Ipfs.Api.Internal.Stream: _dhtFindPeer :: Text -> ClientM (SourceIO DhtObj)
+ Network.Ipfs.Api.Internal.Stream: _dhtFindProvs :: Text -> ClientM (SourceIO DhtObj)
+ Network.Ipfs.Api.Internal.Stream: _dhtGet :: Text -> ClientM (SourceIO DhtObj)
+ Network.Ipfs.Api.Internal.Stream: _dhtProvide :: Text -> ClientM (SourceIO DhtObj)
+ Network.Ipfs.Api.Internal.Stream: _dhtQuery :: Text -> ClientM (SourceIO DhtObj)
+ Network.Ipfs.Api.Internal.Stream: _ipfsStreamApi :: Proxy IpfsStreamApi
+ Network.Ipfs.Api.Internal.Stream: _logTail :: ClientM (SourceIO LogReturnType)
+ Network.Ipfs.Api.Internal.Stream: _ping :: Text -> ClientM (SourceIO PingObj)
+ Network.Ipfs.Api.Internal.Stream: _pubsubSubscribe :: Text -> ClientM (SourceIO PubsubSubObj)
+ Network.Ipfs.Api.Internal.Stream: _refs :: Text -> ClientM (SourceIO RefsObj)
+ Network.Ipfs.Api.Internal.Stream: _refsLocal :: ClientM (SourceIO RefsObj)
+ Network.Ipfs.Api.Internal.Stream: _repoGc :: ClientM (SourceIO RepoGcObj)
+ Network.Ipfs.Api.Internal.Stream: _repoVerify :: ClientM (SourceIO RepoVerifyObj)
+ Network.Ipfs.Api.Key: gen :: MonadIO m => Text -> Text -> IpfsT m KeyDetailsObj
+ Network.Ipfs.Api.Key: list :: MonadIO m => IpfsT m KeyObj
+ Network.Ipfs.Api.Key: rename :: MonadIO m => Text -> Text -> IpfsT m KeyRenameObj
+ Network.Ipfs.Api.Key: rm :: MonadIO m => Text -> IpfsT m KeyObj
+ Network.Ipfs.Api.Log: level :: MonadIO m => Text -> Text -> IpfsT m LogLevelObj
+ Network.Ipfs.Api.Log: ls :: MonadIO m => IpfsT m LogLsObj
+ Network.Ipfs.Api.Log: tail :: MonadIO m => m ()
+ Network.Ipfs.Api.Object: addLink :: MonadIO m => Text -> Text -> Text -> IpfsT m ObjectLinksObj
+ Network.Ipfs.Api.Object: appendData :: MonadIO m => Text -> Text -> IpfsT m (Maybe ObjectLinksObj)
+ Network.Ipfs.Api.Object: diff :: MonadIO m => Text -> Text -> IpfsT m ObjectDiffObj
+ Network.Ipfs.Api.Object: get :: MonadIO m => Text -> IpfsT m ObjectGetObj
+ Network.Ipfs.Api.Object: getLinks :: MonadIO m => Text -> IpfsT m ObjectLinksObj
+ Network.Ipfs.Api.Object: new :: MonadIO m => IpfsT m ObjectObj
+ Network.Ipfs.Api.Object: object :: MonadIO m => Text -> IpfsT m ObjectReturnType
+ Network.Ipfs.Api.Object: objectStat :: MonadIO m => Text -> IpfsT m ObjectStatObj
+ Network.Ipfs.Api.Object: put :: MonadIO m => Text -> IpfsT m (Maybe ObjectObj)
+ Network.Ipfs.Api.Object: rmLink :: MonadIO m => Text -> Text -> IpfsT m ObjectLinksObj
+ Network.Ipfs.Api.Object: setData :: MonadIO m => Text -> Text -> IpfsT m (Maybe ObjectLinksObj)
+ Network.Ipfs.Api.Pin: add :: MonadIO m => Text -> IpfsT m PinObj
+ Network.Ipfs.Api.Pin: remove :: MonadIO m => Text -> IpfsT m PinObj
+ Network.Ipfs.Api.Pubsub: ls :: MonadIO m => IpfsT m PubsubObj
+ Network.Ipfs.Api.Pubsub: peers :: MonadIO m => IpfsT m PubsubObj
+ Network.Ipfs.Api.Pubsub: publish :: MonadIO m => Text -> Text -> IpfsT m NoContent
+ Network.Ipfs.Api.Repo: fsck :: MonadIO m => IpfsT m RepoFsckObj
+ Network.Ipfs.Api.Repo: gc :: MonadIO m => m ()
+ Network.Ipfs.Api.Repo: repoVerify :: MonadIO m => m ()
+ Network.Ipfs.Api.Repo: version :: MonadIO m => IpfsT m RepoVersionObj
+ Network.Ipfs.Api.Stats: bw :: MonadIO m => IpfsT m StatsBwObj
+ Network.Ipfs.Api.Stats: repo :: MonadIO m => IpfsT m StatsRepoObj
+ Network.Ipfs.Api.Swarm: connect :: MonadIO m => Text -> IpfsT m SwarmObj
+ Network.Ipfs.Api.Swarm: disconnect :: MonadIO m => Text -> IpfsT m SwarmObj
+ Network.Ipfs.Api.Swarm: filterAdd :: MonadIO m => Text -> IpfsT m SwarmObj
+ Network.Ipfs.Api.Swarm: filterRm :: MonadIO m => Text -> IpfsT m SwarmObj
+ Network.Ipfs.Api.Swarm: filters :: MonadIO m => IpfsT m SwarmObj
+ Network.Ipfs.Api.Swarm: swarmPeers :: MonadIO m => IpfsT m SwarmPeersObj
+ Network.Ipfs.Api.Types: AddObj :: Text -> Text -> Text -> AddObj
+ Network.Ipfs.Api.Types: BitswapLedgerObj :: Int64 -> Text -> Int64 -> Int64 -> Double -> BitswapLedgerObj
+ Network.Ipfs.Api.Types: BitswapStatObj :: Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> [Text] -> Int -> [WantlistObj] -> BitswapStatObj
+ Network.Ipfs.Api.Types: BitswapWLObj :: [WantlistObj] -> BitswapWLObj
+ Network.Ipfs.Api.Types: BlockObj :: Text -> Int -> BlockObj
+ Network.Ipfs.Api.Types: BootstrapObj :: [Text] -> BootstrapObj
+ Network.Ipfs.Api.Types: CidBasesObj :: Int -> Text -> CidBasesObj
+ Network.Ipfs.Api.Types: CidCodecsObj :: Int -> Text -> CidCodecsObj
+ Network.Ipfs.Api.Types: CidHashesObj :: Int -> Text -> CidHashesObj
+ Network.Ipfs.Api.Types: CidObj :: Text -> Text -> Text -> CidObj
+ Network.Ipfs.Api.Types: ConfigObj :: Text -> Text -> ConfigObj
+ Network.Ipfs.Api.Types: DagCidObj :: Text -> DagCidObj
+ Network.Ipfs.Api.Types: DagPutObj :: DagCidObj -> DagPutObj
+ Network.Ipfs.Api.Types: DagResolveObj :: DagCidObj -> Text -> DagResolveObj
+ Network.Ipfs.Api.Types: DiffObj :: Text -> DiffObj
+ Network.Ipfs.Api.Types: DirLink :: Text -> Text -> Int64 -> Int -> Text -> DirLink
+ Network.Ipfs.Api.Types: DirObj :: Text -> [DirLink] -> DirObj
+ Network.Ipfs.Api.Types: DnsObj :: Text -> DnsObj
+ Network.Ipfs.Api.Types: FilesEntryObj :: Text -> Int -> Int -> Text -> FilesEntryObj
+ Network.Ipfs.Api.Types: FilesFlushObj :: Text -> FilesFlushObj
+ Network.Ipfs.Api.Types: FilesLsObj :: [FilesEntryObj] -> FilesLsObj
+ Network.Ipfs.Api.Types: FilesStatObj :: Text -> Int -> Int -> Int -> Text -> FilesStatObj
+ Network.Ipfs.Api.Types: IdObj :: [Text] -> Text -> Text -> Text -> Text -> IdObj
+ Network.Ipfs.Api.Types: KeyDetailsObj :: Text -> Text -> KeyDetailsObj
+ Network.Ipfs.Api.Types: KeyObj :: [KeyDetailsObj] -> KeyObj
+ Network.Ipfs.Api.Types: KeyRenameObj :: Text -> Text -> Bool -> Text -> KeyRenameObj
+ Network.Ipfs.Api.Types: LogLevelObj :: Text -> LogLevelObj
+ Network.Ipfs.Api.Types: LogLsObj :: [Text] -> LogLsObj
+ Network.Ipfs.Api.Types: LsObj :: [DirObj] -> LsObj
+ Network.Ipfs.Api.Types: ObjectChangeObj :: Maybe DiffObj -> DiffObj -> Text -> Int -> ObjectChangeObj
+ Network.Ipfs.Api.Types: ObjectDiffObj :: [ObjectChangeObj] -> ObjectDiffObj
+ Network.Ipfs.Api.Types: ObjectGetObj :: Text -> [ObjectLinkObj] -> ObjectGetObj
+ Network.Ipfs.Api.Types: ObjectLinkObj :: Text -> Text -> Int64 -> ObjectLinkObj
+ Network.Ipfs.Api.Types: ObjectObj :: Text -> ObjectObj
+ Network.Ipfs.Api.Types: ObjectStatObj :: Int -> Int -> Int -> Text -> Int -> Int -> ObjectStatObj
+ Network.Ipfs.Api.Types: PubsubObj :: [Text] -> PubsubObj
+ Network.Ipfs.Api.Types: RepoFsckObj :: Text -> RepoFsckObj
+ Network.Ipfs.Api.Types: RepoVersionObj :: Text -> RepoVersionObj
+ Network.Ipfs.Api.Types: StatsBwObj :: Double -> Double -> Int64 -> Int64 -> StatsBwObj
+ Network.Ipfs.Api.Types: StatsRepoObj :: Int64 -> Text -> Int64 -> Int64 -> Text -> StatsRepoObj
+ Network.Ipfs.Api.Types: SwarmObj :: [Text] -> SwarmObj
+ Network.Ipfs.Api.Types: SwarmPeerObj :: Text -> Int -> Text -> Text -> Text -> Maybe [SwarmStreamObj] -> SwarmPeerObj
+ Network.Ipfs.Api.Types: SwarmPeersObj :: [SwarmPeerObj] -> SwarmPeersObj
+ Network.Ipfs.Api.Types: SwarmStreamObj :: Text -> SwarmStreamObj
+ Network.Ipfs.Api.Types: VersionObj :: Text -> Text -> Text -> Text -> Text -> VersionObj
+ Network.Ipfs.Api.Types: WantlistObj :: Text -> WantlistObj
+ Network.Ipfs.Api.Types: WithLinks :: Text -> [ObjectLinkObj] -> ObjectLinksObj
+ Network.Ipfs.Api.Types: WithProgress :: [Text] -> Int -> PinObj
+ Network.Ipfs.Api.Types: WithoutLinks :: Text -> ObjectLinksObj
+ Network.Ipfs.Api.Types: WithoutProgress :: [Text] -> PinObj
+ Network.Ipfs.Api.Types: [address] :: SwarmPeerObj -> Text
+ Network.Ipfs.Api.Types: [addresses] :: IdObj -> [Text]
+ Network.Ipfs.Api.Types: [after] :: ObjectChangeObj -> Maybe DiffObj
+ Network.Ipfs.Api.Types: [agentVersion] :: IdObj -> Text
+ Network.Ipfs.Api.Types: [baseCode] :: CidBasesObj -> Int
+ Network.Ipfs.Api.Types: [baseName] :: CidBasesObj -> Text
+ Network.Ipfs.Api.Types: [before] :: ObjectChangeObj -> DiffObj
+ Network.Ipfs.Api.Types: [bitswapKeys] :: BitswapWLObj -> [WantlistObj]
+ Network.Ipfs.Api.Types: [bitswapPeers] :: BitswapStatObj -> [Text]
+ Network.Ipfs.Api.Types: [blockSize] :: BlockObj -> Int
+ Network.Ipfs.Api.Types: [blocksReceived] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [blocksSent] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [blocks] :: FilesStatObj -> Int
+ Network.Ipfs.Api.Types: [bootstrapPeers] :: BootstrapObj -> [Text]
+ Network.Ipfs.Api.Types: [changes] :: ObjectDiffObj -> [ObjectChangeObj]
+ Network.Ipfs.Api.Types: [cidSlash] :: DagCidObj -> Text
+ Network.Ipfs.Api.Types: [cidStr] :: CidObj -> Text
+ Network.Ipfs.Api.Types: [cid] :: DagResolveObj -> DagCidObj
+ Network.Ipfs.Api.Types: [codecCode] :: CidCodecsObj -> Int
+ Network.Ipfs.Api.Types: [codecName] :: CidCodecsObj -> Text
+ Network.Ipfs.Api.Types: [commit] :: VersionObj -> Text
+ Network.Ipfs.Api.Types: [configKey] :: ConfigObj -> Text
+ Network.Ipfs.Api.Types: [configValue] :: ConfigObj -> Text
+ Network.Ipfs.Api.Types: [cumulativeObjectSize] :: FilesStatObj -> Int
+ Network.Ipfs.Api.Types: [cumulativeSize] :: ObjectStatObj -> Int
+ Network.Ipfs.Api.Types: [dataReceived] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [dataSent] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [dataSize] :: ObjectStatObj -> Int
+ Network.Ipfs.Api.Types: [diffSlash] :: DiffObj -> Text
+ Network.Ipfs.Api.Types: [diffType] :: ObjectChangeObj -> Int
+ Network.Ipfs.Api.Types: [dirHash] :: DirObj -> Text
+ Network.Ipfs.Api.Types: [direction] :: SwarmPeerObj -> Int
+ Network.Ipfs.Api.Types: [dlContentType] :: DirLink -> Int
+ Network.Ipfs.Api.Types: [dlHash] :: DirLink -> Text
+ Network.Ipfs.Api.Types: [dlName] :: DirLink -> Text
+ Network.Ipfs.Api.Types: [dlSize] :: DirLink -> Int64
+ Network.Ipfs.Api.Types: [dlTarget] :: DirLink -> Text
+ Network.Ipfs.Api.Types: [dnsPath] :: DnsObj -> Text
+ Network.Ipfs.Api.Types: [dupBlksReceived] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [dupDataReceived] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [enteries] :: FilesLsObj -> [FilesEntryObj]
+ Network.Ipfs.Api.Types: [entryHash] :: FilesEntryObj -> Text
+ Network.Ipfs.Api.Types: [entryName] :: FilesEntryObj -> Text
+ Network.Ipfs.Api.Types: [entrySize] :: FilesEntryObj -> Int
+ Network.Ipfs.Api.Types: [entryType] :: FilesEntryObj -> Int
+ Network.Ipfs.Api.Types: [errorMsg] :: CidObj -> Text
+ Network.Ipfs.Api.Types: [exchanged] :: BitswapLedgerObj -> Int64
+ Network.Ipfs.Api.Types: [fileCid] :: FilesFlushObj -> Text
+ Network.Ipfs.Api.Types: [fileObjectHash] :: FilesStatObj -> Text
+ Network.Ipfs.Api.Types: [forSlash] :: WantlistObj -> Text
+ Network.Ipfs.Api.Types: [formatted] :: CidObj -> Text
+ Network.Ipfs.Api.Types: [golang] :: VersionObj -> Text
+ Network.Ipfs.Api.Types: [hash] :: AddObj -> Text
+ Network.Ipfs.Api.Types: [id] :: IdObj -> Text
+ Network.Ipfs.Api.Types: [keyId] :: KeyDetailsObj -> Text
+ Network.Ipfs.Api.Types: [keyName] :: KeyDetailsObj -> Text
+ Network.Ipfs.Api.Types: [key] :: BlockObj -> Text
+ Network.Ipfs.Api.Types: [keys] :: KeyObj -> [KeyDetailsObj]
+ Network.Ipfs.Api.Types: [latency] :: SwarmPeerObj -> Text
+ Network.Ipfs.Api.Types: [ledgerPeer] :: BitswapLedgerObj -> Text
+ Network.Ipfs.Api.Types: [linkHash] :: ObjectLinkObj -> Text
+ Network.Ipfs.Api.Types: [linkName] :: ObjectLinkObj -> Text
+ Network.Ipfs.Api.Types: [linkSize] :: ObjectLinkObj -> Int64
+ Network.Ipfs.Api.Types: [linksSize] :: ObjectStatObj -> Int
+ Network.Ipfs.Api.Types: [links] :: DirObj -> [DirLink]
+ Network.Ipfs.Api.Types: [logLsStrings] :: LogLsObj -> [Text]
+ Network.Ipfs.Api.Types: [message] :: LogLevelObj -> Text
+ Network.Ipfs.Api.Types: [messagesReceived] :: BitswapStatObj -> Int64
+ Network.Ipfs.Api.Types: [multihashCode] :: CidHashesObj -> Int
+ Network.Ipfs.Api.Types: [multihashName] :: CidHashesObj -> Text
+ Network.Ipfs.Api.Types: [muxer] :: SwarmPeerObj -> Text
+ Network.Ipfs.Api.Types: [name] :: AddObj -> Text
+ Network.Ipfs.Api.Types: [newObjectHash] :: ObjectObj -> Text
+ Network.Ipfs.Api.Types: [now] :: KeyRenameObj -> Text
+ Network.Ipfs.Api.Types: [numLinks] :: ObjectStatObj -> Int
+ Network.Ipfs.Api.Types: [numObjects] :: StatsRepoObj -> Int64
+ Network.Ipfs.Api.Types: [objBlockSize] :: ObjectStatObj -> Int
+ Network.Ipfs.Api.Types: [objHash] :: ObjectStatObj -> Text
+ Network.Ipfs.Api.Types: [objectGetLinks] :: ObjectGetObj -> [ObjectLinkObj]
+ Network.Ipfs.Api.Types: [objectHash] :: ObjectLinksObj -> Text
+ Network.Ipfs.Api.Types: [objectLinks] :: ObjectLinksObj -> [ObjectLinkObj]
+ Network.Ipfs.Api.Types: [objectName] :: ObjectGetObj -> Text
+ Network.Ipfs.Api.Types: [objectSize] :: FilesStatObj -> Int
+ Network.Ipfs.Api.Types: [objectType] :: FilesStatObj -> Text
+ Network.Ipfs.Api.Types: [objs] :: LsObj -> [DirObj]
+ Network.Ipfs.Api.Types: [overwrite] :: KeyRenameObj -> Bool
+ Network.Ipfs.Api.Types: [path] :: ObjectChangeObj -> Text
+ Network.Ipfs.Api.Types: [peerId] :: KeyRenameObj -> Text
+ Network.Ipfs.Api.Types: [peer] :: SwarmPeerObj -> Text
+ Network.Ipfs.Api.Types: [peers] :: SwarmPeersObj -> [SwarmPeerObj]
+ Network.Ipfs.Api.Types: [pins] :: PinObj -> [Text]
+ Network.Ipfs.Api.Types: [progress] :: PinObj -> Int
+ Network.Ipfs.Api.Types: [protocolVersion] :: IdObj -> Text
+ Network.Ipfs.Api.Types: [protocol] :: SwarmStreamObj -> Text
+ Network.Ipfs.Api.Types: [provideBufLen] :: BitswapStatObj -> Int
+ Network.Ipfs.Api.Types: [publicKey] :: IdObj -> Text
+ Network.Ipfs.Api.Types: [pubsubStrings] :: PubsubObj -> [Text]
+ Network.Ipfs.Api.Types: [putCid] :: DagPutObj -> DagCidObj
+ Network.Ipfs.Api.Types: [rateIn] :: StatsBwObj -> Double
+ Network.Ipfs.Api.Types: [rateOut] :: StatsBwObj -> Double
+ Network.Ipfs.Api.Types: [recv] :: BitswapLedgerObj -> Int64
+ Network.Ipfs.Api.Types: [remPath] :: DagResolveObj -> Text
+ Network.Ipfs.Api.Types: [repoMessage] :: RepoFsckObj -> Text
+ Network.Ipfs.Api.Types: [repoPath] :: StatsRepoObj -> Text
+ Network.Ipfs.Api.Types: [repoSize] :: StatsRepoObj -> Int64
+ Network.Ipfs.Api.Types: [repoVer] :: RepoVersionObj -> Text
+ Network.Ipfs.Api.Types: [repoVersion] :: StatsRepoObj -> Text
+ Network.Ipfs.Api.Types: [repo] :: VersionObj -> Text
+ Network.Ipfs.Api.Types: [sent] :: BitswapLedgerObj -> Int64
+ Network.Ipfs.Api.Types: [size] :: AddObj -> Text
+ Network.Ipfs.Api.Types: [storageMax] :: StatsRepoObj -> Int64
+ Network.Ipfs.Api.Types: [streams] :: SwarmPeerObj -> Maybe [SwarmStreamObj]
+ Network.Ipfs.Api.Types: [strings] :: SwarmObj -> [Text]
+ Network.Ipfs.Api.Types: [system] :: VersionObj -> Text
+ Network.Ipfs.Api.Types: [totalIn] :: StatsBwObj -> Int64
+ Network.Ipfs.Api.Types: [totalOut] :: StatsBwObj -> Int64
+ Network.Ipfs.Api.Types: [value] :: BitswapLedgerObj -> Double
+ Network.Ipfs.Api.Types: [version] :: VersionObj -> Text
+ Network.Ipfs.Api.Types: [wantlist] :: BitswapStatObj -> [WantlistObj]
+ Network.Ipfs.Api.Types: [was] :: KeyRenameObj -> Text
+ Network.Ipfs.Api.Types: data AddObj
+ Network.Ipfs.Api.Types: data BitswapLedgerObj
+ Network.Ipfs.Api.Types: data BitswapStatObj
+ Network.Ipfs.Api.Types: data BitswapWLObj
+ Network.Ipfs.Api.Types: data BlockObj
+ Network.Ipfs.Api.Types: data BootstrapObj
+ Network.Ipfs.Api.Types: data CidBasesObj
+ Network.Ipfs.Api.Types: data CidCodecsObj
+ Network.Ipfs.Api.Types: data CidHashesObj
+ Network.Ipfs.Api.Types: data CidObj
+ Network.Ipfs.Api.Types: data ConfigObj
+ Network.Ipfs.Api.Types: data DagCidObj
+ Network.Ipfs.Api.Types: data DagPutObj
+ Network.Ipfs.Api.Types: data DagResolveObj
+ Network.Ipfs.Api.Types: data DiffObj
+ Network.Ipfs.Api.Types: data DirLink
+ Network.Ipfs.Api.Types: data DirObj
+ Network.Ipfs.Api.Types: data DnsObj
+ Network.Ipfs.Api.Types: data FilesEntryObj
+ Network.Ipfs.Api.Types: data FilesFlushObj
+ Network.Ipfs.Api.Types: data FilesLsObj
+ Network.Ipfs.Api.Types: data FilesStatObj
+ Network.Ipfs.Api.Types: data IdObj
+ Network.Ipfs.Api.Types: data IpfsJSON
+ Network.Ipfs.Api.Types: data IpfsText
+ Network.Ipfs.Api.Types: data KeyDetailsObj
+ Network.Ipfs.Api.Types: data KeyObj
+ Network.Ipfs.Api.Types: data KeyRenameObj
+ Network.Ipfs.Api.Types: data LogLevelObj
+ Network.Ipfs.Api.Types: data LogLsObj
+ Network.Ipfs.Api.Types: data LsObj
+ Network.Ipfs.Api.Types: data ObjectChangeObj
+ Network.Ipfs.Api.Types: data ObjectDiffObj
+ Network.Ipfs.Api.Types: data ObjectGetObj
+ Network.Ipfs.Api.Types: data ObjectLinkObj
+ Network.Ipfs.Api.Types: data ObjectLinksObj
+ Network.Ipfs.Api.Types: data ObjectObj
+ Network.Ipfs.Api.Types: data ObjectStatObj
+ Network.Ipfs.Api.Types: data PinObj
+ Network.Ipfs.Api.Types: data PubsubObj
+ Network.Ipfs.Api.Types: data RepoFsckObj
+ Network.Ipfs.Api.Types: data RepoVersionObj
+ Network.Ipfs.Api.Types: data StatsBwObj
+ Network.Ipfs.Api.Types: data StatsRepoObj
+ Network.Ipfs.Api.Types: data SwarmObj
+ Network.Ipfs.Api.Types: data SwarmPeerObj
+ Network.Ipfs.Api.Types: data SwarmPeersObj
+ Network.Ipfs.Api.Types: data SwarmStreamObj
+ Network.Ipfs.Api.Types: data VersionObj
+ Network.Ipfs.Api.Types: data WantlistObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.AddObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.BitswapLedgerObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.BitswapStatObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.BitswapWLObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.BlockObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.BootstrapObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.CidBasesObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.CidCodecsObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.CidHashesObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.CidObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ConfigObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DagCidObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DagPutObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DagResolveObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DiffObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DirLink
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DirObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.DnsObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.FilesEntryObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.FilesFlushObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.FilesLsObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.FilesStatObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.IdObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.KeyDetailsObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.KeyObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.KeyRenameObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.LogLevelObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.LogLsObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.LsObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectChangeObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectDiffObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectGetObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectLinkObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectLinksObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.ObjectStatObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.PinObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.PubsubObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.RepoFsckObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.RepoVersionObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.StatsBwObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.StatsRepoObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.SwarmObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.SwarmPeerObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.SwarmPeersObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.SwarmStreamObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.VersionObj
+ Network.Ipfs.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.WantlistObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.AddObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.BitswapLedgerObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.BitswapStatObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.BitswapWLObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.BlockObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.BootstrapObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.CidBasesObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.CidCodecsObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.CidHashesObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.CidObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ConfigObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DagCidObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DagPutObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DagResolveObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DiffObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DirLink
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DirObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.DnsObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.FilesEntryObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.FilesFlushObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.FilesLsObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.FilesStatObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.IdObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.KeyDetailsObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.KeyObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.KeyRenameObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.LogLevelObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.LogLsObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.LsObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectChangeObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectDiffObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectGetObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectLinkObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectLinksObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.ObjectStatObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.PinObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.PubsubObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.RepoFsckObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.RepoVersionObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.StatsBwObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.StatsRepoObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.SwarmObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.SwarmPeerObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.SwarmPeersObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.SwarmStreamObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.VersionObj
+ Network.Ipfs.Api.Types: instance GHC.Classes.Eq Network.Ipfs.Api.Types.WantlistObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.AddObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.BitswapLedgerObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.BitswapStatObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.BitswapWLObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.BlockObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.BootstrapObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.CidBasesObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.CidCodecsObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.CidHashesObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.CidObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ConfigObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DagCidObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DagPutObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DagResolveObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DiffObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DirLink
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DirObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.DnsObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.FilesEntryObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.FilesFlushObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.FilesLsObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.FilesStatObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.IdObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.KeyDetailsObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.KeyObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.KeyRenameObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.LogLevelObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.LogLsObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.LsObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectChangeObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectDiffObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectGetObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectLinkObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectLinksObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.ObjectStatObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.PinObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.PubsubObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.RepoFsckObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.RepoVersionObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.StatsBwObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.StatsRepoObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.SwarmObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.SwarmPeerObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.SwarmPeersObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.SwarmStreamObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.VersionObj
+ Network.Ipfs.Api.Types: instance GHC.Show.Show Network.Ipfs.Api.Types.WantlistObj
+ Network.Ipfs.Api.Types: instance Servant.API.ContentTypes.Accept Network.Ipfs.Api.Types.IpfsJSON
+ Network.Ipfs.Api.Types: instance Servant.API.ContentTypes.Accept Network.Ipfs.Api.Types.IpfsText
+ Network.Ipfs.Api.Types: instance Servant.API.ContentTypes.MimeUnrender Network.Ipfs.Api.Types.IpfsJSON Data.Text.Internal.Text
+ Network.Ipfs.Api.Types: instance Servant.API.ContentTypes.MimeUnrender Network.Ipfs.Api.Types.IpfsText Data.Text.Internal.Text
+ Network.Ipfs.Api.Types: type BlockReturnType = Text
+ Network.Ipfs.Api.Types: type CatReturnType = Text
+ Network.Ipfs.Api.Types: type DagReturnType = Text
+ Network.Ipfs.Api.Types: type FilesReadType = Text
+ Network.Ipfs.Api.Types: type GetReturnType = Text
+ Network.Ipfs.Api.Types: type IpfsApi = "cat" :> Capture "arg" Text :> Get '[IpfsText] CatReturnType :<|> "ls" :> Capture "arg" Text :> Get '[JSON] LsObj :<|> "get" :> Capture "arg" Text :> Get '[IpfsText] GetReturnType :<|> "swarm" :> "peers" :> Get '[JSON] SwarmPeersObj :<|> "swarm" :> "connect" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj :<|> "swarm" :> "disconnect" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj :<|> "swarm" :> "filters" :> Get '[JSON] SwarmObj :<|> "swarm" :> "filters" :> "add" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj :<|> "swarm" :> "filters" :> "rm" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj :<|> "bitswap" :> "stat" :> Get '[JSON] BitswapStatObj :<|> "bitswap" :> "wantlist" :> Get '[JSON] BitswapWLObj :<|> "bitswap" :> "ledger" :> Capture "peerId" Text :> Get '[JSON] BitswapLedgerObj :<|> "bitswap" :> "reprovide" :> Get '[IpfsText] ReprovideReturnType :<|> "cid" :> "bases" :> Get '[JSON] [CidBasesObj] :<|> "cid" :> "codecs" :> Get '[JSON] [CidCodecsObj] :<|> "cid" :> "hashes" :> Get '[JSON] [CidHashesObj] :<|> "cid" :> "base32" :> Capture "cid" Text :> Get '[JSON] CidObj :<|> "cid" :> "format" :> Capture "cid" Text :> Get '[JSON] CidObj :<|> "block" :> "get" :> Capture "key" Text :> Get '[IpfsText] BlockReturnType :<|> "block" :> "stat" :> Capture "key" Text :> Get '[JSON] BlockObj :<|> "dag" :> "get" :> Capture "ref" Text :> Get '[IpfsJSON] DagReturnType :<|> "dag" :> "resolve" :> Capture "ref" Text :> Get '[JSON] DagResolveObj :<|> "config" :> Capture "ref" Text :> Get '[JSON] ConfigObj :<|> "config" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ConfigObj :<|> "object" :> "data" :> Capture "ref" Text :> Get '[IpfsText] ObjectReturnType :<|> "object" :> "new" :> Get '[JSON] ObjectObj :<|> "object" :> "links" :> Capture "ref" Text :> Get '[JSON] ObjectLinksObj :<|> "object" :> "patch" :> "add-link" :> Capture "arg" Text :> QueryParam "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ObjectLinksObj :<|> "object" :> "patch" :> "rm-link" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ObjectLinksObj :<|> "object" :> "get" :> Capture "arg" Text :> Get '[JSON] ObjectGetObj :<|> "object" :> "diff" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ObjectDiffObj :<|> "object" :> "stat" :> Capture "arg" Text :> Get '[JSON] ObjectStatObj :<|> "pin" :> "add" :> Capture "arg" Text :> Get '[JSON] PinObj :<|> "pin" :> "rm" :> Capture "arg" Text :> Get '[JSON] PinObj :<|> "bootstrap" :> "add" :> QueryParam "arg" Text :> Get '[JSON] BootstrapObj :<|> "bootstrap" :> "list" :> Get '[JSON] BootstrapObj :<|> "bootstrap" :> "rm" :> QueryParam "arg" Text :> Get '[JSON] BootstrapObj :<|> "stats" :> "bw" :> Get '[JSON] StatsBwObj :<|> "stats" :> "repo" :> Get '[JSON] StatsRepoObj :<|> "version" :> Get '[JSON] VersionObj :<|> "id" :> Get '[JSON] IdObj :<|> "id" :> Capture "arg" Text :> Get '[JSON] IdObj :<|> "dns" :> Capture "arg" Text :> Get '[JSON] DnsObj :<|> "pubsub" :> "ls" :> Get '[JSON] PubsubObj :<|> "pubsub" :> "peers" :> Get '[JSON] PubsubObj :<|> "pubsub" :> "pub" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] NoContent :<|> "log" :> "ls" :> Get '[JSON] LogLsObj :<|> "log" :> "level" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] LogLevelObj :<|> "repo" :> "version" :> Get '[JSON] RepoVersionObj :<|> "repo" :> "fsck" :> Get '[JSON] RepoFsckObj :<|> "key" :> "gen" :> Capture "arg" Text :> QueryParam "type" Text :> Get '[JSON] KeyDetailsObj :<|> "key" :> "list" :> Get '[JSON] KeyObj :<|> "key" :> "rename" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] KeyRenameObj :<|> "key" :> "rm" :> Capture "arg" Text :> Get '[JSON] KeyObj :<|> "files" :> "chcid" :> QueryParam "arg" Text :> QueryParam "cid-version" Int :> Get '[JSON] NoContent :<|> "files" :> "cp" :> QueryParam "arg" Text :> QueryParam "arg" Text :> Get '[JSON] NoContent :<|> "files" :> "flush" :> QueryParam "arg" Text :> Get '[JSON] FilesFlushObj :<|> "files" :> "ls" :> QueryParam "arg" Text :> Get '[JSON] FilesLsObj :<|> "files" :> "mkdir" :> QueryParam "arg" Text :> Get '[JSON] NoContent :<|> "files" :> "mv" :> QueryParam "arg" Text :> QueryParam "arg" Text :> Get '[JSON] NoContent :<|> "files" :> "read" :> QueryParam "arg" Text :> Get '[IpfsText] FilesReadType :<|> "files" :> "rm" :> QueryParam "arg" Text :> QueryParam "recursive" Bool :> Get '[JSON] NoContent :<|> "files" :> "stat" :> QueryParam "arg" Text :> Get '[JSON] FilesStatObj :<|> "shutdown" :> Get '[JSON] NoContent
+ Network.Ipfs.Api.Types: type ObjectReturnType = Text
+ Network.Ipfs.Api.Types: type ReprovideReturnType = Text
+ Network.Ipfs.Api.Types.Stream: DhtObj :: Text -> Text -> Maybe [ResponseObj] -> Int -> DhtObj
+ Network.Ipfs.Api.Types.Stream: PingObj :: Bool -> Text -> Int64 -> PingObj
+ Network.Ipfs.Api.Types.Stream: PubsubSubObj :: Text -> Text -> Text -> [Text] -> PubsubSubObj
+ Network.Ipfs.Api.Types.Stream: RefsObj :: Text -> Text -> RefsObj
+ Network.Ipfs.Api.Types.Stream: RepoGcObj :: RepoKeyObj -> RepoGcObj
+ Network.Ipfs.Api.Types.Stream: RepoKeyObj :: Text -> RepoKeyObj
+ Network.Ipfs.Api.Types.Stream: RepoVerifyObj :: Text -> Int -> RepoVerifyObj
+ Network.Ipfs.Api.Types.Stream: ResponseObj :: Maybe [Text] -> Text -> ResponseObj
+ Network.Ipfs.Api.Types.Stream: [addrType] :: DhtObj -> Int
+ Network.Ipfs.Api.Types.Stream: [addrid] :: DhtObj -> Text
+ Network.Ipfs.Api.Types.Stream: [addrs] :: ResponseObj -> Maybe [Text]
+ Network.Ipfs.Api.Types.Stream: [error] :: RefsObj -> Text
+ Network.Ipfs.Api.Types.Stream: [extra] :: DhtObj -> Text
+ Network.Ipfs.Api.Types.Stream: [from] :: PubsubSubObj -> Text
+ Network.Ipfs.Api.Types.Stream: [id] :: ResponseObj -> Text
+ Network.Ipfs.Api.Types.Stream: [msg] :: RepoVerifyObj -> Text
+ Network.Ipfs.Api.Types.Stream: [mssgdata] :: PubsubSubObj -> Text
+ Network.Ipfs.Api.Types.Stream: [progress] :: RepoVerifyObj -> Int
+ Network.Ipfs.Api.Types.Stream: [ref] :: RefsObj -> Text
+ Network.Ipfs.Api.Types.Stream: [repoKey] :: RepoGcObj -> RepoKeyObj
+ Network.Ipfs.Api.Types.Stream: [repoSlash] :: RepoKeyObj -> Text
+ Network.Ipfs.Api.Types.Stream: [responses] :: DhtObj -> Maybe [ResponseObj]
+ Network.Ipfs.Api.Types.Stream: [seqno] :: PubsubSubObj -> Text
+ Network.Ipfs.Api.Types.Stream: [success] :: PingObj -> Bool
+ Network.Ipfs.Api.Types.Stream: [text] :: PingObj -> Text
+ Network.Ipfs.Api.Types.Stream: [time] :: PingObj -> Int64
+ Network.Ipfs.Api.Types.Stream: [topicIDs] :: PubsubSubObj -> [Text]
+ Network.Ipfs.Api.Types.Stream: data DhtObj
+ Network.Ipfs.Api.Types.Stream: data PingObj
+ Network.Ipfs.Api.Types.Stream: data PubsubSubObj
+ Network.Ipfs.Api.Types.Stream: data RefsObj
+ Network.Ipfs.Api.Types.Stream: data RepoGcObj
+ Network.Ipfs.Api.Types.Stream: data RepoKeyObj
+ Network.Ipfs.Api.Types.Stream: data RepoVerifyObj
+ Network.Ipfs.Api.Types.Stream: data ResponseObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.DhtObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.PingObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.PubsubSubObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.RefsObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.RepoGcObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.RepoKeyObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.RepoVerifyObj
+ Network.Ipfs.Api.Types.Stream: instance Data.Aeson.Types.FromJSON.FromJSON Network.Ipfs.Api.Types.Stream.ResponseObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.DhtObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.PingObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.PubsubSubObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.RefsObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.RepoGcObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.RepoKeyObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.RepoVerifyObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Classes.Eq Network.Ipfs.Api.Types.Stream.ResponseObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.DhtObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.PingObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.PubsubSubObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.RefsObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.RepoGcObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.RepoKeyObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.RepoVerifyObj
+ Network.Ipfs.Api.Types.Stream: instance GHC.Show.Show Network.Ipfs.Api.Types.Stream.ResponseObj
+ Network.Ipfs.Api.Types.Stream: type IpfsStreamApi = "ping" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO PingObj) :<|> "dht" :> "findpeer" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO DhtObj) :<|> "dht" :> "findprovs" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO DhtObj) :<|> "dht" :> "get" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO DhtObj) :<|> "dht" :> "provide" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO DhtObj) :<|> "dht" :> "query" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO DhtObj) :<|> "log" :> "tail" :> StreamGet NewlineFraming IpfsText (SourceIO LogReturnType) :<|> "repo" :> "gc" :> StreamGet NewlineFraming JSON (SourceIO RepoGcObj) :<|> "repo" :> "verify" :> StreamGet NewlineFraming JSON (SourceIO RepoVerifyObj) :<|> "refs" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO RefsObj) :<|> "refs" :> "local" :> StreamGet NewlineFraming JSON (SourceIO RefsObj) :<|> "pubsub" :> "sub" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO PubsubSubObj)
+ Network.Ipfs.Api.Types.Stream: type LogReturnType = Text
+ Network.Ipfs.Client: IpfsT :: ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a -> IpfsT m a
+ Network.Ipfs.Client: [unIpfs] :: IpfsT m a -> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
+ Network.Ipfs.Client: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Network.Ipfs.Client.IpfsT m)
+ Network.Ipfs.Client: instance Control.Monad.Trans.Class.MonadTrans Network.Ipfs.Client.IpfsT
+ Network.Ipfs.Client: instance GHC.Base.Functor m => GHC.Base.Functor (Network.Ipfs.Client.IpfsT m)
+ Network.Ipfs.Client: instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError Servant.Client.Core.ClientError.ClientError (Network.Ipfs.Client.IpfsT m)
+ Network.Ipfs.Client: instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Network.HTTP.Client.Types.Manager, Servant.Client.Core.BaseUrl.BaseUrl, GHC.Base.String) (Network.Ipfs.Client.IpfsT m)
+ Network.Ipfs.Client: instance GHC.Base.Monad m => GHC.Base.Applicative (Network.Ipfs.Client.IpfsT m)
+ Network.Ipfs.Client: instance GHC.Base.Monad m => GHC.Base.Monad (Network.Ipfs.Client.IpfsT m)
+ Network.Ipfs.Client: newtype IpfsT m a
+ Network.Ipfs.Client: runIpfs :: Ipfs a -> IO ()
+ Network.Ipfs.Client: runIpfs' :: BaseUrl -> Ipfs a -> IO ()
+ Network.Ipfs.Client: type Ipfs a = IpfsT IO a
+ Network.JsonRpc.TinyClient: JsonRpcHttpClient :: Manager -> String -> JsonRpcClient
+ Network.JsonRpc.TinyClient: JsonRpcWsClient :: Connection -> JsonRpcClient
+ Network.JsonRpc.TinyClient: [jsonRpcManager] :: JsonRpcClient -> Manager
+ Network.JsonRpc.TinyClient: [jsonRpcServer] :: JsonRpcClient -> String
+ Network.JsonRpc.TinyClient: [jsonRpcWsConnection] :: JsonRpcClient -> Connection
+ Network.Polkadot.Api.Account: nextIndex :: JsonRpc m => Text -> m Int
+ Network.Polkadot.Api.Author: hasKey :: JsonRpc m => HexString -> Text -> m Bool
+ Network.Polkadot.Api.Author: hasSessionKeys :: JsonRpc m => HexString -> m Bool
+ Network.Polkadot.Api.Author: insertKey :: JsonRpc m => Text -> Text -> HexString -> m HexString
+ Network.Polkadot.Api.Author: pendingExtrinsics :: JsonRpc m => m [HexString]
+ Network.Polkadot.Api.Author: removeExtrinsic :: JsonRpc m => [HexString] -> m HexString
+ Network.Polkadot.Api.Author: rotateKeys :: JsonRpc m => m HexString
+ Network.Polkadot.Api.Author: submitExtrinsic :: JsonRpc m => HexString -> m HexString
+ Network.Polkadot.Api.Babe: epochAuthorship :: JsonRpc m => m Object
+ Network.Polkadot.Api.Chain: getBlock :: JsonRpc m => Maybe HexString -> m (Maybe SignedBlock)
+ Network.Polkadot.Api.Chain: getBlockHash :: JsonRpc m => Maybe Int -> m (Maybe HexString)
+ Network.Polkadot.Api.Chain: getFinalizedHead :: JsonRpc m => m HexString
+ Network.Polkadot.Api.Chain: getHeader :: JsonRpc m => Maybe HexString -> m (Maybe Header)
+ Network.Polkadot.Api.Childstate: getKeys :: JsonRpc m => HexString -> HexString -> Maybe HexString -> m [HexString]
+ Network.Polkadot.Api.Childstate: getStorage :: JsonRpc m => HexString -> HexString -> Maybe HexString -> m (Maybe HexString)
+ Network.Polkadot.Api.Childstate: getStorageHash :: JsonRpc m => HexString -> HexString -> Maybe HexString -> m (Maybe HexString)
+ Network.Polkadot.Api.Childstate: getStorageSize :: JsonRpc m => HexString -> HexString -> Maybe HexString -> m (Maybe Int)
+ Network.Polkadot.Api.Contracts: call :: JsonRpc m => ContractCall -> Maybe HexString -> m ContractExecResult
+ Network.Polkadot.Api.Contracts: getStorage :: JsonRpc m => Text -> HexString -> Maybe HexString -> m (Maybe HexString)
+ Network.Polkadot.Api.Contracts: rentProjection :: JsonRpc m => Text -> Maybe HexString -> m (Maybe Int)
+ Network.Polkadot.Api.Engine: createBlock :: JsonRpc m => Bool -> Bool -> Maybe HexString -> m CreatedBlock
+ Network.Polkadot.Api.Engine: finalizeBlock :: JsonRpc m => HexString -> Maybe HexString -> m Bool
+ Network.Polkadot.Api.Grandpa: roundState :: JsonRpc m => m Object
+ Network.Polkadot.Api.Offchain: localStorageGet :: JsonRpc m => StorageKind -> HexString -> m (Maybe HexString)
+ Network.Polkadot.Api.Offchain: localStorageSet :: JsonRpc m => StorageKind -> HexString -> HexString -> m ()
+ Network.Polkadot.Api.Payment: queryInfo :: JsonRpc m => HexString -> Maybe HexString -> m RuntimeDispatchInfo
+ Network.Polkadot.Api.Rpc: methods :: JsonRpc m => m Value
+ Network.Polkadot.Api.State: call :: JsonRpc m => Text -> HexString -> Maybe HexString -> m HexString
+ Network.Polkadot.Api.State: getChildKeys :: JsonRpc m => HexString -> HexString -> Int -> HexString -> Maybe HexString -> m [HexString]
+ Network.Polkadot.Api.State: getChildStorage :: JsonRpc m => HexString -> HexString -> Int -> HexString -> Maybe HexString -> m HexString
+ Network.Polkadot.Api.State: getChildStorageHash :: JsonRpc m => HexString -> HexString -> Int -> HexString -> Maybe HexString -> m HexString
+ Network.Polkadot.Api.State: getChildStorageSize :: JsonRpc m => HexString -> HexString -> Int -> HexString -> Maybe HexString -> m Int
+ Network.Polkadot.Api.State: getKeys :: JsonRpc m => HexString -> Maybe HexString -> m [HexString]
+ Network.Polkadot.Api.State: getMetadata :: JsonRpc m => m Metadata
+ Network.Polkadot.Api.State: getReadProof :: JsonRpc m => [HexString] -> Maybe HexString -> m ReadProof
+ Network.Polkadot.Api.State: getRuntimeVersion :: JsonRpc m => Maybe HexString -> m RuntimeVersion
+ Network.Polkadot.Api.State: getStorage :: JsonRpc m => HexString -> Maybe HexString -> m HexString
+ Network.Polkadot.Api.State: getStorageHash :: JsonRpc m => HexString -> Maybe HexString -> m HexString
+ Network.Polkadot.Api.State: getStorageSize :: JsonRpc m => HexString -> Maybe HexString -> m Int
+ Network.Polkadot.Api.State: queryStorage :: JsonRpc m => [HexString] -> HexString -> Maybe HexString -> m [StorageChangeSet]
+ Network.Polkadot.Api.State: queryStorageAt :: JsonRpc m => [HexString] -> Maybe HexString -> m [StorageChangeSet]
+ Network.Polkadot.Api.System: addReservedPeer :: JsonRpc m => Text -> m Text
+ Network.Polkadot.Api.System: chain :: JsonRpc m => m Text
+ Network.Polkadot.Api.System: chainType :: JsonRpc m => m ChainType
+ Network.Polkadot.Api.System: health :: JsonRpc m => m Health
+ Network.Polkadot.Api.System: localListenAddresses :: JsonRpc m => m [Text]
+ Network.Polkadot.Api.System: localPeerId :: JsonRpc m => m Text
+ Network.Polkadot.Api.System: name :: JsonRpc m => m Text
+ Network.Polkadot.Api.System: networkState :: JsonRpc m => m Object
+ Network.Polkadot.Api.System: nodeRoles :: JsonRpc m => m [NodeRole]
+ Network.Polkadot.Api.System: peers :: JsonRpc m => m [PeerInfo]
+ Network.Polkadot.Api.System: properties :: JsonRpc m => m Object
+ Network.Polkadot.Api.System: removeReservedPeer :: JsonRpc m => Text -> m Text
+ Network.Polkadot.Api.System: version :: JsonRpc m => m Text
+ Network.Polkadot.Api.Types: Authority :: NodeRole
+ Network.Polkadot.Api.Types: Block :: Header -> [HexString] -> Block
+ Network.Polkadot.Api.Types: ContractCall :: HexString -> HexString -> Integer -> Integer -> HexString -> ContractCall
+ Network.Polkadot.Api.Types: CreatedBlock :: HexString -> ImportedAux -> CreatedBlock
+ Network.Polkadot.Api.Types: Custom :: Text -> ChainType
+ Network.Polkadot.Api.Types: Development :: ChainType
+ Network.Polkadot.Api.Types: ExecResultError :: ContractExecResult
+ Network.Polkadot.Api.Types: Full :: NodeRole
+ Network.Polkadot.Api.Types: Header :: HexString -> Int -> HexString -> HexString -> HexString -> Header
+ Network.Polkadot.Api.Types: Health :: Int -> Bool -> Bool -> Health
+ Network.Polkadot.Api.Types: ImportedAux :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> ImportedAux
+ Network.Polkadot.Api.Types: LightClient :: NodeRole
+ Network.Polkadot.Api.Types: Live :: ChainType
+ Network.Polkadot.Api.Types: Local :: ChainType
+ Network.Polkadot.Api.Types: Mandatory :: DispatchClass
+ Network.Polkadot.Api.Types: Normal :: DispatchClass
+ Network.Polkadot.Api.Types: Operational :: DispatchClass
+ Network.Polkadot.Api.Types: PeerInfo :: Text -> [NodeRole] -> Int -> Text -> Int -> PeerInfo
+ Network.Polkadot.Api.Types: ReadProof :: HexString -> [HexString] -> ReadProof
+ Network.Polkadot.Api.Types: RuntimeDispatchInfo :: Weight -> DispatchClass -> Integer -> RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: RuntimeVersion :: Text -> Text -> Word32 -> Word32 -> Word32 -> [(HexString, Word32)] -> Word32 -> RuntimeVersion
+ Network.Polkadot.Api.Types: Sentry :: NodeRole
+ Network.Polkadot.Api.Types: SignedBlock :: Block -> Maybe HexString -> SignedBlock
+ Network.Polkadot.Api.Types: StorageChangeSet :: HexString -> [(HexString, Maybe HexString)] -> StorageChangeSet
+ Network.Polkadot.Api.Types: SuccessExec :: Word8 -> Maybe HexString -> ContractExecResult
+ Network.Polkadot.Api.Types: [auxBadJustification] :: ImportedAux -> Bool
+ Network.Polkadot.Api.Types: [auxClearJustificationRequests] :: ImportedAux -> Bool
+ Network.Polkadot.Api.Types: [auxHeaderOnly] :: ImportedAux -> Bool
+ Network.Polkadot.Api.Types: [auxIsNewBest] :: ImportedAux -> Bool
+ Network.Polkadot.Api.Types: [auxNeedsFinalityProof] :: ImportedAux -> Bool
+ Network.Polkadot.Api.Types: [auxNeedsJustification] :: ImportedAux -> Bool
+ Network.Polkadot.Api.Types: [blockExtrinsics] :: Block -> [HexString]
+ Network.Polkadot.Api.Types: [blockHeader] :: Block -> Header
+ Network.Polkadot.Api.Types: [callDest] :: ContractCall -> HexString
+ Network.Polkadot.Api.Types: [callGasLimit] :: ContractCall -> Integer
+ Network.Polkadot.Api.Types: [callInputData] :: ContractCall -> HexString
+ Network.Polkadot.Api.Types: [callOrigin] :: ContractCall -> HexString
+ Network.Polkadot.Api.Types: [callValue] :: ContractCall -> Integer
+ Network.Polkadot.Api.Types: [createdBlockAux] :: CreatedBlock -> ImportedAux
+ Network.Polkadot.Api.Types: [createdBlockHash] :: CreatedBlock -> HexString
+ Network.Polkadot.Api.Types: [dispatchClass] :: RuntimeDispatchInfo -> DispatchClass
+ Network.Polkadot.Api.Types: [dispatchPartialFee] :: RuntimeDispatchInfo -> Integer
+ Network.Polkadot.Api.Types: [dispatchWeight] :: RuntimeDispatchInfo -> Weight
+ Network.Polkadot.Api.Types: [execData] :: ContractExecResult -> Maybe HexString
+ Network.Polkadot.Api.Types: [execStatus] :: ContractExecResult -> Word8
+ Network.Polkadot.Api.Types: [headerDigest] :: Header -> HexString
+ Network.Polkadot.Api.Types: [headerExtrinsicsRoot] :: Header -> HexString
+ Network.Polkadot.Api.Types: [headerNumber] :: Header -> Int
+ Network.Polkadot.Api.Types: [headerParentHash] :: Header -> HexString
+ Network.Polkadot.Api.Types: [headerStateRoot] :: Header -> HexString
+ Network.Polkadot.Api.Types: [healthIsSyncing] :: Health -> Bool
+ Network.Polkadot.Api.Types: [healthPeers] :: Health -> Int
+ Network.Polkadot.Api.Types: [healthShouldHavePeers] :: Health -> Bool
+ Network.Polkadot.Api.Types: [peerInfoBestHash] :: PeerInfo -> Text
+ Network.Polkadot.Api.Types: [peerInfoBestNumber] :: PeerInfo -> Int
+ Network.Polkadot.Api.Types: [peerInfoPeerId] :: PeerInfo -> Text
+ Network.Polkadot.Api.Types: [peerInfoProtocolVersion] :: PeerInfo -> Int
+ Network.Polkadot.Api.Types: [peerInfoRoles] :: PeerInfo -> [NodeRole]
+ Network.Polkadot.Api.Types: [readProofAt] :: ReadProof -> HexString
+ Network.Polkadot.Api.Types: [readProofProof] :: ReadProof -> [HexString]
+ Network.Polkadot.Api.Types: [runtimeApis] :: RuntimeVersion -> [(HexString, Word32)]
+ Network.Polkadot.Api.Types: [runtimeAuthoringVersion] :: RuntimeVersion -> Word32
+ Network.Polkadot.Api.Types: [runtimeImplName] :: RuntimeVersion -> Text
+ Network.Polkadot.Api.Types: [runtimeImplVersion] :: RuntimeVersion -> Word32
+ Network.Polkadot.Api.Types: [runtimeSpecName] :: RuntimeVersion -> Text
+ Network.Polkadot.Api.Types: [runtimeSpecVersion] :: RuntimeVersion -> Word32
+ Network.Polkadot.Api.Types: [runtimeTransactionVersion] :: RuntimeVersion -> Word32
+ Network.Polkadot.Api.Types: [signedBlock] :: SignedBlock -> Block
+ Network.Polkadot.Api.Types: [signedJustification] :: SignedBlock -> Maybe HexString
+ Network.Polkadot.Api.Types: [storageBlock] :: StorageChangeSet -> HexString
+ Network.Polkadot.Api.Types: [storageChanges] :: StorageChangeSet -> [(HexString, Maybe HexString)]
+ Network.Polkadot.Api.Types: data Block
+ Network.Polkadot.Api.Types: data ChainType
+ Network.Polkadot.Api.Types: data ContractCall
+ Network.Polkadot.Api.Types: data ContractExecResult
+ Network.Polkadot.Api.Types: data CreatedBlock
+ Network.Polkadot.Api.Types: data DispatchClass
+ Network.Polkadot.Api.Types: data Header
+ Network.Polkadot.Api.Types: data Health
+ Network.Polkadot.Api.Types: data ImportedAux
+ Network.Polkadot.Api.Types: data NodeRole
+ Network.Polkadot.Api.Types: data PeerInfo
+ Network.Polkadot.Api.Types: data ReadProof
+ Network.Polkadot.Api.Types: data RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: data RuntimeVersion
+ Network.Polkadot.Api.Types: data SignedBlock
+ Network.Polkadot.Api.Types: data StorageChangeSet
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.Block
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.ChainType
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.ContractCall
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.ContractExecResult
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.CreatedBlock
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.DispatchClass
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.Header
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.Health
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.ImportedAux
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.NodeRole
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.PeerInfo
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.ReadProof
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.RuntimeVersion
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.SignedBlock
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.FromJSON.FromJSON Network.Polkadot.Api.Types.StorageChangeSet
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.Block
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.ChainType
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.ContractCall
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.ContractExecResult
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.CreatedBlock
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.DispatchClass
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.Header
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.Health
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.ImportedAux
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.NodeRole
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.PeerInfo
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.ReadProof
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.RuntimeVersion
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.SignedBlock
+ Network.Polkadot.Api.Types: instance Data.Aeson.Types.ToJSON.ToJSON Network.Polkadot.Api.Types.StorageChangeSet
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.Block
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.ChainType
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.ContractCall
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.ContractExecResult
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.CreatedBlock
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.DispatchClass
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.Header
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.Health
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.ImportedAux
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.NodeRole
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.PeerInfo
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.ReadProof
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.RuntimeVersion
+ Network.Polkadot.Api.Types: instance GHC.Classes.Eq Network.Polkadot.Api.Types.SignedBlock
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.Block
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.ChainType
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.ContractCall
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.ContractExecResult
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.CreatedBlock
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.DispatchClass
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.Header
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.Health
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.ImportedAux
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.NodeRole
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.PeerInfo
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.ReadProof
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.RuntimeVersion
+ Network.Polkadot.Api.Types: instance GHC.Generics.Generic Network.Polkadot.Api.Types.SignedBlock
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.Block
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.ChainType
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.ContractCall
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.ContractExecResult
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.CreatedBlock
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.DispatchClass
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.Header
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.Health
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.ImportedAux
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.NodeRole
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.PeerInfo
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.ReadProof
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.RuntimeDispatchInfo
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.RuntimeVersion
+ Network.Polkadot.Api.Types: instance GHC.Show.Show Network.Polkadot.Api.Types.SignedBlock
+ Network.Polkadot.Api.Types: type Metadata = Value
+ Network.Polkadot.Api.Types: type StorageKind = Word8
+ Network.Polkadot.Api.Types: type Weight = Word64
+ Network.Web3: data Web3 a
+ Network.Web3: runWeb3 :: MonadIO m => Web3 a -> m (Either Web3Error a)
+ Network.Web3.Provider: HttpProvider :: String -> Provider
+ Network.Web3.Provider: JsonRpcFail :: !String -> Web3Error
+ Network.Web3.Provider: ParserFail :: !String -> Web3Error
+ Network.Web3.Provider: UserFail :: !String -> Web3Error
+ Network.Web3.Provider: Web3 :: StateT JsonRpcClient IO a -> Web3 a
+ Network.Web3.Provider: WsProvider :: String -> Int -> Provider
+ Network.Web3.Provider: [unWeb3] :: Web3 a -> StateT JsonRpcClient IO a
+ Network.Web3.Provider: data Provider
+ Network.Web3.Provider: data Web3Error
+ Network.Web3.Provider: forkWeb3 :: Web3 a -> Web3 (Async a)
+ Network.Web3.Provider: getConnection :: String -> Int -> String -> IO Connection
+ Network.Web3.Provider: instance Control.Monad.Catch.MonadThrow Network.Web3.Provider.Web3
+ Network.Web3.Provider: instance Control.Monad.IO.Class.MonadIO Network.Web3.Provider.Web3
+ Network.Web3.Provider: instance Control.Monad.State.Class.MonadState Network.JsonRpc.TinyClient.JsonRpcClient Network.Web3.Provider.Web3
+ Network.Web3.Provider: instance Data.Default.Class.Default Network.Web3.Provider.Provider
+ Network.Web3.Provider: instance GHC.Base.Applicative Network.Web3.Provider.Web3
+ Network.Web3.Provider: instance GHC.Base.Functor Network.Web3.Provider.Web3
+ Network.Web3.Provider: instance GHC.Base.Monad Network.Web3.Provider.Web3
+ Network.Web3.Provider: instance GHC.Classes.Eq Network.Web3.Provider.Provider
+ Network.Web3.Provider: instance GHC.Classes.Eq Network.Web3.Provider.Web3Error
+ Network.Web3.Provider: instance GHC.Exception.Type.Exception Network.Web3.Provider.Web3Error
+ Network.Web3.Provider: instance GHC.Generics.Generic Network.Web3.Provider.Provider
+ Network.Web3.Provider: instance GHC.Generics.Generic Network.Web3.Provider.Web3Error
+ Network.Web3.Provider: instance GHC.Show.Show Network.Web3.Provider.Provider
+ Network.Web3.Provider: instance GHC.Show.Show Network.Web3.Provider.Web3Error
+ Network.Web3.Provider: instance Network.JsonRpc.TinyClient.JsonRpc Network.Web3.Provider.Web3
+ Network.Web3.Provider: newtype Web3 a
+ Network.Web3.Provider: runWeb3 :: MonadIO m => Web3 a -> m (Either Web3Error a)
+ Network.Web3.Provider: runWeb3' :: MonadIO m => Provider -> Web3 a -> m (Either Web3Error a)
+ Network.Web3.Provider: runWeb3With :: MonadIO m => Manager -> Provider -> Web3 a -> m (Either Web3Error a)
- Network.Ethereum.Contract.Event.Common: mkBlockNumber :: DefaultBlock -> Web3 Quantity
+ Network.Ethereum.Contract.Event.Common: mkBlockNumber :: JsonRpc m => DefaultBlock -> m Quantity
- Network.Ethereum.Contract.Event.Common: pollTillBlockProgress :: Quantity -> Web3 Quantity
+ Network.Ethereum.Contract.Event.Common: pollTillBlockProgress :: JsonRpc m => Quantity -> m Quantity
- Network.Ethereum.Contract.Event.MultiFilter: multiEvent :: (PollFilters es, QueryAllLogs es, MapHandlers Web3 es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es)) => MultiFilter es -> Handlers es (ReaderT Change Web3 EventAction) -> Web3 (Async ())
+ Network.Ethereum.Contract.Event.MultiFilter: multiEvent :: (PollFilters es, QueryAllLogs es, MapHandlers m es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es), JsonRpc m) => MultiFilter es -> Handlers es (ReaderT Change m EventAction) -> m ()
- Network.Ethereum.Contract.Event.MultiFilter: multiEventNoFilter :: (QueryAllLogs es, MapHandlers Web3 es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es)) => MultiFilter es -> Handlers es (ReaderT Change Web3 EventAction) -> Web3 (Async ())
+ Network.Ethereum.Contract.Event.MultiFilter: multiEventNoFilter :: (QueryAllLogs es, MapHandlers m es (WithChange es), RPureConstrained HasLogIndex (WithChange es), RecApplicative (WithChange es), JsonRpc m) => MultiFilter es -> Handlers es (ReaderT Change m EventAction) -> m ()
- Network.Ethereum.Contract.Event.SingleFilter: event :: DecodeEvent i ni e => Filter e -> (e -> ReaderT Change Web3 EventAction) -> Web3 (Async ())
+ Network.Ethereum.Contract.Event.SingleFilter: event :: (DecodeEvent i ni e, JsonRpc m) => Filter e -> (e -> ReaderT Change m EventAction) -> m ()
- Network.Ethereum.Contract.Event.SingleFilter: eventNoFilter :: DecodeEvent i ni e => Filter e -> (e -> ReaderT Change Web3 EventAction) -> Web3 (Async ())
+ Network.Ethereum.Contract.Event.SingleFilter: eventNoFilter :: (DecodeEvent i ni e, JsonRpc m) => Filter e -> (e -> ReaderT Change m EventAction) -> m ()
- Network.Ethereum.Ens.PublicResolver: aBI :: (JsonRpc m_a1Rij, Account a_a1Rih t_a1Rii, Functor (t_a1Rii m_a1Rij)) => BytesN 32 -> UIntN 256 -> t_a1Rii m_a1Rij (UIntN 256, Bytes)
+ Network.Ethereum.Ens.PublicResolver: aBI :: (JsonRpc m_a1YcK, Account a_a1YcI t_a1YcJ, Functor (t_a1YcJ m_a1YcK)) => BytesN 32 -> UIntN 256 -> t_a1YcJ m_a1YcK (UIntN 256, Bytes)
- Network.Ethereum.Ens.PublicResolver: addr :: (JsonRpc m_a1Rin, Account a_a1Ril t_a1Rim, Functor (t_a1Rim m_a1Rin)) => BytesN 32 -> t_a1Rim m_a1Rin Address
+ Network.Ethereum.Ens.PublicResolver: addr :: (JsonRpc m_a1YcO, Account a_a1YcM t_a1YcN, Functor (t_a1YcN m_a1YcO)) => BytesN 32 -> t_a1YcN m_a1YcO Address
- Network.Ethereum.Ens.PublicResolver: content :: (JsonRpc m_a1Rir, Account a_a1Rip t_a1Riq, Functor (t_a1Riq m_a1Rir)) => BytesN 32 -> t_a1Riq m_a1Rir (BytesN 32)
+ Network.Ethereum.Ens.PublicResolver: content :: (JsonRpc m_a1YcS, Account a_a1YcQ t_a1YcR, Functor (t_a1YcR m_a1YcS)) => BytesN 32 -> t_a1YcR m_a1YcS (BytesN 32)
- Network.Ethereum.Ens.PublicResolver: name :: (JsonRpc m_a1Riv, Account a_a1Rit t_a1Riu, Functor (t_a1Riu m_a1Riv)) => BytesN 32 -> t_a1Riu m_a1Riv Text
+ Network.Ethereum.Ens.PublicResolver: name :: (JsonRpc m_a1YcW, Account a_a1YcU t_a1YcV, Functor (t_a1YcV m_a1YcW)) => BytesN 32 -> t_a1YcV m_a1YcW Text
- Network.Ethereum.Ens.PublicResolver: pubkey :: (JsonRpc m_a1Riz, Account a_a1Rix t_a1Riy, Functor (t_a1Riy m_a1Riz)) => BytesN 32 -> t_a1Riy m_a1Riz (BytesN 32, BytesN 32)
+ Network.Ethereum.Ens.PublicResolver: pubkey :: (JsonRpc m_a1Yd0, Account a_a1YcY t_a1YcZ, Functor (t_a1YcZ m_a1Yd0)) => BytesN 32 -> t_a1YcZ m_a1Yd0 (BytesN 32, BytesN 32)
- Network.Ethereum.Ens.PublicResolver: setABI :: (JsonRpc m_a1RiF, Account a_a1RiD t_a1RiE, Functor (t_a1RiE m_a1RiF)) => BytesN 32 -> UIntN 256 -> Bytes -> t_a1RiE m_a1RiF TxReceipt
+ Network.Ethereum.Ens.PublicResolver: setABI :: (JsonRpc m_a1Yd6, Account a_a1Yd4 t_a1Yd5, Functor (t_a1Yd5 m_a1Yd6)) => BytesN 32 -> UIntN 256 -> Bytes -> t_a1Yd5 m_a1Yd6 TxReceipt
- Network.Ethereum.Ens.PublicResolver: setAddr :: (JsonRpc m_a1RiK, Account a_a1RiI t_a1RiJ, Functor (t_a1RiJ m_a1RiK)) => BytesN 32 -> Address -> t_a1RiJ m_a1RiK TxReceipt
+ Network.Ethereum.Ens.PublicResolver: setAddr :: (JsonRpc m_a1Ydb, Account a_a1Yd9 t_a1Yda, Functor (t_a1Yda m_a1Ydb)) => BytesN 32 -> Address -> t_a1Yda m_a1Ydb TxReceipt
- Network.Ethereum.Ens.PublicResolver: setContent :: (JsonRpc m_a1RiP, Account a_a1RiN t_a1RiO, Functor (t_a1RiO m_a1RiP)) => BytesN 32 -> BytesN 32 -> t_a1RiO m_a1RiP TxReceipt
+ Network.Ethereum.Ens.PublicResolver: setContent :: (JsonRpc m_a1Ydg, Account a_a1Yde t_a1Ydf, Functor (t_a1Ydf m_a1Ydg)) => BytesN 32 -> BytesN 32 -> t_a1Ydf m_a1Ydg TxReceipt
- Network.Ethereum.Ens.PublicResolver: setName :: (JsonRpc m_a1RiU, Account a_a1RiS t_a1RiT, Functor (t_a1RiT m_a1RiU)) => BytesN 32 -> Text -> t_a1RiT m_a1RiU TxReceipt
+ Network.Ethereum.Ens.PublicResolver: setName :: (JsonRpc m_a1Ydl, Account a_a1Ydj t_a1Ydk, Functor (t_a1Ydk m_a1Ydl)) => BytesN 32 -> Text -> t_a1Ydk m_a1Ydl TxReceipt
- Network.Ethereum.Ens.PublicResolver: setPubkey :: (JsonRpc m_a1Rj0, Account a_a1RiY t_a1RiZ, Functor (t_a1RiZ m_a1Rj0)) => BytesN 32 -> BytesN 32 -> BytesN 32 -> t_a1RiZ m_a1Rj0 TxReceipt
+ Network.Ethereum.Ens.PublicResolver: setPubkey :: (JsonRpc m_a1Ydr, Account a_a1Ydp t_a1Ydq, Functor (t_a1Ydq m_a1Ydr)) => BytesN 32 -> BytesN 32 -> BytesN 32 -> t_a1Ydq m_a1Ydr TxReceipt
- Network.Ethereum.Ens.PublicResolver: supportsInterface :: (JsonRpc m_a1Rj4, Account a_a1Rj2 t_a1Rj3, Functor (t_a1Rj3 m_a1Rj4)) => BytesN 4 -> t_a1Rj3 m_a1Rj4 Bool
+ Network.Ethereum.Ens.PublicResolver: supportsInterface :: (JsonRpc m_a1Ydv, Account a_a1Ydt t_a1Ydu, Functor (t_a1Ydu m_a1Ydv)) => BytesN 4 -> t_a1Ydu m_a1Ydv Bool
- Network.Ethereum.Ens.Registry: owner :: (JsonRpc m_a1DNQ, Account a_a1DNO t_a1DNP, Functor (t_a1DNP m_a1DNQ)) => BytesN 32 -> t_a1DNP m_a1DNQ Address
+ Network.Ethereum.Ens.Registry: owner :: (JsonRpc m_a1KIh, Account a_a1KIf t_a1KIg, Functor (t_a1KIg m_a1KIh)) => BytesN 32 -> t_a1KIg m_a1KIh Address
- Network.Ethereum.Ens.Registry: resolver :: (JsonRpc m_a1DNU, Account a_a1DNS t_a1DNT, Functor (t_a1DNT m_a1DNU)) => BytesN 32 -> t_a1DNT m_a1DNU Address
+ Network.Ethereum.Ens.Registry: resolver :: (JsonRpc m_a1KIl, Account a_a1KIj t_a1KIk, Functor (t_a1KIk m_a1KIl)) => BytesN 32 -> t_a1KIk m_a1KIl Address
- Network.Ethereum.Ens.Registry: setOwner :: (JsonRpc m_a1DNZ, Account a_a1DNX t_a1DNY, Functor (t_a1DNY m_a1DNZ)) => BytesN 32 -> Address -> t_a1DNY m_a1DNZ TxReceipt
+ Network.Ethereum.Ens.Registry: setOwner :: (JsonRpc m_a1KIq, Account a_a1KIo t_a1KIp, Functor (t_a1KIp m_a1KIq)) => BytesN 32 -> Address -> t_a1KIp m_a1KIq TxReceipt
- Network.Ethereum.Ens.Registry: setResolver :: (JsonRpc m_a1DO4, Account a_a1DO2 t_a1DO3, Functor (t_a1DO3 m_a1DO4)) => BytesN 32 -> Address -> t_a1DO3 m_a1DO4 TxReceipt
+ Network.Ethereum.Ens.Registry: setResolver :: (JsonRpc m_a1KIv, Account a_a1KIt t_a1KIu, Functor (t_a1KIu m_a1KIv)) => BytesN 32 -> Address -> t_a1KIu m_a1KIv TxReceipt
- Network.Ethereum.Ens.Registry: setSubnodeOwner :: (JsonRpc m_a1DOa, Account a_a1DO8 t_a1DO9, Functor (t_a1DO9 m_a1DOa)) => BytesN 32 -> BytesN 32 -> Address -> t_a1DO9 m_a1DOa TxReceipt
+ Network.Ethereum.Ens.Registry: setSubnodeOwner :: (JsonRpc m_a1KIB, Account a_a1KIz t_a1KIA, Functor (t_a1KIA m_a1KIB)) => BytesN 32 -> BytesN 32 -> Address -> t_a1KIA m_a1KIB TxReceipt
- Network.Ethereum.Ens.Registry: setTTL :: (JsonRpc m_a1DOf, Account a_a1DOd t_a1DOe, Functor (t_a1DOe m_a1DOf)) => BytesN 32 -> UIntN 64 -> t_a1DOe m_a1DOf TxReceipt
+ Network.Ethereum.Ens.Registry: setTTL :: (JsonRpc m_a1KIG, Account a_a1KIE t_a1KIF, Functor (t_a1KIF m_a1KIG)) => BytesN 32 -> UIntN 64 -> t_a1KIF m_a1KIG TxReceipt
- Network.Ethereum.Ens.Registry: ttl :: (JsonRpc m_a1DOj, Account a_a1DOh t_a1DOi, Functor (t_a1DOi m_a1DOj)) => BytesN 32 -> t_a1DOi m_a1DOj (UIntN 64)
+ Network.Ethereum.Ens.Registry: ttl :: (JsonRpc m_a1KIK, Account a_a1KII t_a1KIJ, Functor (t_a1KIJ m_a1KIK)) => BytesN 32 -> t_a1KIJ m_a1KIK (UIntN 64)

Files

CHANGELOG.md view
@@ -1,6 +1,20 @@ # Changelog All notable changes to this project will be documented in this file. +## [0.9.0.0] 2020-05-24+### Added+- Experimental IPFS REST API client+- Experimental Polkadot JSON-RPC API client++### Changed+- Web3 abstraction moved to `Network.Web3`+- Ethereum entry point renamed `Network.Ethereum.Web3` -> `Network.Ethereum`+- Split from common ECDSA staff from `Crypto.Ethereum` to `Crypto.Ecdsa`+- Ethereum related tests moved to `Network.Ethereum.Test`++### Removed+- Support for build on LTS-11, LTS-12, LTS-13+ ## [0.8.4.0] 2020-05-03 ### Added - Tuple support for `pragma experimental ABIEncoderV2`
README.md view
@@ -1,7 +1,7 @@-Ethereum API for Haskell-========================+Web3 API for Haskell+==================== -The Haskell Ethereum API which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC).+This library implements Haskell API client for popular Web3 platforms.  [![Documentation Status](https://readthedocs.org/projects/hs-web3/badge/?version=latest)](https://hs-web3.readthedocs.io/en/latest/?badge=latest) [![Build Status](https://travis-ci.org/airalab/hs-web3.svg?branch=master)](https://travis-ci.org/airalab/hs-web3)@@ -25,7 +25,8 @@ module Main where  -- Basic imports-import           Network.Ethereum.Web3+import           Network.Ethereum+import           Network.Web3  -- Eth API support import qualified Network.Ethereum.Api.Eth   as Eth
+ examples/polkadot/Main.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import           Control.Monad.IO.Class      (liftIO)++import qualified Network.Polkadot.Api.Chain  as Chain+import qualified Network.Polkadot.Api.State  as State+import qualified Network.Polkadot.Api.System as System+import           Network.Web3.Provider       (Provider (..), runWeb3')++main :: IO ()+main = do+    result <- runWeb3' (WsProvider "127.0.0.1" 9944) $ do+        name <- System.name+        liftIO . putStrLn $ "System name: " ++ show name++        best <- Chain.getBlockHash Nothing+        liftIO . putStrLn $ "Best hash: " ++ show best++        State.getRuntimeVersion best++    case result of+      Left err      -> error (show err)+      Right version -> putStrLn (show version)
examples/token/Main.hs view
@@ -6,8 +6,9 @@ import           Text.Printf              (printf)  import           Lens.Micro               ((.~))+import           Network.Ethereum         hiding (name) import           Network.Ethereum.Account-import           Network.Ethereum.Web3    hiding (name)+import           Network.Web3  import           ERC20 
+ src/Crypto/Ecdsa/Signature.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Crypto.Ecdsa.Signature+-- Copyright   :  Alexander Krupenkin 2018+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Recoverable ECC signature support.+--++module Crypto.Ecdsa.Signature+    (+      sign+    , pack+    , unpack+    ) where++import           Control.Monad               (when)+import           Crypto.Hash                 (SHA256)+import           Crypto.Number.Generate      (generateBetween)+import           Crypto.Number.ModArithmetic (inverse)+import           Crypto.Number.Serialize     (i2osp, os2ip)+import           Crypto.PubKey.ECC.ECDSA     (PrivateKey (..))+import           Crypto.PubKey.ECC.Prim      (pointMul)+import           Crypto.PubKey.ECC.Types     (CurveCommon (ecc_g, ecc_n),+                                              Point (..), common_curve)+import           Crypto.Random               (MonadRandom, withDRG)+import           Crypto.Random.HmacDrbg      (HmacDrbg, initialize)+import           Data.Bits                   (xor, (.|.))+import           Data.ByteArray              (ByteArray, ByteArrayAccess, Bytes,+                                              convert, singleton, takeView,+                                              view)+import qualified Data.ByteArray              as BA (unpack)+import           Data.Monoid                 ((<>))+import           Data.Word                   (Word8)++import           Crypto.Ecdsa.Utils          (exportKey)++-- | Sign arbitrary data by given private key.+--+-- /WARNING:/ Vulnerable to timing attacks.+sign :: ByteArrayAccess bin+     => PrivateKey+     -> bin+     -> (Integer, Integer, Word8)+sign pk bin = fst $ withDRG hmac_drbg $ ecsign pk (os2ip truncated)+  where+    hmac_drbg :: HmacDrbg SHA256+    hmac_drbg = initialize $ exportKey pk <> truncated+    truncated = convert $ takeView bin 32 :: Bytes++ecsign :: MonadRandom m+       => PrivateKey+       -> Integer+       -> m (Integer, Integer, Word8)+ecsign pk@(PrivateKey curve d) z = do+    k <- generateBetween 0 (n - 1)+    case trySign k of+        Nothing  -> ecsign pk z+        Just rsv -> return rsv+  where+    n = ecc_n (common_curve curve)+    g = ecc_g (common_curve curve)+    recoveryParam x y r = fromIntegral $+        fromEnum (odd y) .|. if x /= r then 2 else 0+    trySign k = do+        (kpX, kpY) <- case pointMul curve k g of+            PointO    -> Nothing+            Point x y -> return (x, y)+        let r = kpX `mod` n+        kInv <- inverse k n+        let s = kInv * (z + r * d) `mod` n+        when (r == 0 || s == 0) Nothing+        -- Recovery param+        let v = recoveryParam kpX kpY r+        -- Use complement of s if it > n / 2+        let (s', v') | s > n `div` 2 = (n - s, v `xor` 1)+                     | otherwise = (s, v)+        return $ (r, s', v' + 27)++-- | Unpack recoverable signature from byte array.+--+-- Input array should have 65 byte length.+unpack :: ByteArrayAccess rsv => rsv -> (Integer, Integer, Word8)+unpack vrs = (r, s, v)+  where+    r = os2ip (view vrs 1 33)+    s = os2ip (view vrs 33 65)+    v = head (BA.unpack vrs)++-- | Pack recoverable signature as byte array (65 byte length).+pack :: ByteArray rsv => (Integer, Integer, Word8) -> rsv+pack (r, s, v) = i2osp r <> i2osp s <> singleton v
+ src/Crypto/Ecdsa/Utils.hs view
@@ -0,0 +1,46 @@+-- |+-- Module      :  Crypto.Ecdsa.Utils+-- Copyright   :  Alexander Krupenkin 2018+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- ECDSA module helper functions.+--++module Crypto.Ecdsa.Utils where++import           Crypto.Number.Serialize    (i2osp, os2ip)+import           Crypto.PubKey.ECC.ECDSA    (PrivateKey (..), PublicKey (..))+import           Crypto.PubKey.ECC.Generate (generateQ)+import           Crypto.PubKey.ECC.Types    (CurveName (SEC_p256k1), Point (..),+                                             getCurveByName)+import           Data.ByteArray             (ByteArray, ByteArrayAccess)+import           Data.Monoid                ((<>))++-- | Import ECDSA private key from byte array.+--+-- Input array should have 32 byte length.+importKey :: ByteArrayAccess privateKey => privateKey -> PrivateKey+{-# INLINE importKey #-}+importKey = PrivateKey (getCurveByName SEC_p256k1) . os2ip++-- | Export private key to byte array (32 byte length).+exportKey :: ByteArray privateKey => PrivateKey -> privateKey+{-# INLINE exportKey #-}+exportKey (PrivateKey _ key) = i2osp key++-- | Get public key appropriate to private key.+--+-- /WARNING:/ Vulnerable to timing attacks.+derivePubKey :: PrivateKey -> PublicKey+{-# INLINE derivePubKey #-}+derivePubKey (PrivateKey curve p) = PublicKey curve (generateQ curve p)++-- | Export public key to byte array (64 byte length).+exportPubKey :: ByteArray publicKey => PublicKey -> publicKey+{-# INLINE exportPubKey #-}+exportPubKey (PublicKey _ (Point x y)) = i2osp x <> i2osp y+exportPubKey (PublicKey _ PointO)      = mempty
src/Crypto/Ethereum.hs view
@@ -7,12 +7,12 @@ -- Stability   :  experimental -- Portability :  unportable ----- Ethereum ECC support module.+-- Ethereum cryptography primitives. --  module Crypto.Ethereum     (-    -- * Ethereum crypto key ops+    -- * ECDSA crypto key ops       PrivateKey     , PublicKey     , importKey@@ -22,9 +22,10 @@     , signMessage      -- * Hash function-    , sha3+    , keccak256     ) where +import           Crypto.Ecdsa.Utils        (derivePubKey, importKey) import           Crypto.Ethereum.Signature (signMessage)-import           Crypto.Ethereum.Utils     (derivePubKey, importKey, sha3)+import           Crypto.Ethereum.Utils     (keccak256) import           Crypto.PubKey.ECC.ECDSA   (PrivateKey, PublicKey)
src/Crypto/Ethereum/Keyfile.hs view
@@ -10,7 +10,7 @@ -- Stability   :  experimental -- Portability :  portable ----- Web3 Secret Storage implementation.+-- Ethereum Secret Storage implementation. -- Spec https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition. -- @@ -44,25 +44,32 @@ import           Data.UUID.Types          (UUID) import           Data.UUID.Types.Internal (buildFromBytes) -import           Crypto.Ethereum.Utils    (sha3)+import           Crypto.Ethereum.Utils    (keccak256) import           Data.ByteArray.HexString (HexString)  -- | Key derivation function parameters and salt. data Kdf = Pbkdf2 !Pbkdf2.Parameters !HexString-         | Scrypt !Scrypt.Parameters !HexString+    | Scrypt !Scrypt.Parameters !HexString  -- | Cipher parameters. data Cipher = Aes128Ctr-    { cipherIv :: !(IV AES128), cipherText :: !HexString }+    { cipherIv   :: !(IV AES128)+    , cipherText :: !HexString+    }  -- | Secret Storage representation on memory. data EncryptedKey = EncryptedKey-  { encryptedKeyId      :: !UUID        -- ^ Random key ID-  , encryptedKeyVersion :: !Int         -- ^ Version (suppoted version 3 only)-  , encryptedKeyCipher  :: !Cipher      -- ^ Cipher (supported AES-128-CTR only)-  , encryptedKeyKdf     :: !Kdf         -- ^ Key derivation function-  , encryptedKeyMac     :: !HexString   -- ^ MAC-  }+    { encryptedKeyId      :: !UUID+    -- ^ Random key ID+    , encryptedKeyVersion :: !Int+    -- ^ Version (suppoted version 3 only)+    , encryptedKeyCipher  :: !Cipher+    -- ^ Cipher (supported AES-128-CTR only)+    , encryptedKeyKdf     :: !Kdf+    -- ^ Key derivation function+    , encryptedKeyMac     :: !HexString+    -- ^ MAC+    }  instance Eq EncryptedKey where     a == b = encryptedKeyId a == encryptedKeyId b@@ -195,7 +202,7 @@     cipher = throwCryptoError $ cipherInit (BA.take 16 derivedKey) :: AES128     derivedKey = deriveKey encryptedKeyKdf password     ciphertext = cipherText encryptedKeyCipher-    mac = sha3 (BA.drop 16 derivedKey <> ciphertext)+    mac = keccak256 (BA.drop 16 derivedKey <> ciphertext)     iv  = cipherIv encryptedKeyCipher  -- | Encrypt Ethereum private key.@@ -213,7 +220,7 @@     let derivedKey = deriveKey kdf password         cipher = throwCryptoError $ cipherInit (BA.take 16 derivedKey) :: AES128         ciphertext = ctrCombine cipher iv privateKey-        mac = sha3 (BA.drop 16 derivedKey <> ciphertext)+        mac = keccak256 (BA.drop 16 derivedKey <> ciphertext)     uuid <- randomUUID     return $ EncryptedKey uuid 3 (Aes128Ctr iv $ convert ciphertext) kdf mac   where
src/Crypto/Ethereum/Signature.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-}  -- |--- Module      :  Crypto.Ethereum+-- Module      :  Crypto.Ecdsa.Signature -- Copyright   :  Alexander Krupenkin 2018 -- License     :  BSD3 --@@ -9,7 +9,7 @@ -- Stability   :  experimental -- Portability :  portable ----- Recoverable ECC signature support.+-- Recoverable Ethereum signature support. --  module Crypto.Ethereum.Signature@@ -17,35 +17,18 @@       hashMessage     , signMessage     , signTransaction-    , pack-    , unpack     ) where -import           Control.Monad               (when)-import           Crypto.Hash                 (Digest, Keccak_256 (..), SHA256,-                                              hashWith)-import           Crypto.Number.Generate      (generateBetween)-import           Crypto.Number.ModArithmetic (inverse)-import           Crypto.Number.Serialize     (i2osp, os2ip)-import           Crypto.PubKey.ECC.ECDSA     (PrivateKey (..))-import           Crypto.PubKey.ECC.Prim      (pointMul)-import           Crypto.PubKey.ECC.Types     (CurveCommon (ecc_g, ecc_n),-                                              Point (..), common_curve)-import           Crypto.Random               (MonadRandom, withDRG)-import           Crypto.Random.HmacDrbg      (HmacDrbg, initialize)-import           Data.Bits                   (xor, (.|.))-import           Data.ByteArray              (ByteArray, ByteArrayAccess,-                                              convert, singleton, takeView,-                                              view)-import qualified Data.ByteArray              as BA (length, unpack)-import           Data.ByteString.Builder     (intDec, toLazyByteString)-import qualified Data.ByteString.Lazy        as LBS (toStrict)-import           Data.Monoid                 ((<>))-import           Data.Word                   (Word8)+import           Crypto.Hash             (Digest, Keccak_256 (..), hashWith)+import           Crypto.PubKey.ECC.ECDSA (PrivateKey (..))+import           Data.ByteArray          (ByteArray, ByteArrayAccess, convert)+import qualified Data.ByteArray          as BA (length)+import           Data.ByteString.Builder (intDec, toLazyByteString)+import qualified Data.ByteString.Lazy    as LBS (toStrict)+import           Data.Monoid             ((<>))+import           Data.Word               (Word8) -import           Crypto.Ethereum.Utils       (exportKey)-import           Data.ByteArray.HexString    (HexString)-import           Data.Solidity.Prim.Address  (Address)+import           Crypto.Ecdsa.Signature  (pack, sign)  -- | Make Ethereum standard signature. --@@ -84,59 +67,3 @@   where     unsigned = encode Nothing     signed = sign key (hashWith Keccak_256 unsigned)---- | Sign arbitrary data by given private key.------ /WARNING:/ Vulnerable to timing attacks.-sign :: ByteArrayAccess bin-     => PrivateKey-     -> bin-     -> (Integer, Integer, Word8)-sign pk bin = fst $ withDRG hmac_drbg $ ecsign pk (os2ip truncated)-  where-    hmac_drbg :: HmacDrbg SHA256-    hmac_drbg = initialize $ exportKey pk <> truncated-    truncated = convert $ takeView bin 32 :: HexString--ecsign :: MonadRandom m-       => PrivateKey-       -> Integer-       -> m (Integer, Integer, Word8)-ecsign pk@(PrivateKey curve d) z = do-    k <- generateBetween 0 (n - 1)-    case trySign k of-        Nothing  -> ecsign pk z-        Just rsv -> return rsv-  where-    n = ecc_n (common_curve curve)-    g = ecc_g (common_curve curve)-    recoveryParam x y r = fromIntegral $-        fromEnum (odd y) .|. if x /= r then 2 else 0-    trySign k = do-        (kpX, kpY) <- case pointMul curve k g of-            PointO    -> Nothing-            Point x y -> return (x, y)-        let r = kpX `mod` n-        kInv <- inverse k n-        let s = kInv * (z + r * d) `mod` n-        when (r == 0 || s == 0) Nothing-        -- Recovery param-        let v = recoveryParam kpX kpY r-        -- Use complement of s if it > n / 2-        let (s', v') | s > n `div` 2 = (n - s, v `xor` 1)-                     | otherwise = (s, v)-        return $ (r, s', v' + 27)---- | Unpack recoverable signature from byte array.------ Input array should have 65 byte length.-unpack :: ByteArrayAccess rsv => rsv -> (Integer, Integer, Word8)-unpack vrs = (r, s, v)-  where-    r = os2ip (view vrs 1 33)-    s = os2ip (view vrs 33 65)-    v = head (BA.unpack vrs)---- | Pack recoverable signature as byte array (65 byte length).-pack :: ByteArray rsv => (Integer, Integer, Word8) -> rsv-pack (r, s, v) = i2osp r <> i2osp s <> singleton v
src/Crypto/Ethereum/Utils.hs view
@@ -7,47 +7,15 @@ -- Stability   :  experimental -- Portability :  portable ----- EC cryptography on Secp256k1 curve.+-- Ethereum crypto module helper functions. --  module Crypto.Ethereum.Utils where -import           Crypto.Hash                (Keccak_256 (..), hashWith)-import           Crypto.Number.Serialize    (i2osp, os2ip)-import           Crypto.PubKey.ECC.ECDSA    (PrivateKey (..), PublicKey (..))-import           Crypto.PubKey.ECC.Generate (generateQ)-import           Crypto.PubKey.ECC.Types    (CurveName (SEC_p256k1), Point (..),-                                             getCurveByName)-import           Data.ByteArray             (ByteArray, ByteArrayAccess,-                                             convert)-import           Data.Monoid                ((<>))---- | Import Ethereum private key from byte array.------ Input array should have 32 byte length.-importKey :: ByteArrayAccess privateKey => privateKey -> PrivateKey-{-# INLINE importKey #-}-importKey = PrivateKey (getCurveByName SEC_p256k1) . os2ip---- | Export private key to byte array (32 byte length).-exportKey :: ByteArray privateKey => PrivateKey -> privateKey-{-# INLINE exportKey #-}-exportKey (PrivateKey _ key) = i2osp key---- | Get public key appropriate to private key.------ /WARNING:/ Vulnerable to timing attacks.-derivePubKey :: PrivateKey -> PublicKey-{-# INLINE derivePubKey #-}-derivePubKey (PrivateKey curve p) = PublicKey curve (generateQ curve p)---- | Export public key to byte array (64 byte length).-exportPubKey :: ByteArray publicKey => PublicKey -> publicKey-{-# INLINE exportPubKey #-}-exportPubKey (PublicKey _ (Point x y)) = i2osp x <> i2osp y-exportPubKey (PublicKey _ PointO)      = mempty+import           Crypto.Hash    (Keccak_256 (..), hashWith)+import           Data.ByteArray (ByteArray, ByteArrayAccess, convert)  -- | Keccak 256 hash function.-sha3 :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout-{-# INLINE sha3 #-}-sha3 = convert . hashWith Keccak_256+keccak256 :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout+{-# INLINE keccak256 #-}+keccak256 = convert . hashWith Keccak_256
src/Data/Solidity/Prim/Address.hs view
@@ -49,7 +49,8 @@ import           Generics.SOP             (Generic) import qualified GHC.Generics             as GHC (Generic) -import           Crypto.Ethereum.Utils    (exportPubKey, sha3)+import           Crypto.Ecdsa.Utils       (exportPubKey)+import           Crypto.Ethereum.Utils    (keccak256) import           Data.ByteArray.HexString (HexString, fromBytes, toBytes,                                            toText) import           Data.Solidity.Abi        (AbiGet (..), AbiPut (..),@@ -95,7 +96,7 @@         Left e  -> error $ "Impossible error: " ++ e   where     toAddress :: HexString -> HexString-    toAddress = BA.drop 12 . sha3+    toAddress = BA.drop 12 . keccak256  -- | Decode address from hex string fromHexString :: HexString -> Either String Address@@ -113,7 +114,7 @@ toChecksum :: ByteString -> ByteString toChecksum addr = ("0x" <>) . C8.pack $ zipWith ($) upcaseVector lower   where-    upcaseVector = (>>= fourthBits) . BS.unpack . BS.take 20 $ sha3 (C8.pack lower)+    upcaseVector = (>>= fourthBits) . BS.unpack . BS.take 20 $ keccak256 (C8.pack lower)     fourthBits n = bool id C.toUpper <$> [n .&. 0x80 /= 0, n .&. 0x08 /= 0]     lower = drop 2 . fmap C.toLower . C8.unpack $ addr 
+ src/Network/Ethereum.hs view
@@ -0,0 +1,32 @@+-- |+-- Module      :  Network.Ethereum+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--+-- TODO+--++module Network.Ethereum+    (+    -- * Basic transaction sending+      module Account++    -- * Basic EVM event listening+    , EventAction(..)+    , event++    -- * Primitive Solidity data types+    , module Prim++    -- * Metric unit system+    , module Unit+    ) where++import           Data.Solidity.Prim              as Prim+import           Network.Ethereum.Account        as Account+import           Network.Ethereum.Contract.Event (EventAction (..), event)+import           Network.Ethereum.Unit           as Unit
src/Network/Ethereum/Account/Default.hs view
@@ -17,6 +17,7 @@  module Network.Ethereum.Account.Default where +import           Control.Exception                 (TypeError (..)) import           Control.Monad.Catch               (throwM) import           Control.Monad.State.Strict        (get, runStateT) import           Control.Monad.Trans               (MonadTrans (..))@@ -34,7 +35,6 @@ import qualified Network.Ethereum.Api.Eth          as Eth (accounts, call,                                                            estimateGas,                                                            sendTransaction)-import           Network.Ethereum.Api.Provider     (Web3Error (ParserFail)) import           Network.Ethereum.Api.Types        (Call (callData, callFrom, callGas)) import           Network.Ethereum.Contract.Method  (Method (..)) @@ -71,4 +71,4 @@             Eth.call params _block         case decode res of             Right r -> return r-            Left e  -> lift $ throwM (ParserFail e)+            Left e  -> lift (throwM $ TypeError e)
src/Network/Ethereum/Account/LocalKey.hs view
@@ -19,6 +19,7 @@  module Network.Ethereum.Account.LocalKey where +import           Control.Exception                 (TypeError (..)) import           Control.Monad.Catch               (throwM) import           Control.Monad.State.Strict        (get, runStateT) import           Control.Monad.Trans               (lift)@@ -41,7 +42,6 @@ import qualified Network.Ethereum.Api.Eth          as Eth (call, estimateGas,                                                            getTransactionCount,                                                            sendRawTransaction)-import           Network.Ethereum.Api.Provider     (Web3Error (ParserFail)) import           Network.Ethereum.Api.Types        (Call (..)) import           Network.Ethereum.Chain            (foundation) import           Network.Ethereum.Contract.Method  (selector)@@ -95,4 +95,4 @@         res <- lift $ Eth.call params _block         case decode res of             Right r -> return r-            Left e  -> lift $ throwM (ParserFail e)+            Left e  -> lift (throwM $ TypeError e)
src/Network/Ethereum/Account/Personal.hs view
@@ -19,6 +19,7 @@  module Network.Ethereum.Account.Personal where +import           Control.Exception                 (TypeError (..)) import           Control.Monad.Catch               (throwM) import           Control.Monad.State.Strict        (get, runStateT) import           Control.Monad.Trans               (lift)@@ -37,7 +38,6 @@ import qualified Network.Ethereum.Api.Eth          as Eth (call, estimateGas) import           Network.Ethereum.Api.Personal     (Passphrase) import qualified Network.Ethereum.Api.Personal     as Personal (sendTransaction)-import           Network.Ethereum.Api.Provider     (Web3Error (ParserFail)) import           Network.Ethereum.Api.Types        (Call (callData, callFrom, callGas)) import           Network.Ethereum.Contract.Method  (selector) @@ -83,4 +83,4 @@                 res <- lift $ Eth.call params block                 case decode res of                     Right r -> return r-                    Left e  -> lift $ throwM (ParserFail e)+                    Left e  -> lift (throwM $ TypeError e)
− src/Network/Ethereum/Api/Provider.hs
@@ -1,86 +0,0 @@-{-# LANGUAGE DeriveGeneric              #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- |--- Module      :  Network.Ethereum.Api.Provider--- Copyright   :  Alexander Krupenkin 2016-2018--- License     :  BSD3------ Maintainer  :  mail@akru.me--- Stability   :  experimental--- Portability :  portable------ Web3 service provider.-----module Network.Ethereum.Api.Provider where--import           Control.Concurrent.Async   (Async, async)-import           Control.Exception          (Exception, try)-import           Control.Monad.Catch        (MonadThrow)-import           Control.Monad.IO.Class     (MonadIO (..))-import           Control.Monad.State        (MonadState (..))-import           Control.Monad.Trans.State  (StateT, evalStateT)-import           Data.Default               (Default (..))-import           GHC.Generics               (Generic)-import           Lens.Micro.Mtl             ((.=))-import           Network.HTTP.Client        (Manager)--import           Network.JsonRpc.TinyClient (JsonRpc, JsonRpcClient,-                                             defaultSettings, jsonRpcManager)---- | Any communication with Ethereum node wrapped with 'Web3' monad-newtype Web3 a = Web3 { unWeb3 :: StateT JsonRpcClient IO a }-    deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadState JsonRpcClient)--instance JsonRpc Web3---- | Some peace of error response-data Web3Error-  = JsonRpcFail !String-  -- ^ JSON-RPC communication error-  | ParserFail  !String-  -- ^ Error in parser state-  | UserFail    !String-  -- ^ Common head for user errors-  deriving (Show, Eq, Generic)--instance Exception Web3Error----TODO: Change to `HttpProvider ServerUri | IpcProvider FilePath` to support IPC--- | Web3 Provider-data Provider = HttpProvider String-  deriving (Show, Eq, Generic)--instance Default Provider where-  def = HttpProvider "http://localhost:8545"---- | 'Web3' monad runner, using the supplied Manager-runWeb3With :: MonadIO m-            => Manager-            -> Provider-            -> Web3 a-            -> m (Either Web3Error a)-runWeb3With manager provider f =-    runWeb3' provider $ jsonRpcManager .= manager >> f---- | 'Web3' monad runner-runWeb3' :: MonadIO m-         => Provider-         -> Web3 a-         -> m (Either Web3Error a)-runWeb3' (HttpProvider uri) f = do-    cfg <- defaultSettings uri-    liftIO . try . flip evalStateT cfg . unWeb3 $ f---- | 'Web3' runner for default provider-runWeb3 :: MonadIO m-        => Web3 a-        -> m (Either Web3Error a)-{-# INLINE runWeb3 #-}-runWeb3 = runWeb3' def---- | Fork 'Web3' with the same 'Provider' and 'Manager'-forkWeb3 :: Web3 a -> Web3 (Async a)-forkWeb3 f = liftIO . async . evalStateT (unWeb3 f) =<< get
src/Network/Ethereum/Contract/Event/Common.hs view
@@ -21,31 +21,30 @@  module Network.Ethereum.Contract.Event.Common  where -import           Control.Concurrent            (threadDelay)-import           Control.Exception             (Exception, throwIO)-import           Control.Monad.IO.Class        (liftIO)-import           Data.Either                   (lefts, rights)+import           Control.Concurrent         (threadDelay)+import           Control.Exception          (Exception, throwIO)+import           Control.Monad.IO.Class     (liftIO)+import           Data.Either                (lefts, rights) -import           Data.Solidity.Event           (DecodeEvent (..))-import qualified Network.Ethereum.Api.Eth      as Eth-import           Network.Ethereum.Api.Provider (Web3)-import           Network.Ethereum.Api.Types    (Change (..), DefaultBlock (..),-                                                Filter (..), Quantity)+import           Data.Solidity.Event        (DecodeEvent (..))+import qualified Network.Ethereum.Api.Eth   as Eth+import           Network.Ethereum.Api.Types (Change (..), DefaultBlock (..),+                                             Filter (..), Quantity)+import           Network.JsonRpc.TinyClient (JsonRpc (..))  -- | Event callback control response data EventAction = ContinueEvent-                 -- ^ Continue to listen events-                 | TerminateEvent-                 -- ^ Terminate event listener-  deriving (Show, Eq)+    | TerminateEvent+    deriving (Show, Eq)  -data FilterChange a =-  FilterChange { filterChangeRawChange :: Change-               , filterChangeEvent     :: a-               }+data FilterChange a = FilterChange+    { filterChangeRawChange :: Change+    , filterChangeEvent     :: a+    } -data EventParseFailure = EventParseFailure String deriving (Show)+data EventParseFailure = EventParseFailure String+    deriving (Show)  instance Exception EventParseFailure @@ -59,24 +58,22 @@   in if ls /= [] then throwIO (EventParseFailure $ show ls) else pure rs  -data FilterStreamState e =-  FilterStreamState { fssCurrentBlock  :: Quantity-                    , fssInitialFilter :: Filter e-                    , fssWindowSize    :: Integer-                    }+data FilterStreamState e = FilterStreamState+    { fssCurrentBlock  :: Quantity+    , fssInitialFilter :: Filter e+    , fssWindowSize    :: Integer+    }   -- | Coerce a 'DefaultBlock' into a numerical block number.-mkBlockNumber :: DefaultBlock -> Web3 Quantity+mkBlockNumber :: JsonRpc m => DefaultBlock -> m Quantity mkBlockNumber bm = case bm of   BlockWithNumber bn -> return bn   Earliest           -> return 0   _                  -> Eth.blockNumber  -pollTillBlockProgress-  :: Quantity-  -> Web3 Quantity+pollTillBlockProgress :: JsonRpc m => Quantity -> m Quantity pollTillBlockProgress currentBlock = do   bn <- Eth.blockNumber   if currentBlock >= bn
src/Network/Ethereum/Contract/Event/MultiFilter.hs view
@@ -21,7 +21,7 @@ -- Stability   :  experimental -- Portability :  unportable ----- Support for parallel multiple event filters.+-- Parallel multiple event filters. --  module  Network.Ethereum.Contract.Event.MultiFilter@@ -34,13 +34,11 @@      -- * With geth filters     , multiEvent-    , multiEvent'-    , multiEventMany'+    , multiEventMany      -- * Without geth filters     , multiEventNoFilter-    , multiEventNoFilter'-    , multiEventManyNoFilter'+    , multiEventManyNoFilter      -- * Re-exports     , Handlers@@ -49,7 +47,6 @@     ) where  import           Control.Concurrent                     (threadDelay)-import           Control.Concurrent.Async               (Async) import           Control.Monad                          (forM, void, when) import           Control.Monad.IO.Class                 (MonadIO (..)) import           Control.Monad.Trans.Class              (lift)@@ -83,10 +80,10 @@  import           Data.Solidity.Event                    (DecodeEvent (..)) import qualified Network.Ethereum.Api.Eth               as Eth-import           Network.Ethereum.Api.Provider          (Web3, forkWeb3) import           Network.Ethereum.Api.Types             (Change (..),                                                          DefaultBlock (..),                                                          Filter (..), Quantity)+import Network.JsonRpc.TinyClient (JsonRpc(..)) import           Network.Ethereum.Contract.Event.Common  --------------------------------------------------------------------------------@@ -122,34 +119,19 @@ multiEvent   :: ( PollFilters es      , QueryAllLogs es-     , MapHandlers Web3 es (WithChange es)-#if MIN_VERSION_vinyl(0,10,0)-     , RPureConstrained HasLogIndex (WithChange es)-#else-     , AllAllSat '[HasLogIndex] (WithChange es)-#endif-     , RecApplicative (WithChange es)-     )-  => MultiFilter es-  -> Handlers es (ReaderT Change Web3 EventAction)-  -> Web3 (Async ())-multiEvent fltrs = forkWeb3 . multiEvent' fltrs--multiEvent'-  :: ( PollFilters es-     , QueryAllLogs es-     , MapHandlers Web3 es (WithChange es)+     , MapHandlers m es (WithChange es) #if MIN_VERSION_vinyl(0,10,0)      , RPureConstrained HasLogIndex (WithChange es) #else      , AllAllSat '[HasLogIndex] (WithChange es) #endif      , RecApplicative (WithChange es)+     , JsonRpc m      )   => MultiFilter es-  -> Handlers es (ReaderT Change Web3 EventAction)-  -> Web3 ()-multiEvent' fltrs = multiEventMany' fltrs 0+  -> Handlers es (ReaderT Change m EventAction)+  -> m ()+multiEvent fltrs = multiEventMany fltrs 0  data MultiFilterStreamState es =   MultiFilterStreamState { mfssCurrentBlock       :: Quantity@@ -158,22 +140,23 @@                          }  -multiEventMany'+multiEventMany   :: ( PollFilters es      , QueryAllLogs es-     , MapHandlers Web3 es (WithChange es)+     , MapHandlers m es (WithChange es) #if MIN_VERSION_vinyl(0,10,0)      , RPureConstrained HasLogIndex (WithChange es) #else      , AllAllSat '[HasLogIndex] (WithChange es) #endif      , RecApplicative (WithChange es)+     , JsonRpc m      )   => MultiFilter es   -> Integer-  -> Handlers es (ReaderT Change Web3 EventAction)-  -> Web3 ()-multiEventMany' fltrs window handlers = do+  -> Handlers es (ReaderT Change m EventAction)+  -> m ()+multiEventMany fltrs window handlers = do     start <- mkBlockNumber $ minStartBlock fltrs     let initState =           MultiFilterStreamState { mfssCurrentBlock = start@@ -194,15 +177,18 @@       let pollTo = minEndBlock fltrs'       void $ reduceMultiEventStream (pollMultiFilter fIds pollTo) handlers -multiFilterStream-  :: MultiFilterStreamState es-  -> MachineT Web3 k (MultiFilter es)+multiFilterStream :: JsonRpc m+                  => MultiFilterStreamState es+                  -> MachineT m k (MultiFilter es) multiFilterStream initialPlan = do   unfoldPlan initialPlan $ \s -> do     end <- lift . mkBlockNumber . minEndBlock . mfssInitialMultiFilter $ initialPlan     filterPlan end s   where-    filterPlan :: Quantity -> MultiFilterStreamState es -> PlanT k (MultiFilter es) Web3 (MultiFilterStreamState es)+    filterPlan :: JsonRpc m+               => Quantity+               -> MultiFilterStreamState es+               -> PlanT k (MultiFilter es) m (MultiFilterStreamState es)     filterPlan end initialState@MultiFilterStreamState{..} = do       if mfssCurrentBlock > end         then stop@@ -228,7 +214,7 @@   WithChange (e : es) = FilterChange e : WithChange es  class QueryAllLogs (es :: [*]) where-  queryAllLogs :: MultiFilter es -> Web3 [Field (WithChange es)]+    queryAllLogs :: JsonRpc m => MultiFilter es -> m [Field (WithChange es)]  instance QueryAllLogs '[] where   queryAllLogs NilFilters = pure []@@ -315,7 +301,7 @@  -- | 'playLogs' streams the 'filterStream' and calls eth_getLogs on these 'Filter' objects. playMultiLogs-  :: forall es k.+  :: forall es k m.      ( QueryAllLogs es #if MIN_VERSION_vinyl(0,10,0)      , RPureConstrained HasLogIndex (WithChange es)@@ -323,26 +309,27 @@      , AllAllSat '[HasLogIndex] (WithChange es) #endif      , RecApplicative (WithChange es)+     , JsonRpc m      )   => MultiFilterStreamState es-  -> MachineT Web3 k [Field (WithChange es)]+  -> MachineT m k [Field (WithChange es)] playMultiLogs s = fmap sortChanges $      multiFilterStream s   ~> autoM queryAllLogs  data TaggedFilterIds (es :: [*]) where-  TaggedFilterNil :: TaggedFilterIds '[]-  TaggedFilterCons :: Tagged e Quantity -> TaggedFilterIds es -> TaggedFilterIds (e : es)+    TaggedFilterNil :: TaggedFilterIds '[]+    TaggedFilterCons :: Tagged e Quantity -> TaggedFilterIds es -> TaggedFilterIds (e : es)  class PollFilters (es :: [*]) where-  openMultiFilter :: MultiFilter es -> Web3 (TaggedFilterIds es)-  checkMultiFilter :: TaggedFilterIds es -> Web3 [Field (WithChange es)]-  closeMultiFilter :: TaggedFilterIds es -> Web3 ()+    openMultiFilter :: JsonRpc m => MultiFilter es -> m (TaggedFilterIds es)+    checkMultiFilter :: JsonRpc m => TaggedFilterIds es -> m [Field (WithChange es)]+    closeMultiFilter :: JsonRpc m => TaggedFilterIds es -> m ()  instance PollFilters '[] where-  openMultiFilter _ = pure TaggedFilterNil-  checkMultiFilter _ = pure []-  closeMultiFilter _ = pure ()+    openMultiFilter _ = pure TaggedFilterNil+    checkMultiFilter _ = pure []+    closeMultiFilter _ = pure ()  instance forall e i ni es.   ( DecodeEvent i ni e@@ -375,13 +362,13 @@ #else      , AllAllSat '[HasLogIndex] (WithChange es) #endif+     , JsonRpc m      )   => TaggedFilterIds es   -> DefaultBlock-  -> MachineT Web3 k [Field (WithChange es)]+  -> MachineT m k [Field (WithChange es)] pollMultiFilter is = construct . pollPlan is   where-    -- pollPlan :: TaggedFilterIds es -> DefaultBlock -> PlanT k [Field (Map (TyCon1 FilterChange) es)] Web3 ()     pollPlan (fIds :: TaggedFilterIds es) end = do       bn <- lift $ Eth.blockNumber       if BlockWithNumber bn > end@@ -396,53 +383,39 @@  -------------------------------------------------------------------------------- - multiEventNoFilter   :: ( QueryAllLogs es-     , MapHandlers Web3 es (WithChange es)-#if MIN_VERSION_vinyl(0,10,0)-     , RPureConstrained HasLogIndex (WithChange es)-#else-     , AllAllSat '[HasLogIndex] (WithChange es)-#endif-     , RecApplicative (WithChange es)-     )-  => MultiFilter es-  -> Handlers es (ReaderT Change Web3 EventAction)-  -> Web3 (Async ())-multiEventNoFilter fltrs = forkWeb3 . multiEventNoFilter' fltrs--multiEventNoFilter'-  :: ( QueryAllLogs es-     , MapHandlers Web3 es (WithChange es)+     , MapHandlers m es (WithChange es) #if MIN_VERSION_vinyl(0,10,0)      , RPureConstrained HasLogIndex (WithChange es) #else      , AllAllSat '[HasLogIndex] (WithChange es) #endif      , RecApplicative (WithChange es)+     , JsonRpc m      )   => MultiFilter es-  -> Handlers es (ReaderT Change Web3 EventAction)-  -> Web3 ()-multiEventNoFilter' fltrs = multiEventManyNoFilter' fltrs 0+  -> Handlers es (ReaderT Change m EventAction)+  -> m ()+multiEventNoFilter fltrs = multiEventManyNoFilter fltrs 0  -multiEventManyNoFilter'+multiEventManyNoFilter   :: ( QueryAllLogs es-     , MapHandlers Web3 es (WithChange es)+     , MapHandlers m es (WithChange es) #if MIN_VERSION_vinyl(0,10,0)      , RPureConstrained HasLogIndex (WithChange es) #else      , AllAllSat '[HasLogIndex] (WithChange es) #endif      , RecApplicative (WithChange es)+     , JsonRpc m      )   => MultiFilter es   -> Integer-  -> Handlers es (ReaderT Change Web3 EventAction)-  -> Web3 ()-multiEventManyNoFilter' fltrs window handlers = do+  -> Handlers es (ReaderT Change m EventAction)+  -> m ()+multiEventManyNoFilter fltrs window handlers = do     start <- mkBlockNumber $ minStartBlock fltrs     let initState =           MultiFilterStreamState { mfssCurrentBlock = start@@ -467,15 +440,18 @@                                                           }           in void $ reduceMultiEventStream (playNewMultiLogs pollingFilterState) handlers -newMultiFilterStream-  :: MultiFilterStreamState es-  -> MachineT Web3 k (MultiFilter es)+newMultiFilterStream :: JsonRpc m+                     => MultiFilterStreamState es+                     -> MachineT m k (MultiFilter es) newMultiFilterStream initialPlan = do   unfoldPlan initialPlan $ \s -> do     let end = minEndBlock . mfssInitialMultiFilter $ initialPlan     filterPlan end s   where-    filterPlan :: DefaultBlock -> MultiFilterStreamState es -> PlanT k (MultiFilter es) Web3 (MultiFilterStreamState es)+    filterPlan :: JsonRpc m+               => DefaultBlock+               -> MultiFilterStreamState es+               -> PlanT k (MultiFilter es) m (MultiFilterStreamState es)     filterPlan end initialState@MultiFilterStreamState{..} = do       if BlockWithNumber mfssCurrentBlock > end         then stop@@ -489,7 +465,7 @@           filterPlan end initialState { mfssCurrentBlock = newestBlockNumber + 1 }  playNewMultiLogs-  :: forall es k.+  :: forall es k m.      ( QueryAllLogs es #if MIN_VERSION_vinyl(0,10,0)      , RPureConstrained HasLogIndex (WithChange es)@@ -497,9 +473,10 @@      , AllAllSat '[HasLogIndex] (WithChange es) #endif      , RecApplicative (WithChange es)+     , JsonRpc m      )   => MultiFilterStreamState es-  -> MachineT Web3 k [Field (WithChange es)]+  -> MachineT m k [Field (WithChange es)] playNewMultiLogs s = fmap sortChanges $      newMultiFilterStream s   ~> autoM queryAllLogs
src/Network/Ethereum/Contract/Event/SingleFilter.hs view
@@ -19,21 +19,18 @@ -- Stability   :  experimental -- Portability :  unportable ----- Simple contract event filter support.+-- Contract event filters. --  module Network.Ethereum.Contract.Event.SingleFilter     (       event-    , event'-    , eventMany'+    , eventMany     , eventNoFilter-    , eventNoFilter'-    , eventManyNoFilter'+    , eventManyNoFilter     ) where  import           Control.Concurrent                     (threadDelay)-import           Control.Concurrent.Async               (Async) import           Control.Monad                          (forM, void, when) import           Control.Monad.IO.Class                 (MonadIO (..)) import           Control.Monad.Trans.Class              (lift)@@ -48,38 +45,31 @@  import           Data.Solidity.Event                    (DecodeEvent (..)) import qualified Network.Ethereum.Api.Eth               as Eth-import           Network.Ethereum.Api.Provider          (Web3, forkWeb3) import           Network.Ethereum.Api.Types             (Change (..),                                                          DefaultBlock (..),                                                          Filter (..), Quantity) import           Network.Ethereum.Contract.Event.Common---- | Run 'event\'' one block at a time.-event :: DecodeEvent i ni e-      => Filter e-      -> (e -> ReaderT Change Web3 EventAction)-      -> Web3 (Async ())-event fltr = forkWeb3 . event' fltr+import           Network.JsonRpc.TinyClient             (JsonRpc (..)) --- | Same as 'event', but does not immediately spawn a new thread.-event' :: DecodeEvent i ni e+-- | Run one block at a time.+event :: (DecodeEvent i ni e, JsonRpc m)        => Filter e-       -> (e -> ReaderT Change Web3 EventAction)-       -> Web3 ()-event' fltr = eventMany' fltr 0+       -> (e -> ReaderT Change m EventAction)+       -> m ()+event fltr = eventMany fltr 0 --- | 'eventMany\'' take s a filter, a window size, and a handler.+-- | 'eventMany' take s a filter, a window size, and a handler. -- -- It runs the handler over the results of 'eventLogs' results using -- 'reduceEventStream'. If no 'TerminateEvent' action is thrown and -- the toBlock is not yet reached, it then transitions to polling. ---eventMany' :: DecodeEvent i ni e+eventMany :: (DecodeEvent i ni e, JsonRpc m)            => Filter e            -> Integer-           -> (e -> ReaderT Change Web3 EventAction)-           -> Web3 ()-eventMany' fltr window handler = do+           -> (e -> ReaderT Change m EventAction)+           -> m ()+eventMany fltr window handler = do     start <- mkBlockNumber $ filterFromBlock fltr     let initState = FilterStreamState { fssCurrentBlock = start                                       , fssInitialFilter = fltr@@ -127,22 +117,21 @@             return ((,) act <$> changeBlockNumber filterChangeRawChange)  -- | 'playLogs' streams the 'filterStream' and calls eth_getLogs on these 'Filter' objects.-playOldLogs-  :: DecodeEvent i ni e-  => FilterStreamState e-  -> MachineT Web3 k [FilterChange e]+playOldLogs :: (DecodeEvent i ni e, JsonRpc m)+            => FilterStreamState e+            -> MachineT m k [FilterChange e] playOldLogs s = filterStream s           ~> autoM Eth.getLogs           ~> autoM (liftIO . mkFilterChanges)  -- | Polls a filter from the given filterId until the target toBlock is reached.-pollFilter :: forall i ni e k . DecodeEvent i ni e+pollFilter :: forall i ni e k m . (DecodeEvent i ni e, JsonRpc m)            => Quantity            -> DefaultBlock-           -> MachineT Web3 k [FilterChange e]+           -> MachineT m k [FilterChange e] pollFilter i = construct . pollPlan i   where-    pollPlan :: Quantity -> DefaultBlock -> PlanT k [FilterChange e] Web3 ()+    pollPlan :: Quantity -> DefaultBlock -> PlanT k [FilterChange e] m ()     pollPlan fid end = do       bn <- lift $ Eth.blockNumber       if BlockWithNumber bn > end@@ -162,11 +151,12 @@ -- which cover this filter in intervals of size `windowSize`. The machine -- halts whenever the `fromBlock` of a spanning filter either (1) excedes then -- initial filter's `toBlock` or (2) is greater than the chain head's block number.-filterStream :: FilterStreamState e-             -> MachineT Web3 k (Filter e)+filterStream :: JsonRpc m+             => FilterStreamState e+             -> MachineT m k (Filter e) filterStream initialPlan = unfoldPlan initialPlan filterPlan   where-    filterPlan :: FilterStreamState e -> PlanT k (Filter e) Web3 (FilterStreamState e)+    filterPlan :: JsonRpc m => FilterStreamState e -> PlanT k (Filter e) m (FilterStreamState e)     filterPlan initialState@FilterStreamState{..} = do       end <- lift . mkBlockNumber $ filterToBlock fssInitialFilter       if fssCurrentBlock > end@@ -181,29 +171,18 @@  -------------------------------------------------------------------------------- --- | Run 'event\'' one block at a time.-eventNoFilter-  :: DecodeEvent i ni e-  => Filter e-  -> (e -> ReaderT Change Web3 EventAction)-  -> Web3 (Async ())-eventNoFilter fltr = forkWeb3 . event' fltr---- | Same as 'event', but does not immediately spawn a new thread.-eventNoFilter'-  :: DecodeEvent i ni e-  => Filter e-  -> (e -> ReaderT Change Web3 EventAction)-  -> Web3 ()-eventNoFilter' fltr = eventManyNoFilter' fltr 0+eventNoFilter :: (DecodeEvent i ni e, JsonRpc m)+              => Filter e+              -> (e -> ReaderT Change m EventAction)+              -> m ()+eventNoFilter fltr = eventManyNoFilter fltr 0 -eventManyNoFilter'-  :: DecodeEvent i ni e-  => Filter e-  -> Integer-  -> (e -> ReaderT Change Web3 EventAction)-  -> Web3 ()-eventManyNoFilter' fltr window handler = do+eventManyNoFilter :: (DecodeEvent i ni e, JsonRpc m)+                  => Filter e+                  -> Integer+                  -> (e -> ReaderT Change m EventAction)+                  -> m ()+eventManyNoFilter fltr window handler = do     start <- mkBlockNumber $ filterFromBlock fltr     let initState = FilterStreamState { fssCurrentBlock = start                                       , fssInitialFilter = fltr@@ -228,21 +207,20 @@           in void $ reduceEventStream (playNewLogs pollingFilterState) handler  -- | 'playLogs' streams the 'filterStream' and calls eth_getLogs on these 'Filter' objects.-playNewLogs-  :: DecodeEvent i ni e-  => FilterStreamState e-  -> MachineT Web3 k [FilterChange e]+playNewLogs :: (DecodeEvent i ni e, JsonRpc m)+            => FilterStreamState e+            -> MachineT m k [FilterChange e] playNewLogs s =      newFilterStream s   ~> autoM Eth.getLogs   ~> autoM (liftIO . mkFilterChanges) -newFilterStream-  :: FilterStreamState e-  -> MachineT Web3 k (Filter e)+newFilterStream :: JsonRpc m+                => FilterStreamState e+                -> MachineT m k (Filter e) newFilterStream initialState = unfoldPlan initialState filterPlan   where-    filterPlan :: FilterStreamState e -> PlanT k (Filter e) Web3 (FilterStreamState e)+    filterPlan :: JsonRpc m => FilterStreamState e -> PlanT k (Filter e) m (FilterStreamState e)     filterPlan s@FilterStreamState{..} = do       if BlockWithNumber fssCurrentBlock > filterToBlock fssInitialFilter         then stop
src/Network/Ethereum/Contract/TH.hs view
@@ -239,7 +239,7 @@           [funD' 'selector [] [|const mIdent|]]         ]   where mIdent    = T.unpack (methodId $ fun {funName = T.replace "'" "" name})-        dataName  = mkName (toUpperFirst (T.unpack $ name <> "Data"))+        dataName  = mkName (toUpperFirst (T.unpack $ T.dropWhile (== '_') name <> "Data"))         fnName    = mkName (toLowerFirst (T.unpack name))         bangInput = fmap funBangType inputs         derivingD = [''Show, ''Eq, ''Ord, ''GHC.Generic]
− src/Network/Ethereum/Web3.hs
@@ -1,44 +0,0 @@--- |--- Module      :  Network.Ethereum.Web3--- Copyright   :  Alexander Krupenkin 2016-2018--- License     :  BSD3------ Maintainer  :  mail@akru.me--- Stability   :  experimental--- Portability :  unportable------ An Ethereum node offers a RPC interface. This interface gives Ðapp’s--- access to the Ethereum blockchain and functionality that the node provides,--- such as compiling smart contract code. It uses a subset of the JSON-RPC 2.0--- specification (no support for notifications or named parameters) as serialisation--- protocol and is available over HTTP and IPC (unix domain sockets on linux/OSX--- and named pipe’s on Windows).------ Web3 Haskell library currently use JSON-RPC over HTTP to access node functionality.-----module Network.Ethereum.Web3-    (-    -- * Base monad for any Ethereum node communication-      Web3-    , runWeb3--    -- * Basic transaction sending-    , module Account--    -- * Basic event listening-    , EventAction(..)-    , event--    -- * Primitive data types-    , module Prim--    -- * Metric unit system-    , module Unit-    ) where--import           Data.Solidity.Prim              as Prim-import           Network.Ethereum.Account        as Account-import           Network.Ethereum.Api.Provider   (Web3, runWeb3)-import           Network.Ethereum.Contract.Event (EventAction (..), event)-import           Network.Ethereum.Unit           as Unit
+ src/Network/Ipfs/Api/Bitswap.hs view
@@ -0,0 +1,41 @@+-- |+-- Module      :  Network.Ipfs.Api.Bitswap+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `bitswap` prefix.+--++module Network.Ipfs.Api.Bitswap where++import           Control.Monad.IO.Class         (MonadIO (..))+import           Data.Text                      (Text)++import           Network.Ipfs.Api.Internal      (_bitswapLedger,+                                                 _bitswapReprovide,+                                                 _bitswapStat, _bitswapWL)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (BitswapLedgerObj,+                                                 BitswapStatObj, BitswapWLObj,+                                                 ReprovideReturnType)+import           Network.Ipfs.Client            (IpfsT)++-- | 'Show some diagnostic information on the bitswap agent.+stat :: MonadIO m => IpfsT m BitswapStatObj+stat = call _bitswapStat++-- | Show blocks currently on the wantlist.+wl :: MonadIO m => IpfsT m BitswapWLObj+wl = call _bitswapWL++-- | Show the current ledger for a peer.+ledger :: MonadIO m => Text -> IpfsT m BitswapLedgerObj+ledger = call . _bitswapLedger++-- | Trigger reprovider.+reprovide :: MonadIO m => IpfsT m ReprovideReturnType+reprovide = call _bitswapReprovide
+ src/Network/Ipfs/Api/Block.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Block+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `block` prefix.+--++module Network.Ipfs.Api.Block where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Aeson                     (decode)+import           Data.Text                      (Text)+import           Network.HTTP.Client            (responseBody)++import           Network.Ipfs.Api.Internal      (_blockGet, _blockStat)+import           Network.Ipfs.Api.Internal.Call (call, multipartCall)+import           Network.Ipfs.Api.Types         (BlockObj, BlockReturnType)+import           Network.Ipfs.Client            (IpfsT)++-- | Get a raw IPFS block.+get :: MonadIO m => Text -> IpfsT m BlockReturnType+get = call . _blockGet++-- | Store input as an IPFS block.+put :: MonadIO m => Text -> IpfsT m (Maybe BlockObj)+put = fmap decodeResponse . multipartCall "block/put"+  where+    decodeResponse = decode . responseBody++-- | Print information of a raw IPFS block.+stat :: MonadIO m => Text -> IpfsT m BlockObj+stat = call . _blockStat
+ src/Network/Ipfs/Api/Bootstrap.hs view
@@ -0,0 +1,34 @@+-- |+-- Module      :  Network.Ipfs.Api.Bootstrap+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `bootstrap` prefix.+--++module Network.Ipfs.Api.Bootstrap where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)++import           Network.Ipfs.Api.Internal      (_bootstrapAdd, _bootstrapList,+                                                 _bootstrapRM)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (BootstrapObj)+import           Network.Ipfs.Client            (IpfsT)++-- | Add peers to the bootstrap list.+add :: MonadIO m => Text -> IpfsT m BootstrapObj+add = call . _bootstrapAdd . Just++-- | Show peers in the bootstrap list.+list :: MonadIO m => IpfsT m BootstrapObj+list = call _bootstrapList++-- | Remove peers from the bootstrap list.+rm :: MonadIO m => Text -> IpfsT m BootstrapObj+rm = call . _bootstrapRM . Just
+ src/Network/Ipfs/Api/Cid.hs view
@@ -0,0 +1,44 @@+-- |+-- Module      :  Network.Ipfs.Api.Cid+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `cid` prefix.+--++module Network.Ipfs.Api.Cid where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)++import           Network.Ipfs.Api.Internal      (_cidBase32, _cidBases,+                                                 _cidCodecs, _cidFormat,+                                                 _cidHashes)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (CidBasesObj, CidCodecsObj,+                                                 CidHashesObj, CidObj)+import           Network.Ipfs.Client            (IpfsT)++-- | List available multibase encodings.+bases :: MonadIO m => IpfsT m [CidBasesObj]+bases = call _cidBases++-- | List available CID codecs.+codecs :: MonadIO m => IpfsT m [CidCodecsObj]+codecs = call _cidCodecs++-- | List available multihashes.+hashes :: MonadIO m => IpfsT m [CidHashesObj]+hashes = call _cidHashes++-- | Convert CIDs to Base32 CID version 1.+base32 :: MonadIO m => Text -> IpfsT m CidObj+base32 = call . _cidBase32++-- | Format and convert a CID in various useful ways.+format :: MonadIO m => Text -> IpfsT m CidObj+format = call . _cidFormat
+ src/Network/Ipfs/Api/Config.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Config+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `config` prefix.+--++module Network.Ipfs.Api.Config where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)+import           Network.HTTP.Client            (responseStatus)+import           Network.HTTP.Types             (Status (..))++import           Network.Ipfs.Api.Internal      (_configGet, _configSet)+import           Network.Ipfs.Api.Internal.Call (call, multipartCall)+import           Network.Ipfs.Api.Types         (ConfigObj)+import           Network.Ipfs.Client            (IpfsT)+++-- | Get ipfs config values.+get :: MonadIO m => Text -> IpfsT m ConfigObj+get = call . _configGet++-- | Set ipfs config values.+set :: MonadIO m => Text -> Maybe Text -> IpfsT m ConfigObj+set key = call . _configSet key++-- | Replace the config with the file at <filePath>.+replace :: MonadIO m => Text -> IpfsT m Bool+replace = fmap isSuccess . multipartCall "config/replace"+  where+    isSuccess = (== 200) . statusCode . responseStatus
+ src/Network/Ipfs/Api/Core.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Core+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Core IPFS API calls.+--++module Network.Ipfs.Api.Core where++import qualified Codec.Archive.Tar                as Tar+import           Control.Monad.IO.Class           (MonadIO (..))+import           Data.Aeson                       (decode)+import           Data.ByteString.Lazy             (fromStrict)+import           Data.Text                        (Text)+import           Data.Text.Encoding               (encodeUtf8)+import           Network.HTTP.Client              (responseBody)+import           Servant.API.ContentTypes         (NoContent)++import           Network.Ipfs.Api.Internal        (_cat, _dns, _get, _id,+                                                   _idPeer, _ls, _shutdown,+                                                   _version)+import           Network.Ipfs.Api.Internal.Call   (call, multipartCall,+                                                   streamCall)+import           Network.Ipfs.Api.Internal.Stream (_ping, _refs, _refsLocal)+import           Network.Ipfs.Api.Types           (AddObj, CatReturnType,+                                                   DnsObj, IdObj, LsObj,+                                                   VersionObj)+import           Network.Ipfs.Client              (IpfsT)++-- | Show IPFS object data.+cat :: MonadIO m => Text -> IpfsT m CatReturnType+cat = call . _cat++-- | Add a file or directory to ipfs.+add :: MonadIO m => Text -> IpfsT m (Maybe AddObj)+add = fmap decodeResponse . multipartCall "add"+  where+    decodeResponse = decode . responseBody++-- | List directory contents for Unix filesystem objects.+ls :: MonadIO m => Text -> IpfsT m LsObj+ls = call . _ls++-- | Download IPFS objects.+get :: MonadIO m => Text -> IpfsT m Text+get hash = do+    ret <- call $ _get hash+    do liftIO $ Tar.unpack "getResponseDirectory" . Tar.read . fromStrict $ encodeUtf8 ret+       pure "The content has been stored in getResponseDirectory."++-- | Show ipfs version information.+version :: MonadIO m => IpfsT m VersionObj+version = call _version++-- | Show ipfs node id info.+id :: MonadIO m => IpfsT m IdObj+id = call _id++-- | Show ipfs node id info of the given peerId.+idPeer :: MonadIO m => Text -> IpfsT m IdObj+idPeer = call . _idPeer++-- | Resolve DNS links.+dns :: MonadIO m => Text -> IpfsT m DnsObj+dns = call . _dns++-- | List links (references) from an object.+refs :: MonadIO m => Text -> m ()+refs = streamCall . _refs++-- | List all local references.+refsLocal :: MonadIO m => m ()+refsLocal = streamCall _refsLocal++-- | Send echo request packets to IPFS hosts.+ping :: MonadIO m => Text -> m ()+ping = streamCall . _ping++-- | Shut down the ipfs daemon.+shutdown :: MonadIO m => IpfsT m NoContent+shutdown = call _shutdown
+ src/Network/Ipfs/Api/Dag.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Dag+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `dag` prefix.+--++module Network.Ipfs.Api.Dag where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Aeson                     (decode)+import           Data.Text                      (Text)+import           Network.HTTP.Client            (responseBody)++import           Network.Ipfs.Api.Internal      (_dagGet, _dagResolve)+import           Network.Ipfs.Api.Internal.Call (call, multipartCall)+import           Network.Ipfs.Api.Types         (DagPutObj, DagResolveObj,+                                                 DagReturnType)+import           Network.Ipfs.Client            (IpfsT)++-- | Get a dag node from ipfs.+get :: MonadIO m => Text -> IpfsT m DagReturnType+get = call . _dagGet++-- | Resolve ipld block.+resolve :: MonadIO m => Text -> IpfsT m DagResolveObj+resolve = call . _dagResolve++-- | Add a dag node to ipfs.+put :: MonadIO m => Text -> IpfsT m (Maybe DagPutObj)+put = fmap decodeResponse . multipartCall "dag/put"+  where+    decodeResponse = decode . responseBody
+ src/Network/Ipfs/Api/Dht.hs view
@@ -0,0 +1,41 @@+-- |+-- Module      :  Network.Ipfs.Api.Dht+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `dht` prefix.+--++module Network.Ipfs.Api.Dht where++import           Control.Monad.IO.Class           (MonadIO)+import           Data.Text                        (Text)++import           Network.Ipfs.Api.Internal.Call   (streamCall)+import           Network.Ipfs.Api.Internal.Stream (_dhtFindPeer, _dhtFindProvs,+                                                   _dhtGet, _dhtProvide,+                                                   _dhtQuery)++-- | Find the multiaddresses associated with the given peerId.+findPeer :: MonadIO m => Text -> m ()+findPeer = streamCall . _dhtFindPeer++-- | Find peers that can provide a specific value, given a key.+findProvs :: MonadIO m => Text -> m ()+findProvs = streamCall . _dhtFindProvs++-- | Given a key, query the routing system for its best value.+get :: MonadIO m => Text -> m ()+get cid = streamCall $ _dhtGet cid++-- | Announce to the network that you are providing given values.+provide :: MonadIO m => Text -> m ()+provide = streamCall . _dhtProvide++-- | Find the closest Peer IDs to a given peerID by querying the DHT.+query :: MonadIO m => Text -> m ()+query = streamCall . _dhtQuery
+ src/Network/Ipfs/Api/Files.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Files+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `files` prefix.+--++module Network.Ipfs.Api.Files where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text, pack)+import           Network.HTTP.Client            (responseStatus)+import           Network.HTTP.Types             (Status (..))+import           Servant.API.ContentTypes       (NoContent)++import           Network.Ipfs.Api.Internal      (_filesChcid, _filesCp,+                                                 _filesFlush, _filesLs,+                                                 _filesMkdir, _filesMv,+                                                 _filesRead, _filesRm,+                                                 _filesStat)+import           Network.Ipfs.Api.Internal.Call (call, multipartCall)+import           Network.Ipfs.Api.Types         (FilesFlushObj, FilesLsObj,+                                                 FilesReadType, FilesStatObj)+import           Network.Ipfs.Client            (IpfsT)++-- | Change the cid version or hash function of the root node of a given mfsPath.+chcidVer :: MonadIO m => Text -> Int -> IpfsT m NoContent+chcidVer mfsPath = call . _filesChcid (Just mfsPath) . Just++-- | Copy files into mfs.+cp :: MonadIO m => Text -> Text -> IpfsT m NoContent+cp src = call . _filesCp (Just src) . Just++-- | Flush a given path's data to disk.+flush :: MonadIO m => Text -> IpfsT m FilesFlushObj+flush = call . _filesFlush . Just++-- | List directories in the local mutable namespace.+ls :: MonadIO m => Text -> IpfsT m FilesLsObj+ls = call . _filesLs . Just++-- | Make directories.+mkdir :: MonadIO m => Text -> IpfsT m NoContent+mkdir = call . _filesMkdir . Just++-- | Move files.+mv :: MonadIO m => Text -> Text -> IpfsT m NoContent+mv src = call . _filesMv (Just src) . Just++-- | Read a file in a given mfs.+read :: MonadIO m => Text -> IpfsT m FilesReadType+read = call . _filesRead . Just++-- | Display file status.+stat :: MonadIO m => Text -> IpfsT m FilesStatObj+stat = call . _filesStat . Just++-- | Remove a file.+filesRm :: MonadIO m => Text -> IpfsT m NoContent+filesRm = call . flip _filesRm (Just True) . Just++-- | Write to a mutable file in a given filesystem.+write :: MonadIO m => Text -> Text -> Bool -> IpfsT m Bool+write mfsPath filePath toTruncate = isSuccess <$> multipartCall uri filePath+  where+    uri = "files/write?arg=" <> mfsPath <> "&create=true" <> "&truncate=" <> (pack $ show toTruncate)+    isSuccess = (200 ==) . statusCode . responseStatus
+ src/Network/Ipfs/Api/Internal.hs view
@@ -0,0 +1,100 @@+-- |+-- Module      :  Network.Ipfs.Api.Internal+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- IPFS API internals.+--++module Network.Ipfs.Api.Internal where++import           Data.Proxy             (Proxy (..))+import           Data.Text              (Text)+import           Servant.API+import           Servant.Client         (ClientM, client)++import           Network.Ipfs.Api.Types++_ipfsApi :: Proxy IpfsApi+_ipfsApi = Proxy++_cat :: Text -> ClientM CatReturnType+_ls :: Text -> ClientM LsObj+_get :: Text -> ClientM GetReturnType+_swarmPeers :: ClientM SwarmPeersObj+_swarmConnect :: Maybe Text -> ClientM SwarmObj+_swarmDisconnect :: Maybe Text -> ClientM SwarmObj+_swarmFilters :: ClientM SwarmObj+_swarmFilterAdd :: Maybe Text -> ClientM SwarmObj+_swarmFilterRm :: Maybe Text -> ClientM SwarmObj+_bitswapStat :: ClientM BitswapStatObj+_bitswapWL :: ClientM BitswapWLObj+_bitswapLedger :: Text -> ClientM BitswapLedgerObj+_bitswapReprovide :: ClientM ReprovideReturnType+_cidBases :: ClientM [CidBasesObj]+_cidCodecs :: ClientM [CidCodecsObj]+_cidHashes :: ClientM [CidHashesObj]+_cidBase32 :: Text -> ClientM CidObj+_cidFormat :: Text -> ClientM CidObj+_blockGet :: Text -> ClientM BlockReturnType+_blockStat :: Text -> ClientM BlockObj+_dagGet :: Text -> ClientM DagReturnType+_dagResolve :: Text -> ClientM DagResolveObj+_configGet :: Text -> ClientM ConfigObj+_configSet :: Text -> Maybe Text -> ClientM ConfigObj+_objectData :: Text -> ClientM ObjectReturnType+_objectNew :: ClientM ObjectObj+_objectGetLinks :: Text -> ClientM ObjectLinksObj+_objectAddLink :: Text -> Maybe Text -> Maybe Text -> ClientM ObjectLinksObj+_objectRmLink :: Text -> Maybe Text -> ClientM ObjectLinksObj+_objectGet :: Text -> ClientM ObjectGetObj+_objectDiff :: Text -> Maybe Text -> ClientM ObjectDiffObj+_objectStat :: Text -> ClientM ObjectStatObj+_pinAdd :: Text -> ClientM PinObj+_pinRemove :: Text -> ClientM PinObj+_bootstrapAdd :: Maybe Text -> ClientM BootstrapObj+_bootstrapList :: ClientM BootstrapObj+_bootstrapRM :: Maybe Text -> ClientM BootstrapObj+_statsBw :: ClientM StatsBwObj+_statsRepo :: ClientM StatsRepoObj+_version :: ClientM VersionObj+_id :: ClientM IdObj+_idPeer :: Text -> ClientM IdObj+_dns :: Text -> ClientM DnsObj+_pubsubLs :: ClientM PubsubObj+_pubsubPeers :: ClientM PubsubObj+_pubsubPublish :: Text -> Maybe Text -> ClientM NoContent+_logLs :: ClientM LogLsObj+_logLevel :: Text -> Maybe Text -> ClientM LogLevelObj+_repoVersion :: ClientM RepoVersionObj+_repoFsck :: ClientM RepoFsckObj+_keyGen :: Text -> (Maybe Text) -> ClientM KeyDetailsObj+_keyList :: ClientM KeyObj+_keyRename :: Text -> (Maybe Text) -> ClientM KeyRenameObj+_keyRm :: Text -> ClientM KeyObj+_filesChcid :: Maybe Text -> Maybe Int -> ClientM NoContent+_filesCp :: Maybe Text -> Maybe Text -> ClientM NoContent+_filesFlush :: Maybe Text -> ClientM FilesFlushObj+_filesLs :: Maybe Text -> ClientM FilesLsObj+_filesMkdir :: Maybe Text -> ClientM NoContent+_filesMv :: Maybe Text -> Maybe Text -> ClientM NoContent+_filesRead :: Maybe Text -> ClientM FilesReadType+_filesRm :: Maybe Text -> Maybe Bool -> ClientM NoContent+_filesStat :: Maybe Text -> ClientM FilesStatObj+_shutdown :: ClientM NoContent++_cat :<|> _ls :<|> _get :<|> _swarmPeers :<|> _swarmConnect :<|> _swarmDisconnect :<|>+  _swarmFilters :<|> _swarmFilterAdd :<|> _swarmFilterRm :<|>  _bitswapStat :<|> _bitswapWL :<|> _bitswapLedger :<|>+  _bitswapReprovide :<|> _cidBases :<|> _cidCodecs :<|> _cidHashes :<|> _cidBase32 :<|> _cidFormat :<|>+  _blockGet  :<|> _blockStat :<|> _dagGet :<|> _dagResolve :<|> _configGet :<|>+  _configSet :<|> _objectData :<|> _objectNew :<|> _objectGetLinks :<|> _objectAddLink :<|> _objectRmLink :<|>+  _objectGet :<|> _objectDiff :<|> _objectStat :<|> _pinAdd :<|> _pinRemove :<|> _bootstrapAdd :<|>+  _bootstrapList :<|> _bootstrapRM :<|> _statsBw :<|> _statsRepo :<|> _version :<|> _id :<|> _idPeer :<|>+  _dns :<|> _pubsubLs :<|> _pubsubPeers :<|> _pubsubPublish :<|> _logLs :<|> _logLevel :<|> _repoVersion :<|>+  _repoFsck :<|> _keyGen :<|> _keyList :<|> _keyRename :<|> _keyRm :<|> _filesChcid :<|> _filesCp :<|>+  _filesFlush :<|> _filesLs :<|> _filesMkdir :<|> _filesMv :<|> _filesRead :<|> _filesRm :<|> _filesStat :<|>+  _shutdown = client _ipfsApi
+ src/Network/Ipfs/Api/Internal/Call.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE TypeOperators              #-}++-- |+-- Module      :  Network.Ipfs.Api.Internal.Call+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Module containing IPFS API call functions.+--++module Network.Ipfs.Api.Internal.Call where++import           Control.Monad.Except+import           Control.Monad.Reader+import           Data.ByteString.Lazy                  (ByteString)+import           Data.Text                             (Text, pack, unpack)+import           Network.HTTP.Client                   as Net hiding (Proxy)+import           Network.HTTP.Client.MultipartFormData+import           Servant.Client+import qualified Servant.Client.Streaming              as S+import           Servant.Types.SourceT                 (SourceT (..), foreach)++import           Network.Ipfs.Client                   (IpfsT)++-- | Regular Call function.+call :: MonadIO m => ClientM a -> IpfsT m a+call func = do+  (manager', url, _) <- ask+  resp <- liftIO (runClientM func (mkClientEnv manager' url))+  case resp of+    Left l  -> throwError l+    Right r -> return r++-- | Call function for ‘multipart/form-data’.+multipartCall :: MonadIO m => Text -> Text -> IpfsT m (Net.Response ByteString)+multipartCall funcUri filePath = do+    (reqManager, _, url) <- ask+    req <- liftIO $ parseRequest $ unpack (pack url <> "/" <> funcUri )+    liftIO $ flip httpLbs reqManager =<< formDataBody form req+  where+    form = [ partFileSource "file" $ unpack filePath ]++-- | Call function for Streams.+streamCall :: (MonadIO m, Show a) => S.ClientM (SourceT IO a) -> m ()+streamCall func = liftIO $ do+    manager' <- newManager defaultManagerSettings+    S.withClientM func (S.mkClientEnv manager' (BaseUrl Http "localhost" 5001 "/api/v0")) $ \e -> case e of+        Left err -> putStrLn $ "Error: " ++ show err+        Right rs -> foreach fail print rs
+ src/Network/Ipfs/Api/Internal/Stream.hs view
@@ -0,0 +1,41 @@+-- |+-- Module      :  Network.Ipfs.Api.Internal.Stream+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Ipfs Stream API provider.+--++module Network.Ipfs.Api.Internal.Stream where++import qualified Data.ByteString.Lazy.Char8    ()+import           Data.Proxy+import           Data.Text+import           Network.HTTP.Client           ()+import           Servant.API+import           Servant.Client.Streaming      as S++import           Network.Ipfs.Api.Types.Stream++_ipfsStreamApi :: Proxy IpfsStreamApi+_ipfsStreamApi =  Proxy++_ping :: Text -> ClientM (SourceIO PingObj)+_dhtFindPeer :: Text -> ClientM (SourceIO DhtObj)+_dhtFindProvs :: Text -> ClientM (SourceIO DhtObj)+_dhtGet :: Text -> ClientM (SourceIO DhtObj)+_dhtProvide :: Text -> ClientM (SourceIO DhtObj)+_dhtQuery :: Text -> ClientM (SourceIO DhtObj)+_logTail :: ClientM (SourceIO LogReturnType)+_repoGc :: ClientM (SourceIO RepoGcObj)+_repoVerify :: ClientM (SourceIO RepoVerifyObj)+_refs :: Text -> ClientM (SourceIO RefsObj)+_refsLocal :: ClientM (SourceIO RefsObj)+_pubsubSubscribe :: Text -> ClientM (SourceIO PubsubSubObj)++_ping :<|> _dhtFindPeer :<|> _dhtFindProvs :<|> _dhtGet :<|> _dhtProvide :<|> _dhtQuery :<|>+  _logTail :<|> _repoGc :<|> _repoVerify :<|> _refs :<|> _refsLocal :<|> _pubsubSubscribe = client _ipfsStreamApi
+ src/Network/Ipfs/Api/Key.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE TypeOperators              #-}++-- |+-- Module      :  Network.Ipfs.Api.Key+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `key` prefix.+--++module Network.Ipfs.Api.Key where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)++import           Network.Ipfs.Api.Internal      (_keyGen, _keyList, _keyRename,+                                                 _keyRm)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (KeyDetailsObj, KeyObj,+                                                 KeyRenameObj)+import           Network.Ipfs.Client            (IpfsT)+++-- | 'List all local keypairs.+list :: MonadIO m => IpfsT m KeyObj+list = call _keyList++-- | Create a new keypair.+gen :: MonadIO m => Text -> Text -> IpfsT m KeyDetailsObj+gen name = call . _keyGen name . Just++-- | Rename a keypair.+rename :: MonadIO m => Text -> Text -> IpfsT m KeyRenameObj+rename was = call . _keyRename was . Just++-- | Remove a keypair.+rm :: MonadIO m => Text -> IpfsT m KeyObj+rm = call . _keyRm+
+ src/Network/Ipfs/Api/Log.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE TypeOperators              #-}++-- |+-- Module      :  Network.Ipfs.Api.Log+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `log` prefix.+--++module Network.Ipfs.Api.Log where++import           Control.Monad.IO.Class           (MonadIO)+import           Data.Text                        (Text)++import           Network.Ipfs.Api.Internal        (_logLevel, _logLs)+import           Network.Ipfs.Api.Internal.Call   (call, streamCall)+import           Network.Ipfs.Api.Internal.Stream (_logTail)+import           Network.Ipfs.Api.Types           (LogLevelObj, LogLsObj)+import           Network.Ipfs.Client              (IpfsT)+++-- | Change the logging level.+level :: MonadIO m => Text -> Text -> IpfsT m LogLevelObj+level subsystem = call . _logLevel subsystem . Just++-- | Read the event log.+tail :: MonadIO m => m ()+tail = streamCall _logTail++-- | List the logging subsystems.+ls :: MonadIO m => IpfsT m LogLsObj+ls = call _logLs
+ src/Network/Ipfs/Api/Object.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Object+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `object` prefix.+--++module Network.Ipfs.Api.Object where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Aeson                     (decode)+import           Data.Text                      (Text)+import           Network.HTTP.Client            (responseBody)++import           Network.Ipfs.Api.Internal      (_objectAddLink, _objectData,+                                                 _objectDiff, _objectGet,+                                                 _objectGetLinks, _objectNew,+                                                 _objectRmLink, _objectStat)+import           Network.Ipfs.Api.Internal.Call (call, multipartCall)+import           Network.Ipfs.Api.Types         (ObjectDiffObj, ObjectGetObj,+                                                 ObjectLinksObj, ObjectObj,+                                                 ObjectReturnType,+                                                 ObjectStatObj)+import           Network.Ipfs.Client            (IpfsT)++-- | Output the raw bytes of an IPFS object.+object :: MonadIO m => Text -> IpfsT m ObjectReturnType+object = call . _objectData++-- | Create a new object from an ipfs template.+new :: MonadIO m => IpfsT m ObjectObj+new = call _objectNew++-- | Output the links pointed to by the specified object.+getLinks :: MonadIO m => Text -> IpfsT m ObjectLinksObj+getLinks = call . _objectGetLinks++-- | Add a Merkle-link to the given object and return the hash of the result.+addLink :: MonadIO m => Text -> Text -> Text -> IpfsT m ObjectLinksObj+addLink hash name = call . _objectAddLink hash (Just name) . Just++-- | Remove a Merkle-link from the given object and return the hash of the result.+rmLink :: MonadIO m => Text -> Text -> IpfsT m ObjectLinksObj+rmLink key = call . _objectRmLink key . Just++-- | Append data to what already exists in the data segment in the given object.+appendData :: MonadIO m => Text -> Text -> IpfsT m (Maybe ObjectLinksObj)+appendData key = fmap decodeResponse . multipartCall ("object/patch/append-data?arg=" <> key)+  where+    decodeResponse = decode . responseBody++-- | Set the data field of an IPFS object.+setData :: MonadIO m => Text -> Text -> IpfsT m (Maybe ObjectLinksObj)+setData key = fmap decodeResponse . multipartCall ("object/patch/set-data?arg=" <> key)+  where+    decodeResponse = decode . responseBody++-- | Get and serialize the DAG node named by key.+get :: MonadIO m => Text -> IpfsT m ObjectGetObj+get = call . _objectGet++-- | 'Display the diff between two ipfs objects.+diff :: MonadIO m => Text -> Text -> IpfsT m ObjectDiffObj+diff firstKey = call . _objectDiff firstKey . Just++-- | Store input as a DAG object, print its key.+put :: MonadIO m => Text -> IpfsT m (Maybe ObjectObj)+put = fmap decodeResponse . multipartCall "object/put"+  where+    decodeResponse = decode . responseBody++-- | Get stats for the DAG node named by key.+objectStat :: MonadIO m => Text -> IpfsT m ObjectStatObj+objectStat = call . _objectStat
+ src/Network/Ipfs/Api/Pin.hs view
@@ -0,0 +1,29 @@+-- |+-- Module      :  Network.Ipfs.Api.Pin+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `pin` prefix.+--++module Network.Ipfs.Api.Pin where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)++import           Network.Ipfs.Api.Internal      (_pinAdd, _pinRemove)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (PinObj)+import           Network.Ipfs.Client            (IpfsT)++-- | Pin objects to local storage.+add :: MonadIO m => Text -> IpfsT m PinObj+add = call . _pinAdd++-- | Remove pinned objects from local storage.+remove :: MonadIO m => Text -> IpfsT m PinObj+remove = call . _pinRemove
+ src/Network/Ipfs/Api/Pubsub.hs view
@@ -0,0 +1,39 @@+-- |+-- Module      :  Network.Ipfs.Api.Pubsub+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `pubsub` prefix.+--++module Network.Ipfs.Api.Pubsub where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)+import           Servant.API.ContentTypes       (NoContent)++import           Network.Ipfs.Api.Internal      (_pubsubLs, _pubsubPeers,+                                                 _pubsubPublish)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (PubsubObj)+import           Network.Ipfs.Client            (IpfsT)++-- | List subscribed topics by name.+ls :: MonadIO m => IpfsT m PubsubObj+ls = call _pubsubLs++-- | List peers we are currently pubsubbing with.+peers :: MonadIO m => IpfsT m PubsubObj+peers = call _pubsubPeers++-- | Publish a message to a given pubsub topic.+publish :: MonadIO m => Text -> Text -> IpfsT m NoContent+publish topic = call . _pubsubPublish topic . Just++-- | Subscribe to messages on a given topic.+--subscribe :: Text -> m ()+--subscribe = pubsubCall . _pubsubSubscribe
+ src/Network/Ipfs/Api/Repo.hs view
@@ -0,0 +1,37 @@+-- |+-- Module      :  Network.Ipfs.Api.Repo+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `repo` prefix.+--++module Network.Ipfs.Api.Repo where++import           Control.Monad.IO.Class           (MonadIO)++import           Network.Ipfs.Api.Internal        (_repoFsck, _repoVersion)+import           Network.Ipfs.Api.Internal.Call   (call, streamCall)+import           Network.Ipfs.Api.Internal.Stream (_repoGc, _repoVerify)+import           Network.Ipfs.Api.Types           (RepoFsckObj, RepoVersionObj)+import           Network.Ipfs.Client              (IpfsT)++-- | Show the repo version.+version :: MonadIO m => IpfsT m RepoVersionObj+version = call _repoVersion++-- | Remove repo lockfiles.+fsck :: MonadIO m => IpfsT m RepoFsckObj+fsck = call _repoFsck++-- | Perform a garbage collection sweep on the repo.+gc :: MonadIO m => m ()+gc = streamCall _repoGc++-- | Verify all blocks in repo are not corrupted.+repoVerify :: MonadIO m => m ()+repoVerify = streamCall _repoVerify
+ src/Network/Ipfs/Api/Stats.hs view
@@ -0,0 +1,28 @@+-- |+-- Module      :  Network.Ipfs.Api.Stats+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `stats` prefix.+--++module Network.Ipfs.Api.Stats where++import           Control.Monad.IO.Class         (MonadIO)++import           Network.Ipfs.Api.Internal      (_statsBw, _statsRepo)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (StatsBwObj, StatsRepoObj)+import           Network.Ipfs.Client            (IpfsT)++-- | IPFS bandwidth information.+bw :: MonadIO m => IpfsT m StatsBwObj+bw = call _statsBw++-- | Get stats for the currently used repo.+repo :: MonadIO m => IpfsT m StatsRepoObj+repo = call _statsRepo
+ src/Network/Ipfs/Api/Swarm.hs view
@@ -0,0 +1,49 @@+-- |+-- Module      :  Network.Ipfs.Api.Swarm+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Api calls with `swarm` prefix.+--++module Network.Ipfs.Api.Swarm where++import           Control.Monad.IO.Class         (MonadIO)+import           Data.Text                      (Text)++import           Network.Ipfs.Api.Internal      (_swarmConnect,+                                                 _swarmDisconnect,+                                                 _swarmFilterAdd,+                                                 _swarmFilterRm, _swarmFilters,+                                                 _swarmPeers)+import           Network.Ipfs.Api.Internal.Call (call)+import           Network.Ipfs.Api.Types         (SwarmObj, SwarmPeersObj)+import           Network.Ipfs.Client            (IpfsT)++-- | List peers with open connections.+swarmPeers :: MonadIO m => IpfsT m SwarmPeersObj+swarmPeers = call _swarmPeers++-- | Open connection to a given address. 'peerId' has to be of the format - /ipfs/id+connect :: MonadIO m => Text -> IpfsT m SwarmObj+connect = call . _swarmConnect . Just++-- | Close connection to a given address. 'peerId' has to be of the format - /ipfs/id+disconnect :: MonadIO m => Text -> IpfsT m SwarmObj+disconnect = call . _swarmDisconnect . Just++-- | Manipulate address filters.+filters :: MonadIO m => IpfsT m SwarmObj+filters = call _swarmFilters++-- | Add an address filter. 'peerId' has to be of the format - /ip4/{IP addr of peer}/ipcidr/{ip network prefix}+filterAdd :: MonadIO m => Text -> IpfsT m SwarmObj+filterAdd = call . _swarmFilterAdd . Just++-- | Remove an address filter.+filterRm :: MonadIO m => Text -> IpfsT m SwarmObj+filterRm = call . _swarmFilterRm . Just
+ src/Network/Ipfs/Api/Types.hs view
@@ -0,0 +1,823 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TypeOperators         #-}++-- |+-- Module      :  Network.Ipfs.Api.Types+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- IPFS API types.+--++module Network.Ipfs.Api.Types where++import           Control.Arrow              (left)+import           Control.Monad+import           Data.Aeson+import           Data.ByteString.Lazy       (toStrict)+import qualified Data.ByteString.Lazy.Char8 ()+import qualified Data.HashMap.Strict        as H+import           Data.Int+import           Data.Text                  (Text)+import qualified Data.Text.Encoding         as TextS+import           Data.Typeable+import           Network.HTTP.Client        ()+import qualified Network.HTTP.Media         as M ((//))+import           Servant.API++type CatReturnType = Text+type ReprovideReturnType = Text+type GetReturnType = Text+type BlockReturnType = Text+type DagReturnType = Text+type ObjectReturnType = Text+type FilesReadType = Text++data DirLink = DirLink+    { dlName        :: Text+    , dlHash        :: Text+    , dlSize        :: Int64+    , dlContentType :: Int+    , dlTarget      :: Text+    }+    deriving (Show, Eq)++data DirObj = DirObj+    { dirHash :: Text+    , links   :: [DirLink]+    }+    deriving (Show, Eq)++data AddObj = AddObj+    { name :: Text+    , hash :: Text+    , size :: Text+    }+    deriving (Show, Eq)++instance FromJSON AddObj where+    parseJSON (Object o) =+        AddObj  <$> o .: "Name"+                <*> o .: "Hash"+                <*> o .: "Size"++    parseJSON _ = mzero++data LsObj = LsObj+    { objs :: [DirObj]+    }+    deriving (Show, Eq)++data SwarmStreamObj = SwarmStreamObj+    { protocol :: Text+    }+    deriving (Show, Eq)++data SwarmPeerObj = SwarmPeerObj+    { address   :: Text+    , direction :: Int+    , latency   :: Text+    , muxer     :: Text+    , peer      :: Text+    , streams   :: Maybe [SwarmStreamObj]+    }+    deriving (Show, Eq)++data SwarmPeersObj = SwarmPeersObj+    { peers :: [SwarmPeerObj]+    }+    deriving (Show, Eq)++data SwarmObj = SwarmObj+    { strings :: [Text]+    }+    deriving (Show, Eq)++data WantlistObj = WantlistObj+    { forSlash :: Text+    }+    deriving (Show, Eq)++data BitswapStatObj = BitswapStatObj+    { blocksReceived   :: Int64+    , blocksSent       :: Int64+    , dataReceived     :: Int64+    , dataSent         :: Int64+    , dupBlksReceived  :: Int64+    , dupDataReceived  :: Int64+    , messagesReceived :: Int64+    , bitswapPeers     :: [Text]+    , provideBufLen    :: Int+    , wantlist         :: [WantlistObj]+    }+    deriving (Show, Eq)++data BitswapWLObj = BitswapWLObj+    { bitswapKeys :: [WantlistObj]+    }+    deriving (Show, Eq)++data BitswapLedgerObj = BitswapLedgerObj+    { exchanged  :: Int64+    , ledgerPeer :: Text+    , recv       :: Int64+    , sent       :: Int64+    , value      :: Double+    }+    deriving (Show, Eq)++data CidBasesObj = CidBasesObj+    { baseCode :: Int+    , baseName :: Text+    }+    deriving (Show, Eq)++data CidCodecsObj = CidCodecsObj+    { codecCode :: Int+    , codecName :: Text+    }+    deriving (Show, Eq)++data CidHashesObj = CidHashesObj+    { multihashCode :: Int+    , multihashName :: Text+    }+    deriving (Show, Eq)++data CidObj = CidObj+    { cidStr    :: Text+    , errorMsg  :: Text+    , formatted :: Text+    }+    deriving (Show, Eq)++data BlockObj = BlockObj+    { key       :: Text+    , blockSize :: Int+    }+    deriving (Show, Eq)++data DagCidObj = DagCidObj+    { cidSlash :: Text+    }+    deriving (Show, Eq)++data DagResolveObj = DagResolveObj+    { cid     :: DagCidObj+    , remPath :: Text+    }+    deriving (Show, Eq)++data DagPutObj = DagPutObj+    { putCid :: DagCidObj+    }+    deriving (Show, Eq)++data ConfigObj = ConfigObj+    { configKey   :: Text+    , configValue :: Text+    }+    deriving (Show, Eq)++data ObjectLinkObj = ObjectLinkObj+    { linkHash :: Text+    , linkName :: Text+    , linkSize :: Int64+    }+    deriving (Show, Eq)++data ObjectObj = ObjectObj+    { newObjectHash :: Text+    }+    deriving (Show, Eq)++data ObjectLinksObj = WithLinks+    { objectHash  :: Text+    , objectLinks :: [ObjectLinkObj]+    }+    | WithoutLinks+    { objectHash :: Text+    }+    deriving (Show, Eq)++data ObjectGetObj = ObjectGetObj+    { objectName     :: Text+    , objectGetLinks :: [ObjectLinkObj]+    }+    deriving (Show, Eq)++data ObjectStatObj = ObjectStatObj+    { objBlockSize   :: Int+    , cumulativeSize :: Int+    , dataSize       :: Int+    , objHash        :: Text+    , linksSize      :: Int+    , numLinks       :: Int+    }+    deriving (Show, Eq)++data DiffObj = DiffObj+    { diffSlash :: Text+    }+    deriving (Show, Eq)++data ObjectChangeObj = ObjectChangeObj+    { after    :: Maybe DiffObj+    , before   :: DiffObj+    , path     :: Text+    , diffType :: Int+    }+    deriving (Show, Eq)++data ObjectDiffObj = ObjectDiffObj+    { changes :: [ObjectChangeObj]+    }+    deriving (Show, Eq)++data PinObj = WithoutProgress+    { pins :: [Text]+    }+    | WithProgress+    { pins     :: [Text]+    , progress :: Int+    }+    deriving (Show, Eq)++data BootstrapObj = BootstrapObj+    { bootstrapPeers :: [Text]+    }+    deriving (Show, Eq)++data StatsBwObj = StatsBwObj+    { rateIn   :: Double+    , rateOut  :: Double+    , totalIn  :: Int64+    , totalOut :: Int64+    }+    deriving (Show, Eq)++data StatsRepoObj = StatsRepoObj+    { numObjects  :: Int64+    , repoPath    :: Text+    , repoSize    :: Int64+    , storageMax  :: Int64+    , repoVersion :: Text+    }+    deriving (Show, Eq)++data VersionObj = VersionObj+    { commit  :: Text+    , golang  :: Text+    , repo    :: Text+    , system  :: Text+    , version :: Text+    }+    deriving (Show, Eq)++data IdObj = IdObj+    { addresses       :: [Text]+    , agentVersion    :: Text+    , id              :: Text+    , protocolVersion :: Text+    , publicKey       :: Text+    }+    deriving (Show, Eq)++data DnsObj = DnsObj+    { dnsPath :: Text+    }+    deriving (Show, Eq)++data PubsubObj = PubsubObj+    { pubsubStrings :: [Text]+    }+    deriving (Show, Eq)++data LogLsObj = LogLsObj+    { logLsStrings :: [Text]+    }+    deriving (Show, Eq)++data LogLevelObj = LogLevelObj+    { message :: Text+    }+    deriving (Show, Eq)++data RepoVersionObj = RepoVersionObj+    { repoVer :: Text+    }+    deriving (Show, Eq)++data RepoFsckObj = RepoFsckObj+    { repoMessage :: Text+    }+    deriving (Show, Eq)++data KeyDetailsObj = KeyDetailsObj+    { keyId   :: Text+    , keyName :: Text+    }+    deriving (Show, Eq)++data KeyObj = KeyObj+    { keys :: [KeyDetailsObj]+    }+    deriving (Show, Eq)++data KeyRenameObj = KeyRenameObj+    { peerId    :: Text+    , now       :: Text+    , overwrite :: Bool+    , was       :: Text+    }+    deriving (Show, Eq)++data FilesStatObj = FilesStatObj+    { fileObjectHash       :: Text+    , objectSize           :: Int+    , cumulativeObjectSize :: Int+    , blocks               :: Int+    , objectType           :: Text+    }+    deriving (Show, Eq)++data FilesEntryObj = FilesEntryObj+    { entryName :: Text+    , entryType :: Int+    , entrySize :: Int+    , entryHash :: Text+    }+    deriving (Show, Eq)++data FilesLsObj = FilesLsObj+    { enteries :: [FilesEntryObj]+    }+    deriving (Show, Eq)++data FilesFlushObj = FilesFlushObj+    { fileCid :: Text+    }+    deriving (Show, Eq)++instance FromJSON DirLink where+    parseJSON (Object o) =+        DirLink  <$> o .: "Name"+                 <*> o .: "Hash"+                 <*> o .: "Size"+                 <*> o .: "Type"+                 <*> o .: "Target"++    parseJSON _ = mzero++instance FromJSON DirObj where+    parseJSON (Object o) =+        DirObj  <$> o .: "Hash"+                <*> o .: "Links"++    parseJSON _ = mzero++instance FromJSON LsObj where+    parseJSON (Object o) =+        LsObj  <$> o .: "Objects"++    parseJSON _ = mzero+++instance FromJSON SwarmStreamObj where+    parseJSON (Object o) =+        SwarmStreamObj  <$> o .: "Protocol"++    parseJSON _ = mzero++instance FromJSON SwarmPeerObj where+    parseJSON (Object o) =+        SwarmPeerObj  <$> o .: "Addr"+                      <*> o .: "Direction"+                      <*> o .: "Latency"+                      <*> o .: "Muxer"+                      <*> o .: "Peer"+                      <*> o .: "Streams"++    parseJSON _ = mzero++instance FromJSON SwarmPeersObj where+    parseJSON (Object o) =+        SwarmPeersObj  <$> o .: "Peers"++    parseJSON _ = mzero+++instance FromJSON SwarmObj where+    parseJSON (Object o) =+        SwarmObj  <$> o .: "Strings"++    parseJSON _ = mzero++instance FromJSON WantlistObj where+    parseJSON (Object o) =+        WantlistObj  <$> o .: "/"++    parseJSON _ = mzero++instance FromJSON BitswapStatObj where+    parseJSON (Object o) =+        BitswapStatObj  <$> o .: "BlocksReceived"+                        <*> o .: "BlocksSent"+                        <*> o .: "DataReceived"+                        <*> o .: "DataSent"+                        <*> o .: "DupBlksReceived"+                        <*> o .: "DupDataReceived"+                        <*> o .: "MessagesReceived"+                        <*> o .: "Peers"+                        <*> o .: "ProvideBufLen"+                        <*> o .: "Wantlist"++    parseJSON _ = mzero+++instance FromJSON BitswapWLObj where+    parseJSON (Object o) =+        BitswapWLObj  <$> o .: "Keys"++    parseJSON _ = mzero++instance FromJSON BitswapLedgerObj where+    parseJSON (Object o) =+        BitswapLedgerObj  <$> o .: "Exchanged"+                          <*> o .: "Peer"+                          <*> o .: "Recv"+                          <*> o .: "Sent"+                          <*> o .: "Value"++    parseJSON _ = mzero++instance FromJSON CidBasesObj where+    parseJSON (Object o) =+        CidBasesObj  <$> o .: "Code"+                     <*> o .: "Name"++    parseJSON _ = mzero++instance FromJSON CidCodecsObj where+    parseJSON (Object o) =+        CidCodecsObj  <$> o .: "Code"+                      <*> o .: "Name"++    parseJSON _ = mzero++instance FromJSON CidHashesObj where+    parseJSON (Object o) =+        CidHashesObj  <$> o .: "Code"+                      <*> o .: "Name"++    parseJSON _ = mzero++instance FromJSON CidObj where+    parseJSON (Object o) =+        CidObj  <$> o .: "CidStr"+                <*> o .: "ErrorMsg"+                <*> o .: "Formatted"++    parseJSON _ = mzero++instance FromJSON BlockObj where+    parseJSON (Object o) =+        BlockObj  <$> o .: "Key"+                  <*> o .: "Size"++    parseJSON _ = mzero++instance FromJSON DagCidObj where+    parseJSON (Object o) =+        DagCidObj  <$> o .: "/"++    parseJSON _ = mzero++instance FromJSON DagResolveObj where+    parseJSON (Object o) =+        DagResolveObj  <$> o .: "Cid"+                       <*> o .: "RemPath"++    parseJSON _ = mzero++instance FromJSON DagPutObj where+    parseJSON (Object o) =+        DagPutObj  <$> o .: "Cid"++    parseJSON _ = mzero++instance FromJSON ConfigObj where+    parseJSON (Object o) =+        ConfigObj  <$> o .: "Key"+                   <*> o .: "Value"++    parseJSON _ = mzero++instance FromJSON ObjectLinkObj where+    parseJSON (Object o) =+        ObjectLinkObj  <$> o .: "Hash"+                       <*> o .: "Name"+                       <*> o .: "Size"++    parseJSON _ = mzero++instance FromJSON ObjectObj where+    parseJSON (Object o) =+        ObjectObj  <$> o .: "Hash"++    parseJSON _ = mzero++instance FromJSON ObjectLinksObj where+    parseJSON (Object v) =+        case H.lookup "Links" v of+            Just (_) -> WithLinks <$> v .: "Hash"+                                  <*> v .: "Links"++            Nothing ->+                case H.lookup "Hash" v of+                      Just (_) -> WithoutLinks <$> v .: "Hash"+                      Nothing  -> mzero++    parseJSON _ = mzero++instance FromJSON ObjectGetObj where+    parseJSON (Object o) =+        ObjectGetObj  <$> o .: "Data"+                      <*> o .: "Links"++    parseJSON _ = mzero++instance FromJSON ObjectStatObj where+    parseJSON (Object o) =+        ObjectStatObj  <$> o .: "BlockSize"+                       <*> o .: "CumulativeSize"+                       <*> o .: "DataSize"+                       <*> o .: "Hash"+                       <*> o .: "LinksSize"+                       <*> o .: "NumLinks"++    parseJSON _ = mzero++instance FromJSON ObjectChangeObj where+    parseJSON (Object o) =+        ObjectChangeObj  <$> o .: "After"+                         <*> o .: "Before"+                         <*> o .: "Path"+                         <*> o .: "Type"++    parseJSON _ = mzero++instance FromJSON DiffObj where+    parseJSON (Object o) =+        DiffObj  <$> o .: "/"++    parseJSON _ = mzero++instance FromJSON ObjectDiffObj where+    parseJSON (Object o) =+        ObjectDiffObj  <$> o .: "Changes"++    parseJSON _ = mzero++instance FromJSON PinObj where+    parseJSON (Object v) =+        case H.lookup "Progress" v of+            Just (_) -> WithProgress <$> v .: "Pins"+                                     <*> v .: "Progress"++            Nothing ->+                case H.lookup "Pins" v of+                      Just (_) -> WithoutProgress <$> v .: "Pins"+                      Nothing  -> mzero++    parseJSON _ = mzero++instance FromJSON BootstrapObj where+    parseJSON (Object o) =+        BootstrapObj  <$> o .: "Peers"++    parseJSON _ = mzero++instance FromJSON StatsBwObj where+    parseJSON (Object o) =+        StatsBwObj  <$> o .: "RateIn"+                    <*> o .: "RateOut"+                    <*> o .: "TotalIn"+                    <*> o .: "TotalOut"++    parseJSON _ = mzero++instance FromJSON StatsRepoObj where+    parseJSON (Object o) =+        StatsRepoObj  <$> o .: "NumObjects"+                      <*> o .: "RepoPath"+                      <*> o .: "RepoSize"+                      <*> o .: "StorageMax"+                      <*> o .: "Version"++    parseJSON _ = mzero++instance FromJSON VersionObj where+    parseJSON (Object o) =+        VersionObj  <$> o .: "Commit"+                    <*> o .: "Golang"+                    <*> o .: "Repo"+                    <*> o .: "System"+                    <*> o .: "Version"++    parseJSON _ = mzero++instance FromJSON IdObj where+    parseJSON (Object o) =+        IdObj  <$> o .: "Addresses"+               <*> o .: "AgentVersion"+               <*> o .: "ID"+               <*> o .: "ProtocolVersion"+               <*> o .: "PublicKey"++    parseJSON _ = mzero++instance FromJSON DnsObj where+    parseJSON (Object o) =+        DnsObj  <$> o .: "Path"++    parseJSON _ = mzero++instance FromJSON PubsubObj where+    parseJSON (Object o) =+        PubsubObj  <$> o .: "Strings"++    parseJSON _ = mzero++instance FromJSON LogLsObj where+    parseJSON (Object o) =+        LogLsObj  <$> o .: "Strings"++    parseJSON _ = mzero++instance FromJSON LogLevelObj where+    parseJSON (Object o) =+        LogLevelObj  <$> o .: "Message"++    parseJSON _ = mzero++instance FromJSON RepoVersionObj where+    parseJSON (Object o) =+        RepoVersionObj  <$> o .: "Version"++    parseJSON _ = mzero++instance FromJSON RepoFsckObj where+    parseJSON (Object o) =+        RepoFsckObj  <$> o .: "Message"++    parseJSON _ = mzero+++instance FromJSON KeyDetailsObj where+    parseJSON (Object o) =+        KeyDetailsObj <$> o .: "Id"+                      <*> o .: "Name"++    parseJSON _ = mzero++instance FromJSON KeyObj where+    parseJSON (Object o) =+        KeyObj  <$> o .: "Keys"++    parseJSON _ = mzero++instance FromJSON KeyRenameObj where+    parseJSON (Object o) =+        KeyRenameObj  <$> o .: "Id"+                      <*> o .: "Now"+                      <*> o .: "Overwrite"+                      <*> o .: "Was"++    parseJSON _ = mzero++instance FromJSON FilesStatObj where+    parseJSON (Object o) =+        FilesStatObj  <$> o .: "Hash"+                      <*> o .: "Size"+                      <*> o .: "CumulativeSize"+                      <*> o .: "Blocks"+                      <*> o .: "Type"++    parseJSON _ = mzero++instance FromJSON FilesEntryObj where+    parseJSON (Object o) =+        FilesEntryObj  <$> o .: "Name"+                       <*> o .: "Type"+                       <*> o .: "Size"+                       <*> o .: "Hash"++    parseJSON _ = mzero++instance FromJSON FilesLsObj where+    parseJSON (Object o) =+        FilesLsObj  <$> o .: "Entries"++    parseJSON _ = mzero++instance FromJSON FilesFlushObj where+    parseJSON (Object o) =+        FilesFlushObj  <$> o .: "Cid"++    parseJSON _ = mzero++-- | Defining a content type same as PlainText without charset+data IpfsText deriving Typeable++instance Servant.API.Accept IpfsText where+    contentType _ = "text" M.// "plain"++-- | @left show . TextS.decodeUtf8' . toStrict@+instance MimeUnrender IpfsText Text where+    mimeUnrender _ = left show . TextS.decodeUtf8' . toStrict+++-- | Defining a content type same as IpfsJSON+data IpfsJSON deriving Typeable++instance Servant.API.Accept IpfsJSON where+    contentType _ = "application" M.// "json"++-- | @left show . TextS.decodeUtf8' . toStrict@+instance MimeUnrender IpfsJSON Text where+    mimeUnrender _ = left show . TextS.decodeUtf8' . toStrict++type IpfsApi = "cat" :> Capture "arg" Text :> Get '[IpfsText] CatReturnType+            :<|> "ls" :> Capture "arg" Text :> Get '[JSON] LsObj+            :<|> "get" :> Capture "arg" Text :> Get '[IpfsText] GetReturnType+            :<|> "swarm" :> "peers" :> Get '[JSON] SwarmPeersObj+            :<|> "swarm" :> "connect" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj+            :<|> "swarm" :> "disconnect" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj+            :<|> "swarm" :> "filters" :> Get '[JSON] SwarmObj+            :<|> "swarm" :> "filters" :> "add" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj+            :<|> "swarm" :> "filters" :> "rm" :> QueryParam "arg" Text :> Get '[JSON] SwarmObj+            :<|> "bitswap" :> "stat" :> Get '[JSON] BitswapStatObj+            :<|> "bitswap" :> "wantlist" :> Get '[JSON] BitswapWLObj+            :<|> "bitswap" :> "ledger" :> Capture "peerId" Text :> Get '[JSON] BitswapLedgerObj+            :<|> "bitswap" :> "reprovide" :> Get '[IpfsText] ReprovideReturnType+            :<|> "cid" :> "bases" :> Get '[JSON] [CidBasesObj]+            :<|> "cid" :> "codecs" :> Get '[JSON] [CidCodecsObj]+            :<|> "cid" :> "hashes" :> Get '[JSON] [CidHashesObj]+            :<|> "cid" :> "base32" :> Capture "cid" Text :> Get '[JSON] CidObj+            :<|> "cid" :> "format" :> Capture "cid" Text :> Get '[JSON] CidObj+            :<|> "block" :> "get" :> Capture "key" Text :> Get '[IpfsText] BlockReturnType+            :<|> "block" :> "stat" :> Capture "key" Text :> Get '[JSON] BlockObj+            :<|> "dag" :> "get" :> Capture "ref" Text :> Get '[IpfsJSON] DagReturnType+            :<|> "dag" :> "resolve" :> Capture "ref" Text :> Get '[JSON] DagResolveObj+            :<|> "config" :> Capture "ref" Text :> Get '[JSON] ConfigObj+            :<|> "config" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ConfigObj+            :<|> "object" :> "data" :> Capture "ref" Text :> Get '[IpfsText] ObjectReturnType+            :<|> "object" :> "new" :> Get '[JSON] ObjectObj+            :<|> "object" :> "links" :>  Capture "ref" Text :> Get '[JSON] ObjectLinksObj+            :<|> "object" :> "patch" :> "add-link" :> Capture "arg" Text+                :> QueryParam "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ObjectLinksObj+            :<|> "object" :> "patch" :> "rm-link" :> Capture "arg" Text+                :> QueryParam "arg" Text :> Get '[JSON] ObjectLinksObj+            :<|> "object" :> "get" :> Capture "arg" Text :> Get '[JSON] ObjectGetObj+            :<|> "object" :> "diff" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] ObjectDiffObj+            :<|> "object" :> "stat" :> Capture "arg" Text :> Get '[JSON] ObjectStatObj+            :<|> "pin" :> "add" :> Capture "arg" Text :> Get '[JSON] PinObj+            :<|> "pin" :> "rm" :> Capture "arg" Text :> Get '[JSON] PinObj+            :<|> "bootstrap" :> "add" :> QueryParam "arg" Text :> Get '[JSON] BootstrapObj+            :<|> "bootstrap" :> "list" :> Get '[JSON] BootstrapObj+            :<|> "bootstrap" :> "rm" :> QueryParam "arg" Text :> Get '[JSON] BootstrapObj+            :<|> "stats" :> "bw" :> Get '[JSON] StatsBwObj+            :<|> "stats" :> "repo" :> Get '[JSON] StatsRepoObj+            :<|> "version" :> Get '[JSON] VersionObj+            :<|> "id" :> Get '[JSON] IdObj+            :<|> "id" :> Capture "arg" Text :> Get '[JSON] IdObj+            :<|> "dns" :> Capture "arg" Text :> Get '[JSON] DnsObj+            :<|> "pubsub" :> "ls" :>  Get '[JSON] PubsubObj+            :<|> "pubsub" :> "peers" :>  Get '[JSON] PubsubObj+            :<|> "pubsub" :> "pub" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] NoContent+            :<|> "log" :> "ls" :>  Get '[JSON] LogLsObj+            :<|> "log" :> "level" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] LogLevelObj+            :<|> "repo" :> "version" :>  Get '[JSON] RepoVersionObj+            :<|> "repo" :> "fsck" :>  Get '[JSON] RepoFsckObj+            :<|> "key" :> "gen" :> Capture "arg" Text :> QueryParam "type" Text :> Get '[JSON] KeyDetailsObj+            :<|> "key" :> "list" :>  Get '[JSON] KeyObj+            :<|> "key" :> "rename" :> Capture "arg" Text :> QueryParam "arg" Text :> Get '[JSON] KeyRenameObj+            :<|> "key" :> "rm" :> Capture "arg" Text :> Get '[JSON] KeyObj+            :<|> "files" :> "chcid" :> QueryParam "arg" Text :> QueryParam "cid-version" Int :> Get '[JSON] NoContent+            :<|> "files" :> "cp" :> QueryParam "arg" Text :> QueryParam "arg" Text :> Get '[JSON] NoContent+            :<|> "files" :> "flush" :> QueryParam "arg" Text :> Get '[JSON] FilesFlushObj+            :<|> "files" :> "ls" :> QueryParam "arg" Text :> Get '[JSON] FilesLsObj+            :<|> "files" :> "mkdir" :> QueryParam "arg" Text :> Get '[JSON] NoContent+            :<|> "files" :> "mv" :> QueryParam "arg" Text :> QueryParam "arg" Text :> Get '[JSON] NoContent+            :<|> "files" :> "read" :> QueryParam "arg" Text :> Get '[IpfsText] FilesReadType+            :<|> "files" :> "rm" :> QueryParam "arg" Text :> QueryParam "recursive" Bool :> Get '[JSON] NoContent+            :<|> "files" :> "stat" :> QueryParam "arg" Text :> Get '[JSON] FilesStatObj+            :<|> "shutdown" :> Get '[JSON] NoContent
+ src/Network/Ipfs/Api/Types/Stream.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TypeOperators         #-}++-- |+-- Module      :  Network.Ipfs.Api.Types.Stream+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Ipfs Stream API types.+--++module Network.Ipfs.Api.Types.Stream where++import           Control.Monad+import           Data.Aeson+import qualified Data.ByteString.Lazy.Char8 ()+import           Data.Int+import           Data.Text+import           Network.HTTP.Client        ()+import           Servant.API++import           Network.Ipfs.Api.Types     (IpfsText)++type LogReturnType = Text++data PingObj = PingObj+    { success :: Bool+    , text    :: Text+    , time    :: Int64+    }+    deriving (Show, Eq)++data ResponseObj = ResponseObj+    { addrs :: Maybe [Text]+    , id    :: Text+    }+    deriving (Show, Eq)++data DhtObj = DhtObj+    { extra     :: Text+    , addrid    :: Text+    , responses :: Maybe [ResponseObj]+    , addrType  :: Int+    }+    deriving (Show, Eq)++data RepoKeyObj = RepoKeyObj+    { repoSlash :: Text+    }+    deriving (Show, Eq)++data RepoGcObj = RepoGcObj+    { repoKey :: RepoKeyObj+    }+    deriving (Show, Eq)++data RepoVerifyObj = RepoVerifyObj+    { msg      :: Text+    , progress :: Int+    }+    deriving (Show, Eq)++data RefsObj = RefsObj+    { error :: Text+    , ref   :: Text+    }+    deriving (Show, Eq)++data PubsubSubObj = PubsubSubObj+    { mssgdata :: Text+    , from     :: Text+    , seqno    :: Text+    , topicIDs :: [Text]+    }+    deriving (Show, Eq)++instance FromJSON PingObj where+    parseJSON (Object o) =+        PingObj  <$> o .: "Success"+                 <*> o .: "Text"+                 <*> o .: "Time"++    parseJSON _ = mzero++instance FromJSON DhtObj where+    parseJSON (Object o) =+        DhtObj   <$> o .: "Extra"+                 <*> o .: "ID"+                 <*> o .: "Responses"+                 <*> o .: "Type"++    parseJSON _ = mzero++instance FromJSON ResponseObj where+    parseJSON (Object o) =+        ResponseObj  <$> o .: "Addrs"+                     <*> o .: "ID"++    parseJSON _ = mzero++instance FromJSON RepoKeyObj where+    parseJSON (Object o) =+        RepoKeyObj  <$> o .: "/"++    parseJSON _ = mzero++instance FromJSON RepoGcObj where+    parseJSON (Object o) =+        RepoGcObj  <$> o .: "Key"++    parseJSON _ = mzero++instance FromJSON RepoVerifyObj where+    parseJSON (Object o) =+        RepoVerifyObj <$> o .: "Msg"+                      <*> o .: "Progress"++    parseJSON _ = mzero++instance FromJSON RefsObj where+    parseJSON (Object o) =+        RefsObj  <$> o .: "Err"+                 <*> o .: "Ref"++    parseJSON _ = mzero++instance FromJSON PubsubSubObj where+    parseJSON (Object o) =+        PubsubSubObj   <$> o .: "data"+                       <*> o .: "from"+                       <*> o .: "seqno"+                       <*> o .: "topicIDs"++    parseJSON _ = mzero++type IpfsStreamApi = "ping" :> Capture "arg" Text :> StreamGet NewlineFraming JSON ( SourceIO PingObj )+                :<|> "dht" :> "findpeer" :> Capture "arg" Text :> StreamGet NewlineFraming JSON ( SourceIO DhtObj )+                :<|> "dht" :> "findprovs" :> Capture "arg" Text :> StreamGet NewlineFraming JSON ( SourceIO DhtObj )+                :<|> "dht" :> "get" :> Capture "arg" Text :> StreamGet NewlineFraming JSON ( SourceIO DhtObj )+                :<|> "dht" :> "provide" :> Capture "arg" Text :> StreamGet NewlineFraming JSON ( SourceIO DhtObj )+                :<|> "dht" :> "query" :>  Capture "arg" Text :>  StreamGet NewlineFraming JSON ( SourceIO DhtObj )+                :<|> "log" :> "tail" :>  StreamGet NewlineFraming IpfsText ( SourceIO LogReturnType)+                :<|> "repo" :> "gc" :>  StreamGet NewlineFraming JSON ( SourceIO RepoGcObj)+                :<|> "repo" :> "verify" :>  StreamGet NewlineFraming JSON ( SourceIO RepoVerifyObj)+                :<|> "refs" :> Capture "arg" Text :> StreamGet NewlineFraming JSON (SourceIO RefsObj)+                :<|> "refs" :> "local" :> StreamGet NewlineFraming JSON (SourceIO RefsObj)+                :<|> "pubsub" :> "sub" :>  Capture "arg" Text :>  StreamGet NewlineFraming JSON ( SourceIO PubsubSubObj )
+ src/Network/Ipfs/Client.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- |+-- Module      :  Network.Ipfs.Client+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- IPFS daemon HTTP client.+--++module Network.Ipfs.Client where++import           Control.Monad.Except+import           Control.Monad.Reader+import           Network.HTTP.Client  as Net hiding (Proxy)+import           Servant.Client++newtype IpfsT m a = IpfsT { unIpfs :: ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a }+  deriving ( Functor+           , Applicative+           , Monad+           , MonadIO+           , MonadReader (Manager, BaseUrl, String)+           , MonadError ClientError+           )++instance MonadTrans IpfsT where+  lift = IpfsT . lift . lift++type Ipfs a = IpfsT IO a++-- | 'IpfsT' monad runner.+runIpfs' :: BaseUrl -> Ipfs a -> IO ()+runIpfs' url ipfs = do+  manager' <- liftIO $ newManager defaultManagerSettings+  ret <- runExceptT (runReaderT (unIpfs ipfs) (manager', url, showBaseUrl url))+  case ret of+    Left err -> putStrLn $ "Error: " ++ show err+    Right _  -> putStr ""++-- | 'IpfsT' monad runner with default arguments.+runIpfs :: Ipfs a -> IO ()+runIpfs = runIpfs' (BaseUrl Http "localhost" 5001 "/api/v0")
src/Network/JsonRpc/TinyClient.hs view
@@ -53,10 +53,8 @@     , MethodName      -- * JSON-RPC client settings-    , JsonRpcClient+    , JsonRpcClient(..)     , defaultSettings-    , jsonRpcServer-    , jsonRpcManager      -- * Error handling     , JsonRpcException(..)@@ -68,49 +66,55 @@ import           Control.Monad           ((<=<)) import           Control.Monad.Catch     (MonadThrow (..)) import           Control.Monad.IO.Class  (MonadIO (..))-import           Control.Monad.State     (MonadState)+import           Control.Monad.State     (MonadState, get) import           Crypto.Number.Generate  (generateMax) import           Data.Aeson              (FromJSON (..), ToJSON (..),                                           Value (String), eitherDecode, encode,                                           object, withObject, (.:), (.:?), (.=)) import           Data.ByteString.Lazy    (ByteString) import           Data.Text               (Text, unpack)-import           Lens.Micro.Mtl          (use)-import           Lens.Micro.TH           (makeLenses) import           Network.HTTP.Client     (Manager, RequestBody (RequestBodyLBS),                                           httpLbs, method, newManager,                                           parseRequest, requestBody,                                           requestHeaders, responseBody) import           Network.HTTP.Client.TLS (tlsManagerSettings)+import qualified Network.WebSockets      as WS (Connection, receiveData,+                                                sendTextData)  -- | JSON-RPC monad constrait. type JsonRpcM m = (MonadIO m, MonadThrow m, MonadState JsonRpcClient m)  -- | JSON-RPC client state vars.-data JsonRpcClient = JsonRpcClient-    { _jsonRpcManager :: !Manager    -- ^ HTTP connection manager.-    , _jsonRpcServer  :: !String     -- ^ Remote server URI.+data JsonRpcClient = JsonRpcHttpClient+    { jsonRpcManager :: Manager+    -- ^ HTTP connection manager.+    , jsonRpcServer  :: String+    -- ^ Remote server URI.     }--$(makeLenses ''JsonRpcClient)+    | JsonRpcWsClient+    { jsonRpcWsConnection :: WS.Connection+    -- ^ WebSocket connection.+    }  -- | Create default 'JsonRpcClient' settings. defaultSettings :: MonadIO m                 => String           -- ^ JSON-RPC server URI                 -> m JsonRpcClient-defaultSettings srv = liftIO $ JsonRpcClient+defaultSettings srv = liftIO $ JsonRpcHttpClient   <$> newManager tlsManagerSettings   <*> pure srv  instance Show JsonRpcClient where-    show JsonRpcClient{..} = "JsonRpcClient<" ++ _jsonRpcServer ++ ">"+    show JsonRpcHttpClient{..} = "<JSON-RPC HTTP Client>"+    show JsonRpcWsClient{..} = "<JSON-RPC WebSocket Client>"  -- | JSON-RPC request. data Request = Request     { rqMethod :: !Text     , rqId     :: !Int     , rqParams :: !Value-    } deriving (Eq, Show)+    }+    deriving (Eq, Show)  instance ToJSON Request where     toJSON rq = object [ "jsonrpc" .= String "2.0"@@ -122,7 +126,8 @@ -- | JSON-RPC response. data Response = Response     { rsResult :: !(Either RpcError Value)-    } deriving (Eq, Show)+    }+    deriving (Eq, Show)  instance FromJSON Response where     parseJSON =@@ -135,7 +140,8 @@     { errCode    :: !Int     , errMessage :: !Text     , errData    :: !(Maybe Value)-    } deriving Eq+    }+    deriving Eq  instance Show RpcError where     show (RpcError code msg dat) =@@ -148,8 +154,7 @@                        <*> v .: "message"                        <*> v .:? "data" -data JsonRpcException-    = ParsingException String+data JsonRpcException = ParsingException String     | CallException RpcError     deriving (Show, Eq) @@ -184,15 +189,22 @@   where     maxInt = toInteger (maxBound :: Int)     connection body = do-        serverUri <- use jsonRpcServer-        request <- parseRequest serverUri-        let request' = request-                     { requestBody = RequestBodyLBS body-                     , requestHeaders = [("Content-Type", "application/json")]-                     , method = "POST"-                     }-        manager <- use jsonRpcManager-        responseBody <$> liftIO (httpLbs request' manager)+        jsonRpcInstance <- get+        case jsonRpcInstance of+            JsonRpcHttpClient{..} -> do+                request <- parseRequest jsonRpcServer+                let request' = request {+                      requestBody = RequestBodyLBS body+                    , requestHeaders = [("Content-Type", "application/json")]+                    , method = "POST"+                    }+                responseBody <$> liftIO (httpLbs request' jsonRpcManager)++            JsonRpcWsClient{..} -> liftIO $ do+                WS.sendTextData jsonRpcWsConnection body+                WS.receiveData jsonRpcWsConnection++  decodeResponse :: (MonadThrow m, FromJSON a)                => ByteString
+ src/Network/Polkadot/Api/Account.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Account+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `account` prefix.+--++module Network.Polkadot.Api.Account where++import           Data.Text                  (Text)++import           Network.JsonRpc.TinyClient (JsonRpc (..))++-- | Retrieves the next accountIndex as available on the node.+nextIndex :: JsonRpc m+          => Text+          -- ^ AccountId+          -> m Int+{-# INLINE nextIndex #-}+nextIndex = remote "account_nextIndex"
+ src/Network/Polkadot/Api/Author.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Author+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `author` prefix.+--++module Network.Polkadot.Api.Author where++import           Data.Text                  (Text)++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))++-- | Returns true if the keystore has private keys for the given public key and key type.+hasKey :: JsonRpc m+       => HexString+       -- ^ Public key+       -> Text+       -- ^ Key type+       -> m Bool+{-# INLINE hasKey #-}+hasKey = remote "author_hasKey"++-- | Returns true if the keystore has private keys for the given session public keys.+hasSessionKeys :: JsonRpc m+               => HexString+               -- ^ Session keys+               -> m Bool+{-# INLINE hasSessionKeys #-}+hasSessionKeys = remote "author_hasSessionKeys"++-- | Insert a key into the keystore.+insertKey :: JsonRpc m+          => Text+          -- ^ Key type+          -> Text+          -- ^ Key secret URI+          -> HexString+          -- ^ Public key+          -> m HexString+{-# INLINE insertKey #-}+insertKey = remote "author_insertKey"++-- | Returns all pending extrinsics, potentially grouped by sender.+pendingExtrinsics :: JsonRpc m => m [HexString]+{-# INLINE pendingExtrinsics #-}+pendingExtrinsics = remote "author_pendingExtrinsics"++-- | Remove given extrinsic from the pool and temporarily ban it to prevent reimporting.+removeExtrinsic :: JsonRpc m+                => [HexString]+                -- ^ Extrinsic or hash+                -> m HexString+{-# INLINE removeExtrinsic #-}+removeExtrinsic = remote "author_removeExtrinsic"++-- | Generate new session keys and returns the corresponding public keys.+rotateKeys :: JsonRpc m => m HexString+{-# INLINE rotateKeys #-}+rotateKeys = remote "author_rotateKeys"++-- | Submit a fully formatted extrinsic for block inclusion.+submitExtrinsic :: JsonRpc m+                => HexString+                -- ^ Extrinsic+                -> m HexString+                -- ^ Hash+{-# INLINE submitExtrinsic #-}+submitExtrinsic = remote "author_submitExtrinsic"
+ src/Network/Polkadot/Api/Babe.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Babe+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `babe` prefix.+--++module Network.Polkadot.Api.Babe where++import           Data.Aeson                 (Object)++import           Network.JsonRpc.TinyClient (JsonRpc (..))++-- | Returns data about which slots (primary or secondary) can be claimed+-- in the current epoch with the keys in the keystore.+epochAuthorship :: JsonRpc m => m Object+{-# INLINE epochAuthorship #-}+epochAuthorship = remote "babe_epochAuthorship"
+ src/Network/Polkadot/Api/Chain.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Chain+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `chain` prefix.+--++module Network.Polkadot.Api.Chain where++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (Header, SignedBlock)++-- | Get header and body of a relay chain block.+getBlock :: JsonRpc m+         => Maybe HexString+         -- ^ Block hash+         -> m (Maybe SignedBlock)+{-# INLINE getBlock #-}+getBlock = remote "chain_getBlock"++-- | Get the block hash for a specific block.+getBlockHash :: JsonRpc m+             => Maybe Int+             -- ^ Block number+             -> m (Maybe HexString)+{-# INLINE getBlockHash #-}+getBlockHash = remote "chain_getBlockHash"++-- | Get hash of the last finalized block in the canon chain.+getFinalizedHead :: JsonRpc m => m HexString+{-# INLINE getFinalizedHead #-}+getFinalizedHead = remote "chain_getFinalizedHead"++-- | Retrieves the header for a specific block.+getHeader :: JsonRpc m+          => Maybe HexString+          -- ^ Block hash+          -> m (Maybe Header)+{-# INLINE getHeader #-}+getHeader = remote "chain_getHeader"
+ src/Network/Polkadot/Api/Childstate.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Childstate+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `childstate` prefix.+--++module Network.Polkadot.Api.Childstate where++import           Data.Text                  (Text)++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))++-- | Returns the keys with prefix from a child storage, leave empty to get all the keys.+getKeys :: JsonRpc m+        => HexString+        -- ^ Prefixed storage key+        -> HexString+        -- ^ Storage key+        -> Maybe HexString+        -- ^ Block hash+        -> m [HexString]+{-# INLINE getKeys #-}+getKeys = remote "childstate_getKeys"++-- | Returns a child storage entry at a specific block state.+getStorage :: JsonRpc m+           => HexString+           -- ^ Prefixed storage key+           -> HexString+           -- ^ Storage key+           -> Maybe HexString+           -- ^ Block hash+           -> m (Maybe HexString)+{-# INLINE getStorage #-}+getStorage = remote "childstate_getStorage"++-- | Returns the hash of a child storage entry at a block state+getStorageHash :: JsonRpc m+               => HexString+               -- ^ Prefixed storage key+               -> HexString+               -- ^ Storage key+               -> Maybe HexString+               -- ^ Block hash+               -> m (Maybe HexString)+{-# INLINE getStorageHash #-}+getStorageHash = remote "childstate_getStorageHash"++-- | Returns the size of a child storage entry at a block state.+getStorageSize :: JsonRpc m+               => HexString+               -- ^ Prefixed storage key+               -> HexString+               -- ^ Storage key+               -> Maybe HexString+               -- ^ Block hash+               -> m (Maybe Int)+{-# INLINE getStorageSize #-}+getStorageSize = remote "childstate_getStorageSize"
+ src/Network/Polkadot/Api/Contracts.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Contracts+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `contracts` prefix.+--++module Network.Polkadot.Api.Contracts where++import           Data.Text                  (Text)++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (ContractCall, ContractExecResult)++-- | Executes a call to a contract.+call :: JsonRpc m+     => ContractCall+     -- ^ Contract call+     -> Maybe HexString+     -- ^ Block hash or nothing for head+     -> m ContractExecResult+{-# INLINE call #-}+call = remote "contracts_call"++-- | Returns the value under a specified storage key in a contract+getStorage :: JsonRpc m+           => Text+           -- ^ AccountId+           -> HexString+           -- ^ Storage key+           -> Maybe HexString+           -- ^ Block hash or nothing for head+           -> m (Maybe HexString)+{-# INLINE getStorage #-}+getStorage = remote "contracts_getStorage"++-- | Returns the projected time a given contract will be able to sustain paying its rent.+rentProjection :: JsonRpc m+               => Text+               -- ^ AccountId+               -> Maybe HexString+               -- ^ Block hash or nothing for head+               -> m (Maybe Int)+{-# INLINE rentProjection #-}+rentProjection = remote "contracts_rentProjection"
+ src/Network/Polkadot/Api/Engine.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Engine+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `engine` prefix.+--++module Network.Polkadot.Api.Engine where++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (CreatedBlock)++-- | Instructs the manual-seal authorship task to create a new block.+createBlock :: JsonRpc m+            => Bool+            -- ^ Create empty+            -> Bool+            -- ^ Finalize+            -> Maybe HexString+            -- ^ Parent hash+            -> m CreatedBlock+{-# INLINE createBlock #-}+createBlock = remote "engine_createBlock"++-- | Instructs the manual-seal authorship task to finalize a block.+finalizeBlock :: JsonRpc m+              => HexString+              -- ^ Block hash+              -> Maybe HexString+              -- ^ Justification+              -> m Bool+{-# INLINE finalizeBlock #-}+finalizeBlock = remote "engine_finalizeBlock"
+ src/Network/Polkadot/Api/Grandpa.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Grandpa+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `grandpa` prefix.+--++module Network.Polkadot.Api.Grandpa where++import           Data.Aeson                 (Object)+import           Data.Text                  (Text)++import           Network.JsonRpc.TinyClient (JsonRpc (..))++-- | Returns the state of the current best round state as well as the ongoing background rounds.+roundState :: JsonRpc m => m Object+{-# INLINE roundState #-}+roundState = remote "grandpa_roundState"
+ src/Network/Polkadot/Api/Offchain.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Offchain+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `offchain` prefix.+--++module Network.Polkadot.Api.Offchain where++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (StorageKind)++-- | Get offchain local storage under given key and prefix.+localStorageGet :: JsonRpc m+                => StorageKind+                -- ^ Offchain storage kind+                -> HexString+                -- ^ Key+                -> m (Maybe HexString)+{-# INLINE localStorageGet #-}+localStorageGet = remote "offchain_localStorageGet"++-- | Set offchain local storage under given key and prefix+localStorageSet :: JsonRpc m+                => StorageKind+                -- ^ Offchain storage kind+                -> HexString+                -- ^ Key+                -> HexString+                -- ^ Value+                -> m ()+{-# INLINE localStorageSet #-}+localStorageSet = remote "offchain_localStorageSet"
+ src/Network/Polkadot/Api/Payment.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Payment+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `payment` prefix.+--++module Network.Polkadot.Api.Payment where++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (RuntimeDispatchInfo)++-- | Retrieves the fee information for an encoded extrinsic.+queryInfo :: JsonRpc m+          => HexString+          -- ^ Extrinsic+          -> Maybe HexString+          -- ^ Block hash or nothing for head block+          -> m RuntimeDispatchInfo+{-# INLINE queryInfo #-}+queryInfo = remote "payment_queryInfo"
+ src/Network/Polkadot/Api/Rpc.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.Rpc+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `rpc` prefix.+--++module Network.Polkadot.Api.Rpc where++import           Data.Aeson                 (Value)++import           Network.JsonRpc.TinyClient (JsonRpc (..))++-- | Retrieves the list of RPC methods that are exposed by the node.+methods :: JsonRpc m => m Value+{-# INLINE methods #-}+methods = remote "rpc_methods"
+ src/Network/Polkadot/Api/State.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.State+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `state` prefix.+--++module Network.Polkadot.Api.State where++import           Data.Text                  (Text)++import           Data.ByteArray.HexString   (HexString)+import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (Metadata, ReadProof,+                                             RuntimeVersion, StorageChangeSet)++-- | Perform a call to a builtin on the chain.+call :: JsonRpc m+     => Text+     -- ^ Call method+     -> HexString+     -- ^ Call data+     -> Maybe HexString+     -- ^ Block hash or nothing for head+     -> m HexString+{-# INLINE call #-}+call = remote "state_call"++-- | Retrieves the keys with prefix of a specific child storage.+getChildKeys :: JsonRpc m+             => HexString+             -- ^ Child storage key+             -> HexString+             -- ^ Child definition+             -> Int+             -- ^ Child type+             -> HexString+             -- ^ Key+             -> Maybe HexString+             -- ^ Block hash or nothing for head+             -> m [HexString]+{-# INLINE getChildKeys #-}+getChildKeys = remote "state_getChildKeys"++-- | Retrieves the child storage for a key.+getChildStorage :: JsonRpc m+                => HexString+                -- ^ Child storage key+                -> HexString+                -- ^ Child definition+                -> Int+                -- ^ Child type+                -> HexString+                -- ^ Key+                -> Maybe HexString+                -- ^ Block hash or nothing for head+                -> m HexString+{-# INLINE getChildStorage #-}+getChildStorage = remote "state_getChildStorage"++-- | Retrieves the child storage hash.+getChildStorageHash :: JsonRpc m+                    => HexString+                    -- ^ Child storage key+                    -> HexString+                    -- ^ Child definition+                    -> Int+                    -- ^ Child type+                    -> HexString+                    -- ^ Key+                    -> Maybe HexString+                    -- ^ Block hash or nothing for head+                    -> m HexString+{-# INLINE getChildStorageHash #-}+getChildStorageHash = remote "state_getChildStorageHash"++-- | Retrieves the child storage size.+getChildStorageSize :: JsonRpc m+                    => HexString+                    -- ^ Child storage key+                    -> HexString+                    -- ^ Child definition+                    -> Int+                    -- ^ Child type+                    -> HexString+                    -- ^ Key+                    -> Maybe HexString+                    -- ^ Block hash or nothing for head+                    -> m Int+{-# INLINE getChildStorageSize #-}+getChildStorageSize = remote "state_getChildStorageSize"++-- | Retrieves the keys with a certain prefix.+getKeys :: JsonRpc m+        => HexString+        -- ^ Key+        -> Maybe HexString+        -- ^ Block hash or nothing for head+        -> m [HexString]+{-# INLINE getKeys #-}+getKeys = remote "state_getKeys"++-- | Returns the runtime metadata.+getMetadata :: JsonRpc m => m Metadata+{-# INLINE getMetadata #-}+getMetadata = remote "state_getMetadata"++-- | Returns proof of storage entries at a specific block state.+getReadProof :: JsonRpc m+             => [HexString]+             -- ^ Keys+             -> Maybe HexString+             -- ^ Block hash or nothing for head+             -> m ReadProof+{-# INLINE getReadProof #-}+getReadProof = remote "state_getReadProof"++-- | Get runtime version.+getRuntimeVersion :: JsonRpc m+                  => Maybe HexString+                  -- ^ Block hash or nothing for head+                  -> m RuntimeVersion+{-# INLINE getRuntimeVersion #-}+getRuntimeVersion = remote "state_getRuntimeVersion"++-- | Retrieves the storage for a key.+getStorage :: JsonRpc m+           => HexString+           -- ^ Key+           -> Maybe HexString+           -- ^ Block hash or nothing for head+           -> m HexString+{-# INLINE getStorage #-}+getStorage = remote "state_getStorage"++-- | Retrieves the storage hash.+getStorageHash :: JsonRpc m+               => HexString+               -- ^ Key+               -> Maybe HexString+               -- ^ Block hash or nothing for head+               -> m HexString+{-# INLINE getStorageHash #-}+getStorageHash = remote "state_getStorageHash"++-- | Retrieves the storage size.+getStorageSize :: JsonRpc m+               => HexString+               -- ^ Key+               -> Maybe HexString+               -- ^ Block hash or nothing for head+               -> m Int+{-# INLINE getStorageSize #-}+getStorageSize = remote "state_getStorageSize"++-- | Query historical storage entries (by key) starting from a start block.+queryStorage :: JsonRpc m+             => [HexString]+             -- ^ Storage keys+             -> HexString+             -- ^ From block hash+             -> Maybe HexString+             -- ^ To block hash+             -> m [StorageChangeSet]+{-# INLINE queryStorage #-}+queryStorage = remote "state_queryStorage"++-- | Query storage entries (by key) starting at block hash given as the second parameter.+queryStorageAt :: JsonRpc m+               => [HexString]+               -- ^ Storage keys+               -> Maybe HexString+               -- ^ Block hash or nothing for head+               -> m [StorageChangeSet]+{-# INLINE queryStorageAt #-}+queryStorageAt = remote "state_queryStorageAt"
+ src/Network/Polkadot/Api/System.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Polkadot.Api.System+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot RPC methods with `system` prefix.+--++module Network.Polkadot.Api.System where++import           Data.Aeson                 (Object)+import           Data.Text                  (Text)++import           Network.JsonRpc.TinyClient (JsonRpc (..))+import           Network.Polkadot.Api.Types (ChainType, Health, NodeRole,+                                             PeerInfo)++-- | Adds a reserved peer.+addReservedPeer :: JsonRpc m+                => Text+                -- ^ Peer URI+                -> m Text+{-# INLINE addReservedPeer #-}+addReservedPeer = remote "system_addReservedPeer"++-- | Retrieves the chain.+chain :: JsonRpc m => m Text+{-# INLINE chain #-}+chain = remote "system_chain"++-- | Retrieves the chain type.+chainType :: JsonRpc m => m ChainType+{-# INLINE chainType #-}+chainType = remote "system_chainType"++-- | Return health status of the node.+health :: JsonRpc m => m Health+{-# INLINE health #-}+health = remote "system_health"++-- | The addresses include a trailing /p2p/ with the local PeerId,+-- and are thus suitable to be passed to addReservedPeer or as a bootnode address.+localListenAddresses :: JsonRpc m => m [Text]+{-# INLINE localListenAddresses #-}+localListenAddresses = remote "system_localListenAddresses"++-- | Returns the base58-encoded PeerId of the node.+localPeerId :: JsonRpc m => m Text+{-# INLINE localPeerId #-}+localPeerId = remote "system_localPeerId"++-- | Retrieves the node name.+name :: JsonRpc m => m Text+{-# INLINE name #-}+name = remote "system_name"++-- | Returns current state of the network.+--+-- Warning: This API isn't stable.+networkState :: JsonRpc m => m Object+{-# INLINE networkState #-}+networkState = remote "system_networkState"++-- | Returns the roles the node is running as.+nodeRoles :: JsonRpc m => m [NodeRole]+{-# INLINE nodeRoles #-}+nodeRoles = remote "system_nodeRoles"++-- | Returns the currently connected peers.+peers :: JsonRpc m => m [PeerInfo]+{-# INLINE peers #-}+peers = remote "system_peers"++-- | Get a custom set of properties as a JSON object, defined in the chain spec.+properties :: JsonRpc m => m Object+{-# INLINE properties #-}+properties = remote "system_properties"++-- | Remove a reserved peer.+removeReservedPeer :: JsonRpc m+                   => Text+                   -- ^ Peer URI+                   -> m Text+{-# INLINE removeReservedPeer #-}+removeReservedPeer = remote "system_removeReservedPeer"++-- | Retrieves the version of the node.+version :: JsonRpc m => m Text+{-# INLINE version #-}+version = remote "system_version"
+ src/Network/Polkadot/Api/Types.hs view
@@ -0,0 +1,270 @@+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE TemplateHaskell            #-}++-- |+-- Module      :  Network.Polkadot.Api.Types+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Polkadot JSON-RPC types.+--++module Network.Polkadot.Api.Types where++import           Data.Aeson               (FromJSON (..),+                                           Options (fieldLabelModifier),+                                           ToJSON (..), Value (String),+                                           defaultOptions)+import           Data.Aeson.TH            (deriveJSON)+import           Data.Text                (Text)+import           Data.Word                (Word32, Word64, Word8)+import           GHC.Generics             (Generic)++import           Data.ByteArray.HexString (HexString)+import           Data.String.Extra        (toLowerFirst)++-- | The role the node is running as.+data NodeRole = Full+    | LightClient+    | Authority+    | Sentry+    deriving (Eq, Generic, Show)++$(deriveJSON defaultOptions ''NodeRole)++-- | Type op a chain.+data ChainType = Development+    | Local+    | Live+    | Custom Text+    deriving (Eq, Generic, Show)++instance FromJSON ChainType where+    parseJSON (String v) = return $ case v of+        "Development" -> Development+        "Local"       -> Local+        "Live"        -> Live+        custom_name   -> Custom custom_name+    parseJSON _ = fail "ChainType should be a JSON String"++instance ToJSON ChainType where+    toJSON (Custom v) = toJSON v+    toJSON v          = toJSON (show v)++-- | System health struct returned by the RPC+data Health = Health+    { healthPeers           :: Int+    -- ^ Number of connected peers.+    , healthIsSyncing       :: Bool+    -- ^ Is the node syncing.+    , healthShouldHavePeers :: Bool+    -- ^ Should this node have any peers.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 6 }) ''Health)++-- | Network Peer information.+data PeerInfo = PeerInfo+    { peerInfoPeerId          :: Text+    -- ^ Peer ID+    , peerInfoRoles           :: [NodeRole]+    -- ^ Roles+    , peerInfoProtocolVersion :: Int+    -- ^ Protocol version.+    , peerInfoBestHash        :: Text+    -- ^ Peer best block hash+    , peerInfoBestNumber      :: Int+    -- ^ Peer best block number+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 8 }) ''PeerInfo)++-- | Executes a call to a contract.+data ContractCall = ContractCall+    { callOrigin    :: HexString+    , callDest      :: HexString+    , callValue     :: Integer+    , callGasLimit  :: Integer+    , callInputData :: HexString+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 4 }) ''ContractCall)++-- | A result of execution of a contract.+data ContractExecResult = SuccessExec+    { execStatus :: Word8+    -- ^ Status code returned by contract.+    , execData   :: Maybe HexString+    -- ^ Output data returned by contract. Can be empty.+    }+    | ExecResultError+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 4 }) ''ContractExecResult)++type Metadata = Value++-- | ReadProof struct returned by RPC.+data ReadProof = ReadProof+    { readProofAt    :: HexString+    -- ^ Block hash used to generate the proof.+    , readProofProof :: [HexString]+    -- ^ A proof used to prove that storage entries are included in the storage trie.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 9 }) ''ReadProof)++-- | Runtime version.+-- This should not be thought of as classic Semver (major/minor/tiny).+-- This triplet have different semantics and mis-interpretation could cause problems.+-- In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`,+-- absolutely not `impl_version` since they change the semantics of the runtime.+data RuntimeVersion = RuntimeVersion+    { runtimeSpecName           :: Text+    -- ^ Identifies the different Substrate runtimes.+    , runtimeImplName           :: Text+    -- ^ Name of the implementation of the spec.+    , runtimeAuthoringVersion   :: Word32+    -- ^ `authoring_version` is the version of the authorship interface.+    , runtimeSpecVersion        :: Word32+    -- ^ Version of the runtime specification.+    , runtimeImplVersion        :: Word32+    -- ^ Version of the implementation of the specification.+    , runtimeApis               :: [(HexString, Word32)]+    -- ^ List of supported API "features" along with their versions.+    , runtimeTransactionVersion :: Word32+    -- ^ All existing dispatches are fully compatible when this number doesn't change.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 7 }) ''RuntimeVersion)++-- | Type of supported offchain storages.+--+-- 1: persistent storage is non-revertible and not fork-aware;+-- 2: local storage is revertible and fork-aware.+type StorageKind = Word8++-- | Storage changes.+data StorageChangeSet = StorageChangeSet+    { storageBlock   :: HexString+    -- ^ Block hash.+    , storageChanges :: [(HexString, Maybe HexString)]+    -- ^ A list of changes.+    }++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 7 }) ''StorageChangeSet)++-- | Numeric range of transaction weight.+type Weight = Word64++-- | Generalized group of dispatch types.+data DispatchClass = Normal+    | Operational+    | Mandatory+    deriving (Eq, Generic, Show)++$(deriveJSON defaultOptions ''DispatchClass)++-- | Some information related to a dispatchable that can be queried from the runtime.+data RuntimeDispatchInfo = RuntimeDispatchInfo+    { dispatchWeight     :: Weight+    -- ^ Weight of this dispatch.+    , dispatchClass      :: DispatchClass+    -- ^ Class of this dispatch.+    , dispatchPartialFee :: Integer+    -- ^ The partial inclusion fee of this dispatch.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 8 }) ''RuntimeDispatchInfo)++-- | Auxiliary data associated with an imported block result.+data ImportedAux = ImportedAux+    { auxHeaderOnly                 :: Bool+    -- ^ Only the header has been imported. Block body verification was skipped.+    , auxClearJustificationRequests :: Bool+    -- ^ Clear all pending justification requests.+    , auxNeedsJustification         :: Bool+    -- ^ Request a justification for the given block.+    , auxBadJustification           :: Bool+    -- ^ Received a bad justification.+    , auxNeedsFinalityProof         :: Bool+    -- ^ Request a finality proof for the given block.+    , auxIsNewBest                  :: Bool+    -- ^ Whether the block that was imported is the new best block.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 3 }) ''ImportedAux)++data CreatedBlock = CreatedBlock+    { createdBlockHash :: HexString+    , createdBlockAux  :: ImportedAux+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 12 }) ''CreatedBlock)++-- | Abstraction over a block header for a substrate chain.+data Header = Header+    { headerParentHash     :: HexString+    -- ^ The parent hash.+    , headerNumber         :: Int+    -- ^ The block number.+    , headerStateRoot      :: HexString+    -- ^ The state trie merkle root+    , headerExtrinsicsRoot :: HexString+    -- ^ The merkle root of the extrinsics.+    , headerDigest         :: HexString+    -- ^ A chain-specific digest of data useful for light clients or referencing auxiliary data.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 5 }) ''Header)++-- | Abstraction over a substrate block.+data Block = Block+    { blockHeader     :: Header+    -- ^ The block header.+    , blockExtrinsics :: [HexString]+    -- ^ The accompanying extrinsics.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 5 }) ''Block)++-- | Abstraction over a substrate block and justification.+data SignedBlock = SignedBlock+    { signedBlock         :: Block+    -- ^ Full block.+    , signedJustification :: Maybe HexString+    -- ^ Block justification.+    }+    deriving (Eq, Generic, Show)++$(deriveJSON (defaultOptions+    { fieldLabelModifier = toLowerFirst . drop 6 }) ''SignedBlock)
+ src/Network/Web3.hs view
@@ -0,0 +1,20 @@+-- |+-- Module      :  Network.Web3+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--+-- Client library for Third Generation of Web.+--++module Network.Web3+    (+    -- * Web3 library uses JSON-RPC over WebSocket/HTTP(S) to access node functionality.+      Web3+    , runWeb3+    ) where++import           Network.Web3.Provider (Web3, runWeb3)
+ src/Network/Web3/Provider.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE RecordWildCards            #-}++-- |+-- Module      :  Network.Web3.Provider+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  portable+--+-- Web3 service provider.+--++module Network.Web3.Provider where++import           Control.Concurrent.Async   (Async, async)+import           Control.Exception          (Exception, try)+import           Control.Monad.Catch        (MonadThrow)+import           Control.Monad.IO.Class     (MonadIO (..))+import           Control.Monad.State        (MonadState (..))+import           Control.Monad.Trans.State  (StateT, evalStateT, withStateT)+import           Data.Default               (Default (..))+import           Data.Text                  (Text)+import           GHC.Generics               (Generic)+import           Network.HTTP.Client        (Manager)+import qualified Network.Socket             as S+import qualified Network.WebSockets         as WS (Connection,+                                                   defaultConnectionOptions,+                                                   newClientConnection,+                                                   sendClose)+import qualified Network.WebSockets.Stream  as Stream++import           Network.JsonRpc.TinyClient (JsonRpc, JsonRpcClient (..),+                                             defaultSettings, jsonRpcManager)++-- | Any communication with node wrapped with 'Web3' monad+newtype Web3 a = Web3 { unWeb3 :: StateT JsonRpcClient IO a }+    deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadState JsonRpcClient)++instance JsonRpc Web3++-- | Some peace of error response+data Web3Error = JsonRpcFail !String+    | ParserFail !String+    | UserFail !String+    deriving (Show, Eq, Generic)++instance Exception Web3Error++--TODO: Change to `HttpProvider ServerUri | IpcProvider FilePath` to support IPC+-- | Web3 Provider+data Provider = HttpProvider String+    | WsProvider String Int+    deriving (Show, Eq, Generic)++-- | Default Provider URI+instance Default Provider where+  def = HttpProvider "http://localhost:8545"++-- | 'Web3' monad runner, using the supplied Manager+runWeb3With :: MonadIO m+            => Manager+            -> Provider+            -> Web3 a+            -> m (Either Web3Error a)+runWeb3With manager provider f = do+    runWeb3' provider Web3 { unWeb3 = withStateT changeManager $ unWeb3 f}+    where+      changeManager jRpcClient = case jRpcClient of+        JsonRpcHttpClient{..} -> jRpcClient { jsonRpcManager = manager }+        JsonRpcWsClient{..}   -> jRpcClient++-- | 'Web3' monad runner+runWeb3' :: MonadIO m+         => Provider+         -> Web3 a+         -> m (Either Web3Error a)+runWeb3' (HttpProvider uri) f = do+    cfg <- defaultSettings uri+    liftIO . try . flip evalStateT cfg . unWeb3 $ f++runWeb3' (WsProvider host port) f = do+    connection <- liftIO $ getConnection host port "/"+    let currentClient = JsonRpcWsClient { jsonRpcWsConnection = connection }+    response <- liftIO $ try . flip evalStateT currentClient . unWeb3 $ f+    liftIO $ WS.sendClose connection ("Bye-" :: Text)+    return response++-- | 'Web3' runner for default Http provider+runWeb3 :: MonadIO m+        => Web3 a+        -> m (Either Web3Error a)+{-# INLINE runWeb3 #-}+runWeb3 = runWeb3' def++-- | Fork 'Web3' with the same 'Provider' and 'Manager'+forkWeb3 :: Web3 a -> Web3 (Async a)+forkWeb3 f = liftIO . async . evalStateT (unWeb3 f) =<< get++-- | Returns a WebSocket Connection Instance+getConnection :: String           -- ^ Host+              -> Int              -- ^ Port+              -> String           -- ^ Path+              -> IO WS.Connection+{-# INLINE getConnection #-}+getConnection host port path = do+    -- Create and connect socket+    let hints = S.defaultHints+                    {S.addrSocketType = S.Stream}++        -- Correct host and path.+        fullHost = if port == 80 then host else (host ++ ":" ++ show port)+        path0     = if null path then "/" else path++    addr:_ <- S.getAddrInfo (Just hints) (Just host) (Just $ show port)+    sock      <- S.socket (S.addrFamily addr) S.Stream S.defaultProtocol+    S.setSocketOption sock S.NoDelay 1++    -- Connect WebSocket and run client++    res <-  ( S.connect sock (S.addrAddress addr) >>+            Stream.makeSocketStream sock) >>=+              (\stream ->+                    WS.newClientConnection stream fullHost+                    path0 WS.defaultConnectionOptions [] )+    return res
stack.yaml view
@@ -1,5 +1,5 @@ # Resolver to choose a 'specific' stackage snapshot or a compiler version.-resolver: lts-15.10+resolver: lts-15.13  # User packages to be built. packages:@@ -9,7 +9,6 @@ extra-deps: - relapse-1.0.0.0@sha256:b89ea23189e07f377be4e2a4deccf3d6ba7f547ed8ad77e27b35d78801efd81c - vinyl-0.12.1@sha256:03f5e246fae2434250987bbfe708015dc6e23f60c20739c34738acde1383b96c-- time-1.8.0.4@sha256:3f6eddf238b828eb4f82683acce1c3afe64784f0d20114239b738c123316c85c  # Dependencies bounds pvp-bounds: both
+ test/Network/Ethereum/Test/ComplexStorageSpec.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NamedFieldPuns        #-}+{-# LANGUAGE OverloadedLists       #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE QuasiQuotes           #-}+{-# LANGUAGE TemplateHaskell       #-}++-- |+-- Module      :  Network.Ethereum.Test.ComplexStorageSpec+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--+-- ComplexStorage is a Solidity contract which has global variables of+-- several different types. The point of this test is to test the encoding+-- of a complicated Solidity tuple, consisting of dynamically and statically+-- sized components.+--++module Network.Ethereum.Test.ComplexStorageSpec where++import           Control.Concurrent.Async     (async, wait)+import           Control.Concurrent.MVar      (newEmptyMVar, putMVar, takeMVar)+import           Control.Monad.IO.Class       (liftIO)+import           Data.Default                 (def)++import           Network.Ethereum             hiding (convert)+import           Network.Ethereum.Api.Types   (Filter (..))+import           Network.Ethereum.Contract    (new)+import           Network.Ethereum.Contract.TH+import           Network.Ethereum.Test.Utils+++import           Test.Hspec++[abiFrom|test/contracts/ComplexStorage.json|]++deploy :: IO Address+deploy = do+    Just address <- web3 $ withAccount () $ withParam id $ new ComplexStorageContract+    putStrLn $ "ComplexStorage: " ++ show address+    return address++spec :: Spec+spec = deploy `before` complexStorageSpec++complexStorageSpec :: SpecWith Address+complexStorageSpec = do+  describe "can interact with a ComplexStorage contract" $ do+        -- todo: these should ideally be arbitrary!+        let sUint   = 1+            sInt    = -1+            sBool   = True+            sInt224 = 221+            sBools   = [True, False]+            sInts    = [1, 1, -3]+            sString  = "hello"+            sBytes16 = "\x12\x34\x56\x78\x12\x34\x56\x78\x12\x34\x56\x78\x12\x34\x56\x78"+            sByte2sElem = "\x12\x34"+            sByte2sVec = [sByte2sElem, sByte2sElem, sByte2sElem, sByte2sElem]+            sByte2s = [sByte2sVec, sByte2sVec]++        it "can set the values of a ComplexStorage and validate them with an event" $ \storage -> do+            let fltr = (def :: Filter ValsSet) { filterAddress = Just [storage] }+            -- kick off listening for the ValsSet event+            vals <- newEmptyMVar+            fiber <- async . web3 $+                event fltr $ \vs -> do+                    liftIO $ putMVar vals vs+                    pure TerminateEvent+            -- kick off tx+            _ <- contract storage $ setValues+                                    sUint+                                    sInt+                                    sBool+                                    sInt224+                                    sBools+                                    sInts+                                    sString+                                    sBytes16+                                    sByte2s+            -- wait for its ValsSet event+            wait fiber+            (ValsSet vsA vsB vsC vsD vsE vsF vsG vsH vsI) <- takeMVar vals+            vsA `shouldBe` sUint+            vsB `shouldBe` sInt+            vsC `shouldBe` sBool+            vsD `shouldBe` sInt224+            vsE `shouldBe` sBools+            vsF `shouldBe` sInts+            vsG `shouldBe` sString+            vsH `shouldBe` sBytes16+            vsI `shouldBe` sByte2s++        it "can verify that it set the values correctly" $ \storage -> do+            -- Write a values+            _ <- contract storage $ setValues+                                    sUint+                                    sInt+                                    sBool+                                    sInt224+                                    sBools+                                    sInts+                                    sString+                                    sBytes16+                                    sByte2s+            -- Read a couple of values+            (uintVal', intVal', boolVal', int224Val', boolsVal, intsVal, stringVal', bytes16Val', bytes2s)+                <- contract storage $ (,,,,,,,,)+                    <$> uintVal+                    <*> intVal+                    <*> boolVal+                    <*> int224Val+                    <*> boolVectorVal 0+                    <*> intListVal 0+                    <*> stringVal+                    <*> bytes16Val+                    <*> bytes2VectorListVal 0 0++            uintVal'    `shouldBe` sUint+            intVal'     `shouldBe` sInt+            boolVal'    `shouldBe` sBool+            int224Val'  `shouldBe` sInt224+            boolsVal    `shouldBe` True+            intsVal     `shouldBe` head sInts+            stringVal'  `shouldBe` sString+            bytes16Val' `shouldBe` sBytes16+            bytes2s     `shouldBe` sByte2sElem++        it "can decode a complicated value correctly" $ \storage -> do+            -- Write a values+            _ <- contract storage $ setValues+                                    sUint+                                    sInt+                                    sBool+                                    sInt224+                                    sBools+                                    sInts+                                    sString+                                    sBytes16+                                    sByte2s+            -- Read a all values+            allVals <- contract storage getVals+            allVals `shouldBe` (sUint, sInt, sBool, sInt224, sBools, sInts, sString, sBytes16, sByte2s)
+ test/Network/Ethereum/Test/ERC20Spec.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE QuasiQuotes           #-}++-- |+-- Module      :  Network.Ethereum.Test.ERC20Spec+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--+--++module Network.Ethereum.Test.ERC20Spec where++import           Test.Hspec++import           Network.Ethereum             (Account, UIntN)+import           Network.Ethereum.Contract.TH (abiFrom)+import           Network.JsonRpc.TinyClient   (JsonRpc)++[abiFrom|examples/token/ERC20.json|]++-- this spec is just to test compilation+spec :: Spec+spec = return ()++getBalance :: (JsonRpc m, Account p t, Functor (t m))+           => t m (UIntN 256)+getBalance = balanceOf "0x1234567890123456789011234567890234567890"
+ test/Network/Ethereum/Test/LinearizationSpec.hs view
@@ -0,0 +1,193 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE KindSignatures        #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NamedFieldPuns        #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE QuasiQuotes           #-}+{-# LANGUAGE RecordWildCards       #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TemplateHaskell       #-}+{-# LANGUAGE TypeApplications      #-}++-- Module      :  Network.Ethereum.Test.LinearizationSpec+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--++module Network.Ethereum.Test.LinearizationSpec where++import           Control.Concurrent              (forkIO)+import           Control.Concurrent.Async        (forConcurrently_)+import           Control.Concurrent.MVar+import           Control.Concurrent.STM          (atomically)+import           Control.Concurrent.STM.TQueue   (TQueue, flushTQueue,+                                                  newTQueueIO, writeTQueue)+import           Control.Monad                   (void)+import           Control.Monad.IO.Class          (MonadIO (..))+import           Control.Monad.Trans.Reader      (ReaderT, ask)+import           Data.Default+import           Data.Either+import           Data.List                       (sort)+import           Data.Maybe                      (fromJust)+import           System.Random                   (randomRIO)+import           Test.Hspec++import           Network.Ethereum+import qualified Network.Ethereum.Api.Eth        as Eth+import           Network.Ethereum.Api.Types      (Change (..), Filter (..),+                                                  TxReceipt, unQuantity)+import           Network.Ethereum.Contract       (new)+import           Network.Ethereum.Contract.Event+import           Network.Ethereum.Contract.TH    (abiFrom)+import           Network.Ethereum.Test.Utils+import           Network.Web3++[abiFrom|test/contracts/Linearization.json|]++deploy :: IO Address+deploy = do+    Just address <- web3 $ withAccount () $ withParam id $ new LinearizationContract+    putStrLn $ "Linearization: " ++ show address+    return address++spec :: Spec+spec = do+    deploy `before` linearizationSpec+    deploy `before` floodSpec++floodCount :: Int+floodCount = 200++linearizationSpec :: SpecWith Address+linearizationSpec =+    describe "can bundle and linearize events" $ do+        it "can call e12" $ \linearization -> do+            var <- monitorE1OrE2 linearization+            _ <- contract linearization e12+            res <- takeMVar var+            res `shouldSatisfy` isLeft++        it "can call e21" $ \linearization -> do+            -- wait on the next block+            web3 Eth.blockNumber >>= \bn -> awaitBlock (bn + 1)+            var <- monitorE1OrE2 linearization+            _ <- contract linearization e21+            res <- takeMVar var+            res `shouldSatisfy` isRight++singleFlood :: forall m. (MonadIO m) => Address -> m TxReceipt+singleFlood linearization = liftIO $ do+    rando :: Int <- randomRIO (1, 4)+    contract linearization $+        case rando of+            1 -> e1+            2 -> e2+            3 -> e3+            4 -> e4+            _ -> error "got a number outside of (1,4) after randomR (1,4)"++floodSpec :: SpecWith Address+floodSpec = describe "can correctly demonstrate the difference between `multiEvent` and multiple `event`s" $ do+    it "properly linearizes with `multiEvent` when flooded and doesn't with multiple `event`s" $ \linearization -> do+        multiQ <- monitorAllFourMulti linearization+        parQ <- monitorAllFourPar linearization+        -- to let the filter settle so we dont block indefinitely on missing events?+        sleepBlocks 10++        -- flood em and wait for all to finish+        liftIO . forConcurrently_ [1..floodCount] . const $ singleFlood linearization++        -- to let the event listeners catch up+        sleepBlocks 10++        -- wait for all multiEvents to be received and flush em out+        multiReceivedEvents <- liftIO . atomically $ flushTQueue multiQ+        parReceivedEvents <- liftIO . atomically $ flushTQueue parQ++        -- did we get at least 1/4 of the events? (this is a gotcha when flooding, sometimes nonces get repeated)+        length multiReceivedEvents `shouldSatisfy` (>= (floodCount `div` 4))+        length parReceivedEvents `shouldSatisfy` (>= (floodCount `div` 4))++        -- did both listeners see the same amount of events?+        length multiReceivedEvents `shouldBe` length parReceivedEvents++        -- the events pushed into the multi TQueue should already be sorted if they happened in the right order+        sort multiReceivedEvents `shouldBe` multiReceivedEvents+        -- the events pushed into the TQueue should not be sorted if they didnt come in in the right order+        sort parReceivedEvents `shouldNotBe` parReceivedEvents++monitorE1OrE2 :: Address -> IO (MVar (Either E1 E2))+monitorE1OrE2 addr = do+    var <- newEmptyMVar+    let fltr1 = (def :: Filter E1) { filterAddress = Just [addr] }+        fltr2 = (def :: Filter E2) { filterAddress = Just [addr] }+        filters = fltr1 :? fltr2 :? NilFilters+        handler1 ev1 = do+            liftIO $ putMVar var (Left ev1)+            return TerminateEvent+        handler2 ev2 = do+            liftIO $ putMVar var (Right ev2)+            return TerminateEvent+        handlers = H handler1 :& H handler2 :& RNil+    _ <- web3 $ multiEvent filters handlers+    return var++data EventTag = ETE1+    | ETE2+    | ETE3+    | ETE4+    deriving (Eq, Read, Show)++instance {-# OVERLAPPING #-} Ord (EventTag, Integer, Integer) where+    (_, b1, t1) `compare` (_, b2, t2) =+        let bCmp = b1 `compare` b2+        in if bCmp == EQ then t1 `compare` t2+                         else bCmp++monitorAllFourMulti :: Address+                    -> IO (TQueue (EventTag, Integer, Integer))+monitorAllFourMulti addr = do+    q <- newTQueueIO+    let f :: forall a. Default (Filter a) => Filter a+        f = defFilter addr+        h = enqueueingHandler q+        filters = f @E1 :? f @E2 :? f @E3 :? f @E4 :? NilFilters+        handlers = h ETE1 :& h ETE2 :& h ETE3 :& h ETE4 :& RNil+    void . web3 $ multiEvent filters handlers+    return q++monitorAllFourPar :: Address+                  -> IO (TQueue (EventTag, Integer, Integer))+monitorAllFourPar addr = do+    q <- newTQueueIO+    let f :: forall a. Default (Filter a) => Filter a+        f = defFilter addr+        h = enqueueingHandler q+        unH (H h) = h++    void . forkIO . web3 $ event (f @E1) (unH $ h ETE1)+    void . forkIO . web3 $ event (f @E2) (unH $ h ETE2)+    void . forkIO . web3 $ event (f @E3) (unH $ h ETE3)+    void . forkIO . web3 $ event (f @E4) (unH $ h ETE4)+    return q++defFilter :: forall a. Default (Filter a) => Address -> Filter a+defFilter addr = (def :: Filter a) { filterAddress = Just [addr] }++enqueueingHandler :: forall a. TQueue (EventTag, Integer, Integer)+                  -> EventTag+                  -> Handler (ReaderT Change Web3 EventAction) a+enqueueingHandler q tag = H . const $ do+    Change{..} <- ask+    let bn = unQuantity $ fromJust changeBlockNumber+        li = unQuantity $ fromJust changeLogIndex+    liftIO . atomically $ writeTQueue q (tag, bn, li)+    return ContinueEvent
+ test/Network/Ethereum/Test/LocalAccountSpec.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE OverloadedStrings #-}++-- Module      :  Network.Ethereum.Test.LocalAccountSpec+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--+-- Simple local account transaction test.+--++module Network.Ethereum.Test.LocalAccountSpec where++import           Lens.Micro                  ((.~))+import           Lens.Micro.Mtl              ((.=))+import           Test.Hspec++import           Crypto.Ecdsa.Utils          (derivePubKey, importKey)+import           Data.ByteArray.HexString    (HexString)+import           Data.Solidity.Prim.Address  (fromPubKey)+import           Network.Ethereum.Account    (LocalKey (..), send, to, value,+                                              withAccount, withParam)+import           Network.Ethereum.Api.Eth    (getBalance)+import           Network.Ethereum.Api.Types  (DefaultBlock (Pending))+import           Network.Ethereum.Test.Utils (web3)+import           Network.Ethereum.Unit       (Ether, toWei)++spec :: Spec+spec = describe "Local account transactions" $ do+    it "should send value" $ do+        let key = "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" :: HexString+            local = LocalKey (importKey key) 420123+            localAddress = fromPubKey (derivePubKey $ importKey key)+            dest = "0x0000000000000000000000000000000000000042"++        -- Prepare+        web3 $ withAccount () $+            withParam (to .~ localAddress) $ do+                value .= (1 :: Ether)+                send ()++        balance <- web3 $ do+            withAccount local $+                withParam (to .~ dest) $ do+                    value .= (0.5 :: Ether)+                    send ()+            getBalance dest Pending++        fromIntegral balance `shouldBe` toWei (0.5 :: Ether)
+ test/Network/Ethereum/Test/RegistrySpec.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLists       #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE QuasiQuotes           #-}+{-# LANGUAGE TemplateHaskell       #-}++module Network.Ethereum.Test.RegistrySpec where++import           Data.Default                 (def)+import           Test.Hspec                   (Spec)++import           Network.Ethereum             (EventAction (TerminateEvent),+                                               event)+import           Network.Ethereum.Api.Types   (Filter)+import           Network.Ethereum.Contract.TH (abiFrom)+import           Network.Web3                 (Web3)++[abiFrom|test/contracts/Registry.json|]++-- this spec is just to test compilation+spec :: Spec+spec = return ()++monitor :: Web3 ()+monitor = do+  let fltr1 = def :: Filter A+      fltr2 = def :: Filter B+  event fltr1 $ \_ -> pure TerminateEvent+  event fltr2 $ \_ -> pure TerminateEvent+  pure ()
+ test/Network/Ethereum/Test/SimpleStorageSpec.hs view
@@ -0,0 +1,202 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE KindSignatures        #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NamedFieldPuns        #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE QuasiQuotes           #-}+{-# LANGUAGE RecordWildCards       #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TemplateHaskell       #-}++-- Module      :  Network.Ethereum.Test.SimpleStorageSpec+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unportable+--+-- SimpleStorage is a Solidity contract which stores a uint256.+-- The point of this test is to test function calls to update and+-- read the value, as well as an event monitor.+--++module Network.Ethereum.Test.SimpleStorageSpec where++import           Control.Concurrent.Async     (wait)+import           Control.Concurrent.MVar+import           Control.Monad.IO.Class       (liftIO)+import           Control.Monad.Trans.Class    (lift)+import           Control.Monad.Trans.Reader   (ask)+import           Data.Default                 (def)+import           Data.List                    (sort)+import           Data.Monoid                  ((<>))+import           Lens.Micro                   ((.~))+import           Test.Hspec++import           Network.Ethereum+import qualified Network.Ethereum.Api.Eth     as Eth+import           Network.Ethereum.Api.Types+import           Network.Ethereum.Contract    (new)+import           Network.Ethereum.Contract.TH+import           Network.Web3+import           Network.Web3.Provider        (forkWeb3)++import           Network.Ethereum.Test.Utils++[abiFrom|test/contracts/SimpleStorage.json|]++unEvT_CountSet :: EvT_CountSet -> UIntN 256+unEvT_CountSet (EvT_CountSet n) = n++deploy :: IO Address+deploy = do+    Just address <- web3 $ withAccount () $ withParam id $ new SimpleStorageContract+    putStrLn $ "SimpleStorage: " ++ show address+    return address++spec :: Spec+spec = deploy `before` do+  interactions+  events++interactions :: SpecWith Address+interactions = describe "can interact with a SimpleStorage contract" $ do+    -- todo: this should ideally be arbitrary!+    let theValue = 12345++    it "can set the value of a SimpleStorage contract and read the value back" $ \storage -> do+        _ <- contract storage $ setCount theValue++        now <- web3 Eth.blockNumber+        let later = now + 3+        awaitBlock later++        v <- contract storage count+        v `shouldBe` theValue++    it "can set transaction gas limit" $ \storage -> do+        TxReceipt{..} <- contract storage $ withParam (gasLimit .~ 500000) $ setCount theValue+        Just Transaction{..} <- web3 $ Eth.getTransactionByHash receiptTransactionHash+        txGas `shouldBe` 500000++    it "can estimate transaction gas limit" $ \storage -> do+        TxReceipt{..} <- contract storage $ setCount theValue+        Just Transaction{..} <- web3 $ Eth.getTransactionByHash receiptTransactionHash+        txGas `shouldBe` 42822++events :: SpecWith Address+events = do+    describe "can interact with a SimpleStorage contract across block intervals" $ do+        it "can stream events starting and ending in the future, unbounded" $ \storage -> do+            var <- newMVar []+            let theSets = [1, 2, 3]+            putStrLn "Setting up the filter..."+            fiber <- web3 $ do+                let fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage] }+                forkWeb3 $ processUntil' var fltr ((3 ==) . length)+            putStrLn "Setting the values..."+            setValues storage theSets+            wait fiber+            putStrLn "Filter caught 3 values..."+            vals <- takeMVar var+            sort (unEvT_CountSet <$> vals) `shouldBe` sort theSets++        it "can stream events starting and ending in the future, bounded" $ \storage -> do+            var <- newMVar []+            let theSets = [13, 14, 15]+            start <- web3 Eth.blockNumber+            let later = BlockWithNumber (start + 3)+                latest = BlockWithNumber (start + 8)+                fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage]+                                                    , filterFromBlock = later+                                                    , filterToBlock = latest+                                                    }+            putStrLn "Setting up the filter..."+            fiber <- web3 $+                forkWeb3 $ processUntil' var fltr ((3 ==) . length)+            awaitBlock (start + 3)+            putStrLn "Setting the values..."+            setValues storage theSets+            wait fiber+            putStrLn "Filter caught 3 values..."+            vals <- takeMVar var+            sort (unEvT_CountSet <$> vals) `shouldBe` init (sort theSets)++        it "can stream events starting in the past and ending in the future" $ \storage -> do+            var <- newMVar []+            blockNumberVar <- newEmptyMVar+            let theSets1 = [7, 8, 9]+                theSets2 = [10, 11, 12]+            start <- web3 Eth.blockNumber+            let fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage] }+            fiber <- web3 $ do+                forkWeb3 $ processUntil var fltr ((3 ==) . length) (liftIO . putMVar blockNumberVar . changeBlockNumber)+            putStrLn "Running first transactions as past transactions..."+            setValues storage theSets1+            wait fiber+            putStrLn "All past transactions succeeded... "+            Just end <- takeMVar blockNumberVar+            awaitBlock $ end + 1  -- make past transactions definitively in past+            var' <- newMVar []+            fiber' <- web3 $ do+                let fltr' = (def :: Filter EvT_CountSet) { filterAddress = Just [storage]+                                                        , filterFromBlock = BlockWithNumber start}+                forkWeb3 $ processUntil' var' fltr' ((6 ==) . length)+            putStrLn "Setting more values"+            setValues storage theSets2+            wait fiber'+            putStrLn "All new values have ben set"+            vals <- takeMVar var'+            sort (unEvT_CountSet <$> vals) `shouldBe` sort (theSets1 <> theSets2)++    it "can stream events starting and ending in the past, bounded" $ \storage -> do+        var <- newMVar []+        let theSets = [4, 5, 6]+        start <- web3 Eth.blockNumber+        blockNumberVar <- newEmptyMVar+        let fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage] }+        putStrLn "Setting up filter for past transactions..."+        fiber <- web3 $ do+          forkWeb3 $ processUntil var fltr ((3 ==) . length) (liftIO . putMVar blockNumberVar . changeBlockNumber)+        putStrLn "Setting values"+        setValues storage theSets+        wait fiber+        putStrLn "All values have been set"+        Just end <- takeMVar blockNumberVar+        var' <- newMVar []+        let fltr' = fltr { filterFromBlock = BlockWithNumber start+                         , filterToBlock = BlockWithNumber end+                         }+        awaitBlock $ end + 1  -- make it definitively in the past+        web3 $ processUntil' var' fltr' ((3 ==) . length)+        vals <- takeMVar var'+        sort (unEvT_CountSet <$> vals) `shouldBe` sort theSets++processUntil :: MVar [EvT_CountSet]+             -> Filter EvT_CountSet+             -> ([EvT_CountSet] -> Bool)  -- TODO: make it work for any event+             -> (Change -> Web3 ())+             -> Web3 ()+processUntil var fltr predicate action = do+  event fltr $ \(ev :: EvT_CountSet) -> do+    newV <- liftIO $ modifyMVar var $ \v -> return (ev:v, ev:v)+    if predicate newV+        then do+          change <- ask+          lift $ action change+          return TerminateEvent+        else return ContinueEvent++processUntil' :: MVar [EvT_CountSet]+              -> Filter EvT_CountSet+              -> ([EvT_CountSet] -> Bool)+              -> Web3 ()+processUntil' var fltr predicate = processUntil var fltr predicate (const $ return ())++setValues :: Address -> [UIntN 256] -> IO ()+setValues storage = mapM_ (contract storage . setCount)
+ test/Network/Ethereum/Test/Utils.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Network.Ethereum.Test.Utils where++import           Control.Concurrent         (threadDelay)+import           Control.Exception          (SomeException, catch)+import           Control.Monad.IO.Class     (liftIO)+import           Data.Maybe                 (fromMaybe)+import           Data.Ratio                 (numerator)+import           Data.Time.Clock.POSIX      (getPOSIXTime)+import           Lens.Micro                 ((.~))+import           Network.HTTP.Client        (Manager, defaultManagerSettings,+                                             managerConnCount,+                                             managerRawConnection,+                                             managerRetryableException,+                                             newManager)+import           System.Environment         (lookupEnv)+import           System.IO.Unsafe           (unsafePerformIO)++import           Data.Solidity.Prim.Address (Address)+import           Network.Ethereum.Account   (DefaultAccount, to, withAccount,+                                             withParam)+import           Network.Ethereum.Api.Eth   (accounts, blockNumber)+import           Network.Ethereum.Api.Types (Quantity)+import           Network.Web3.Provider      (Provider (..), Web3, runWeb3With)++-- shared manager used throughout the helpers here to prevent hammering geth from ruining everything+-- this also retrys on ALL exceptions, including ConnectionResetByPeer and stuff like that+sharedManager :: Manager+sharedManager = unsafePerformIO $ newManager defaultManagerSettings+    { managerConnCount = 5+    , managerRetryableException = const False+    , managerRawConnection = fixRawConnection retryOpenConnection+    }++    where retryOpenConnection = threadDelay 500000 >> managerRawConnection defaultManagerSettings+          fixRawConnection f = f `catch` (\(_ :: SomeException) -> fixRawConnection f)+{-# NOINLINE sharedManager #-}++rpcUri :: IO String+rpcUri = liftIO (fromMaybe "http://localhost:8545" <$> lookupEnv "WEB3_PROVIDER")++contract :: Address+         -> DefaultAccount Web3 a+         -> IO a+contract a = web3 . withAccount () . withParam (to .~ a)++web3 :: Web3 a -> IO a+web3 ma = do+    provider <- HttpProvider <$> rpcUri+    v <- runWeb3With sharedManager provider ma+    case v of+        Left e   -> print e >> threadDelay 1000000 >> web3 ma+        Right v' -> return v'++withAccounts :: ([Address] -> IO a) -> IO a+withAccounts f = web3 accounts >>= f++withPrimaryEthereumAccount :: IO Address+withPrimaryEthereumAccount = withAccounts (pure . head)++sleepSeconds :: Int -> IO ()+sleepSeconds = threadDelay . (* 1000000)++microtime :: IO Integer+microtime = numerator . toRational . (* 1000000) <$> getPOSIXTime++awaitBlock :: Quantity -> IO ()+awaitBlock bn = do+    bn' <- web3 blockNumber+    -- putStrLn $ "awaiting block " ++ show bn ++ ", currently " ++ show bn'+    if bn' >= bn+        then return ()+        else threadDelay 1000000 >> awaitBlock bn++sleepBlocks :: Int -> IO ()+sleepBlocks n = do+    now <- web3 blockNumber+    awaitBlock $ now + fromIntegral n
− test/Network/Ethereum/Web3/Test/ComplexStorageSpec.hs
@@ -1,152 +0,0 @@-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NamedFieldPuns        #-}-{-# LANGUAGE OverloadedLists       #-}-{-# LANGUAGE OverloadedStrings     #-}-{-# LANGUAGE QuasiQuotes           #-}-{-# LANGUAGE TemplateHaskell       #-}---- |--- Module      :  Network.Ethereum.Web3.Test.ComplexStorageSpec--- Copyright   :  Alexander Krupenkin 2016--- License     :  BSD3------ Maintainer  :  mail@akru.me--- Stability   :  experimental--- Portability :  unportable------ ComplexStorage is a Solidity contract which has global variables of--- several different types. The point of this test is to test the encoding--- of a complicated Solidity tuple, consisting of dynamically and statically--- sized components.-----module Network.Ethereum.Web3.Test.ComplexStorageSpec where--import           Control.Concurrent.Async         (wait)-import           Control.Concurrent.MVar          (newEmptyMVar, putMVar,-                                                   takeMVar)-import           Control.Monad.IO.Class           (liftIO)-import           Data.Default                     (def)--import           Network.Ethereum.Api.Types       (Filter (..))-import           Network.Ethereum.Contract        (new)-import           Network.Ethereum.Contract.TH-import           Network.Ethereum.Web3            hiding (convert)-import           Network.Ethereum.Web3.Test.Utils---import           Test.Hspec--[abiFrom|test/contracts/ComplexStorage.json|]--deploy :: IO Address-deploy = do-    Just address <- web3 $ withAccount () $ withParam id $ new ComplexStorageContract-    putStrLn $ "ComplexStorage: " ++ show address-    return address--spec :: Spec-spec = deploy `before` complexStorageSpec--complexStorageSpec :: SpecWith Address-complexStorageSpec = do-  describe "can interact with a ComplexStorage contract" $ do-        -- todo: these should ideally be arbitrary!-        let sUint   = 1-            sInt    = -1-            sBool   = True-            sInt224 = 221-            sBools   = [True, False]-            sInts    = [1, 1, -3]-            sString  = "hello"-            sBytes16 = "\x12\x34\x56\x78\x12\x34\x56\x78\x12\x34\x56\x78\x12\x34\x56\x78"-            sByte2sElem = "\x12\x34"-            sByte2sVec = [sByte2sElem, sByte2sElem, sByte2sElem, sByte2sElem]-            sByte2s = [sByte2sVec, sByte2sVec]--        it "can set the values of a ComplexStorage and validate them with an event" $ \storage -> do-            let fltr = (def :: Filter ValsSet) { filterAddress = Just [storage] }-            -- kick off listening for the ValsSet event-            vals <- newEmptyMVar-            fiber <- web3 $-                event fltr $ \vs -> do-                    liftIO $ putMVar vals vs-                    pure TerminateEvent-            -- kick off tx-            _ <- contract storage $ setValues-                                    sUint-                                    sInt-                                    sBool-                                    sInt224-                                    sBools-                                    sInts-                                    sString-                                    sBytes16-                                    sByte2s-            -- wait for its ValsSet event-            wait fiber-            (ValsSet vsA vsB vsC vsD vsE vsF vsG vsH vsI) <- takeMVar vals-            vsA `shouldBe` sUint-            vsB `shouldBe` sInt-            vsC `shouldBe` sBool-            vsD `shouldBe` sInt224-            vsE `shouldBe` sBools-            vsF `shouldBe` sInts-            vsG `shouldBe` sString-            vsH `shouldBe` sBytes16-            vsI `shouldBe` sByte2s--        it "can verify that it set the values correctly" $ \storage -> do-            -- Write a values-            _ <- contract storage $ setValues-                                    sUint-                                    sInt-                                    sBool-                                    sInt224-                                    sBools-                                    sInts-                                    sString-                                    sBytes16-                                    sByte2s-            -- Read a couple of values-            (uintVal', intVal', boolVal', int224Val', boolsVal, intsVal, stringVal', bytes16Val', bytes2s)-                <- contract storage $ (,,,,,,,,)-                    <$> uintVal-                    <*> intVal-                    <*> boolVal-                    <*> int224Val-                    <*> boolVectorVal 0-                    <*> intListVal 0-                    <*> stringVal-                    <*> bytes16Val-                    <*> bytes2VectorListVal 0 0--            uintVal'    `shouldBe` sUint-            intVal'     `shouldBe` sInt-            boolVal'    `shouldBe` sBool-            int224Val'  `shouldBe` sInt224-            boolsVal    `shouldBe` True-            intsVal     `shouldBe` head sInts-            stringVal'  `shouldBe` sString-            bytes16Val' `shouldBe` sBytes16-            bytes2s     `shouldBe` sByte2sElem--        it "can decode a complicated value correctly" $ \storage -> do-            -- Write a values-            _ <- contract storage $ setValues-                                    sUint-                                    sInt-                                    sBool-                                    sInt224-                                    sBools-                                    sInts-                                    sString-                                    sBytes16-                                    sByte2s-            -- Read a all values-            allVals <- contract storage getVals-            allVals `shouldBe` (sUint, sInt, sBool, sInt224, sBools, sInts, sString, sBytes16, sByte2s)
− test/Network/Ethereum/Web3/Test/ERC20Spec.hs
@@ -1,24 +0,0 @@-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedStrings     #-}-{-# LANGUAGE QuasiQuotes           #-}-module Network.Ethereum.Web3.Test.ERC20Spec where--import           Test.Hspec--import           Network.Ethereum.Contract.TH (abiFrom)-import           Network.Ethereum.Web3        (Account, UIntN)-import           Network.JsonRpc.TinyClient   (JsonRpc)--[abiFrom|examples/token/ERC20.json|]---- this spec is just to test compilation-spec :: Spec-spec = return ()--getBalance :: (JsonRpc m, Account p t, Functor (t m))-           => t m (UIntN 256)-getBalance = balanceOf "0x1234567890123456789011234567890234567890"
− test/Network/Ethereum/Web3/Test/LinearizationSpec.hs
@@ -1,189 +0,0 @@-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE KindSignatures        #-}-{-# LANGUAGE LambdaCase            #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NamedFieldPuns        #-}-{-# LANGUAGE OverloadedStrings     #-}-{-# LANGUAGE QuasiQuotes           #-}-{-# LANGUAGE RecordWildCards       #-}-{-# LANGUAGE ScopedTypeVariables   #-}-{-# LANGUAGE TemplateHaskell       #-}-{-# LANGUAGE TypeApplications      #-}---- Module      :  Network.Ethereum.Web3.Test.LinearizationSpec--- Copyright   :  Alexander Krupenkin 2016--- License     :  BSD3------ Maintainer  :  mail@akru.me--- Stability   :  experimental--- Portability :  unportable-----module Network.Ethereum.Web3.Test.LinearizationSpec where--import           Control.Concurrent               (forkIO)-import           Control.Concurrent.Async         (forConcurrently_)-import           Control.Concurrent.MVar-import           Control.Concurrent.STM           (atomically)-import           Control.Concurrent.STM.TQueue    (TQueue, flushTQueue,-                                                   newTQueueIO, writeTQueue)-import           Control.Monad                    (void)-import           Control.Monad.IO.Class           (MonadIO (..))-import           Control.Monad.Trans.Reader       (ReaderT, ask)-import           Data.Default-import           Data.Either-import           Data.List                        (sort)-import           Data.Maybe                       (fromJust)-import           System.Random                    (randomRIO)-import           Test.Hspec--import qualified Network.Ethereum.Api.Eth         as Eth-import           Network.Ethereum.Api.Types       (Change (..), Filter (..),-                                                   TxReceipt, unQuantity)-import           Network.Ethereum.Contract        (new)-import           Network.Ethereum.Contract.Event-import           Network.Ethereum.Contract.TH     (abiFrom)-import           Network.Ethereum.Web3-import           Network.Ethereum.Web3.Test.Utils--[abiFrom|test/contracts/Linearization.json|]--deploy :: IO Address-deploy = do-    Just address <- web3 $ withAccount () $ withParam id $ new LinearizationContract-    putStrLn $ "Linearization: " ++ show address-    return address--spec :: Spec-spec = do-    deploy `before` linearizationSpec-    deploy `before` floodSpec--floodCount :: Int-floodCount = 200--linearizationSpec :: SpecWith Address-linearizationSpec =-    describe "can bundle and linearize events" $ do-        it "can call e12" $ \linearization -> do-            var <- monitorE1OrE2 linearization-            _ <- contract linearization e12-            res <- takeMVar var-            res `shouldSatisfy` isLeft--        it "can call e21" $ \linearization -> do-            -- wait on the next block-            web3 Eth.blockNumber >>= \bn -> awaitBlock (bn + 1)-            var <- monitorE1OrE2 linearization-            _ <- contract linearization e21-            res <- takeMVar var-            res `shouldSatisfy` isRight--singleFlood :: forall m. (MonadIO m) => Address -> m TxReceipt-singleFlood linearization = liftIO $ do-    rando :: Int <- randomRIO (1, 4)-    contract linearization $-        case rando of-            1 -> e1-            2 -> e2-            3 -> e3-            4 -> e4-            _ -> error "got a number outside of (1,4) after randomR (1,4)"--floodSpec :: SpecWith Address-floodSpec = describe "can correctly demonstrate the difference between `multiEvent` and multiple `event'`s" $ do-    it "properly linearizes with `multiEvent` when flooded and doesn't with multiple `event`s" $ \linearization -> do-        multiQ <- monitorAllFourMulti linearization-        parQ <- monitorAllFourPar linearization-        -- to let the filter settle so we dont block indefinitely on missing events?-        sleepBlocks 10--        -- flood em and wait for all to finish-        liftIO . forConcurrently_ [1..floodCount] . const $ singleFlood linearization--        -- to let the event listeners catch up-        sleepBlocks 10--        -- wait for all multiEvents to be received and flush em out-        multiReceivedEvents <- liftIO . atomically $ flushTQueue multiQ-        parReceivedEvents <- liftIO . atomically $ flushTQueue parQ--        -- did we get at least 1/4 of the events? (this is a gotcha when flooding, sometimes nonces get repeated)-        length multiReceivedEvents `shouldSatisfy` (>= (floodCount `div` 4))-        length parReceivedEvents `shouldSatisfy` (>= (floodCount `div` 4))--        -- did both listeners see the same amount of events?-        length multiReceivedEvents `shouldBe` length parReceivedEvents--        -- the events pushed into the multi TQueue should already be sorted if they happened in the right order-        sort multiReceivedEvents `shouldBe` multiReceivedEvents-        -- the events pushed into the TQueue should not be sorted if they didnt come in in the right order-        sort parReceivedEvents `shouldNotBe` parReceivedEvents--monitorE1OrE2 :: Address -> IO (MVar (Either E1 E2))-monitorE1OrE2 addr = do-    var <- newEmptyMVar-    let fltr1 = (def :: Filter E1) { filterAddress = Just [addr] }-        fltr2 = (def :: Filter E2) { filterAddress = Just [addr] }-        filters = fltr1 :? fltr2 :? NilFilters-        handler1 ev1 = do-            liftIO $ putMVar var (Left ev1)-            return TerminateEvent-        handler2 ev2 = do-            liftIO $ putMVar var (Right ev2)-            return TerminateEvent-        handlers = H handler1 :& H handler2 :& RNil-    _ <- web3 $ multiEvent filters handlers-    return var--data EventTag = ETE1 | ETE2 | ETE3 | ETE4-    deriving (Eq, Read, Show)--instance {-# OVERLAPPING #-} Ord (EventTag, Integer, Integer) where-    (_, b1, t1) `compare` (_, b2, t2) =-        let bCmp = b1 `compare` b2-        in if bCmp == EQ then t1 `compare` t2-                         else bCmp--monitorAllFourMulti :: Address-                    -> IO (TQueue (EventTag, Integer, Integer))-monitorAllFourMulti addr = do-    q <- newTQueueIO-    let f :: forall a. Default (Filter a) => Filter a-        f = defFilter addr-        h = enqueueingHandler q-        filters = f @E1 :? f @E2 :? f @E3 :? f @E4 :? NilFilters-        handlers = h ETE1 :& h ETE2 :& h ETE3 :& h ETE4 :& RNil-    void . web3 $ multiEvent filters handlers-    return q--monitorAllFourPar :: Address-                  -> IO (TQueue (EventTag, Integer, Integer))-monitorAllFourPar addr = do-    q <- newTQueueIO-    let f :: forall a. Default (Filter a) => Filter a-        f = defFilter addr-        h = enqueueingHandler q-        unH (H h) = h--    void . forkIO . web3 $ event' (f @E1) (unH $ h ETE1)-    void . forkIO . web3 $ event' (f @E2) (unH $ h ETE2)-    void . forkIO . web3 $ event' (f @E3) (unH $ h ETE3)-    void . forkIO . web3 $ event' (f @E4) (unH $ h ETE4)-    return q--defFilter :: forall a. Default (Filter a) => Address -> Filter a-defFilter addr = (def :: Filter a) { filterAddress = Just [addr] }--enqueueingHandler :: forall a. TQueue (EventTag, Integer, Integer)-                  -> EventTag-                  -> Handler (ReaderT Change Web3 EventAction) a-enqueueingHandler q tag = H . const $ do-    Change{..} <- ask-    let bn = unQuantity $ fromJust changeBlockNumber-        li = unQuantity $ fromJust changeLogIndex-    liftIO . atomically $ writeTQueue q (tag, bn, li)-    return ContinueEvent
− test/Network/Ethereum/Web3/Test/LocalAccountSpec.hs
@@ -1,52 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- Module      :  Network.Ethereum.Web3.Test.LocalAccountSpec--- Copyright   :  Alexander Krupenkin 2018--- License     :  BSD3------ Maintainer  :  mail@akru.me--- Stability   :  experimental--- Portability :  unportable------ Simple local account transaction test.-----module Network.Ethereum.Web3.Test.LocalAccountSpec where--import           Lens.Micro                       ((.~))-import           Lens.Micro.Mtl                   ((.=))-import           Test.Hspec--import           Crypto.Ethereum.Utils            (derivePubKey, importKey)-import           Data.ByteArray.HexString         (HexString)-import           Data.Solidity.Prim.Address       (fromPubKey)-import           Network.Ethereum.Account         (LocalKey (..), send, to,-                                                   value, withAccount,-                                                   withParam)-import           Network.Ethereum.Api.Eth         (getBalance)-import           Network.Ethereum.Api.Types       (DefaultBlock (Pending))-import           Network.Ethereum.Unit            (Ether, toWei)-import           Network.Ethereum.Web3.Test.Utils (web3)--spec :: Spec-spec = describe "Local account transactions" $ do-    it "should send value" $ do-        let key = "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" :: HexString-            local = LocalKey (importKey key) 420123-            localAddress = fromPubKey (derivePubKey $ importKey key)-            dest = "0x0000000000000000000000000000000000000042"--        -- Prepare-        web3 $ withAccount () $-            withParam (to .~ localAddress) $ do-                value .= (1 :: Ether)-                send ()--        balance <- web3 $ do-            withAccount local $-                withParam (to .~ dest) $ do-                    value .= (0.5 :: Ether)-                    send ()-            getBalance dest Pending--        fromIntegral balance `shouldBe` toWei (0.5 :: Ether)
− test/Network/Ethereum/Web3/Test/RegistrySpec.hs
@@ -1,32 +0,0 @@-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedLists       #-}-{-# LANGUAGE OverloadedStrings     #-}-{-# LANGUAGE QuasiQuotes           #-}-{-# LANGUAGE TemplateHaskell       #-}--module Network.Ethereum.Web3.Test.RegistrySpec where--import           Data.Default                 (def)-import           Test.Hspec                   (Spec)--import           Network.Ethereum.Api.Types   (Filter)-import           Network.Ethereum.Contract.TH (abiFrom)-import           Network.Ethereum.Web3        (EventAction (TerminateEvent),-                                               Web3, event)--[abiFrom|test/contracts/Registry.json|]---- this spec is just to test compilation-spec :: Spec-spec = return ()--monitor :: Web3 ()-monitor = do-  let fltr1 = def :: Filter A-      fltr2 = def :: Filter B-  event fltr1 $ \_ -> pure TerminateEvent-  event fltr2 $ \_ -> pure TerminateEvent-  pure ()
− test/Network/Ethereum/Web3/Test/SimpleStorageSpec.hs
@@ -1,203 +0,0 @@-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE KindSignatures        #-}-{-# LANGUAGE LambdaCase            #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NamedFieldPuns        #-}-{-# LANGUAGE OverloadedStrings     #-}-{-# LANGUAGE QuasiQuotes           #-}-{-# LANGUAGE RecordWildCards       #-}-{-# LANGUAGE ScopedTypeVariables   #-}-{-# LANGUAGE TemplateHaskell       #-}---- Module      :  Network.Ethereum.Web3.Test.SimpleStorageSpec--- Copyright   :  Alexander Krupenkin 2016--- License     :  BSD3------ Maintainer  :  mail@akru.me--- Stability   :  experimental--- Portability :  unportable------ SimpleStorage is a Solidity contract which stores a uint256.--- The point of this test is to test function calls to update and--- read the value, as well as an event monitor.-----module Network.Ethereum.Web3.Test.SimpleStorageSpec where--import           Control.Concurrent.Async         (wait)-import           Control.Concurrent.MVar-import           Control.Monad.IO.Class           (liftIO)-import           Control.Monad.Trans.Class        (lift)-import           Control.Monad.Trans.Reader       (ask)-import           Data.Default                     (def)-import           Data.List                        (sort)-import           Data.Monoid                      ((<>))-import           Lens.Micro                       ((.~))-import           Test.Hspec--import qualified Network.Ethereum.Api.Eth         as Eth-import           Network.Ethereum.Api.Provider    (forkWeb3)-import           Network.Ethereum.Api.Types-import           Network.Ethereum.Contract        (new)-import           Network.Ethereum.Contract.Event  (event')-import           Network.Ethereum.Contract.TH-import           Network.Ethereum.Web3---import           Network.Ethereum.Web3.Test.Utils--[abiFrom|test/contracts/SimpleStorage.json|]--unEvT_CountSet :: EvT_CountSet -> UIntN 256-unEvT_CountSet (EvT_CountSet n) = n--deploy :: IO Address-deploy = do-    Just address <- web3 $ withAccount () $ withParam id $ new SimpleStorageContract-    putStrLn $ "SimpleStorage: " ++ show address-    return address--spec :: Spec-spec = deploy `before` do-  interactions-  events--interactions :: SpecWith Address-interactions = describe "can interact with a SimpleStorage contract" $ do-    -- todo: this should ideally be arbitrary!-    let theValue = 12345--    it "can set the value of a SimpleStorage contract and read the value back" $ \storage -> do-        _ <- contract storage $ setCount theValue--        now <- web3 Eth.blockNumber-        let later = now + 3-        awaitBlock later--        v <- contract storage count-        v `shouldBe` theValue--    it "can set transaction gas limit" $ \storage -> do-        TxReceipt{..} <- contract storage $ withParam (gasLimit .~ 500000) $ setCount theValue-        Just Transaction{..} <- web3 $ Eth.getTransactionByHash receiptTransactionHash-        txGas `shouldBe` 500000--    it "can estimate transaction gas limit" $ \storage -> do-        TxReceipt{..} <- contract storage $ setCount theValue-        Just Transaction{..} <- web3 $ Eth.getTransactionByHash receiptTransactionHash-        txGas `shouldBe` 42822--events :: SpecWith Address-events = do-    describe "can interact with a SimpleStorage contract across block intervals" $ do-        it "can stream events starting and ending in the future, unbounded" $ \storage -> do-            var <- newMVar []-            let theSets = [1, 2, 3]-            putStrLn "Setting up the filter..."-            fiber <- web3 $ do-                let fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage] }-                forkWeb3 $ processUntil' var fltr ((3 ==) . length)-            putStrLn "Setting the values..."-            setValues storage theSets-            wait fiber-            putStrLn "Filter caught 3 values..."-            vals <- takeMVar var-            sort (unEvT_CountSet <$> vals) `shouldBe` sort theSets--        it "can stream events starting and ending in the future, bounded" $ \storage -> do-            var <- newMVar []-            let theSets = [13, 14, 15]-            start <- web3 Eth.blockNumber-            let later = BlockWithNumber (start + 3)-                latest = BlockWithNumber (start + 8)-                fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage]-                                                    , filterFromBlock = later-                                                    , filterToBlock = latest-                                                    }-            putStrLn "Setting up the filter..."-            fiber <- web3 $-                forkWeb3 $ processUntil' var fltr ((3 ==) . length)-            awaitBlock (start + 3)-            putStrLn "Setting the values..."-            setValues storage theSets-            wait fiber-            putStrLn "Filter caught 3 values..."-            vals <- takeMVar var-            sort (unEvT_CountSet <$> vals) `shouldBe` init (sort theSets)--        it "can stream events starting in the past and ending in the future" $ \storage -> do-            var <- newMVar []-            blockNumberVar <- newEmptyMVar-            let theSets1 = [7, 8, 9]-                theSets2 = [10, 11, 12]-            start <- web3 Eth.blockNumber-            let fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage] }-            fiber <- web3 $ do-                forkWeb3 $ processUntil var fltr ((3 ==) . length) (liftIO . putMVar blockNumberVar . changeBlockNumber)-            putStrLn "Running first transactions as past transactions..."-            setValues storage theSets1-            wait fiber-            putStrLn "All past transactions succeeded... "-            Just end <- takeMVar blockNumberVar-            awaitBlock $ end + 1  -- make past transactions definitively in past-            var' <- newMVar []-            fiber' <- web3 $ do-                let fltr' = (def :: Filter EvT_CountSet) { filterAddress = Just [storage]-                                                        , filterFromBlock = BlockWithNumber start}-                forkWeb3 $ processUntil' var' fltr' ((6 ==) . length)-            putStrLn "Setting more values"-            setValues storage theSets2-            wait fiber'-            putStrLn "All new values have ben set"-            vals <- takeMVar var'-            sort (unEvT_CountSet <$> vals) `shouldBe` sort (theSets1 <> theSets2)--    it "can stream events starting and ending in the past, bounded" $ \storage -> do-        var <- newMVar []-        let theSets = [4, 5, 6]-        start <- web3 Eth.blockNumber-        blockNumberVar <- newEmptyMVar-        let fltr = (def :: Filter EvT_CountSet) { filterAddress = Just [storage] }-        putStrLn "Setting up filter for past transactions..."-        fiber <- web3 $ do-          forkWeb3 $ processUntil var fltr ((3 ==) . length) (liftIO . putMVar blockNumberVar . changeBlockNumber)-        putStrLn "Setting values"-        setValues storage theSets-        wait fiber-        putStrLn "All values have been set"-        Just end <- takeMVar blockNumberVar-        var' <- newMVar []-        let fltr' = fltr { filterFromBlock = BlockWithNumber start-                         , filterToBlock = BlockWithNumber end-                         }-        awaitBlock $ end + 1  -- make it definitively in the past-        web3 $ processUntil' var' fltr' ((3 ==) . length)-        vals <- takeMVar var'-        sort (unEvT_CountSet <$> vals) `shouldBe` sort theSets--processUntil :: MVar [EvT_CountSet]-             -> Filter EvT_CountSet-             -> ([EvT_CountSet] -> Bool)  -- TODO: make it work for any event-             -> (Change -> Web3 ())-             -> Web3 ()-processUntil var fltr predicate action = do-  event' fltr $ \(ev :: EvT_CountSet) -> do-    newV <- liftIO $ modifyMVar var $ \v -> return (ev:v, ev:v)-    if predicate newV-        then do-          change <- ask-          lift $ action change-          return TerminateEvent-        else return ContinueEvent--processUntil' :: MVar [EvT_CountSet]-              -> Filter EvT_CountSet-              -> ([EvT_CountSet] -> Bool)-              -> Web3 ()-processUntil' var fltr predicate = processUntil var fltr predicate (const $ return ())--setValues :: Address -> [UIntN 256] -> IO ()-setValues storage = mapM_ (contract storage . setCount)
− test/Network/Ethereum/Web3/Test/Utils.hs
@@ -1,81 +0,0 @@-{-# LANGUAGE OverloadedStrings   #-}-{-# LANGUAGE ScopedTypeVariables #-}--module Network.Ethereum.Web3.Test.Utils where--import           Control.Concurrent            (threadDelay)-import           Control.Exception             (SomeException, catch)-import           Control.Monad.IO.Class        (liftIO)-import           Data.Maybe                    (fromMaybe)-import           Data.Ratio                    (numerator)-import           Data.Time.Clock.POSIX         (getPOSIXTime)-import           Lens.Micro                    ((.~))-import           Network.HTTP.Client           (Manager, defaultManagerSettings,-                                                managerConnCount,-                                                managerRawConnection,-                                                managerRetryableException,-                                                newManager)-import           System.Environment            (lookupEnv)-import           System.IO.Unsafe              (unsafePerformIO)--import           Data.Solidity.Prim.Address    (Address)-import           Network.Ethereum.Account      (DefaultAccount, to, withAccount,-                                                withParam)-import           Network.Ethereum.Api.Eth      (accounts, blockNumber)-import           Network.Ethereum.Api.Provider (Provider (..), Web3,-                                                runWeb3With)-import           Network.Ethereum.Api.Types    (Quantity)---- shared manager used throughout the helpers here to prevent hammering geth from ruining everything--- this also retrys on ALL exceptions, including ConnectionResetByPeer and stuff like that-sharedManager :: Manager-sharedManager = unsafePerformIO $ newManager defaultManagerSettings-    { managerConnCount = 5-    , managerRetryableException = const False-    , managerRawConnection = fixRawConnection retryOpenConnection-    }--    where retryOpenConnection = threadDelay 500000 >> managerRawConnection defaultManagerSettings-          fixRawConnection f = f `catch` (\(_ :: SomeException) -> fixRawConnection f)-{-# NOINLINE sharedManager #-}--rpcUri :: IO String-rpcUri = liftIO (fromMaybe "http://localhost:8545" <$> lookupEnv "WEB3_PROVIDER")--contract :: Address-         -> DefaultAccount Web3 a-         -> IO a-contract a = web3 . withAccount () . withParam (to .~ a)--web3 :: Web3 a -> IO a-web3 ma = do-    provider <- HttpProvider <$> rpcUri-    v <- runWeb3With sharedManager provider ma-    case v of-        Left e   -> print e >> threadDelay 1000000 >> web3 ma-        Right v' -> return v'--withAccounts :: ([Address] -> IO a) -> IO a-withAccounts f = web3 accounts >>= f--withPrimaryEthereumAccount :: IO Address-withPrimaryEthereumAccount = withAccounts (pure . head)--sleepSeconds :: Int -> IO ()-sleepSeconds = threadDelay . (* 1000000)--microtime :: IO Integer-microtime = numerator . toRational . (* 1000000) <$> getPOSIXTime--awaitBlock :: Quantity -> IO ()-awaitBlock bn = do-    bn' <- web3 blockNumber-    -- putStrLn $ "awaiting block " ++ show bn ++ ", currently " ++ show bn'-    if bn' >= bn-        then return ()-        else threadDelay 1000000 >> awaitBlock bn--sleepBlocks :: Int -> IO ()-sleepBlocks n = do-    now <- web3 blockNumber-    awaitBlock $ now + fromIntegral n
+ test/Network/Ipfs/Api/Test/Key.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      :  Network.Ipfs.Api.Test.Key+-- Copyright   :  Alexander Krupenkin 2016+-- License     :  BSD3+--+-- Maintainer  :  mail@akru.me+-- Stability   :  experimental+-- Portability :  unknown+--+-- Key IPFS API testing module.+--++module Network.Ipfs.Api.Test.Key where++import           Control.Exception      ()+import           Control.Monad.Trans+import           Test.Hspec++import qualified Network.Ipfs.Api.Key   as Key+import           Network.Ipfs.Api.Types (KeyDetailsObj (..), KeyObj (..))+import           Network.Ipfs.Client    (runIpfs)++main :: IO ()+main = hspec $ do+  describe "keyGen" $ do+    it "should return the given key name in its response" $ runIpfs $ do+      res <- Key.gen "TestA" "rsa"+      liftIO $ keyName res `shouldBe` "TestA"++    it "KeyDetailsObj returned by KeyGen should be present in the KeyObj's list returned returned by KeyList" $+        runIpfs $ do+            resGen <- Key.gen "TestB" "rsa"+            resList <- Key.list+            liftIO $ keys resList `shouldContain` [resGen]++  describe "keyRm" $ do+    it "should return the given key name in its response" $ runIpfs $ do+      res <- Key.rm "TestA"+      liftIO $ (keyName $ Prelude.head $ keys res) `shouldBe` "TestA"++    it "KeyDetailsObj returned by KeyRm should not be present in the KeyObj's list returned returned by KeyList" $+        runIpfs $ do+            resRm <- Key.rm "TestB"+            resList <- Key.list+            liftIO $ keys resList `shouldNotContain` keys resRm
unit/Crypto/Ethereum/Test/SignatureSpec.hs view
@@ -6,9 +6,9 @@ import           Test.Hspec import           Test.Hspec.QuickCheck +import           Crypto.Ecdsa.Utils           (importKey) import           Crypto.Ethereum.Signature    (hashMessage, signMessage,                                                signTransaction)-import           Crypto.Ethereum.Utils        (importKey) import           Data.ByteArray.HexString     (HexString) import           Data.Solidity.Prim.Address   (fromPubKey) import           Network.Ethereum.Api.Types   (Call (..))
unit/Data/Solidity/Test/AddressSpec.hs view
@@ -7,7 +7,7 @@ import           Data.Monoid                ((<>)) import           Test.Hspec -import           Crypto.Ethereum.Utils      (derivePubKey, importKey)+import           Crypto.Ecdsa.Utils         (derivePubKey, importKey) import           Data.ByteArray.HexString   (HexString) import           Data.Solidity.Prim.Address 
web3.cabal view
@@ -1,15 +1,15 @@-cabal-version: 2.4+cabal-version: 2.2  -- This file has been generated from package.yaml by hpack version 0.33.0. -- -- see: https://github.com/sol/hpack ----- hash: 52f53efab4c596377b85d0718660446c92da89530ee76214df53a18a0fdd589d+-- hash: 916c1e312da75f2dfe78e0e6a6613adc7b6a4e68a1da8d57e82be1facc937203  name:           web3-version:        0.8.4.0-synopsis:       Ethereum API for Haskell-description:    Web3 is a Haskell client library for Ethereum+version:        0.9.0.0+synopsis:       Web3 API for Haskell.+description:    Client library for Third Generation of Web. category:       Network homepage:       https://github.com/airalab/hs-web3#readme bug-reports:    https://github.com/airalab/hs-web3/issues@@ -26,6 +26,7 @@     examples/token/ERC20.hs     examples/token/ERC20.json     examples/token/Main.hs+    examples/polkadot/Main.hs     test/contracts/Registry.json     test/contracts/SimpleStorage.json     test/contracts/ComplexStorage.json@@ -47,6 +48,8 @@  library   exposed-modules:+      Crypto.Ecdsa.Signature+      Crypto.Ecdsa.Utils       Crypto.Ethereum       Crypto.Ethereum.Keyfile       Crypto.Ethereum.Signature@@ -70,6 +73,7 @@       Data.Solidity.Prim.Tuple.TH       Data.String.Extra       Language.Solidity.Abi+      Network.Ethereum       Network.Ethereum.Account       Network.Ethereum.Account.Class       Network.Ethereum.Account.Default@@ -80,7 +84,6 @@       Network.Ethereum.Api.Eth       Network.Ethereum.Api.Net       Network.Ethereum.Api.Personal-      Network.Ethereum.Api.Provider       Network.Ethereum.Api.Types       Network.Ethereum.Api.Web3       Network.Ethereum.Chain@@ -96,8 +99,46 @@       Network.Ethereum.Ens.Registry       Network.Ethereum.Transaction       Network.Ethereum.Unit-      Network.Ethereum.Web3+      Network.Ipfs.Api.Bitswap+      Network.Ipfs.Api.Block+      Network.Ipfs.Api.Bootstrap+      Network.Ipfs.Api.Cid+      Network.Ipfs.Api.Config+      Network.Ipfs.Api.Core+      Network.Ipfs.Api.Dag+      Network.Ipfs.Api.Dht+      Network.Ipfs.Api.Files+      Network.Ipfs.Api.Internal+      Network.Ipfs.Api.Internal.Call+      Network.Ipfs.Api.Internal.Stream+      Network.Ipfs.Api.Key+      Network.Ipfs.Api.Log+      Network.Ipfs.Api.Object+      Network.Ipfs.Api.Pin+      Network.Ipfs.Api.Pubsub+      Network.Ipfs.Api.Repo+      Network.Ipfs.Api.Stats+      Network.Ipfs.Api.Swarm+      Network.Ipfs.Api.Types+      Network.Ipfs.Api.Types.Stream+      Network.Ipfs.Client       Network.JsonRpc.TinyClient+      Network.Polkadot.Api.Account+      Network.Polkadot.Api.Author+      Network.Polkadot.Api.Babe+      Network.Polkadot.Api.Chain+      Network.Polkadot.Api.Childstate+      Network.Polkadot.Api.Contracts+      Network.Polkadot.Api.Engine+      Network.Polkadot.Api.Grandpa+      Network.Polkadot.Api.Offchain+      Network.Polkadot.Api.Payment+      Network.Polkadot.Api.Rpc+      Network.Polkadot.Api.State+      Network.Polkadot.Api.System+      Network.Polkadot.Api.Types+      Network.Web3+      Network.Web3.Provider   other-modules:       Paths_web3   autogen-modules:@@ -109,16 +150,22 @@       OneTuple >=0.2.1 && <0.3     , aeson >=1.2.2.0 && <1.5     , async >=2.1.1.1 && <2.3+    , attoparsec >=0.13.2.1 && <0.14     , base >4.10 && <4.14+    , base58string >=0.10.0 && <0.11     , basement >=0.0.4 && <0.1     , bytestring >=0.10.8.1 && <0.11     , cereal >=0.5.4.0 && <0.6     , cryptonite >=0.23 && <0.27     , data-default >=0.7.1.1 && <0.8+    , errors >=2.2 && <2.4     , exceptions >=0.8.3 && <0.11     , generics-sop >=0.3.1.0 && <0.6+    , hspec >=2.4 && <2.8     , http-client >=0.5.7.1 && <0.7     , http-client-tls >=0.3.5.1 && <0.4+    , http-media >=0.7 && <0.8.1+    , http-types >=0.12 && <0.14     , machines >=0.6.3 && <0.8     , memory >=0.14.11 && <0.16     , microlens >=0.4.8.1 && <0.5@@ -126,14 +173,20 @@     , microlens-mtl >=0.1.11.0 && <0.3     , microlens-th >=0.4.1.1 && <0.5     , mtl >=2.2.1 && <2.3+    , network >=2.6 && <3.2     , parsec >=3.1.11 && <3.2     , relapse >=1.0.0.0 && <2.0+    , servant >=0.13 && <0.17+    , servant-client >=0.13 && <0.17     , tagged >=0.8.5 && <0.9+    , tar >=0.5 && <0.6     , template-haskell >=2.12 && <2.16     , text >=1.2.2.2 && <1.3     , transformers >=0.5.2.0 && <0.6+    , unordered-containers >=0.2 && <0.3     , uuid-types >=1.0.3 && <1.1     , vinyl >=0.5.3 && <0.13+    , websockets >=0.11 && <0.13   if flag(debug)     ghc-options: -ddump-splices   if flag(compiler)@@ -157,13 +210,16 @@   type: exitcode-stdio-1.0   main-is: Spec.hs   other-modules:-      Network.Ethereum.Web3.Test.ComplexStorageSpec-      Network.Ethereum.Web3.Test.ERC20Spec-      Network.Ethereum.Web3.Test.LinearizationSpec-      Network.Ethereum.Web3.Test.LocalAccountSpec-      Network.Ethereum.Web3.Test.RegistrySpec-      Network.Ethereum.Web3.Test.SimpleStorageSpec-      Network.Ethereum.Web3.Test.Utils+      Network.Ethereum.Test.ComplexStorageSpec+      Network.Ethereum.Test.ERC20Spec+      Network.Ethereum.Test.LinearizationSpec+      Network.Ethereum.Test.LocalAccountSpec+      Network.Ethereum.Test.RegistrySpec+      Network.Ethereum.Test.SimpleStorageSpec+      Network.Ethereum.Test.Utils+      Network.Ipfs.Api.Test.Key+      Crypto.Ecdsa.Signature+      Crypto.Ecdsa.Utils       Crypto.Ethereum       Crypto.Ethereum.Keyfile       Crypto.Ethereum.Signature@@ -187,6 +243,7 @@       Data.Solidity.Prim.Tuple.TH       Data.String.Extra       Language.Solidity.Abi+      Network.Ethereum       Network.Ethereum.Account       Network.Ethereum.Account.Class       Network.Ethereum.Account.Default@@ -197,7 +254,6 @@       Network.Ethereum.Api.Eth       Network.Ethereum.Api.Net       Network.Ethereum.Api.Personal-      Network.Ethereum.Api.Provider       Network.Ethereum.Api.Types       Network.Ethereum.Api.Web3       Network.Ethereum.Chain@@ -213,8 +269,46 @@       Network.Ethereum.Ens.Registry       Network.Ethereum.Transaction       Network.Ethereum.Unit-      Network.Ethereum.Web3+      Network.Ipfs.Api.Bitswap+      Network.Ipfs.Api.Block+      Network.Ipfs.Api.Bootstrap+      Network.Ipfs.Api.Cid+      Network.Ipfs.Api.Config+      Network.Ipfs.Api.Core+      Network.Ipfs.Api.Dag+      Network.Ipfs.Api.Dht+      Network.Ipfs.Api.Files+      Network.Ipfs.Api.Internal+      Network.Ipfs.Api.Internal.Call+      Network.Ipfs.Api.Internal.Stream+      Network.Ipfs.Api.Key+      Network.Ipfs.Api.Log+      Network.Ipfs.Api.Object+      Network.Ipfs.Api.Pin+      Network.Ipfs.Api.Pubsub+      Network.Ipfs.Api.Repo+      Network.Ipfs.Api.Stats+      Network.Ipfs.Api.Swarm+      Network.Ipfs.Api.Types+      Network.Ipfs.Api.Types.Stream+      Network.Ipfs.Client       Network.JsonRpc.TinyClient+      Network.Polkadot.Api.Account+      Network.Polkadot.Api.Author+      Network.Polkadot.Api.Babe+      Network.Polkadot.Api.Chain+      Network.Polkadot.Api.Childstate+      Network.Polkadot.Api.Contracts+      Network.Polkadot.Api.Engine+      Network.Polkadot.Api.Grandpa+      Network.Polkadot.Api.Offchain+      Network.Polkadot.Api.Payment+      Network.Polkadot.Api.Rpc+      Network.Polkadot.Api.State+      Network.Polkadot.Api.System+      Network.Polkadot.Api.Types+      Network.Web3+      Network.Web3.Provider       Paths_web3   hs-source-dirs:       test@@ -224,12 +318,15 @@       OneTuple >=0.2.1 && <0.3     , aeson >=1.2.2.0 && <1.5     , async >=2.1.1.1 && <2.3+    , attoparsec >=0.13.2.1 && <0.14     , base >4.10 && <4.14+    , base58string >=0.10.0 && <0.11     , basement >=0.0.4 && <0.1     , bytestring >=0.10.8.1 && <0.11     , cereal >=0.5.4.0 && <0.6     , cryptonite >=0.23 && <0.27     , data-default >=0.7.1.1 && <0.8+    , errors >=2.2 && <2.4     , exceptions >=0.8.3 && <0.11     , generics-sop >=0.3.1.0 && <0.6     , hspec >=2.4.4 && <2.8@@ -238,6 +335,8 @@     , hspec-expectations >=0.8.2 && <0.9     , http-client >=0.5.7.1 && <0.7     , http-client-tls >=0.3.5.1 && <0.4+    , http-media >=0.7 && <0.8.1+    , http-types >=0.12 && <0.14     , machines >=0.6.3 && <0.8     , memory >=0.14.11 && <0.16     , microlens >=0.4.8.1 && <0.5@@ -245,18 +344,24 @@     , microlens-mtl >=0.1.11.0 && <0.3     , microlens-th >=0.4.1.1 && <0.5     , mtl >=2.2.1 && <2.3+    , network >=2.6 && <3.2     , parsec >=3.1.11 && <3.2     , random >=1.1 && <1.2     , relapse >=1.0.0.0 && <2.0+    , servant >=0.13 && <0.17+    , servant-client >=0.13 && <0.17     , split >=0.2.3 && <0.3     , stm >=2.4.4 && <2.6     , tagged >=0.8.5 && <0.9+    , tar >=0.5 && <0.6     , template-haskell >=2.12 && <2.16     , text >=1.2.2.2 && <1.3     , time >=1.6.0 && <1.11     , transformers >=0.5.2.0 && <0.6+    , unordered-containers >=0.2 && <0.3     , uuid-types >=1.0.3 && <1.1     , vinyl >=0.5.3 && <0.13+    , websockets >=0.11 && <0.13   if flag(debug)     ghc-options: -ddump-splices   if flag(compiler)@@ -291,6 +396,8 @@       Network.Ethereum.Contract.Test.THSpec       Network.Ethereum.Web3.Test.EventSpec       Network.Ethereum.Web3.Test.MethodDumpSpec+      Crypto.Ecdsa.Signature+      Crypto.Ecdsa.Utils       Crypto.Ethereum       Crypto.Ethereum.Keyfile       Crypto.Ethereum.Signature@@ -314,6 +421,7 @@       Data.Solidity.Prim.Tuple.TH       Data.String.Extra       Language.Solidity.Abi+      Network.Ethereum       Network.Ethereum.Account       Network.Ethereum.Account.Class       Network.Ethereum.Account.Default@@ -324,7 +432,6 @@       Network.Ethereum.Api.Eth       Network.Ethereum.Api.Net       Network.Ethereum.Api.Personal-      Network.Ethereum.Api.Provider       Network.Ethereum.Api.Types       Network.Ethereum.Api.Web3       Network.Ethereum.Chain@@ -340,8 +447,46 @@       Network.Ethereum.Ens.Registry       Network.Ethereum.Transaction       Network.Ethereum.Unit-      Network.Ethereum.Web3+      Network.Ipfs.Api.Bitswap+      Network.Ipfs.Api.Block+      Network.Ipfs.Api.Bootstrap+      Network.Ipfs.Api.Cid+      Network.Ipfs.Api.Config+      Network.Ipfs.Api.Core+      Network.Ipfs.Api.Dag+      Network.Ipfs.Api.Dht+      Network.Ipfs.Api.Files+      Network.Ipfs.Api.Internal+      Network.Ipfs.Api.Internal.Call+      Network.Ipfs.Api.Internal.Stream+      Network.Ipfs.Api.Key+      Network.Ipfs.Api.Log+      Network.Ipfs.Api.Object+      Network.Ipfs.Api.Pin+      Network.Ipfs.Api.Pubsub+      Network.Ipfs.Api.Repo+      Network.Ipfs.Api.Stats+      Network.Ipfs.Api.Swarm+      Network.Ipfs.Api.Types+      Network.Ipfs.Api.Types.Stream+      Network.Ipfs.Client       Network.JsonRpc.TinyClient+      Network.Polkadot.Api.Account+      Network.Polkadot.Api.Author+      Network.Polkadot.Api.Babe+      Network.Polkadot.Api.Chain+      Network.Polkadot.Api.Childstate+      Network.Polkadot.Api.Contracts+      Network.Polkadot.Api.Engine+      Network.Polkadot.Api.Grandpa+      Network.Polkadot.Api.Offchain+      Network.Polkadot.Api.Payment+      Network.Polkadot.Api.Rpc+      Network.Polkadot.Api.State+      Network.Polkadot.Api.System+      Network.Polkadot.Api.Types+      Network.Web3+      Network.Web3.Provider       Paths_web3   hs-source-dirs:       unit@@ -351,12 +496,15 @@       OneTuple >=0.2.1 && <0.3     , aeson >=1.2.2.0 && <1.5     , async >=2.1.1.1 && <2.3+    , attoparsec >=0.13.2.1 && <0.14     , base >4.10 && <4.14+    , base58string >=0.10.0 && <0.11     , basement >=0.0.4 && <0.1     , bytestring >=0.10.8.1 && <0.11     , cereal >=0.5.4.0 && <0.6     , cryptonite >=0.23 && <0.27     , data-default >=0.7.1.1 && <0.8+    , errors >=2.2 && <2.4     , exceptions >=0.8.3 && <0.11     , generics-sop >=0.3.1.0 && <0.6     , hspec >=2.4.4 && <2.8@@ -365,6 +513,8 @@     , hspec-expectations >=0.8.2 && <0.9     , http-client >=0.5.7.1 && <0.7     , http-client-tls >=0.3.5.1 && <0.4+    , http-media >=0.7 && <0.8.1+    , http-types >=0.12 && <0.14     , machines >=0.6.3 && <0.8     , memory >=0.14.11 && <0.16     , microlens >=0.4.8.1 && <0.5@@ -372,14 +522,20 @@     , microlens-mtl >=0.1.11.0 && <0.3     , microlens-th >=0.4.1.1 && <0.5     , mtl >=2.2.1 && <2.3+    , network >=2.6 && <3.2     , parsec >=3.1.11 && <3.2     , relapse >=1.0.0.0 && <2.0+    , servant >=0.13 && <0.17+    , servant-client >=0.13 && <0.17     , tagged >=0.8.5 && <0.9+    , tar >=0.5 && <0.6     , template-haskell >=2.12 && <2.16     , text >=1.2.2.2 && <1.3     , transformers >=0.5.2.0 && <0.6+    , unordered-containers >=0.2 && <0.3     , uuid-types >=1.0.3 && <1.1     , vinyl >=0.5.3 && <0.13+    , websockets >=0.11 && <0.13   if flag(debug)     ghc-options: -ddump-splices   if flag(compiler)