Compare commits
40 commits
96c9df571e
...
e9e342e77f
Author | SHA1 | Date | |
---|---|---|---|
e9e342e77f | |||
51cf375265 | |||
2f88c89083 | |||
77a0890ac8 | |||
3a9c5a8430 | |||
f8bac14df3 | |||
244bbf76a7 | |||
b63b0ff444 | |||
d1a5fdfa50 | |||
122d24a929 | |||
f89e9b72ca | |||
84265de3e2 | |||
3f33295bdc | |||
8754c79079 | |||
4f0fa9bc34 | |||
c5b7714917 | |||
ddbd08d474 | |||
772025e317 | |||
d57ac5db14 | |||
51116e8083 | |||
1c88ea5f08 | |||
0b70bbb8de | |||
dbfc91d33a | |||
edb7422951 | |||
a33ae3b595 | |||
4cb4f401a3 | |||
bd1f4e3a5c | |||
28bbcb48f0 | |||
939a23f7ca | |||
16b5acabf2 | |||
e946df43f8 | |||
2fb889b1a2 | |||
8cb5211453 | |||
146e111586 | |||
83cc1905ad | |||
e9e56453c1 | |||
2fb6747bfb | |||
94b16f743f | |||
d6faa3e5e5 | |||
3f4bfefe64 |
13 changed files with 580 additions and 162 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1,7 @@
|
||||||
.stack-work/
|
.stack-work/
|
||||||
*~
|
*~
|
||||||
dist-newstyle/
|
dist-newstyle/
|
||||||
|
zenith.db
|
||||||
|
zenith.log
|
||||||
|
zenith.db-shm
|
||||||
|
zenith.db-wal
|
||||||
|
|
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -5,7 +5,7 @@ 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).
|
||||||
|
|
||||||
## [Unreleased]
|
## [0.6.0.0-beta]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
@ -25,12 +25,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Unconfirmed balance display on TUI and GUI
|
- Unconfirmed balance display on TUI and GUI
|
||||||
- Tracking of unconfirmed notes
|
- Tracking of unconfirmed notes
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Upgraded to GHC 9.6.5
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Validation of input of amount for sending in TUI
|
- Validation of input of amount for sending in TUI
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Legacy interface to `zcashd`
|
||||||
|
|
||||||
|
## [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
|
||||||
|
|
|
@ -21,6 +21,7 @@ Zenith is a wallet for the [Zebra](https://zfnd.org/zebra/) Zcash node . It has
|
||||||
- Listing transactions for specific addresses, decoding memos for easy reading.
|
- Listing transactions for specific addresses, decoding memos for easy reading.
|
||||||
- Copying addresses to the clipboard.
|
- Copying addresses to the clipboard.
|
||||||
- Sending transactions with shielded memo support.
|
- Sending transactions with shielded memo support.
|
||||||
|
- Address Book for storing frequently used zcash addresses
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
23
app/Main.hs
23
app/Main.hs
|
@ -11,7 +11,8 @@ import Data.Sort
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as TIO
|
import qualified Data.Text.IO as TIO
|
||||||
import Data.Time.Clock.POSIX
|
import Data.Time.Clock.POSIX
|
||||||
import System.Console.StructuredCLI
|
|
||||||
|
{-import System.Console.StructuredCLI-}
|
||||||
import System.Environment (getArgs)
|
import System.Environment (getArgs)
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import System.IO
|
import System.IO
|
||||||
|
@ -23,7 +24,7 @@ import Zenith.GUI (runZenithGUI)
|
||||||
import Zenith.Types (Config(..), ZcashAddress(..), ZcashPool(..), ZcashTx(..))
|
import Zenith.Types (Config(..), ZcashAddress(..), ZcashPool(..), ZcashTx(..))
|
||||||
import Zenith.Utils
|
import Zenith.Utils
|
||||||
import Zenith.Zcashd
|
import Zenith.Zcashd
|
||||||
|
{-
|
||||||
prompt :: String -> IO String
|
prompt :: String -> IO String
|
||||||
prompt text = do
|
prompt text = do
|
||||||
putStr text
|
putStr text
|
||||||
|
@ -197,21 +198,22 @@ processUri user pwd =
|
||||||
_ -> False
|
_ -> False
|
||||||
_ <- liftIO $ sendWithUri user pwd (addList !! (idx - 1)) u repTo
|
_ <- liftIO $ sendWithUri user pwd (addList !! (idx - 1)) u repTo
|
||||||
return NoAction
|
return NoAction
|
||||||
|
-}
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
config <- load ["zenith.cfg"]
|
config <- load ["zenith.cfg"]
|
||||||
args <- getArgs
|
args <- getArgs
|
||||||
dbFilePath <- require config "dbFilePath"
|
dbFilePath <- require config "dbFilePath"
|
||||||
nodeUser <- require config "nodeUser"
|
{-nodeUser <- require config "nodeUser"-}
|
||||||
nodePwd <- require config "nodePwd"
|
{-nodePwd <- require config "nodePwd"-}
|
||||||
zebraPort <- require config "zebraPort"
|
zebraPort <- require config "zebraPort"
|
||||||
zebraHost <- require config "zebraHost"
|
zebraHost <- require config "zebraHost"
|
||||||
let myConfig = Config dbFilePath zebraHost zebraPort
|
let myConfig = Config dbFilePath zebraHost zebraPort
|
||||||
if not (null args)
|
if not (null args)
|
||||||
then do
|
then do
|
||||||
case head args of
|
case head args
|
||||||
"legacy" -> do
|
{-"legacy" -> do
|
||||||
checkServer nodeUser nodePwd
|
checkServer nodeUser nodePwd
|
||||||
void $
|
void $
|
||||||
runCLI
|
runCLI
|
||||||
|
@ -220,9 +222,10 @@ main = do
|
||||||
{ getBanner =
|
{ getBanner =
|
||||||
" ______ _ _ _ \n |___ / (_) | | | \n / / ___ _ __ _| |_| |__ \n / / / _ \\ '_ \\| | __| '_ \\ \n / /_| __/ | | | | |_| | | |\n /_____\\___|_| |_|_|\\__|_| |_|\n Zcash Full Node CLI v0.4.0"
|
" ______ _ _ _ \n |___ / (_) | | | \n / / ___ _ __ _| |_| |__ \n / / / _ \\ '_ \\| | __| '_ \\ \n / /_| __/ | | | | |_| | | |\n /_____\\___|_| |_|_|\\__|_| |_|\n Zcash Full Node CLI v0.4.0"
|
||||||
}
|
}
|
||||||
(root nodeUser nodePwd)
|
(root nodeUser nodePwd) -}
|
||||||
"cli" -> runZenithCLI myConfig
|
of
|
||||||
"gui" -> runZenithGUI myConfig
|
"gui" -> runZenithGUI myConfig
|
||||||
|
"tui" -> runZenithTUI myConfig
|
||||||
"rescan" -> clearSync myConfig
|
"rescan" -> clearSync myConfig
|
||||||
_ -> printUsage
|
_ -> printUsage
|
||||||
else printUsage
|
else printUsage
|
||||||
|
@ -231,6 +234,6 @@ printUsage :: IO ()
|
||||||
printUsage = do
|
printUsage = do
|
||||||
putStrLn "zenith [command] [parameters]\n"
|
putStrLn "zenith [command] [parameters]\n"
|
||||||
putStrLn "Available commands:"
|
putStrLn "Available commands:"
|
||||||
putStrLn "legacy\tLegacy CLI for zcashd"
|
{-putStrLn "legacy\tLegacy CLI for zcashd"-}
|
||||||
putStrLn "cli\tCLI for zebrad"
|
putStrLn "tui\tTUI for zebrad"
|
||||||
putStrLn "rescan\tRescan the existing wallet(s)"
|
putStrLn "rescan\tRescan the existing wallet(s)"
|
||||||
|
|
|
@ -2,7 +2,7 @@ packages:
|
||||||
./*.cabal
|
./*.cabal
|
||||||
zcash-haskell/zcash-haskell.cabal
|
zcash-haskell/zcash-haskell.cabal
|
||||||
|
|
||||||
with-compiler: ghc-9.4.8
|
with-compiler: ghc-9.6.5
|
||||||
|
|
||||||
source-repository-package
|
source-repository-package
|
||||||
type: git
|
type: git
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
active-repositories: hackage.haskell.org:merge
|
active-repositories: hackage.haskell.org:merge
|
||||||
constraints: any.Cabal ==3.8.1.0,
|
constraints: any.Cabal ==3.10.3.0,
|
||||||
any.Cabal-syntax ==3.8.1.0,
|
any.Cabal-syntax ==3.10.3.0,
|
||||||
any.Clipboard ==2.3.2.0,
|
any.Clipboard ==2.3.2.0,
|
||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.Hclip ==3.0.0.4,
|
any.Hclip ==3.0.0.4,
|
||||||
any.JuicyPixels ==3.3.8,
|
any.JuicyPixels ==3.3.9,
|
||||||
JuicyPixels -mmap,
|
JuicyPixels -mmap,
|
||||||
any.OneTuple ==0.4.1.1,
|
any.OneTuple ==0.4.2,
|
||||||
any.OpenGLRaw ==3.3.4.1,
|
any.OpenGLRaw ==3.3.4.1,
|
||||||
OpenGLRaw -osandroid +usegles2 +useglxgetprocaddress +usenativewindowslibraries,
|
OpenGLRaw -osandroid +usegles2 +useglxgetprocaddress +usenativewindowslibraries,
|
||||||
any.QuickCheck ==2.14.3,
|
any.QuickCheck ==2.14.3,
|
||||||
|
@ -18,32 +18,32 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.X11 ==1.10.3,
|
any.X11 ==1.10.3,
|
||||||
X11 -pedantic,
|
X11 -pedantic,
|
||||||
any.adjunctions ==4.4.2,
|
any.adjunctions ==4.4.2,
|
||||||
any.aeson ==2.2.1.0,
|
any.aeson ==2.2.3.0,
|
||||||
aeson +ordered-keymap,
|
aeson +ordered-keymap,
|
||||||
any.alex ==3.5.1.0,
|
any.alex ==3.5.1.0,
|
||||||
any.ansi-terminal ==1.1,
|
any.ansi-terminal ==1.1.1,
|
||||||
ansi-terminal -example,
|
ansi-terminal -example,
|
||||||
any.ansi-terminal-types ==1.1,
|
any.ansi-terminal-types ==1.1,
|
||||||
any.appar ==0.1.8,
|
any.appar ==0.1.8,
|
||||||
any.array ==0.5.4.0,
|
any.array ==0.5.6.0,
|
||||||
any.ascii-progress ==0.3.3.0,
|
any.ascii-progress ==0.3.3.0,
|
||||||
ascii-progress -examples,
|
ascii-progress -examples,
|
||||||
any.asn1-encoding ==0.9.6,
|
any.asn1-encoding ==0.9.6,
|
||||||
any.asn1-parse ==0.9.5,
|
any.asn1-parse ==0.9.5,
|
||||||
any.asn1-types ==0.3.4,
|
any.asn1-types ==0.3.4,
|
||||||
any.assoc ==1.1,
|
any.assoc ==1.1.1,
|
||||||
assoc +tagged,
|
assoc -tagged,
|
||||||
any.async ==2.2.5,
|
any.async ==2.2.5,
|
||||||
async -bench,
|
async -bench,
|
||||||
any.attoparsec ==0.14.4,
|
any.attoparsec ==0.14.4,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.attoparsec-aeson ==2.2.0.1,
|
any.attoparsec-aeson ==2.2.2.0,
|
||||||
any.authenticate-oauth ==1.7,
|
any.authenticate-oauth ==1.7,
|
||||||
any.auto-update ==0.1.6,
|
any.auto-update ==0.2.1,
|
||||||
any.base ==4.17.2.1,
|
any.base ==4.18.2.1,
|
||||||
any.base-compat ==0.13.1,
|
any.base-compat ==0.14.0,
|
||||||
any.base-compat-batteries ==0.13.1,
|
any.base-compat-batteries ==0.14.0,
|
||||||
any.base-orphans ==0.9.1,
|
any.base-orphans ==0.9.2,
|
||||||
any.base16 ==1.0,
|
any.base16 ==1.0,
|
||||||
any.base16-bytestring ==1.0.2.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base58-bytestring ==0.1.0,
|
any.base58-bytestring ==0.1.0,
|
||||||
|
@ -53,14 +53,14 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
bifunctors +tagged,
|
bifunctors +tagged,
|
||||||
any.bimap ==0.5.0,
|
any.bimap ==0.5.0,
|
||||||
any.binary ==0.8.9.1,
|
any.binary ==0.8.9.1,
|
||||||
any.binary-orphans ==1.0.4.1,
|
any.binary-orphans ==1.0.5,
|
||||||
any.bitvec ==1.1.5.0,
|
any.bitvec ==1.1.5.0,
|
||||||
bitvec +simd,
|
bitvec +simd,
|
||||||
any.blaze-builder ==0.4.2.3,
|
any.blaze-builder ==0.4.2.3,
|
||||||
any.blaze-html ==0.9.2.0,
|
any.blaze-html ==0.9.2.0,
|
||||||
any.blaze-markup ==0.8.3.0,
|
any.blaze-markup ==0.8.3.0,
|
||||||
any.borsh ==0.3.0,
|
any.borsh ==0.3.0,
|
||||||
any.brick ==2.3.1,
|
any.brick ==2.4,
|
||||||
brick -demos,
|
brick -demos,
|
||||||
any.byteorder ==1.0.4,
|
any.byteorder ==1.0.4,
|
||||||
any.bytes ==0.17.3,
|
any.bytes ==0.17.3,
|
||||||
|
@ -70,19 +70,20 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.bytestring-to-vector ==0.3.0.1,
|
any.bytestring-to-vector ==0.3.0.1,
|
||||||
any.c2hs ==0.28.8,
|
any.c2hs ==0.28.8,
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.cabal-doctest ==1.0.9,
|
any.cabal-doctest ==1.0.10,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.4.0,
|
||||||
any.case-insensitive ==1.2.1.0,
|
any.case-insensitive ==1.2.1.0,
|
||||||
any.cborg ==0.2.10.0,
|
any.cborg ==0.2.10.0,
|
||||||
cborg +optimize-gmp,
|
cborg +optimize-gmp,
|
||||||
any.cereal ==0.5.8.3,
|
any.cereal ==0.5.8.3,
|
||||||
cereal -bytestring-builder,
|
cereal -bytestring-builder,
|
||||||
|
any.character-ps ==0.1,
|
||||||
any.clock ==0.8.4,
|
any.clock ==0.8.4,
|
||||||
clock -llvm,
|
clock -llvm,
|
||||||
any.colour ==2.3.6,
|
any.colour ==2.3.6,
|
||||||
any.comonad ==5.0.8,
|
any.comonad ==5.0.8,
|
||||||
comonad +containers +distributive +indexed-traversable,
|
comonad +containers +distributive +indexed-traversable,
|
||||||
any.concurrent-output ==1.10.20,
|
any.concurrent-output ==1.10.21,
|
||||||
any.conduit ==1.3.5,
|
any.conduit ==1.3.5,
|
||||||
any.conduit-extra ==1.3.6,
|
any.conduit-extra ==1.3.6,
|
||||||
any.config-ini ==0.2.7.0,
|
any.config-ini ==0.2.7.0,
|
||||||
|
@ -92,14 +93,14 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.containers ==0.6.7,
|
any.containers ==0.6.7,
|
||||||
any.contravariant ==1.5.5,
|
any.contravariant ==1.5.5,
|
||||||
contravariant +semigroups +statevar +tagged,
|
contravariant +semigroups +statevar +tagged,
|
||||||
any.cookie ==0.4.6,
|
any.cookie ==0.5.0,
|
||||||
any.crypto-api ==0.13.3,
|
any.crypto-api ==0.13.3,
|
||||||
crypto-api -all_cpolys,
|
crypto-api -all_cpolys,
|
||||||
any.crypto-pubkey-types ==0.4.3,
|
any.crypto-pubkey-types ==0.4.3,
|
||||||
any.crypton ==0.34,
|
any.crypton ==1.0.0,
|
||||||
crypton -check_alignment +integer-gmp -old_toolchain_inliner +support_aesni +support_deepseq +support_pclmuldq +support_rdrand -support_sse +use_target_attributes,
|
crypton -check_alignment +integer-gmp -old_toolchain_inliner +support_aesni +support_deepseq +support_pclmuldq +support_rdrand -support_sse +use_target_attributes,
|
||||||
any.crypton-connection ==0.3.2,
|
any.crypton-connection ==0.4.1,
|
||||||
any.crypton-x509 ==1.7.6,
|
any.crypton-x509 ==1.7.7,
|
||||||
any.crypton-x509-store ==1.6.9,
|
any.crypton-x509-store ==1.6.9,
|
||||||
any.crypton-x509-system ==1.6.7,
|
any.crypton-x509-system ==1.6.7,
|
||||||
any.crypton-x509-validation ==1.6.12,
|
any.crypton-x509-validation ==1.6.12,
|
||||||
|
@ -111,9 +112,9 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.data-default-instances-containers ==0.0.1,
|
any.data-default-instances-containers ==0.0.1,
|
||||||
any.data-default-instances-dlist ==0.0.1,
|
any.data-default-instances-dlist ==0.0.1,
|
||||||
any.data-default-instances-old-locale ==0.0.1,
|
any.data-default-instances-old-locale ==0.0.1,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.4,
|
||||||
any.deepseq ==1.4.8.0,
|
any.deepseq ==1.4.8.1,
|
||||||
any.directory ==1.3.7.1,
|
any.directory ==1.3.8.4,
|
||||||
any.distributive ==0.6.2.1,
|
any.distributive ==0.6.2.1,
|
||||||
distributive +semigroups +tagged,
|
distributive +semigroups +tagged,
|
||||||
any.dlist ==1.0,
|
any.dlist ==1.0,
|
||||||
|
@ -125,13 +126,11 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
entropy -donotgetentropy,
|
entropy -donotgetentropy,
|
||||||
any.envy ==2.1.3.0,
|
any.envy ==2.1.3.0,
|
||||||
any.esqueleto ==3.5.11.2,
|
any.esqueleto ==3.5.11.2,
|
||||||
any.exceptions ==0.10.5,
|
any.exceptions ==0.10.7,
|
||||||
any.extra ==1.7.14,
|
any.extra ==1.7.16,
|
||||||
any.fast-logger ==3.2.2,
|
any.fast-logger ==3.2.3,
|
||||||
any.filepath ==1.4.2.2,
|
any.filepath ==1.4.300.1,
|
||||||
any.fixed ==0.3,
|
any.fixed ==0.3,
|
||||||
any.foldable1-classes-compat ==0.1,
|
|
||||||
foldable1-classes-compat +tagged,
|
|
||||||
any.foreign-rust ==0.1.0,
|
any.foreign-rust ==0.1.0,
|
||||||
any.foreign-store ==0.2.1,
|
any.foreign-store ==0.2.1,
|
||||||
any.formatting ==7.2.0,
|
any.formatting ==7.2.0,
|
||||||
|
@ -141,30 +140,29 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
generic-deriving +base-4-9,
|
generic-deriving +base-4-9,
|
||||||
any.generically ==0.1.1,
|
any.generically ==0.1.1,
|
||||||
any.generics-sop ==0.5.1.4,
|
any.generics-sop ==0.5.1.4,
|
||||||
any.ghc ==9.4.8,
|
any.ghc ==9.6.5,
|
||||||
any.ghc-bignum ==1.3,
|
any.ghc-bignum ==1.3,
|
||||||
any.ghc-boot ==9.4.8,
|
any.ghc-boot ==9.6.5,
|
||||||
any.ghc-boot-th ==9.4.8,
|
any.ghc-boot-th ==9.6.5,
|
||||||
any.ghc-heap ==9.4.8,
|
any.ghc-heap ==9.6.5,
|
||||||
any.ghc-prim ==0.9.1,
|
any.ghc-prim ==0.10.0,
|
||||||
any.ghci ==9.4.8,
|
any.ghci ==9.6.5,
|
||||||
any.half ==0.3.1,
|
any.half ==0.3.1,
|
||||||
any.happy ==1.20.1.1,
|
any.happy ==1.20.1.1,
|
||||||
any.hashable ==1.4.4.0,
|
any.hashable ==1.4.7.0,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable -arch-native +integer-gmp -random-initial-seed,
|
||||||
any.haskeline ==0.8.2,
|
|
||||||
any.haskell-lexer ==1.1.1,
|
any.haskell-lexer ==1.1.1,
|
||||||
any.haskoin-core ==1.1.0,
|
any.haskoin-core ==1.1.0,
|
||||||
any.hexstring ==0.12.1.0,
|
any.hexstring ==0.12.1.0,
|
||||||
any.hourglass ==0.2.12,
|
any.hourglass ==0.2.12,
|
||||||
any.hpc ==0.6.1.0,
|
any.hpc ==0.6.2.0,
|
||||||
any.hsc2hs ==0.68.10,
|
any.hsc2hs ==0.68.10,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.11.7,
|
any.hspec ==2.11.9,
|
||||||
any.hspec-core ==2.11.7,
|
any.hspec-core ==2.11.9,
|
||||||
any.hspec-discover ==2.11.7,
|
any.hspec-discover ==2.11.9,
|
||||||
any.hspec-expectations ==0.8.4,
|
any.hspec-expectations ==0.8.4,
|
||||||
any.http-api-data ==0.6,
|
any.http-api-data ==0.6.1,
|
||||||
http-api-data -use-text-show,
|
http-api-data -use-text-show,
|
||||||
any.http-client ==0.7.17,
|
any.http-client ==0.7.17,
|
||||||
http-client +network-uri,
|
http-client +network-uri,
|
||||||
|
@ -172,18 +170,18 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.http-conduit ==2.3.8.3,
|
any.http-conduit ==2.3.8.3,
|
||||||
http-conduit +aeson,
|
http-conduit +aeson,
|
||||||
any.http-types ==0.12.4,
|
any.http-types ==0.12.4,
|
||||||
any.indexed-traversable ==0.1.3,
|
any.indexed-traversable ==0.1.4,
|
||||||
any.indexed-traversable-instances ==0.1.1.2,
|
any.indexed-traversable-instances ==0.1.2,
|
||||||
any.integer-conversion ==0.1.0.1,
|
any.integer-conversion ==0.1.1,
|
||||||
any.integer-gmp ==1.1,
|
any.integer-gmp ==1.1,
|
||||||
any.integer-logarithms ==1.0.3.1,
|
any.integer-logarithms ==1.0.3.1,
|
||||||
integer-logarithms -check-bounds +integer-gmp,
|
integer-logarithms -check-bounds +integer-gmp,
|
||||||
any.invariant ==0.6.3,
|
any.invariant ==0.6.3,
|
||||||
any.iproute ==1.7.12,
|
any.iproute ==1.7.12,
|
||||||
any.kan-extensions ==5.2.5,
|
any.kan-extensions ==5.2.6,
|
||||||
any.language-c ==0.9.3,
|
any.language-c ==0.9.3,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.lens ==5.2.3,
|
any.lens ==5.3.2,
|
||||||
lens -benchmark-uniplate -dump-splices +inlining -j +test-hunit +test-properties +test-templates +trustworthy,
|
lens -benchmark-uniplate -dump-splices +inlining -j +test-hunit +test-properties +test-templates +trustworthy,
|
||||||
any.lens-aeson ==1.2.3,
|
any.lens-aeson ==1.2.3,
|
||||||
any.lift-type ==0.1.1.1,
|
any.lift-type ==0.1.1.1,
|
||||||
|
@ -196,7 +194,7 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
memory +support_bytestring +support_deepseq,
|
memory +support_bytestring +support_deepseq,
|
||||||
any.microlens ==0.4.13.1,
|
any.microlens ==0.4.13.1,
|
||||||
any.microlens-mtl ==0.2.0.3,
|
any.microlens-mtl ==0.2.0.3,
|
||||||
any.microlens-th ==0.4.3.14,
|
any.microlens-th ==0.4.3.15,
|
||||||
any.mime-types ==0.1.2.0,
|
any.mime-types ==0.1.2.0,
|
||||||
any.monad-control ==1.0.3.1,
|
any.monad-control ==1.0.3.1,
|
||||||
any.monad-logger ==0.3.40,
|
any.monad-logger ==0.3.40,
|
||||||
|
@ -206,16 +204,16 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.mono-traversable ==1.0.17.0,
|
any.mono-traversable ==1.0.17.0,
|
||||||
any.monomer ==1.6.0.1,
|
any.monomer ==1.6.0.1,
|
||||||
monomer -examples,
|
monomer -examples,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.3.1,
|
||||||
any.murmur3 ==1.0.5,
|
any.murmur3 ==1.0.5,
|
||||||
any.nanovg ==0.8.1.0,
|
any.nanovg ==0.8.1.0,
|
||||||
nanovg -examples -gl2 -gles3 -stb_truetype,
|
nanovg -examples -gl2 -gles3 -stb_truetype,
|
||||||
any.network ==3.1.4.0,
|
any.network ==3.2.1.0,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.2,
|
any.network-uri ==2.6.4.2,
|
||||||
any.old-locale ==1.0.0.7,
|
any.old-locale ==1.0.0.7,
|
||||||
any.old-time ==1.1.0.4,
|
any.old-time ==1.1.0.4,
|
||||||
any.os-string ==2.0.2,
|
any.os-string ==2.0.6,
|
||||||
any.parallel ==3.2.2.0,
|
any.parallel ==3.2.2.0,
|
||||||
any.parsec ==3.1.16.1,
|
any.parsec ==3.1.16.1,
|
||||||
any.parser-combinators ==1.3.0,
|
any.parser-combinators ==1.3.0,
|
||||||
|
@ -228,7 +226,7 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.persistent-template ==2.12.0.0,
|
any.persistent-template ==2.12.0.0,
|
||||||
any.pretty ==1.1.3.6,
|
any.pretty ==1.1.3.6,
|
||||||
any.primitive ==0.9.0.0,
|
any.primitive ==0.9.0.0,
|
||||||
any.process ==1.6.18.0,
|
any.process ==1.6.19.0,
|
||||||
any.profunctors ==5.6.2,
|
any.profunctors ==5.6.2,
|
||||||
any.psqueues ==0.2.8.0,
|
any.psqueues ==0.2.8.0,
|
||||||
any.pureMD5 ==2.1.4,
|
any.pureMD5 ==2.1.4,
|
||||||
|
@ -238,7 +236,7 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.quickcheck-io ==0.2.0,
|
any.quickcheck-io ==0.2.0,
|
||||||
any.quickcheck-transformer ==0.3.1.2,
|
any.quickcheck-transformer ==0.3.1.2,
|
||||||
any.random ==1.2.1.2,
|
any.random ==1.2.1.2,
|
||||||
any.reflection ==2.1.7,
|
any.reflection ==2.1.8,
|
||||||
reflection -slow +template-haskell,
|
reflection -slow +template-haskell,
|
||||||
any.regex-base ==0.94.0.2,
|
any.regex-base ==0.94.0.2,
|
||||||
any.regex-compat ==0.95.2.1,
|
any.regex-compat ==0.95.2.1,
|
||||||
|
@ -249,14 +247,14 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.rts ==1.0.2,
|
any.rts ==1.0.2,
|
||||||
any.safe ==0.3.21,
|
any.safe ==0.3.21,
|
||||||
any.safe-exceptions ==0.1.7.4,
|
any.safe-exceptions ==0.1.7.4,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.8.0,
|
||||||
scientific -bytestring-builder -integer-simple,
|
scientific -integer-simple,
|
||||||
any.sdl2 ==2.5.5.0,
|
any.sdl2 ==2.5.5.0,
|
||||||
sdl2 -examples -no-linear -opengl-example +pkgconfig +recent-ish,
|
sdl2 -examples -no-linear -opengl-example +pkgconfig +recent-ish,
|
||||||
any.secp256k1-haskell ==1.2.0,
|
any.secp256k1-haskell ==1.2.0,
|
||||||
any.semialign ==1.3,
|
any.semialign ==1.3.1,
|
||||||
semialign +semigroupoids,
|
semialign +semigroupoids,
|
||||||
any.semigroupoids ==6.0.0.1,
|
any.semigroupoids ==6.0.1,
|
||||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||||
any.semigroups ==0.20,
|
any.semigroups ==0.20,
|
||||||
semigroups +binary +bytestring -bytestring-builder +containers +deepseq +hashable +tagged +template-haskell +text +transformers +unordered-containers,
|
semigroups +binary +bytestring -bytestring-builder +containers +deepseq +hashable +tagged +template-haskell +text +transformers +unordered-containers,
|
||||||
|
@ -273,57 +271,53 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
any.stm-chans ==3.0.0.9,
|
any.stm-chans ==3.0.0.9,
|
||||||
any.streaming-commons ==0.2.2.6,
|
any.streaming-commons ==0.2.2.6,
|
||||||
streaming-commons -use-bytestring-builder,
|
streaming-commons -use-bytestring-builder,
|
||||||
any.strict ==0.5,
|
any.strict ==0.5.1,
|
||||||
any.string-conversions ==0.4.0.1,
|
any.string-conversions ==0.4.0.1,
|
||||||
any.structured-cli ==2.7.0.1,
|
|
||||||
structured-cli -debug,
|
|
||||||
any.system-cxx-std-lib ==1.0,
|
any.system-cxx-std-lib ==1.0,
|
||||||
any.tagged ==0.8.8,
|
any.tagged ==0.8.8,
|
||||||
tagged +deepseq +transformers,
|
tagged +deepseq +transformers,
|
||||||
any.template-haskell ==2.19.0.0,
|
any.template-haskell ==2.20.0.0,
|
||||||
any.terminal-size ==0.3.4,
|
any.terminal-size ==0.3.4,
|
||||||
any.terminfo ==0.4.1.5,
|
any.terminfo ==0.4.1.6,
|
||||||
any.text ==2.0.2,
|
any.text ==2.0.2,
|
||||||
any.text-iso8601 ==0.1,
|
any.text-iso8601 ==0.1.1,
|
||||||
any.text-short ==0.1.5,
|
any.text-short ==0.1.6,
|
||||||
text-short -asserts,
|
text-short -asserts,
|
||||||
any.text-show ==3.10.4,
|
any.text-show ==3.10.5,
|
||||||
text-show +base-4-9 +integer-gmp +new-functor-classes +template-haskell-2-11,
|
text-show +base-4-9 +integer-gmp +new-functor-classes +template-haskell-2-11,
|
||||||
any.text-zipper ==0.13,
|
any.text-zipper ==0.13,
|
||||||
any.tf-random ==0.5,
|
any.tf-random ==0.5,
|
||||||
any.th-abstraction ==0.6.0.0,
|
any.th-abstraction ==0.7.0.0,
|
||||||
any.th-compat ==0.1.5,
|
any.th-compat ==0.1.5,
|
||||||
any.th-lift ==0.8.4,
|
any.th-lift ==0.8.4,
|
||||||
any.th-lift-instances ==0.1.20,
|
any.th-lift-instances ==0.1.20,
|
||||||
any.these ==1.2,
|
any.these ==1.2.1,
|
||||||
any.time ==1.12.2,
|
any.time ==1.12.2,
|
||||||
any.time-compat ==1.9.6.1,
|
any.time-compat ==1.9.7,
|
||||||
time-compat -old-locale,
|
|
||||||
any.time-locale-compat ==0.1.1.5,
|
any.time-locale-compat ==0.1.1.5,
|
||||||
time-locale-compat -old-locale,
|
time-locale-compat -old-locale,
|
||||||
any.tls ==2.0.2,
|
any.tls ==2.1.0,
|
||||||
tls -devel,
|
tls -devel,
|
||||||
any.transformers ==0.5.6.2,
|
any.transformers ==0.6.1.0,
|
||||||
any.transformers-base ==0.4.6,
|
any.transformers-base ==0.4.6,
|
||||||
transformers-base +orphaninstances,
|
transformers-base +orphaninstances,
|
||||||
any.transformers-compat ==0.7.2,
|
any.transformers-compat ==0.7.2,
|
||||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||||
any.typed-process ==0.2.11.1,
|
any.typed-process ==0.2.11.1,
|
||||||
any.unix ==2.7.3,
|
any.unix ==2.8.4.0,
|
||||||
any.unix-compat ==0.7.1,
|
any.unix-compat ==0.7.2,
|
||||||
unix-compat -old-time,
|
any.unix-time ==0.4.15,
|
||||||
any.unix-time ==0.4.12,
|
|
||||||
any.unliftio ==0.2.25.0,
|
any.unliftio ==0.2.25.0,
|
||||||
any.unliftio-core ==0.2.1.0,
|
any.unliftio-core ==0.2.1.0,
|
||||||
any.unordered-containers ==0.2.20,
|
any.unordered-containers ==0.2.20,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.utf8-string ==1.0.2,
|
any.utf8-string ==1.0.2,
|
||||||
any.uuid-types ==1.0.5.1,
|
any.uuid-types ==1.0.6,
|
||||||
any.vault ==0.3.1.5,
|
any.vault ==0.3.1.5,
|
||||||
vault +useghc,
|
vault +useghc,
|
||||||
any.vector ==0.13.1.0,
|
any.vector ==0.13.1.0,
|
||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.vector-algorithms ==0.9.0.1,
|
any.vector-algorithms ==0.9.0.2,
|
||||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||||
any.vector-stream ==0.1.0.1,
|
any.vector-stream ==0.1.0.1,
|
||||||
any.void ==0.7.3,
|
any.void ==0.7.3,
|
||||||
|
@ -333,10 +327,10 @@ constraints: any.Cabal ==3.8.1.0,
|
||||||
vty-crossplatform -demos,
|
vty-crossplatform -demos,
|
||||||
any.vty-unix ==0.2.0.0,
|
any.vty-unix ==0.2.0.0,
|
||||||
any.wide-word ==0.1.6.0,
|
any.wide-word ==0.1.6.0,
|
||||||
any.witherable ==0.4.2,
|
any.witherable ==0.5,
|
||||||
any.word-wrap ==0.5,
|
any.word-wrap ==0.5,
|
||||||
any.wreq ==0.5.4.3,
|
any.wreq ==0.5.4.3,
|
||||||
wreq -aws -developer +doctest -httpbin,
|
wreq -aws -developer +doctest -httpbin,
|
||||||
any.zlib ==0.6.3.0,
|
any.zlib ==0.7.1.0,
|
||||||
zlib -bundled-c-zlib +non-blocking-ffi +pkg-config
|
zlib -bundled-c-zlib +non-blocking-ffi +pkg-config
|
||||||
index-state: hackage.haskell.org 2024-04-07T10:14:52Z
|
index-state: hackage.haskell.org 2024-07-10T18:40:26Z
|
||||||
|
|
|
@ -10,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
|
||||||
|
@ -40,6 +42,9 @@ import Brick.Widgets.Core
|
||||||
, joinBorders
|
, joinBorders
|
||||||
, padAll
|
, padAll
|
||||||
, padBottom
|
, padBottom
|
||||||
|
, padLeft
|
||||||
|
, padTop
|
||||||
|
, setAvailableSize
|
||||||
, str
|
, str
|
||||||
, strWrap
|
, strWrap
|
||||||
, strWrapWith
|
, strWrapWith
|
||||||
|
@ -49,6 +54,7 @@ import Brick.Widgets.Core
|
||||||
, updateAttrMap
|
, updateAttrMap
|
||||||
, vBox
|
, vBox
|
||||||
, vLimit
|
, vLimit
|
||||||
|
, viewport
|
||||||
, withAttr
|
, withAttr
|
||||||
, withBorderStyle
|
, withBorderStyle
|
||||||
)
|
)
|
||||||
|
@ -116,6 +122,10 @@ data Name
|
||||||
| RecField
|
| RecField
|
||||||
| AmtField
|
| AmtField
|
||||||
| MemoField
|
| MemoField
|
||||||
|
| ABViewport
|
||||||
|
| ABList
|
||||||
|
| DescripField
|
||||||
|
| AddressField
|
||||||
deriving (Eq, Show, Ord)
|
deriving (Eq, Show, Ord)
|
||||||
|
|
||||||
data DialogInput = DialogInput
|
data DialogInput = DialogInput
|
||||||
|
@ -132,6 +142,13 @@ data SendInput = SendInput
|
||||||
|
|
||||||
makeLenses ''SendInput
|
makeLenses ''SendInput
|
||||||
|
|
||||||
|
data AdrBookEntry = AdrBookEntry
|
||||||
|
{ _descrip :: !T.Text
|
||||||
|
, _address :: !T.Text
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
makeLenses ''AdrBookEntry
|
||||||
|
|
||||||
data DialogType
|
data DialogType
|
||||||
= WName
|
= WName
|
||||||
| AName
|
| AName
|
||||||
|
@ -140,6 +157,10 @@ data DialogType
|
||||||
| ASelect
|
| ASelect
|
||||||
| SendTx
|
| SendTx
|
||||||
| Blank
|
| Blank
|
||||||
|
| AdrBook
|
||||||
|
| AdrBookForm
|
||||||
|
| AdrBookUpdForm
|
||||||
|
| AdrBookDelForm
|
||||||
|
|
||||||
data DisplayType
|
data DisplayType
|
||||||
= AddrDisplay
|
= AddrDisplay
|
||||||
|
@ -149,6 +170,7 @@ data DisplayType
|
||||||
| TxIdDisplay
|
| TxIdDisplay
|
||||||
| SyncDisplay
|
| SyncDisplay
|
||||||
| SendDisplay
|
| SendDisplay
|
||||||
|
| AdrBookEntryDisplay
|
||||||
| BlankDisplay
|
| BlankDisplay
|
||||||
|
|
||||||
data Tick
|
data Tick
|
||||||
|
@ -179,6 +201,9 @@ data State = State
|
||||||
, _eventDispatch :: !(BC.BChan Tick)
|
, _eventDispatch :: !(BC.BChan Tick)
|
||||||
, _timer :: !Int
|
, _timer :: !Int
|
||||||
, _txForm :: !(Form SendInput () Name)
|
, _txForm :: !(Form SendInput () Name)
|
||||||
|
, _abAddresses :: !(L.List Name (Entity AddressBook))
|
||||||
|
, _abForm :: !(Form AdrBookEntry () Name)
|
||||||
|
, _abCurAdrs :: !T.Text -- used for address book CRUD operations
|
||||||
, _sentTx :: !(Maybe HexString)
|
, _sentTx :: !(Maybe HexString)
|
||||||
, _unconfBalance :: !Integer
|
, _unconfBalance :: !Integer
|
||||||
}
|
}
|
||||||
|
@ -194,14 +219,15 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
withBorderStyle unicode $
|
withBorderStyle unicode $
|
||||||
B.borderWithLabel
|
B.borderWithLabel
|
||||||
(str
|
(str
|
||||||
("Zenith - " <>
|
(" Zenith - " <>
|
||||||
show (st ^. network) <>
|
show (st ^. network) <>
|
||||||
" - " <>
|
" - " <>
|
||||||
T.unpack
|
(T.unpack
|
||||||
(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: " ++
|
||||||
|
@ -224,15 +250,18 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
else displayTaz (st ^. unconfBalance))) <=>
|
else displayTaz (st ^. unconfBalance))) <=>
|
||||||
listAddressBox "Addresses" (st ^. addresses) <+>
|
listAddressBox "Addresses" (st ^. addresses) <+>
|
||||||
B.vBorder <+>
|
B.vBorder <+>
|
||||||
(C.hCenter (str ("Last block seen: " ++ show (st ^. syncBlock))) <=>
|
(C.hCenter
|
||||||
listTxBox "Transactions" (st ^. network) (st ^. transactions))) <=>
|
(str ("Last block seen: " ++ show (st ^. syncBlock) ++ "\n")) <=>
|
||||||
|
listTxBox " Transactions " (st ^. network) (st ^. transactions))) <=>
|
||||||
C.hCenter
|
C.hCenter
|
||||||
(hBox
|
(hBox
|
||||||
[ capCommand "W" "allets"
|
[ capCommand "W" "allets"
|
||||||
, capCommand "A" "ccounts"
|
, capCommand "A" "ccounts"
|
||||||
, capCommand "V" "iew address"
|
, capCommand "V" "iew address"
|
||||||
, capCommand "S" "end Tx"
|
, capCommand "S" "end Tx"
|
||||||
|
, capCommand2 "Address " "B" "ook"
|
||||||
, capCommand "Q" "uit"
|
, capCommand "Q" "uit"
|
||||||
|
, capCommand "?" " Help"
|
||||||
, str $ show (st ^. timer)
|
, str $ show (st ^. timer)
|
||||||
])
|
])
|
||||||
listBox :: Show e => String -> L.List Name e -> Widget Name
|
listBox :: Show e => String -> L.List Name e -> Widget Name
|
||||||
|
@ -271,7 +300,7 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
(hBox
|
(hBox
|
||||||
[ capCommand "↑↓ " "move"
|
[ capCommand "↑↓ " "move"
|
||||||
, capCommand "↲ " "select"
|
, capCommand "↲ " "select"
|
||||||
, capCommand "Tab " "->"
|
, capCommand3 "" "Tab" " ->"
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
listTxBox ::
|
listTxBox ::
|
||||||
|
@ -287,19 +316,20 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
(hBox
|
(hBox
|
||||||
[ capCommand "↑↓ " "move"
|
[ capCommand "↑↓ " "move"
|
||||||
, capCommand "T" "x Display"
|
, capCommand "T" "x Display"
|
||||||
, capCommand "Tab " "<-"
|
, capCommand3 "" "Tab" " <-"
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
helpDialog :: State -> Widget Name
|
helpDialog :: State -> Widget Name
|
||||||
helpDialog st =
|
helpDialog st =
|
||||||
if st ^. helpBox
|
if st ^. helpBox
|
||||||
then D.renderDialog
|
then D.renderDialog
|
||||||
(D.dialog (Just (str "Commands")) Nothing 55)
|
(D.dialog (Just (str " Commands ")) Nothing 55)
|
||||||
(vBox ([C.hCenter $ str "Key", B.hBorder] <> keyList) <+>
|
(vBox ([C.hCenter $ str "Key", B.hBorder] <> keyList) <+>
|
||||||
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", "q"]
|
keyList =
|
||||||
|
map (C.hCenter . str) ["?", "Esc", "w", "a", "v", "s", "b", "q"]
|
||||||
actionList =
|
actionList =
|
||||||
map
|
map
|
||||||
(hLimit 40 . str)
|
(hLimit 40 . str)
|
||||||
|
@ -308,6 +338,8 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
, "Switch wallets"
|
, "Switch wallets"
|
||||||
, "Switch accounts"
|
, "Switch accounts"
|
||||||
, "View address"
|
, "View address"
|
||||||
|
, "Send Tx"
|
||||||
|
, "Address Book"
|
||||||
, "Quit"
|
, "Quit"
|
||||||
]
|
]
|
||||||
inputDialog :: State -> Widget Name
|
inputDialog :: State -> Widget Name
|
||||||
|
@ -315,20 +347,20 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
case st ^. dialogBox of
|
case st ^. dialogBox of
|
||||||
WName ->
|
WName ->
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just (str "Create Wallet")) Nothing 50)
|
(D.dialog (Just (str " Create Wallet ")) Nothing 50)
|
||||||
(renderForm $ st ^. inputForm)
|
(renderForm $ st ^. inputForm)
|
||||||
AName ->
|
AName ->
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just (str "Create Account")) Nothing 50)
|
(D.dialog (Just (str " Create Account ")) Nothing 50)
|
||||||
(renderForm $ st ^. inputForm)
|
(renderForm $ st ^. inputForm)
|
||||||
AdName ->
|
AdName ->
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just (str "Create Address")) Nothing 50)
|
(D.dialog (Just (str " Create Address ")) Nothing 50)
|
||||||
(renderForm $ st ^. inputForm)
|
(renderForm $ st ^. inputForm)
|
||||||
WSelect ->
|
WSelect ->
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just (str "Select Wallet")) Nothing 50)
|
(D.dialog (Just (str " Select Wallet ")) Nothing 50)
|
||||||
(selectListBox "Wallets" (st ^. wallets) listDrawWallet <=>
|
(selectListBox " Wallets " (st ^. wallets) listDrawWallet <=>
|
||||||
C.hCenter
|
C.hCenter
|
||||||
(hBox
|
(hBox
|
||||||
[ capCommand "↑↓ " "move"
|
[ capCommand "↑↓ " "move"
|
||||||
|
@ -339,8 +371,8 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
]))
|
]))
|
||||||
ASelect ->
|
ASelect ->
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just (str "Select Account")) Nothing 50)
|
(D.dialog (Just (str " Select Account ")) Nothing 50)
|
||||||
(selectListBox "Accounts" (st ^. accounts) listDrawAccount <=>
|
(selectListBox " Accounts " (st ^. accounts) listDrawAccount <=>
|
||||||
C.hCenter
|
C.hCenter
|
||||||
(hBox
|
(hBox
|
||||||
[ capCommand "↑↓ " "move"
|
[ capCommand "↑↓ " "move"
|
||||||
|
@ -350,11 +382,63 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
]))
|
]))
|
||||||
SendTx ->
|
SendTx ->
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just (str "Send Transaction")) Nothing 50)
|
(D.dialog (Just (str " Send Transaction ")) Nothing 50)
|
||||||
(renderForm (st ^. txForm) <=>
|
(renderForm (st ^. txForm) <=>
|
||||||
C.hCenter
|
C.hCenter
|
||||||
(hBox [capCommand "↲ " "Send", capCommand "<esc> " "Cancel"]))
|
(hBox [capCommand "↲ " "Send", capCommand "<esc> " "Cancel"]))
|
||||||
Blank -> emptyWidget
|
Blank -> emptyWidget
|
||||||
|
-- Address Book List
|
||||||
|
AdrBook ->
|
||||||
|
D.renderDialog
|
||||||
|
(D.dialog (Just $ str " Address Book ") Nothing 60)
|
||||||
|
(withAttr abDefAttr $
|
||||||
|
setAvailableSize (50, 20) $
|
||||||
|
viewport ABViewport BT.Vertical $
|
||||||
|
vLimit 20 $
|
||||||
|
hLimit 50 $
|
||||||
|
vBox
|
||||||
|
[ vLimit 16 $
|
||||||
|
hLimit 50 $
|
||||||
|
vBox $ [L.renderList listDrawAB True (s ^. abAddresses)]
|
||||||
|
, padTop Max $
|
||||||
|
vLimit 4 $
|
||||||
|
hLimit 50 $
|
||||||
|
withAttr abMBarAttr $
|
||||||
|
vBox $
|
||||||
|
[ C.hCenter $
|
||||||
|
(capCommand "N" "ew Address" <+>
|
||||||
|
capCommand "E" "dit Address" <+>
|
||||||
|
capCommand3 "" "C" "opy Address")
|
||||||
|
, C.hCenter $
|
||||||
|
(capCommand "D" "elete Address" <+>
|
||||||
|
capCommand "S" "end Zcash" <+> capCommand3 "E" "x" "it")
|
||||||
|
]
|
||||||
|
])
|
||||||
|
-- Address Book new entry form
|
||||||
|
AdrBookForm ->
|
||||||
|
D.renderDialog
|
||||||
|
(D.dialog (Just $ str " New Address Book Entry ") Nothing 50)
|
||||||
|
(renderForm (st ^. abForm) <=>
|
||||||
|
C.hCenter
|
||||||
|
(hBox [capCommand "↲" " Save", capCommand3 "" "<Esc>" " Cancel"]))
|
||||||
|
-- Address Book edit/update entry form
|
||||||
|
AdrBookUpdForm ->
|
||||||
|
D.renderDialog
|
||||||
|
(D.dialog (Just $ str " Edit Address Book Entry ") Nothing 50)
|
||||||
|
(renderForm (st ^. abForm) <=>
|
||||||
|
C.hCenter
|
||||||
|
(hBox [capCommand "↲" " Save", capCommand3 "" "<Esc>" " Cancel"]))
|
||||||
|
-- Address Book edit/update entry form
|
||||||
|
AdrBookDelForm ->
|
||||||
|
D.renderDialog
|
||||||
|
(D.dialog (Just $ str " Delete Address Book Entry ") Nothing 50)
|
||||||
|
(renderForm (st ^. abForm) <=>
|
||||||
|
C.hCenter
|
||||||
|
(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
|
||||||
|
@ -366,9 +450,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.6.0.0-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 l h e = hBox [str l, withAttr titleAttr (str h), str e]
|
||||||
|
capCommand2 :: String -> String -> String -> Widget Name
|
||||||
|
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
|
||||||
|
@ -419,7 +508,7 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
Just (_, w) ->
|
Just (_, w) ->
|
||||||
withBorderStyle unicodeBold $
|
withBorderStyle unicodeBold $
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just $ txt "Seed Phrase") Nothing 50)
|
(D.dialog (Just $ txt " Seed Phrase ") Nothing 50)
|
||||||
(padAll 1 $
|
(padAll 1 $
|
||||||
txtWrap $
|
txtWrap $
|
||||||
E.decodeUtf8Lenient $
|
E.decodeUtf8Lenient $
|
||||||
|
@ -428,12 +517,12 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
MsgDisplay ->
|
MsgDisplay ->
|
||||||
withBorderStyle unicodeBold $
|
withBorderStyle unicodeBold $
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just $ txt "Message") Nothing 50)
|
(D.dialog (Just $ txt " Message ") Nothing 50)
|
||||||
(padAll 1 $ strWrap $ st ^. msg)
|
(padAll 1 $ strWrap $ st ^. msg)
|
||||||
TxIdDisplay ->
|
TxIdDisplay ->
|
||||||
withBorderStyle unicodeBold $
|
withBorderStyle unicodeBold $
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just $ txt "Success") Nothing 50)
|
(D.dialog (Just $ txt " Success ") Nothing 50)
|
||||||
(padAll 1 $
|
(padAll 1 $
|
||||||
(txt "Tx ID: " <+>
|
(txt "Tx ID: " <+>
|
||||||
txtWrapWith
|
txtWrapWith
|
||||||
|
@ -446,7 +535,7 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
Just (_, tx) ->
|
Just (_, tx) ->
|
||||||
withBorderStyle unicodeBold $
|
withBorderStyle unicodeBold $
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just $ txt "Transaction") Nothing 50)
|
(D.dialog (Just $ txt " Transaction ") Nothing 50)
|
||||||
(padAll
|
(padAll
|
||||||
1
|
1
|
||||||
(str
|
(str
|
||||||
|
@ -472,7 +561,7 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
SyncDisplay ->
|
SyncDisplay ->
|
||||||
withBorderStyle unicodeBold $
|
withBorderStyle unicodeBold $
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just $ txt "Sync") Nothing 50)
|
(D.dialog (Just $ txt " Sync ") Nothing 50)
|
||||||
(padAll
|
(padAll
|
||||||
1
|
1
|
||||||
(updateAttrMap
|
(updateAttrMap
|
||||||
|
@ -486,12 +575,28 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
SendDisplay ->
|
SendDisplay ->
|
||||||
withBorderStyle unicodeBold $
|
withBorderStyle unicodeBold $
|
||||||
D.renderDialog
|
D.renderDialog
|
||||||
(D.dialog (Just $ txt "Sending Transaction") Nothing 50)
|
(D.dialog (Just $ txt " Sending Transaction ") Nothing 50)
|
||||||
(padAll
|
(padAll
|
||||||
1
|
1
|
||||||
(strWrapWith
|
(strWrapWith
|
||||||
(WrapSettings False True NoFill FillAfterFirst)
|
(WrapSettings False True NoFill FillAfterFirst)
|
||||||
(st ^. msg)))
|
(st ^. msg)))
|
||||||
|
AdrBookEntryDisplay -> do
|
||||||
|
case L.listSelectedElement $ st ^. abAddresses of
|
||||||
|
Just (_, a) -> do
|
||||||
|
let abentry =
|
||||||
|
T.pack $
|
||||||
|
" Descr: " ++
|
||||||
|
T.unpack (addressBookAbdescrip (entityVal a)) ++
|
||||||
|
"\n Address: " ++
|
||||||
|
T.unpack (addressBookAbaddress (entityVal a))
|
||||||
|
withBorderStyle unicodeBold $
|
||||||
|
D.renderDialog
|
||||||
|
(D.dialog (Just $ txt " Address Book Entry ") Nothing 60)
|
||||||
|
(padAll 1 $
|
||||||
|
txtWrapWith (WrapSettings False True NoFill FillAfterFirst) $
|
||||||
|
abentry)
|
||||||
|
_ -> emptyWidget
|
||||||
BlankDisplay -> emptyWidget
|
BlankDisplay -> emptyWidget
|
||||||
|
|
||||||
mkInputForm :: DialogInput -> Form DialogInput e Name
|
mkInputForm :: DialogInput -> Form DialogInput e Name
|
||||||
|
@ -516,6 +621,16 @@ mkSendForm bal =
|
||||||
label s w =
|
label s w =
|
||||||
padBottom (Pad 1) $ vLimit 1 (hLimit 15 $ str s <+> fill ' ') <+> w
|
padBottom (Pad 1) $ vLimit 1 (hLimit 15 $ str s <+> fill ' ') <+> w
|
||||||
|
|
||||||
|
mkNewABForm :: AdrBookEntry -> Form AdrBookEntry e Name
|
||||||
|
mkNewABForm =
|
||||||
|
newForm
|
||||||
|
[ label "Descrip: " @@= editTextField descrip DescripField (Just 1)
|
||||||
|
, label "Address: " @@= editTextField address AddressField (Just 1)
|
||||||
|
]
|
||||||
|
where
|
||||||
|
label s w =
|
||||||
|
padBottom (Pad 1) $ vLimit 1 (hLimit 10 $ str s <+> fill ' ') <+> w
|
||||||
|
|
||||||
listDrawElement :: (Show a) => Bool -> a -> Widget Name
|
listDrawElement :: (Show a) => Bool -> a -> Widget Name
|
||||||
listDrawElement sel a =
|
listDrawElement sel a =
|
||||||
let selStr s =
|
let selStr s =
|
||||||
|
@ -572,6 +687,14 @@ listDrawTx znet sel tx =
|
||||||
then withAttr customAttr (txt $ "> " <> s)
|
then withAttr customAttr (txt $ "> " <> s)
|
||||||
else txt $ " " <> s
|
else txt $ " " <> s
|
||||||
|
|
||||||
|
listDrawAB :: Bool -> Entity AddressBook -> Widget Name
|
||||||
|
listDrawAB sel ab =
|
||||||
|
let selStr s =
|
||||||
|
if sel
|
||||||
|
then withAttr abSelAttr (txt $ " " <> s)
|
||||||
|
else txt $ " " <> s
|
||||||
|
in selStr $ addressBookAbdescrip (entityVal ab)
|
||||||
|
|
||||||
customAttr :: A.AttrName
|
customAttr :: A.AttrName
|
||||||
customAttr = L.listSelectedAttr <> A.attrName "custom"
|
customAttr = L.listSelectedAttr <> A.attrName "custom"
|
||||||
|
|
||||||
|
@ -590,6 +713,15 @@ barDoneAttr = A.attrName "done"
|
||||||
barToDoAttr :: A.AttrName
|
barToDoAttr :: A.AttrName
|
||||||
barToDoAttr = A.attrName "remaining"
|
barToDoAttr = A.attrName "remaining"
|
||||||
|
|
||||||
|
abDefAttr :: A.AttrName
|
||||||
|
abDefAttr = A.attrName "abdefault"
|
||||||
|
|
||||||
|
abSelAttr :: A.AttrName
|
||||||
|
abSelAttr = A.attrName "abselected"
|
||||||
|
|
||||||
|
abMBarAttr :: A.AttrName
|
||||||
|
abMBarAttr = A.attrName "menubar"
|
||||||
|
|
||||||
scanZebra :: T.Text -> T.Text -> Int -> Int -> BC.BChan Tick -> IO ()
|
scanZebra :: T.Text -> T.Text -> Int -> Int -> BC.BChan Tick -> IO ()
|
||||||
scanZebra dbP zHost zPort b eChan = do
|
scanZebra dbP zHost zPort b eChan = do
|
||||||
_ <- liftIO $ initDb dbP
|
_ <- liftIO $ initDb dbP
|
||||||
|
@ -627,8 +759,7 @@ scanZebra dbP zHost zPort b eChan = do
|
||||||
"getblock"
|
"getblock"
|
||||||
[Data.Aeson.String $ T.pack $ show bl, jsonNumber 1]
|
[Data.Aeson.String $ T.pack $ show bl, jsonNumber 1]
|
||||||
case r of
|
case r of
|
||||||
Left e1 -> do
|
Left e1 -> liftIO $ BC.writeBChan eChan $ TickMsg e1
|
||||||
liftIO $ BC.writeBChan eChan $ TickMsg e1
|
|
||||||
Right blk -> do
|
Right blk -> do
|
||||||
r2 <-
|
r2 <-
|
||||||
liftIO $
|
liftIO $
|
||||||
|
@ -638,8 +769,7 @@ scanZebra dbP zHost zPort b eChan = do
|
||||||
"getblock"
|
"getblock"
|
||||||
[Data.Aeson.String $ T.pack $ show bl, jsonNumber 0]
|
[Data.Aeson.String $ T.pack $ show bl, jsonNumber 0]
|
||||||
case r2 of
|
case r2 of
|
||||||
Left e2 -> do
|
Left e2 -> liftIO $ BC.writeBChan eChan $ TickMsg e2
|
||||||
liftIO $ BC.writeBChan eChan $ TickMsg e2
|
|
||||||
Right hb -> do
|
Right hb -> do
|
||||||
let blockTime = getBlockTime hb
|
let blockTime = getBlockTime hb
|
||||||
mapM_ (runNoLoggingT . processTx zHost zPort blockTime pool) $
|
mapM_ (runNoLoggingT . processTx zHost zPort blockTime pool) $
|
||||||
|
@ -666,8 +796,8 @@ appEvent (BT.AppEvent t) = do
|
||||||
TxDisplay -> return ()
|
TxDisplay -> return ()
|
||||||
TxIdDisplay -> return ()
|
TxIdDisplay -> return ()
|
||||||
SyncDisplay -> return ()
|
SyncDisplay -> return ()
|
||||||
SendDisplay -> do
|
SendDisplay -> BT.modify $ set msg m
|
||||||
BT.modify $ set msg m
|
AdrBookEntryDisplay -> return ()
|
||||||
BlankDisplay -> return ()
|
BlankDisplay -> return ()
|
||||||
TickTx txid -> do
|
TickTx txid -> do
|
||||||
BT.modify $ set sentTx (Just txid)
|
BT.modify $ set sentTx (Just txid)
|
||||||
|
@ -680,6 +810,7 @@ appEvent (BT.AppEvent t) = do
|
||||||
TxDisplay -> return ()
|
TxDisplay -> return ()
|
||||||
TxIdDisplay -> return ()
|
TxIdDisplay -> return ()
|
||||||
SendDisplay -> return ()
|
SendDisplay -> return ()
|
||||||
|
AdrBookEntryDisplay -> return ()
|
||||||
SyncDisplay -> do
|
SyncDisplay -> do
|
||||||
if s ^. barValue == 1.0
|
if s ^. barValue == 1.0
|
||||||
then do
|
then do
|
||||||
|
@ -712,6 +843,10 @@ appEvent (BT.AppEvent t) = do
|
||||||
WSelect -> return ()
|
WSelect -> return ()
|
||||||
ASelect -> return ()
|
ASelect -> return ()
|
||||||
SendTx -> return ()
|
SendTx -> return ()
|
||||||
|
AdrBook -> return ()
|
||||||
|
AdrBookForm -> return ()
|
||||||
|
AdrBookUpdForm -> return ()
|
||||||
|
AdrBookDelForm -> return ()
|
||||||
Blank -> do
|
Blank -> do
|
||||||
if s ^. timer == 90
|
if s ^. timer == 90
|
||||||
then do
|
then do
|
||||||
|
@ -729,8 +864,7 @@ appEvent (BT.AppEvent t) = do
|
||||||
(s ^. eventDispatch)
|
(s ^. eventDispatch)
|
||||||
BT.modify $ set timer 0
|
BT.modify $ set timer 0
|
||||||
return ()
|
return ()
|
||||||
else do
|
else BT.modify $ set timer $ 1 + s ^. timer
|
||||||
BT.modify $ set timer $ 1 + s ^. timer
|
|
||||||
appEvent (BT.VtyEvent e) = do
|
appEvent (BT.VtyEvent e) = do
|
||||||
r <- F.focusGetCurrent <$> use focusRing
|
r <- F.focusGetCurrent <$> use focusRing
|
||||||
s <- BT.get
|
s <- BT.get
|
||||||
|
@ -739,8 +873,7 @@ appEvent (BT.VtyEvent e) = do
|
||||||
else if s ^. helpBox
|
else if s ^. helpBox
|
||||||
then do
|
then do
|
||||||
case e of
|
case e of
|
||||||
V.EvKey V.KEsc [] -> do
|
V.EvKey V.KEsc [] -> BT.modify $ set helpBox False
|
||||||
BT.modify $ set helpBox False
|
|
||||||
_ev -> return ()
|
_ev -> return ()
|
||||||
else do
|
else do
|
||||||
case s ^. displayBox of
|
case s ^. displayBox of
|
||||||
|
@ -811,6 +944,7 @@ appEvent (BT.VtyEvent e) = do
|
||||||
_ev -> return ()
|
_ev -> return ()
|
||||||
SendDisplay -> BT.modify $ set displayBox BlankDisplay
|
SendDisplay -> BT.modify $ set displayBox BlankDisplay
|
||||||
SyncDisplay -> BT.modify $ set displayBox BlankDisplay
|
SyncDisplay -> BT.modify $ set displayBox BlankDisplay
|
||||||
|
AdrBookEntryDisplay -> BT.modify $ set displayBox BlankDisplay
|
||||||
BlankDisplay -> do
|
BlankDisplay -> do
|
||||||
case s ^. dialogBox of
|
case s ^. dialogBox of
|
||||||
WName -> do
|
WName -> do
|
||||||
|
@ -873,7 +1007,7 @@ appEvent (BT.VtyEvent e) = do
|
||||||
V.EvKey (V.KChar 'n') [] -> do
|
V.EvKey (V.KChar 'n') [] -> do
|
||||||
BT.modify $
|
BT.modify $
|
||||||
set inputForm $
|
set inputForm $
|
||||||
updateFormState (DialogInput "New Wallet") $
|
updateFormState (DialogInput " New Wallet ") $
|
||||||
s ^. inputForm
|
s ^. inputForm
|
||||||
BT.modify $ set dialogBox WName
|
BT.modify $ set dialogBox WName
|
||||||
V.EvKey (V.KChar 's') [] ->
|
V.EvKey (V.KChar 's') [] ->
|
||||||
|
@ -890,7 +1024,7 @@ appEvent (BT.VtyEvent e) = do
|
||||||
V.EvKey (V.KChar 'n') [] -> do
|
V.EvKey (V.KChar 'n') [] -> do
|
||||||
BT.modify $
|
BT.modify $
|
||||||
set inputForm $
|
set inputForm $
|
||||||
updateFormState (DialogInput "New Account") $
|
updateFormState (DialogInput " New Account ") $
|
||||||
s ^. inputForm
|
s ^. inputForm
|
||||||
BT.modify $ set dialogBox AName
|
BT.modify $ set dialogBox AName
|
||||||
ev -> BT.zoom accounts $ L.handleListEvent ev
|
ev -> BT.zoom accounts $ L.handleListEvent ev
|
||||||
|
@ -951,7 +1085,7 @@ 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 -> do
|
ev ->
|
||||||
BT.zoom txForm $ do
|
BT.zoom txForm $ do
|
||||||
handleFormEvent (BT.VtyEvent ev)
|
handleFormEvent (BT.VtyEvent ev)
|
||||||
fs <- BT.gets formState
|
fs <- BT.gets formState
|
||||||
|
@ -959,6 +1093,189 @@ appEvent (BT.VtyEvent e) = do
|
||||||
setFieldValid
|
setFieldValid
|
||||||
(isRecipientValid (fs ^. sendTo))
|
(isRecipientValid (fs ^. sendTo))
|
||||||
RecField
|
RecField
|
||||||
|
AdrBook -> do
|
||||||
|
case e of
|
||||||
|
V.EvKey (V.KChar 'x') [] ->
|
||||||
|
BT.modify $ set dialogBox Blank
|
||||||
|
V.EvKey (V.KChar 'c') []
|
||||||
|
-- Copy Address to Clipboard
|
||||||
|
-> do
|
||||||
|
case L.listSelectedElement $ s ^. abAddresses of
|
||||||
|
Just (_, a) -> do
|
||||||
|
liftIO $
|
||||||
|
setClipboard $
|
||||||
|
T.unpack $ addressBookAbaddress (entityVal a)
|
||||||
|
BT.modify $
|
||||||
|
set msg $
|
||||||
|
"Address copied to Clipboard from >>\n" ++
|
||||||
|
T.unpack (addressBookAbdescrip (entityVal a))
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
_ -> do
|
||||||
|
BT.modify $
|
||||||
|
set msg "Error while copying the address!!"
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
-- Send Zcash transaction
|
||||||
|
V.EvKey (V.KChar 's') [] -> do
|
||||||
|
case L.listSelectedElement $ s ^. abAddresses of
|
||||||
|
Just (_, a) -> do
|
||||||
|
BT.modify $
|
||||||
|
set txForm $
|
||||||
|
mkSendForm
|
||||||
|
(s ^. balance)
|
||||||
|
(SendInput
|
||||||
|
(addressBookAbaddress (entityVal a))
|
||||||
|
0.0
|
||||||
|
"")
|
||||||
|
BT.modify $ set dialogBox SendTx
|
||||||
|
_ -> do
|
||||||
|
BT.modify $
|
||||||
|
set msg "No receiver address available!!"
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
-- Edit an entry in Address Book
|
||||||
|
V.EvKey (V.KChar 'e') [] -> do
|
||||||
|
case L.listSelectedElement $ s ^. abAddresses of
|
||||||
|
Just (_, a) -> do
|
||||||
|
BT.modify $
|
||||||
|
set
|
||||||
|
abCurAdrs
|
||||||
|
(addressBookAbaddress (entityVal a))
|
||||||
|
BT.modify $
|
||||||
|
set abForm $
|
||||||
|
mkNewABForm
|
||||||
|
(AdrBookEntry
|
||||||
|
(addressBookAbdescrip (entityVal a))
|
||||||
|
(addressBookAbaddress (entityVal a)))
|
||||||
|
BT.modify $ set dialogBox AdrBookUpdForm
|
||||||
|
_ -> do
|
||||||
|
BT.modify $ set dialogBox Blank
|
||||||
|
-- Delete an entry from Address Book
|
||||||
|
V.EvKey (V.KChar 'd') [] -> do
|
||||||
|
case L.listSelectedElement $ s ^. abAddresses of
|
||||||
|
Just (_, a) -> do
|
||||||
|
BT.modify $
|
||||||
|
set
|
||||||
|
abCurAdrs
|
||||||
|
(addressBookAbaddress (entityVal a))
|
||||||
|
BT.modify $
|
||||||
|
set abForm $
|
||||||
|
mkNewABForm
|
||||||
|
(AdrBookEntry
|
||||||
|
(addressBookAbdescrip (entityVal a))
|
||||||
|
(addressBookAbaddress (entityVal a)))
|
||||||
|
BT.modify $ set dialogBox AdrBookDelForm
|
||||||
|
_ -> do
|
||||||
|
BT.modify $ set dialogBox Blank
|
||||||
|
-- Create a new entry in Address Book
|
||||||
|
V.EvKey (V.KChar 'n') [] -> do
|
||||||
|
BT.modify $
|
||||||
|
set abForm $ mkNewABForm (AdrBookEntry "" "")
|
||||||
|
BT.modify $ set dialogBox AdrBookForm
|
||||||
|
-- Show AddressBook entry data
|
||||||
|
V.EvKey V.KEnter [] -> do
|
||||||
|
BT.modify $ set displayBox AdrBookEntryDisplay
|
||||||
|
-- Process any other event
|
||||||
|
ev -> BT.zoom abAddresses $ L.handleListEvent ev
|
||||||
|
-- Process new address book entry
|
||||||
|
AdrBookForm -> do
|
||||||
|
case e of
|
||||||
|
V.EvKey V.KEsc [] -> BT.modify $ set dialogBox AdrBook
|
||||||
|
V.EvKey V.KEnter [] -> do
|
||||||
|
pool <- liftIO $ runNoLoggingT $ initPool $ s ^. dbPath
|
||||||
|
fs <- BT.zoom abForm $ BT.gets formState
|
||||||
|
let idescr = T.unpack $ T.strip (fs ^. descrip)
|
||||||
|
let iabadr = fs ^. address
|
||||||
|
if not (null idescr) && isRecipientValid iabadr
|
||||||
|
then do
|
||||||
|
res <-
|
||||||
|
liftIO $
|
||||||
|
saveAdrsInAdrBook pool $
|
||||||
|
AddressBook
|
||||||
|
(ZcashNetDB (s ^. network))
|
||||||
|
(fs ^. descrip)
|
||||||
|
(fs ^. address)
|
||||||
|
case res of
|
||||||
|
Nothing -> do
|
||||||
|
BT.modify $
|
||||||
|
set
|
||||||
|
msg
|
||||||
|
("AddressBook Entry already exists: " ++
|
||||||
|
T.unpack (fs ^. address))
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
Just _ -> do
|
||||||
|
BT.modify $
|
||||||
|
set
|
||||||
|
msg
|
||||||
|
("New AddressBook entry created!!\n" ++
|
||||||
|
T.unpack (fs ^. address))
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
-- case end
|
||||||
|
s' <- liftIO $ refreshAddressBook s
|
||||||
|
BT.put s'
|
||||||
|
BT.modify $ set dialogBox AdrBook
|
||||||
|
else do
|
||||||
|
BT.modify $ set msg "Invalid or missing data!!: "
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
BT.modify $ set dialogBox AdrBookForm
|
||||||
|
ev ->
|
||||||
|
BT.zoom abForm $ do
|
||||||
|
handleFormEvent (BT.VtyEvent ev)
|
||||||
|
fs <- BT.gets formState
|
||||||
|
BT.modify $
|
||||||
|
setFieldValid
|
||||||
|
(isRecipientValid (fs ^. address))
|
||||||
|
AddressField
|
||||||
|
AdrBookUpdForm -> do
|
||||||
|
case e of
|
||||||
|
V.EvKey V.KEsc [] -> BT.modify $ set dialogBox AdrBook
|
||||||
|
V.EvKey V.KEnter [] -> do
|
||||||
|
pool <- liftIO $ runNoLoggingT $ initPool $ s ^. dbPath
|
||||||
|
fs <- BT.zoom abForm $ BT.gets formState
|
||||||
|
let idescr = T.unpack $ T.strip (fs ^. descrip)
|
||||||
|
let iabadr = fs ^. address
|
||||||
|
if not (null idescr) && isRecipientValid iabadr
|
||||||
|
then do
|
||||||
|
res <-
|
||||||
|
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
|
||||||
|
-- case end
|
||||||
|
s' <- liftIO $ refreshAddressBook s
|
||||||
|
BT.put s'
|
||||||
|
BT.modify $ set dialogBox AdrBook
|
||||||
|
else do
|
||||||
|
BT.modify $ set msg "Invalid or missing data!!: "
|
||||||
|
BT.modify $ set displayBox MsgDisplay
|
||||||
|
BT.modify $ set dialogBox AdrBookForm
|
||||||
|
ev ->
|
||||||
|
BT.zoom abForm $ do
|
||||||
|
handleFormEvent (BT.VtyEvent ev)
|
||||||
|
fs <- BT.gets formState
|
||||||
|
BT.modify $
|
||||||
|
setFieldValid
|
||||||
|
(isRecipientValid (fs ^. address))
|
||||||
|
AddressField
|
||||||
|
-- Process delete AddresBook entry
|
||||||
|
AdrBookDelForm -> do
|
||||||
|
case e of
|
||||||
|
V.EvKey V.KEsc [] -> BT.modify $ set dialogBox AdrBook
|
||||||
|
V.EvKey (V.KChar 'c') [] -> do
|
||||||
|
pool <- liftIO $ runNoLoggingT $ initPool $ s ^. dbPath
|
||||||
|
fs <- BT.zoom abForm $ BT.gets formState
|
||||||
|
res <- liftIO $ deleteAdrsFromAB pool (fs ^. address)
|
||||||
|
s' <- liftIO $ refreshAddressBook s
|
||||||
|
BT.put s'
|
||||||
|
BT.modify $ set dialogBox AdrBook
|
||||||
|
ev -> BT.modify $ set dialogBox AdrBookDelForm
|
||||||
|
-- Process any other event
|
||||||
Blank -> do
|
Blank -> do
|
||||||
case e of
|
case e of
|
||||||
V.EvKey (V.KChar '\t') [] -> focusRing %= F.focusNext
|
V.EvKey (V.KChar '\t') [] -> focusRing %= F.focusNext
|
||||||
|
@ -982,12 +1299,16 @@ appEvent (BT.VtyEvent e) = do
|
||||||
set txForm $
|
set txForm $
|
||||||
mkSendForm (s ^. balance) (SendInput "" 0.0 "")
|
mkSendForm (s ^. balance) (SendInput "" 0.0 "")
|
||||||
BT.modify $ set dialogBox SendTx
|
BT.modify $ set dialogBox SendTx
|
||||||
|
V.EvKey (V.KChar 'b') [] ->
|
||||||
|
BT.modify $ set dialogBox AdrBook
|
||||||
ev ->
|
ev ->
|
||||||
case r of
|
case r of
|
||||||
Just AList ->
|
Just AList ->
|
||||||
BT.zoom addresses $ L.handleListEvent ev
|
BT.zoom addresses $ L.handleListEvent ev
|
||||||
Just TList ->
|
Just TList ->
|
||||||
BT.zoom transactions $ L.handleListEvent ev
|
BT.zoom transactions $ L.handleListEvent ev
|
||||||
|
Just ABList ->
|
||||||
|
BT.zoom abAddresses $ L.handleListEvent ev
|
||||||
_anyName -> return ()
|
_anyName -> return ()
|
||||||
where
|
where
|
||||||
printMsg :: String -> BT.EventM Name State ()
|
printMsg :: String -> BT.EventM Name State ()
|
||||||
|
@ -1007,11 +1328,14 @@ theMap =
|
||||||
, (blinkAttr, style V.blink)
|
, (blinkAttr, style V.blink)
|
||||||
, (focusedFormInputAttr, V.white `on` V.blue)
|
, (focusedFormInputAttr, V.white `on` V.blue)
|
||||||
, (invalidFormInputAttr, V.red `on` V.black)
|
, (invalidFormInputAttr, V.red `on` V.black)
|
||||||
, (E.editAttr, V.white `on` V.blue)
|
, (E.editAttr, V.white `on` V.black)
|
||||||
, (E.editFocusedAttr, V.blue `on` V.white)
|
, (E.editFocusedAttr, V.black `on` V.white)
|
||||||
, (baseAttr, bg V.brightBlack)
|
, (baseAttr, bg V.brightBlack)
|
||||||
, (barDoneAttr, V.white `on` V.blue)
|
, (barDoneAttr, V.white `on` V.blue)
|
||||||
, (barToDoAttr, V.white `on` V.black)
|
, (barToDoAttr, V.white `on` V.black)
|
||||||
|
, (abDefAttr, V.white `on` V.blue)
|
||||||
|
, (abSelAttr, V.black `on` V.white)
|
||||||
|
, (abMBarAttr, V.white `on` V.black)
|
||||||
]
|
]
|
||||||
|
|
||||||
theApp :: M.App State Tick Name
|
theApp :: M.App State Tick Name
|
||||||
|
@ -1024,8 +1348,8 @@ theApp =
|
||||||
, M.appAttrMap = const theMap
|
, M.appAttrMap = const theMap
|
||||||
}
|
}
|
||||||
|
|
||||||
runZenithCLI :: Config -> IO ()
|
runZenithTUI :: Config -> IO ()
|
||||||
runZenithCLI config = do
|
runZenithTUI config = do
|
||||||
let host = c_zebraHost config
|
let host = c_zebraHost config
|
||||||
let port = c_zebraPort config
|
let port = c_zebraPort config
|
||||||
let dbFilePath = c_dbPath config
|
let dbFilePath = c_dbPath config
|
||||||
|
@ -1057,6 +1381,7 @@ runZenithCLI 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
|
||||||
bal <-
|
bal <-
|
||||||
if not (null accList)
|
if not (null accList)
|
||||||
then getBalance pool $ entityKey $ head accList
|
then getBalance pool $ entityKey $ head accList
|
||||||
|
@ -1101,6 +1426,9 @@ runZenithCLI config = do
|
||||||
eventChan
|
eventChan
|
||||||
0
|
0
|
||||||
(mkSendForm 0 $ SendInput "" 0.0 "")
|
(mkSendForm 0 $ SendInput "" 0.0 "")
|
||||||
|
(L.list ABList (Vec.fromList abookList) 1)
|
||||||
|
(mkNewABForm (AdrBookEntry "" ""))
|
||||||
|
""
|
||||||
Nothing
|
Nothing
|
||||||
uBal
|
uBal
|
||||||
Left e -> do
|
Left e -> do
|
||||||
|
@ -1163,14 +1491,13 @@ addNewWallet n s = do
|
||||||
let netName = s ^. network
|
let netName = s ^. network
|
||||||
r <- saveWallet pool $ ZcashWallet n (ZcashNetDB netName) (PhraseDB sP) bH 0
|
r <- saveWallet pool $ ZcashWallet n (ZcashNetDB netName) (PhraseDB sP) bH 0
|
||||||
case r of
|
case r of
|
||||||
Nothing -> do
|
Nothing -> return $ s & msg .~ ("Wallet already exists: " ++ T.unpack n)
|
||||||
return $ s & msg .~ ("Wallet already exists: " ++ T.unpack n)
|
|
||||||
Just _ -> do
|
Just _ -> do
|
||||||
wL <- getWallets pool netName
|
wL <- getWallets pool netName
|
||||||
let aL =
|
let aL =
|
||||||
L.listFindBy (\x -> zcashWalletName (entityVal x) == n) $
|
L.listFindBy (\x -> zcashWalletName (entityVal x) == n) $
|
||||||
L.listReplace (Vec.fromList wL) (Just 0) (s ^. wallets)
|
L.listReplace (Vec.fromList wL) (Just 0) (s ^. wallets)
|
||||||
return $ (s & wallets .~ aL) & msg .~ "Created new wallet: " ++ T.unpack n
|
return $ s & wallets .~ aL & msg .~ "Created new wallet: " ++ T.unpack n
|
||||||
|
|
||||||
addNewAccount :: T.Text -> State -> IO State
|
addNewAccount :: T.Text -> State -> IO State
|
||||||
addNewAccount n s = do
|
addNewAccount n s = do
|
||||||
|
@ -1189,19 +1516,18 @@ addNewAccount n s = do
|
||||||
try $ createZcashAccount n (aL' + 1) selWallet :: IO
|
try $ createZcashAccount n (aL' + 1) selWallet :: IO
|
||||||
(Either IOError ZcashAccount)
|
(Either IOError ZcashAccount)
|
||||||
case zA of
|
case zA of
|
||||||
Left e -> return $ s & msg .~ ("Error: " ++ show e)
|
Left e -> return $ s & msg .~ "Error: " ++ show e
|
||||||
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 =
|
||||||
L.listMoveToElement x $
|
L.listMoveToElement x $
|
||||||
L.listReplace (Vec.fromList aL) (Just 0) (s ^. accounts)
|
L.listReplace (Vec.fromList aL) (Just 0) (s ^. accounts)
|
||||||
return $
|
return $
|
||||||
(s & accounts .~ nL) & msg .~ "Created new account: " ++ T.unpack n
|
s & accounts .~ nL & msg .~ "Created new account: " ++ T.unpack n
|
||||||
|
|
||||||
refreshAccount :: State -> IO State
|
refreshAccount :: State -> IO State
|
||||||
refreshAccount s = do
|
refreshAccount s = do
|
||||||
|
@ -1259,6 +1585,21 @@ refreshTxs s = do
|
||||||
let tL' = L.listReplace (Vec.fromList tList) (Just 0) (s ^. transactions)
|
let tL' = L.listReplace (Vec.fromList tList) (Just 0) (s ^. transactions)
|
||||||
return $ s & transactions .~ tL'
|
return $ s & transactions .~ tL'
|
||||||
|
|
||||||
|
refreshAddressBook :: State -> IO State
|
||||||
|
refreshAddressBook s = do
|
||||||
|
pool <- runNoLoggingT $ initPool $ s ^. dbPath
|
||||||
|
selAddress <-
|
||||||
|
do case L.listSelectedElement $ s ^. abAddresses of
|
||||||
|
Nothing -> do
|
||||||
|
let fAdd =
|
||||||
|
L.listSelectedElement $
|
||||||
|
L.listMoveToBeginning $ s ^. abAddresses
|
||||||
|
return fAdd
|
||||||
|
Just a2 -> return $ Just a2
|
||||||
|
abookList <- getAdrBook pool (s ^. network)
|
||||||
|
let tL' = L.listReplace (Vec.fromList abookList) (Just 0) (s ^. abAddresses)
|
||||||
|
return $ s & abAddresses .~ tL'
|
||||||
|
|
||||||
addNewAddress :: T.Text -> Scope -> State -> IO State
|
addNewAddress :: T.Text -> Scope -> State -> IO State
|
||||||
addNewAddress n scope s = do
|
addNewAddress n scope s = do
|
||||||
pool <- runNoLoggingT $ initPool $ s ^. dbPath
|
pool <- runNoLoggingT $ initPool $ s ^. dbPath
|
||||||
|
@ -1276,19 +1617,18 @@ addNewAddress n scope s = do
|
||||||
try $ createWalletAddress n (maxAddr + 1) (s ^. network) scope selAccount :: IO
|
try $ createWalletAddress n (maxAddr + 1) (s ^. network) scope selAccount :: IO
|
||||||
(Either IOError WalletAddress)
|
(Either IOError WalletAddress)
|
||||||
case uA of
|
case uA of
|
||||||
Left e -> return $ s & msg .~ ("Error: " ++ show e)
|
Left e -> return $ s & msg .~ "Error: " ++ show e
|
||||||
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 =
|
||||||
L.listMoveToElement x $
|
L.listMoveToElement x $
|
||||||
L.listReplace (Vec.fromList addrL) (Just 0) (s ^. addresses)
|
L.listReplace (Vec.fromList addrL) (Just 0) (s ^. addresses)
|
||||||
return $
|
return $
|
||||||
(s & addresses .~ nL) & msg .~ "Created new address: " ++
|
s & addresses .~ nL & msg .~ "Created new address: " ++
|
||||||
T.unpack n ++
|
T.unpack n ++
|
||||||
"(" ++
|
"(" ++
|
||||||
T.unpack (showAddress $ walletAddressUAddress $ entityVal x) ++ ")"
|
T.unpack (showAddress $ walletAddressUAddress $ entityVal x) ++ ")"
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Data.Binary.Get hiding (getBytes)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
import Data.Digest.Pure.MD5
|
import Data.Digest.Pure.MD5
|
||||||
import Data.HexString (HexString, hexString, toBytes)
|
import Data.HexString (HexString, hexString, toBytes, toText)
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust)
|
||||||
import Data.Pool (Pool)
|
import Data.Pool (Pool)
|
||||||
|
@ -574,6 +574,7 @@ prepareTx pool zebraHost zebraPort zn za bh amt ua memo = do
|
||||||
zn
|
zn
|
||||||
(bh + 3)
|
(bh + 3)
|
||||||
True
|
True
|
||||||
|
logDebugN $ T.pack $ show tx
|
||||||
return tx
|
return tx
|
||||||
where
|
where
|
||||||
makeOutgoing ::
|
makeOutgoing ::
|
||||||
|
|
|
@ -254,6 +254,12 @@ share
|
||||||
name T.Text
|
name T.Text
|
||||||
UniqueQr address version
|
UniqueQr address version
|
||||||
deriving Show Eq
|
deriving Show Eq
|
||||||
|
AddressBook
|
||||||
|
network ZcashNetDB
|
||||||
|
abdescrip T.Text
|
||||||
|
abaddress T.Text
|
||||||
|
UniqueABA abaddress
|
||||||
|
deriving Show Eq
|
||||||
|]
|
|]
|
||||||
|
|
||||||
-- * Database functions
|
-- * Database functions
|
||||||
|
@ -1666,5 +1672,55 @@ readUnifiedAddressDB :: WalletAddress -> Maybe UnifiedAddress
|
||||||
readUnifiedAddressDB =
|
readUnifiedAddressDB =
|
||||||
isValidUnifiedAddress . TE.encodeUtf8 . getUA . walletAddressUAddress
|
isValidUnifiedAddress . TE.encodeUtf8 . getUA . walletAddressUAddress
|
||||||
|
|
||||||
|
-- | Get list of external zcash addresses from database
|
||||||
|
getAdrBook :: ConnectionPool -> ZcashNet -> IO [Entity AddressBook]
|
||||||
|
getAdrBook pool n =
|
||||||
|
runNoLoggingT $
|
||||||
|
PS.retryOnBusy $
|
||||||
|
flip PS.runSqlPool pool $ do
|
||||||
|
select $ do
|
||||||
|
adrbook <- from $ table @AddressBook
|
||||||
|
where_ (adrbook ^. AddressBookNetwork ==. val (ZcashNetDB n))
|
||||||
|
pure adrbook
|
||||||
|
|
||||||
|
-- | Save a new address into AddressBook
|
||||||
|
saveAdrsInAdrBook ::
|
||||||
|
ConnectionPool -- ^ The database path to use
|
||||||
|
-> AddressBook -- ^ The address to add to the database
|
||||||
|
-> IO (Maybe (Entity AddressBook))
|
||||||
|
saveAdrsInAdrBook pool a =
|
||||||
|
runNoLoggingT $
|
||||||
|
PS.retryOnBusy $ flip PS.runSqlPool pool $ insertUniqueEntity a
|
||||||
|
|
||||||
|
-- | Update an existing address into AddressBook
|
||||||
|
updateAdrsInAdrBook :: ConnectionPool -> T.Text -> T.Text -> T.Text -> IO ()
|
||||||
|
updateAdrsInAdrBook pool d a ia = do
|
||||||
|
runNoLoggingT $
|
||||||
|
PS.retryOnBusy $
|
||||||
|
flip PS.runSqlPool pool $ do
|
||||||
|
update $ \ab -> do
|
||||||
|
set ab [AddressBookAbdescrip =. val d, AddressBookAbaddress =. val a]
|
||||||
|
where_ $ ab ^. AddressBookAbaddress ==. val ia
|
||||||
|
|
||||||
|
-- | Get one AddrssBook record using the Address as a key
|
||||||
|
-- getABookRec :: ConnectionPool -> T.Tex t -> IO (Maybe (Entity AddressBook))
|
||||||
|
-- getABookRec pool a = do
|
||||||
|
-- runNoLoggingT $
|
||||||
|
-- PS.retryOnBusy $
|
||||||
|
-- flip PS.runSqlPool pool $
|
||||||
|
-- select $ do
|
||||||
|
-- adrbook <- from $ table @AddressBook
|
||||||
|
-- where_ ((adrbook ^. AddressBookAbaddress) ==. val a)
|
||||||
|
-- return adrbook
|
||||||
|
-- | delete an existing address from AddressBook
|
||||||
|
deleteAdrsFromAB :: ConnectionPool -> T.Text -> IO ()
|
||||||
|
deleteAdrsFromAB pool ia = do
|
||||||
|
runNoLoggingT $
|
||||||
|
PS.retryOnBusy $
|
||||||
|
flip PS.runSqlPool pool $ do
|
||||||
|
delete $ do
|
||||||
|
ab <- from $ table @AddressBook
|
||||||
|
where_ (ab ^. AddressBookAbaddress ==. val ia)
|
||||||
|
|
||||||
rmdups :: Ord a => [a] -> [a]
|
rmdups :: Ord a => [a] -> [a]
|
||||||
rmdups = map head . group . sort
|
rmdups = map head . group . sort
|
||||||
|
|
|
@ -37,18 +37,18 @@ jsonNumber i = Number $ scientific (fromIntegral i) 0
|
||||||
-- | Helper function to display small amounts of ZEC
|
-- | Helper function to display small amounts of ZEC
|
||||||
displayZec :: Integer -> String
|
displayZec :: Integer -> String
|
||||||
displayZec s
|
displayZec s
|
||||||
| abs s < 100 = show s ++ " zats "
|
| abs s < 100 = show s ++ " zats"
|
||||||
| abs s < 100000 = show (fromIntegral s / 100) ++ " μZEC "
|
| abs s < 100000 = show (fromIntegral s / 100) ++ " μZEC"
|
||||||
| abs s < 100000000 = show (fromIntegral s / 100000) ++ " mZEC "
|
| abs s < 100000000 = show (fromIntegral s / 100000) ++ " mZEC"
|
||||||
| otherwise = show (fromIntegral s / 100000000) ++ " ZEC "
|
| otherwise = show (fromIntegral s / 100000000) ++ " ZEC "
|
||||||
|
|
||||||
-- | Helper function to display small amounts of ZEC
|
-- | Helper function to display small amounts of ZEC
|
||||||
displayTaz :: Integer -> String
|
displayTaz :: Integer -> String
|
||||||
displayTaz s
|
displayTaz s
|
||||||
| abs s < 100 = show s ++ " tazs "
|
| abs s < 100 = show s ++ " tazs"
|
||||||
| abs s < 100000 = show (fromIntegral s / 100) ++ " μTAZ "
|
| abs s < 100000 = show (fromIntegral s / 100) ++ " μTAZ"
|
||||||
| abs s < 100000000 = show (fromIntegral s / 100000) ++ " mTAZ "
|
| abs s < 100000000 = show (fromIntegral s / 100000) ++ " mTAZ"
|
||||||
| otherwise = show (fromIntegral s / 100000000) ++ " TAZ "
|
| otherwise = show (fromIntegral s / 100000000) ++ " TAZ"
|
||||||
|
|
||||||
displayAmount :: ZcashNet -> Integer -> T.Text
|
displayAmount :: ZcashNet -> Integer -> T.Text
|
||||||
displayAmount n a =
|
displayAmount n a =
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: zenith
|
name: zenith
|
||||||
version: 0.5.3.0-beta
|
version: 0.6.0.0-beta
|
||||||
license: MIT
|
license: MIT
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
author: Rene Vergara
|
author: Rene Vergara
|
||||||
|
@ -53,7 +53,7 @@ library
|
||||||
, exceptions
|
, exceptions
|
||||||
, monad-logger
|
, monad-logger
|
||||||
, vty-crossplatform
|
, vty-crossplatform
|
||||||
, secp256k1-haskell
|
, secp256k1-haskell >= 1
|
||||||
, pureMD5
|
, pureMD5
|
||||||
, ghc
|
, ghc
|
||||||
, haskoin-core
|
, haskoin-core
|
||||||
|
@ -100,7 +100,7 @@ executable zenith
|
||||||
, configurator
|
, configurator
|
||||||
, data-default
|
, data-default
|
||||||
, sort
|
, sort
|
||||||
, structured-cli
|
--, structured-cli
|
||||||
, text
|
, text
|
||||||
, time
|
, time
|
||||||
, zenith
|
, zenith
|
||||||
|
|
BIN
zenith_er.bmp
Normal file
BIN
zenith_er.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 MiB |
BIN
zenith_er.png
Normal file
BIN
zenith_er.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 KiB |
Loading…
Reference in a new issue