Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fission-codes/ipfs-haskell

IPFS wrapper for Haskell
https://github.com/fission-codes/ipfs-haskell

content-addressing ipfs library

Last synced: 1 day ago
JSON representation

IPFS wrapper for Haskell

Awesome Lists containing this project

README

        

# ipfs-haskell

[![Build Status](https://travis-ci.org/fission-suite/PROJECTNAME.svg?branch=master)](https://travis-ci.org/fission-suite/ipfs-haskell)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/fission-suite/blob/master/LICENSE)
[![Maintainability](https://api.codeclimate.com/v1/badges/44fb6a8a0cfd88bc41ef/maintainability)](https://codeclimate.com/github/fission-suite/ipfs-haskell/maintainability)
[![Built by FISSION](https://img.shields.io/badge/⌘-Built_by_FISSION-purple.svg)](https://fission.codes)
[![Discord](https://img.shields.io/discord/478735028319158273.svg)](https://discord.gg/zAQBDEq)
[![Discourse](https://img.shields.io/discourse/https/talk.fission.codes/topics)](https://talk.fission.codes)

Documentation: [ipfs on hackage](http://hackage.haskell.org/package/ipfs)

A library for integrating IPFS into your haskell applications. Interact with the IPFS network by shelling out to a local IPFS node or communicating via the HTTP interface of a remote node.

# QuickStart

Define instances for `MonadLocalIPFS` and/or `MonadRemoteIPFS`. Each requires only one function:

```haskell
class Monad m => MonadRemoteIPFS m where
runRemote :: Servant.ClientM a -> m (Either Servant.ClientError a)

class Monad m => MonadLocalIPFS m where
runLocal ::
[IPFS.Opt]
-> Lazy.ByteString
-> m (Either Process.Error Process.RawMessage)
```

We use RIO processes to shell out to a local IPFS node and Servant for HTTP requests to a remote node.

After that, simply add `MonadLocalIPFS m` as a constraint to a function and you'll be able to call IPFS within it.
For instance:
```haskell
import Network.IPFS
import qualified Network.IPFS.Add as IPFS
import Network.IPFS.File.Types as File

add ::
MonadLocalIPFS m
=> File.Serialzed
-> m ()
add (Serialized rawData) = IPFS.addRaw rawData >>= \case
Right newCID ->
-- ...
Left err ->
-- ...

```

You can see example instances below:
```haskell
instance
( HasProcessContext cfg
, HasLogFunc cfg
, Has IPFS.BinPath cfg
, Has IPFS.Timeout cfg
)
=> MonadLocalIPFS (RIO cfg) where
runLocal opts arg = do
IPFS.BinPath ipfs <- view hasLens
IPFS.Timeout secs <- view hasLens
let opts' = ("--timeout=" <> show secs <> "s") : opts

runProc readProcess ipfs (byteStringInput arg) byteStringOutput opts' >>= \case
(ExitSuccess, contents, _) ->
return $ Right contents
(ExitFailure _, _, stdErr)
| Lazy.isSuffixOf "context deadline exceeded" stdErr ->
return . Left $ Process.Timeout secs
| otherwise ->
return . Left $ Process.UnknownErr stdErr

instance
( Has IPFS.URL cfg
, Has HTTP.Manager cfg
)
=> MonadRemoteIPFS (RIO cfg) where
runRemote query = do
IPFS.URL url <- view hasLens
manager <- view hasLens

url
& mkClientEnv manager
& runClientM query
& liftIO
```