@@ -13,14 +13,16 @@ import Control.Exception (throw, throwIO)
1313import Control.Monad.Except (runExceptT , throwError )
1414import Control.Monad.Reader
1515
16- import Data.Aeson (Value (.. ), Array , decode , encode , ToJSON , toJSON )
16+ import Data.Aeson (Value (.. ), Array , decode , ToJSON , toJSON )
1717import Data.Bool (Bool )
1818import Data.List (sortOn , sort )
1919import qualified Data.Map as Map
2020import Data.Maybe (Maybe (Nothing ), catMaybes , fromMaybe , mapMaybe )
2121import Data.Ord (Down (.. ))
2222import Data.Text hiding (any , drop , elem , filter , length , map , null , take )
2323import qualified Data.Text as Text
24+ import qualified Data.Text.Lazy as TL
25+ import qualified Data.Text.Lazy.Encoding as TL
2426import qualified Data.Vector as V
2527import Data.Time.LocalTime (TimeZone , getCurrentTimeZone )
2628
@@ -48,9 +50,14 @@ import VVA.Types (App, AppEnv (..),
4850 AppError (CriticalError , InternalError , ValidationError ),
4951 CacheEnv (.. ))
5052import Data.Time (TimeZone , localTimeToUTC )
53+ import qualified VVA.Ipfs as Ipfs
54+ import Data.ByteString.Lazy (ByteString )
55+ import qualified Data.ByteString.Lazy as BSL
5156
5257type VVAApi =
53- " drep" :> " list"
58+ " ipfs"
59+ :> " upload" :> QueryParam " fileName" Text :> ReqBody '[PlainText ] Text :> Post '[JSON ] UploadResponse
60+ :<|> " drep" :> " list"
5461 :> QueryParam " search" Text
5562 :> QueryParams " status" DRepStatus
5663 :> QueryParam " sort" DRepSortMode
@@ -89,7 +96,8 @@ type VVAApi =
8996 :<|> " account" :> Capture " stakeKey" HexText :> Get '[JSON ] GetAccountInfoResponse
9097
9198server :: App m => ServerT VVAApi m
92- server = drepList
99+ server = upload
100+ :<|> drepList
93101 :<|> getVotingPower
94102 :<|> getVotes
95103 :<|> drepInfo
@@ -107,6 +115,19 @@ server = drepList
107115 :<|> getNetworkTotalStake
108116 :<|> getAccountInfo
109117
118+ upload :: App m => Maybe Text -> Text -> m UploadResponse
119+ upload mFileName fileContentText = do
120+ AppEnv {vvaConfig} <- ask
121+ let fileContent = TL. encodeUtf8 $ TL. fromStrict fileContentText
122+ vvaPinataJwt = pinataApiJwt vvaConfig
123+ fileName = fromMaybe " data.txt" mFileName -- Default to data.txt if no filename is provided
124+ when (BSL. length fileContent > 1024 * 512 ) $
125+ throwError $ ValidationError " The uploaded file is larger than 500Kb"
126+ eIpfsHash <- liftIO $ Ipfs. ipfsUpload vvaPinataJwt fileName fileContent
127+ case eIpfsHash of
128+ Left err -> throwError $ InternalError $ " IPFS upload failed: " <> pack err
129+ Right ipfsHash -> return $ UploadResponse ipfsHash
130+
110131mapDRepType :: Types. DRepType -> DRepType
111132mapDRepType Types. DRep = NormalDRep
112133mapDRepType Types. SoleVoter = SoleVoter
0 commit comments