diff --git a/CHANGELOG.md b/CHANGELOG.md index 0035626..11b8225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## Added +### Added - `Core` module - `CLI` module - `DB` module - Command line arguments to switch to legacy version +- New configuration parameter for Zebra port +- New functions to call `getinfo` and `getblockchaininfo` RPC methods ## [0.4.1] diff --git a/package.yaml b/package.yaml index d986cc6..4d5b0e1 100644 --- a/package.yaml +++ b/package.yaml @@ -30,6 +30,7 @@ library: - text - bytestring - http-conduit + - http-client - scientific - vector - regex-base diff --git a/src/Zenith/CLI.hs b/src/Zenith/CLI.hs index b2682f4..37c5fe4 100644 --- a/src/Zenith/CLI.hs +++ b/src/Zenith/CLI.hs @@ -1,4 +1,5 @@ {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE OverloadedStrings #-} module Zenith.CLI where @@ -33,6 +34,8 @@ import Brick.Widgets.Core ) import qualified Brick.Widgets.List as L import qualified Data.Vector as Vec +import Network.HTTP.Simple +import ZcashHaskell.Types import Zenith.Core data Name @@ -85,15 +88,6 @@ listDrawElement sel a = else str s in C.hCenter $ selStr $ show a -initialState :: State -initialState = - State - "Main" - (L.list WList (Vec.fromList ["wall1"]) 1) - (L.list AList (Vec.fromList ["addr1", "addr2"]) 1) - (L.list TList (Vec.fromList ["tx1", "tx2", "tx3"]) 1) - "Start up Ok!" - customAttr :: A.AttrName customAttr = L.listSelectedAttr <> A.attrName "custom" @@ -129,10 +123,25 @@ theApp = , M.appAttrMap = const theMap } -runZenithCLI :: T.Text -> IO () -runZenithCLI dbName = do - w <- checkWallets dbName - if (null w) - then void $ M.defaultMain theApp initialState - else do - print "No wallet found. Create one? Y/N" +runZenithCLI :: Int -> T.Text -> IO () +runZenithCLI port dbName = do + w <- checkZebra port + case (w :: Maybe ZebraGetInfo) of + Just zebra -> do + bc <- checkBlockChain port + case (bc :: Maybe ZebraGetBlockChainInfo) of + Nothing -> print "Unable to determine blockchain status" + Just chainInfo -> do + void $ + M.defaultMain theApp $ + State + ((show . zgb_net) chainInfo) + (L.list WList (Vec.fromList ["wall1"]) 1) + (L.list AList (Vec.fromList ["addr1", "addr2"]) 1) + (L.list TList (Vec.fromList ["tx1", "tx2", "tx3"]) 1) + ("Start up Ok! Connected to Zebra " ++ + (T.unpack . zgi_build) zebra ++ " on port " ++ show port ++ ".") + Nothing -> do + print $ + "No Zebra node available on port " <> + show port <> ". Check your configuration" diff --git a/src/Zenith/Core.hs b/src/Zenith/Core.hs index 1356300..f2f2bbb 100644 --- a/src/Zenith/Core.hs +++ b/src/Zenith/Core.hs @@ -1,12 +1,48 @@ +{-# LANGUAGE OverloadedStrings #-} + +-- Core wallet functionality for Zenith module Zenith.Core where +import Data.Aeson import qualified Data.Text as T import Database.Persist import Database.Persist.Sqlite +import Network.HTTP.Client +import ZcashHaskell.Types +import ZcashHaskell.Utils import Zenith.DB -checkWallets :: T.Text -> IO [Entity ZcashWallet] +-- * Database functions +-- | Returns the list of wallets available in the given database +checkWallets :: + T.Text -- ^ The database name to check + -> IO [Entity ZcashWallet] checkWallets dbName = do runSqlite dbName $ do runMigration migrateAll - wallets <- runSqlite dbName $ selectList [ZcashWalletBirthdayHeight >. 0] [] - return wallets + runSqlite dbName $ selectList [ZcashWalletBirthdayHeight >. 0] [] + +-- * Zebra Node interaction +-- | Checks the status of the `zebrad` node +checkZebra :: + Int -- ^ Port where `zebrad` is available + -> IO (Maybe ZebraGetInfo) +checkZebra port = do + res <- makeZebraCall port "getinfo" [] + let body = responseBody (res :: Response (RpcResponse ZebraGetInfo)) + return $ result body + +-- | Checks the status of the Zcash blockchain +checkBlockChain :: + Int -- ^ Port where `zebrad` is available + -> IO (Maybe ZebraGetBlockChainInfo) +checkBlockChain port = do + let f = makeZebraCall port + result <$> (responseBody <$> f "getblockchaininfo" []) + +-- | Generic RPC call function +connectZebra :: + FromJSON a => Int -> T.Text -> [Data.Aeson.Value] -> IO (Maybe a) +connectZebra port m params = do + res <- makeZebraCall port m params + let body = responseBody res + return $ result body