Implement creating new addresses

This commit is contained in:
Rene Vergara 2024-06-19 15:37:56 -05:00
parent eae4bfc949
commit bf663843b3
Signed by: pitmutt
GPG key ID: 65122AD495A7F5B2
3 changed files with 93 additions and 11 deletions

View file

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Balance display
- Account selector
- Menu for new addresses, accounts, wallets
- Dialog to add new address
## [0.5.3.0-beta]

View file

@ -233,6 +233,8 @@ constraints: any.Cabal ==3.8.1.0,
any.psqueues ==0.2.8.0,
any.pureMD5 ==2.1.4,
pureMD5 -test,
any.qrcode-core ==0.9.9,
any.qrcode-juicypixels ==0.8.5,
any.quickcheck-io ==0.2.0,
any.quickcheck-transformer ==0.3.1.2,
any.random ==1.2.1.2,

View file

@ -26,7 +26,10 @@ import TextShow
import ZcashHaskell.Orchard (getSaplingFromUA, isValidUnifiedAddress)
import ZcashHaskell.Transparent (encodeTransparentReceiver)
import ZcashHaskell.Types
( UnifiedAddress(..)
( Phrase(..)
, Scope(..)
, ToBytes(..)
, UnifiedAddress(..)
, ZcashNet(..)
, ZebraGetBlockChainInfo(..)
, ZebraGetInfo(..)
@ -34,7 +37,7 @@ import ZcashHaskell.Types
import Zenith.Core
import Zenith.DB
import Zenith.GUI.Theme
import Zenith.Types hiding (ZcashAddress)
import Zenith.Types hiding (ZcashAddress(..))
import Zenith.Utils (displayAmount, showAddress)
data AppEvent
@ -62,6 +65,9 @@ data AppEvent
| SaveAddress
| SaveAccount
| SaveWallet
| CloseSeed
| ShowSeed
| CopySeed !T.Text
deriving (Eq, Show)
data AppModel = AppModel
@ -91,6 +97,7 @@ data AppModel = AppModel
, _confirmCancel :: !T.Text
, _confirmEvent :: !AppEvent
, _inError :: !Bool
, _showSeed :: !Bool
} deriving (Eq, Show)
makeLenses ''AppModel
@ -126,6 +133,7 @@ buildUI wenv model = widgetTree
zstack
[ mainWindow
, confirmOverlay `nodeVisible` isJust (model ^. confirmTitle)
, seedOverlay `nodeVisible` model ^. showSeed
, msgOverlay `nodeVisible` isJust (model ^. msg)
]
mainWindow =
@ -187,7 +195,7 @@ buildUI wenv model = widgetTree
, widgetIf (model ^. newPopup) $ animSlideIn newBox
]) `styleBasic`
[bgColor white, borderB 1 gray, padding 3]
, box_ [alignLeft] (label "Backup Wallet") `styleBasic`
, box_ [alignLeft, onClick ShowSeed] (label "Backup Wallet") `styleBasic`
[bgColor white, borderB 1 gray, padding 3]
]) `styleBasic`
[bgColor btnColor, padding 3]
@ -252,7 +260,10 @@ buildUI wenv model = widgetTree
, styleIf (model ^. selAcc == idx) (borderL 2 btnHiLite)
, styleIf (model ^. selAcc == idx) (borderR 2 btnHiLite)
]
mainPane = box_ [alignMiddle] $ hstack [addressBox, txBox]
mainPane =
box_ [alignMiddle] $
hstack
[addressBox, txBox `nodeVisible` not (null $ model ^. transactions)]
balanceBox =
hstack
[ filler
@ -450,9 +461,10 @@ buildUI wenv model = widgetTree
alert CloseMsg $
hstack
[ filler
, image_ "./assets/1F616_color.png" [fitHeight] `styleBasic`
[height 44, width 44] `nodeVisible`
, remixIcon remixErrorWarningFill `styleBasic`
[textSize 32, textColor btnColor] `nodeVisible`
(model ^. inError)
, spacer
, label $ fromMaybe "" (model ^. msg)
, filler
]
@ -465,6 +477,44 @@ buildUI wenv model = widgetTree
, cancelCaption $ model ^. confirmCancel
]
(hstack [label "Name:", filler, textField_ mainInput [maxLength 25]])
seedOverlay =
alert CloseSeed $
vstack
[ box_
[]
(label "Seed Phrase" `styleBasic`
[textFont "Bold", textSize 12, textColor white]) `styleBasic`
[bgColor btnColor, radius 2, padding 3]
, spacer
, textAreaV_
(maybe
"None"
(E.decodeUtf8Lenient .
getBytes . getPhrase . zcashWalletSeedPhrase . entityVal)
currentWallet)
(const CloseSeed)
[readOnly, maxLines 2] `styleBasic`
[textSize 8]
, spacer
, hstack
[ filler
, box_
[ onClick $
CopySeed $
maybe
"None"
(E.decodeUtf8Lenient .
getBytes . getPhrase . zcashWalletSeedPhrase . entityVal)
currentWallet
]
(hstack
[ label "Copy" `styleBasic` [textColor white]
, remixIcon remixFileCopyLine `styleBasic` [textColor white]
]) `styleBasic`
[cursorHand, bgColor btnColor, radius 2, padding 3]
, filler
]
]
generateQRCodes :: Config -> IO ()
generateQRCodes config = do
@ -581,12 +631,13 @@ handleEvent wenv node model evt =
False
]
ConfirmCancel -> [Model $ model & confirmTitle .~ Nothing & mainInput .~ ""]
ShowSeed -> [Model $ model & showSeed .~ True & menuPopup .~ False]
SaveAddress ->
[ if T.length (model ^. mainInput) > 1
then Event $ ShowMsg $ "You saved address: " <> model ^. mainInput
else Event $ ShowError "Invalid input"
, Event ConfirmCancel
]
if T.length (model ^. mainInput) > 1
then [ Task $ addNewAddress (model ^. mainInput) External currentAccount
, Event ConfirmCancel
]
else [Event $ ShowError "Invalid input", Event ConfirmCancel]
SaveAccount ->
[ if T.length (model ^. mainInput) > 1
then Event $ ShowMsg $ "You saved account: " <> model ^. mainInput
@ -654,10 +705,15 @@ handleEvent wenv node model evt =
a
, Event $ ShowMsg "Copied address!"
]
CopySeed s ->
[ setClipboardData $ ClipboardText s
, Event $ ShowMsg "Copied seed phrase!"
]
LoadTxs t -> [Model $ model & transactions .~ t]
LoadAddrs a -> [Model $ model & addresses .~ a, Event $ SetPool Orchard]
LoadAccs a -> [Model $ model & accounts .~ a, Event $ SwitchAcc 0]
CloseMsg -> [Model $ model & msg .~ Nothing & inError .~ False]
CloseSeed -> [Model $ model & showSeed .~ False]
where
currentWallet =
if null (model ^. wallets)
@ -679,6 +735,27 @@ handleEvent wenv node model evt =
if null (model ^. addresses)
then Nothing
else Just ((model ^. addresses) !! (model ^. selAddr))
addNewAddress ::
T.Text -> Scope -> Maybe (Entity ZcashAccount) -> IO AppEvent
addNewAddress n scope acc = do
case acc of
Nothing -> return $ ShowError "No account available"
Just a -> do
pool <- runNoLoggingT $ initPool $ c_dbPath $ model ^. configuration
maxAddr <- getMaxAddress pool (entityKey a) scope
uA <-
try $ createWalletAddress n (maxAddr + 1) (model ^. network) scope a :: IO
(Either IOError WalletAddress)
case uA of
Left e -> return $ ShowError $ "Error: " <> T.pack (show e)
Right uA' -> do
nAddr <- saveAddress pool uA'
case nAddr of
Nothing -> return $ ShowError $ "Address already exists: " <> n
Just _x -> do
generateQRCodes $ model ^. configuration
addrL <- runNoLoggingT $ getAddresses pool $ entityKey a
return $ LoadAddrs addrL
runZenithGUI :: Config -> IO ()
runZenithGUI config = do
@ -742,6 +819,7 @@ runZenithGUI config = do
""
SaveAddress
False
False
startApp model handleEvent buildUI params
Left e -> do
initDb dbFilePath
@ -775,6 +853,7 @@ runZenithGUI config = do
""
SaveAddress
False
False
startApp model handleEvent buildUI params
where
params =