Docker image #89

Merged
pitmutt merged 45 commits from milestone2 into master 2024-06-21 18:15:53 +00:00
3 changed files with 226 additions and 169 deletions
Showing only changes of commit 2f88c89083 - Show all commits

View file

@ -5,8 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.5.3.1-beta]
### Added
- Docker image
## [0.5.3.0-beta] ## [0.5.3.0-beta]
### Added
- Address Book functionality. Allows users to store frequently used zcash addresses and
generate transactions using them.
### Changed ### Changed
- Improved formatting of sync progress - Improved formatting of sync progress
@ -17,11 +28,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.5.2.0-beta] ## [0.5.2.0-beta]
### Added
- Address Book functionality. Allows users to store frequently used zcash addresses and
generate transactions using them.
### Changed ### Changed
- Update to `zcash-haskell-0.6.2.0` to increase performance of transaction creation - Update to `zcash-haskell-0.6.2.0` to increase performance of transaction creation

View file

@ -3,7 +3,6 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
module Zenith.CLI where module Zenith.CLI where
import qualified Brick.AttrMap as A import qualified Brick.AttrMap as A
@ -11,8 +10,10 @@ import qualified Brick.BChan as BC
import qualified Brick.Focus as F import qualified Brick.Focus as F
import Brick.Forms import Brick.Forms
( Form(..) ( Form(..)
, FormFieldState
, (@@=) , (@@=)
, allFieldsValid , allFieldsValid
, editShowableField
, editShowableFieldWithValidate , editShowableFieldWithValidate
, editTextField , editTextField
, focusedFormInputAttr , focusedFormInputAttr
@ -22,8 +23,6 @@ import Brick.Forms
, renderForm , renderForm
, setFieldValid , setFieldValid
, updateFormState , updateFormState
, FormFieldState
, editShowableField
) )
import qualified Brick.Main as M import qualified Brick.Main as M
import qualified Brick.Types as BT import qualified Brick.Types as BT
@ -43,8 +42,8 @@ import Brick.Widgets.Core
, joinBorders , joinBorders
, padAll , padAll
, padBottom , padBottom
, padTop
, padLeft , padLeft
, padTop
, setAvailableSize , setAvailableSize
, str , str
, strWrap , strWrap
@ -54,8 +53,8 @@ import Brick.Widgets.Core
, txtWrapWith , txtWrapWith
, updateAttrMap , updateAttrMap
, vBox , vBox
, viewport
, vLimit , vLimit
, viewport
, withAttr , withAttr
, withBorderStyle , withBorderStyle
) )
@ -219,7 +218,8 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
(maybe (maybe
"(None)" "(None)"
(\(_, w) -> zcashWalletName $ entityVal w) (\(_, w) -> zcashWalletName $ entityVal w)
(L.listSelectedElement (st ^. wallets)))) ++ " ")) (L.listSelectedElement (st ^. wallets)))) ++
" "))
(C.hCenter (C.hCenter
(str (str
("Account: " ++ ("Account: " ++
@ -236,7 +236,8 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
else displayTaz (st ^. balance))) <=> else displayTaz (st ^. balance))) <=>
listAddressBox " Addresses " (st ^. addresses) <+> listAddressBox " Addresses " (st ^. addresses) <+>
B.vBorder <+> B.vBorder <+>
(C.hCenter (str ("Last block seen: " ++ show (st ^. syncBlock) ++ "\n")) <=> (C.hCenter
(str ("Last block seen: " ++ show (st ^. syncBlock) ++ "\n")) <=>
listTxBox " Transactions " (st ^. network) (st ^. transactions))) <=> listTxBox " Transactions " (st ^. network) (st ^. transactions))) <=>
C.hCenter C.hCenter
(hBox (hBox
@ -313,7 +314,8 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
vBox ([str "Actions", B.hBorder] <> actionList)) vBox ([str "Actions", B.hBorder] <> actionList))
else emptyWidget else emptyWidget
where where
keyList = map (C.hCenter . str) ["?", "Esc", "w", "a", "v", "s", "b", "q"] keyList =
map (C.hCenter . str) ["?", "Esc", "w", "a", "v", "s", "b", "q"]
actionList = actionList =
map map
(hLimit 40 . str) (hLimit 40 . str)
@ -376,25 +378,28 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
D.renderDialog D.renderDialog
(D.dialog (Just $ str " Address Book ") Nothing 60) (D.dialog (Just $ str " Address Book ") Nothing 60)
(withAttr abDefAttr $ (withAttr abDefAttr $
setAvailableSize (50,20) $ setAvailableSize (50, 20) $
viewport ABViewport BT.Vertical $ viewport ABViewport BT.Vertical $
vLimit 20 $ vLimit 20 $
hLimit 50 $ hLimit 50 $
vBox [vLimit 16 $ vBox
[ vLimit 16 $
hLimit 50 $ hLimit 50 $
vBox $ [ L.renderList listDrawAB True (s ^. abAddresses) ], vBox $ [L.renderList listDrawAB True (s ^. abAddresses)]
padTop Max $ , padTop Max $
vLimit 4 $ vLimit 4 $
hLimit 50 $ hLimit 50 $
withAttr abMBarAttr $ withAttr abMBarAttr $
vBox $ [C.hCenter $ vBox $
[ C.hCenter $
(capCommand "N" "ew Address" <+> (capCommand "N" "ew Address" <+>
capCommand "E" "dit Address" <+> capCommand "E" "dit Address" <+>
capCommand3 "" "C" "opy Address"), capCommand3 "" "C" "opy Address")
C.hCenter $ , C.hCenter $
(capCommand "D" "elete Address" <+> (capCommand "D" "elete Address" <+>
capCommand "S" "end Zcash" <+> capCommand "S" "end Zcash" <+> capCommand3 "E" "x" "it")
capCommand3 "E" "x" "it")]]) ]
])
-- Address Book new entry form -- Address Book new entry form
AdrBookForm -> AdrBookForm ->
D.renderDialog D.renderDialog
@ -415,9 +420,11 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
(D.dialog (Just $ str " Delete Address Book Entry ") Nothing 50) (D.dialog (Just $ str " Delete Address Book Entry ") Nothing 50)
(renderForm (st ^. abForm) <=> (renderForm (st ^. abForm) <=>
C.hCenter C.hCenter
(hBox [capCommand "C" "onfirm delete", capCommand3 "" "<Esc>" " Cancel"])) (hBox
[ capCommand "C" "onfirm delete"
, capCommand3 "" "<Esc>" " Cancel"
]))
-- --
splashDialog :: State -> Widget Name splashDialog :: State -> Widget Name
splashDialog st = splashDialog st =
if st ^. splashBox if st ^. splashBox
@ -429,16 +436,14 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
(str (str
" _____ _ _ _ \n|__ /___ _ __ (_) |_| |__\n / // _ \\ '_ \\| | __| '_ \\\n / /| __/ | | | | |_| | | |\n/____\\___|_| |_|_|\\__|_| |_|") <=> " _____ _ _ _ \n|__ /___ _ __ (_) |_| |__\n / // _ \\ '_ \\| | __| '_ \\\n / /| __/ | | | | |_| | | |\n/____\\___|_| |_|_|\\__|_| |_|") <=>
C.hCenter C.hCenter
(withAttr titleAttr (str "Zcash Wallet v0.5.3.0-beta")) <=> (withAttr titleAttr (str "Zcash Wallet v0.5.3.1-beta")) <=>
C.hCenter (withAttr blinkAttr $ str "Press any key...")) C.hCenter (withAttr blinkAttr $ str "Press any key..."))
else emptyWidget else emptyWidget
capCommand3 :: String -> String -> String -> Widget Name capCommand3 :: String -> String -> String -> Widget Name
capCommand3 l h e = hBox [str l, withAttr titleAttr (str h), str e] capCommand3 l h e = hBox [str l, withAttr titleAttr (str h), str e]
capCommand2 :: String -> String -> String -> Widget Name capCommand2 :: String -> String -> String -> Widget Name
capCommand2 l h e = hBox [str l, withAttr titleAttr (str h), str e, str " | "] capCommand2 l h e =
hBox [str l, withAttr titleAttr (str h), str e, str " | "]
capCommand :: String -> String -> Widget Name capCommand :: String -> String -> Widget Name
capCommand k comm = hBox [withAttr titleAttr (str k), str comm, str " | "] capCommand k comm = hBox [withAttr titleAttr (str k), str comm, str " | "]
xCommand :: Widget Name xCommand :: Widget Name
@ -565,7 +570,8 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
AdrBookEntryDisplay -> do AdrBookEntryDisplay -> do
case L.listSelectedElement $ st ^. abAddresses of case L.listSelectedElement $ st ^. abAddresses of
Just (_, a) -> do Just (_, a) -> do
let abentry = T.pack $ let abentry =
T.pack $
" Descr: " ++ " Descr: " ++
T.unpack (addressBookAbdescrip (entityVal a)) ++ T.unpack (addressBookAbdescrip (entityVal a)) ++
"\n Address: " ++ "\n Address: " ++
@ -684,7 +690,7 @@ listDrawAB :: Bool -> Entity AddressBook -> Widget Name
listDrawAB sel ab = listDrawAB sel ab =
let selStr s = let selStr s =
if sel if sel
then withAttr abSelAttr (txt $ " " <> s ) then withAttr abSelAttr (txt $ " " <> s)
else txt $ " " <> s else txt $ " " <> s
in selStr $ addressBookAbdescrip (entityVal ab) in selStr $ addressBookAbdescrip (entityVal ab)
@ -726,7 +732,8 @@ scanZebra dbP zHost zPort b eChan = do
dbBlock <- runNoLoggingT $ getMaxBlock pool dbBlock <- runNoLoggingT $ getMaxBlock pool
let sb = max dbBlock b let sb = max dbBlock b
if sb > zgb_blocks bStatus || sb < 1 if sb > zgb_blocks bStatus || sb < 1
then liftIO $ BC.writeBChan eChan $ TickMsg "Invalid starting block for scan" then liftIO $
BC.writeBChan eChan $ TickMsg "Invalid starting block for scan"
else do else do
let bList = [(sb + 1) .. (zgb_blocks bStatus)] let bList = [(sb + 1) .. (zgb_blocks bStatus)]
if not (null bList) if not (null bList)
@ -1072,7 +1079,8 @@ appEvent (BT.VtyEvent e) = do
BT.modify $ set msg "Invalid inputs" BT.modify $ set msg "Invalid inputs"
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
BT.modify $ set dialogBox Blank BT.modify $ set dialogBox Blank
ev -> BT.zoom txForm $ do ev ->
BT.zoom txForm $ do
handleFormEvent (BT.VtyEvent ev) handleFormEvent (BT.VtyEvent ev)
fs <- BT.gets formState fs <- BT.gets formState
BT.modify $ BT.modify $
@ -1083,8 +1091,9 @@ appEvent (BT.VtyEvent e) = do
case e of case e of
V.EvKey (V.KChar 'x') [] -> V.EvKey (V.KChar 'x') [] ->
BT.modify $ set dialogBox Blank BT.modify $ set dialogBox Blank
V.EvKey (V.KChar 'c') [] -> do V.EvKey (V.KChar 'c') []
-- Copy Address to Clipboard -- Copy Address to Clipboard
-> do
case L.listSelectedElement $ s ^. abAddresses of case L.listSelectedElement $ s ^. abAddresses of
Just (_, a) -> do Just (_, a) -> do
liftIO $ liftIO $
@ -1096,7 +1105,8 @@ appEvent (BT.VtyEvent e) = do
T.unpack (addressBookAbdescrip (entityVal a)) T.unpack (addressBookAbdescrip (entityVal a))
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
_ -> do _ -> do
BT.modify $ set msg "Error while copying the address!!" BT.modify $
set msg "Error while copying the address!!"
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
-- Send Zcash transaction -- Send Zcash transaction
V.EvKey (V.KChar 's') [] -> do V.EvKey (V.KChar 's') [] -> do
@ -1104,19 +1114,31 @@ appEvent (BT.VtyEvent e) = do
Just (_, a) -> do Just (_, a) -> do
BT.modify $ BT.modify $
set txForm $ set txForm $
mkSendForm (s ^. balance) (SendInput (addressBookAbaddress (entityVal a)) 0.0 "") mkSendForm
(s ^. balance)
(SendInput
(addressBookAbaddress (entityVal a))
0.0
"")
BT.modify $ set dialogBox SendTx BT.modify $ set dialogBox SendTx
_ -> do _ -> do
BT.modify $ set msg "No receiver address available!!" BT.modify $
set msg "No receiver address available!!"
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
-- Edit an entry in Address Book -- Edit an entry in Address Book
V.EvKey (V.KChar 'e') [] -> do V.EvKey (V.KChar 'e') [] -> do
case L.listSelectedElement $ s ^. abAddresses of case L.listSelectedElement $ s ^. abAddresses of
Just (_, a) -> do Just (_, a) -> do
BT.modify $ set abCurAdrs (addressBookAbaddress (entityVal a)) BT.modify $
set
abCurAdrs
(addressBookAbaddress (entityVal a))
BT.modify $ BT.modify $
set abForm $ set abForm $
mkNewABForm (AdrBookEntry (addressBookAbdescrip (entityVal a)) (addressBookAbaddress (entityVal a))) mkNewABForm
(AdrBookEntry
(addressBookAbdescrip (entityVal a))
(addressBookAbaddress (entityVal a)))
BT.modify $ set dialogBox AdrBookUpdForm BT.modify $ set dialogBox AdrBookUpdForm
_ -> do _ -> do
BT.modify $ set dialogBox Blank BT.modify $ set dialogBox Blank
@ -1124,21 +1146,27 @@ appEvent (BT.VtyEvent e) = do
V.EvKey (V.KChar 'd') [] -> do V.EvKey (V.KChar 'd') [] -> do
case L.listSelectedElement $ s ^. abAddresses of case L.listSelectedElement $ s ^. abAddresses of
Just (_, a) -> do Just (_, a) -> do
BT.modify $ set abCurAdrs (addressBookAbaddress (entityVal a)) BT.modify $
set
abCurAdrs
(addressBookAbaddress (entityVal a))
BT.modify $ BT.modify $
set abForm $ set abForm $
mkNewABForm (AdrBookEntry (addressBookAbdescrip (entityVal a)) (addressBookAbaddress (entityVal a))) mkNewABForm
(AdrBookEntry
(addressBookAbdescrip (entityVal a))
(addressBookAbaddress (entityVal a)))
BT.modify $ set dialogBox AdrBookDelForm BT.modify $ set dialogBox AdrBookDelForm
_ -> do _ -> do
BT.modify $ set dialogBox Blank BT.modify $ set dialogBox Blank
-- Create a new entry in Address Book -- Create a new entry in Address Book
V.EvKey (V.KChar 'n') [] -> do V.EvKey (V.KChar 'n') [] -> do
BT.modify $ set abForm $ mkNewABForm (AdrBookEntry "" "") BT.modify $
set abForm $ mkNewABForm (AdrBookEntry "" "")
BT.modify $ set dialogBox AdrBookForm BT.modify $ set dialogBox AdrBookForm
-- Show AddressBook entry data -- Show AddressBook entry data
V.EvKey V.KEnter [] -> do V.EvKey V.KEnter [] -> do
BT.modify $ set displayBox AdrBookEntryDisplay BT.modify $ set displayBox AdrBookEntryDisplay
-- Process any other event -- Process any other event
ev -> BT.zoom abAddresses $ L.handleListEvent ev ev -> BT.zoom abAddresses $ L.handleListEvent ev
-- Process new address book entry -- Process new address book entry
@ -1152,13 +1180,27 @@ appEvent (BT.VtyEvent e) = do
let iabadr = fs ^. address let iabadr = fs ^. address
if not (null idescr) && isRecipientValid iabadr if not (null idescr) && isRecipientValid iabadr
then do then do
res <- liftIO $ saveAdrsInAdrBook pool $ AddressBook (ZcashNetDB (s ^. network)) (fs ^. descrip) (fs ^.address) res <-
liftIO $
saveAdrsInAdrBook pool $
AddressBook
(ZcashNetDB (s ^. network))
(fs ^. descrip)
(fs ^. address)
case res of case res of
Nothing -> do Nothing -> do
BT.modify $ set msg ("AddressBook Entry already exists: " ++ T.unpack (fs ^.address)) BT.modify $
set
msg
("AddressBook Entry already exists: " ++
T.unpack (fs ^. address))
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
Just _ -> do Just _ -> do
BT.modify $ set msg ("New AddressBook entry created!!\n" ++ T.unpack (fs ^.address)) BT.modify $
set
msg
("New AddressBook entry created!!\n" ++
T.unpack (fs ^. address))
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
-- case end -- case end
s' <- liftIO $ refreshAddressBook s s' <- liftIO $ refreshAddressBook s
@ -1168,7 +1210,8 @@ appEvent (BT.VtyEvent e) = do
BT.modify $ set msg "Invalid or missing data!!: " BT.modify $ set msg "Invalid or missing data!!: "
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
BT.modify $ set dialogBox AdrBookForm BT.modify $ set dialogBox AdrBookForm
ev -> BT.zoom abForm $ do ev ->
BT.zoom abForm $ do
handleFormEvent (BT.VtyEvent ev) handleFormEvent (BT.VtyEvent ev)
fs <- BT.gets formState fs <- BT.gets formState
BT.modify $ BT.modify $
@ -1185,8 +1228,18 @@ appEvent (BT.VtyEvent e) = do
let iabadr = fs ^. address let iabadr = fs ^. address
if not (null idescr) && isRecipientValid iabadr if not (null idescr) && isRecipientValid iabadr
then do then do
res <- liftIO $ updateAdrsInAdrBook pool (fs ^. descrip) (fs ^.address) (s ^. abCurAdrs) res <-
BT.modify $ set msg ("AddressBook entry modified!!\n" ++ T.unpack (fs ^.address)) liftIO $
updateAdrsInAdrBook
pool
(fs ^. descrip)
(fs ^. address)
(s ^. abCurAdrs)
BT.modify $
set
msg
("AddressBook entry modified!!\n" ++
T.unpack (fs ^. address))
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
-- case end -- case end
s' <- liftIO $ refreshAddressBook s s' <- liftIO $ refreshAddressBook s
@ -1196,7 +1249,8 @@ appEvent (BT.VtyEvent e) = do
BT.modify $ set msg "Invalid or missing data!!: " BT.modify $ set msg "Invalid or missing data!!: "
BT.modify $ set displayBox MsgDisplay BT.modify $ set displayBox MsgDisplay
BT.modify $ set dialogBox AdrBookForm BT.modify $ set dialogBox AdrBookForm
ev -> BT.zoom abForm $ do ev ->
BT.zoom abForm $ do
handleFormEvent (BT.VtyEvent ev) handleFormEvent (BT.VtyEvent ev)
fs <- BT.gets formState fs <- BT.gets formState
BT.modify $ BT.modify $
@ -1210,7 +1264,7 @@ appEvent (BT.VtyEvent e) = do
V.EvKey (V.KChar 'c') [] -> do V.EvKey (V.KChar 'c') [] -> do
pool <- liftIO $ runNoLoggingT $ initPool $ s ^. dbPath pool <- liftIO $ runNoLoggingT $ initPool $ s ^. dbPath
fs <- BT.zoom abForm $ BT.gets formState fs <- BT.zoom abForm $ BT.gets formState
res <- liftIO $ deleteAdrsFromAB pool (fs ^.address) res <- liftIO $ deleteAdrsFromAB pool (fs ^. address)
s' <- liftIO $ refreshAddressBook s s' <- liftIO $ refreshAddressBook s
BT.put s' BT.put s'
BT.modify $ set dialogBox AdrBook BT.modify $ set dialogBox AdrBook
@ -1321,9 +1375,7 @@ runZenithTUI config = do
if not (null walList) if not (null walList)
then zcashWalletLastSync $ entityVal $ head walList then zcashWalletLastSync $ entityVal $ head walList
else 0 else 0
abookList <- getAdrBook pool $ zgb_net chainInfo abookList <- getAdrBook pool $ zgb_net chainInfo
bal <- bal <-
if not (null accList) if not (null accList)
then getBalance pool $ entityKey $ head accList then getBalance pool $ entityKey $ head accList
@ -1451,8 +1503,7 @@ addNewAccount n s = do
Right zA' -> do Right zA' -> do
r <- saveAccount pool zA' r <- saveAccount pool zA'
case r of case r of
Nothing -> Nothing -> return $ s & msg .~ "Account already exists: " ++ T.unpack n
return $ s & msg .~ "Account already exists: " ++ T.unpack n
Just x -> do Just x -> do
aL <- runNoLoggingT $ getAccounts pool (entityKey selWallet) aL <- runNoLoggingT $ getAccounts pool (entityKey selWallet)
let nL = let nL =
@ -1519,7 +1570,8 @@ refreshAddressBook s = do
do case L.listSelectedElement $ s ^. abAddresses of do case L.listSelectedElement $ s ^. abAddresses of
Nothing -> do Nothing -> do
let fAdd = let fAdd =
L.listSelectedElement $ L.listMoveToBeginning $ s ^. abAddresses L.listSelectedElement $
L.listMoveToBeginning $ s ^. abAddresses
return fAdd return fAdd
Just a2 -> return $ Just a2 Just a2 -> return $ Just a2
abookList <- getAdrBook pool (s ^. network) abookList <- getAdrBook pool (s ^. network)
@ -1547,8 +1599,7 @@ addNewAddress n scope s = do
Right uA' -> do Right uA' -> do
nAddr <- saveAddress pool uA' nAddr <- saveAddress pool uA'
case nAddr of case nAddr of
Nothing -> Nothing -> return $ s & msg .~ "Address already exists: " ++ T.unpack n
return $ s & msg .~ "Address already exists: " ++ T.unpack n
Just x -> do Just x -> do
addrL <- runNoLoggingT $ getAddresses pool (entityKey selAccount) addrL <- runNoLoggingT $ getAddresses pool (entityKey selAccount)
let nL = let nL =

View file

@ -1,6 +1,6 @@
cabal-version: 3.0 cabal-version: 3.0
name: zenith name: zenith
version: 0.5.3.0-beta version: 0.5.3.1-beta
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Rene Vergara author: Rene Vergara