Compare commits

..

No commits in common. "01459544a5104e6337da64942e9e5864f86e424b" and "3a9c5a843071916f2a695349dc9d20fdc5077fed" have entirely different histories.

32 changed files with 346 additions and 2558 deletions

View file

@ -5,53 +5,8 @@ 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.6.0.0-beta]
### Added
- GUI module
- Address list
- Transaction list
- Balance display
- Account selector
- Menu for new addresses, accounts, wallets
- Dialog to display and copy seed phrase
- Dialog to add new address
- Dialog to add new account
- Dialog to add new wallet
- Dialog to display transaction details and copy TX ID
- Dialog to send a new transaction
- Dialog to display Tx ID after successful broadcast
- Unconfirmed balance display on TUI and GUI
- Tracking of unconfirmed notes
### Changed
- Upgraded to GHC 9.6.5
- Implemented config and data folder
- Improved the `configure` script for installation
### Fixed
- 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
@ -62,6 +17,11 @@ 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

@ -11,8 +11,7 @@ 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
@ -20,11 +19,10 @@ import Text.Read (readMaybe)
import ZcashHaskell.Types import ZcashHaskell.Types
import Zenith.CLI import Zenith.CLI
import Zenith.Core (clearSync, testSync) import Zenith.Core (clearSync, testSync)
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
@ -198,22 +196,21 @@ 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 ["$(HOME)/Zenith/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 case head args of
{-"legacy" -> do "legacy" -> do
checkServer nodeUser nodePwd checkServer nodeUser nodePwd
void $ void $
runCLI runCLI
@ -222,9 +219,7 @@ 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)
of
"gui" -> runZenithGUI myConfig
"tui" -> runZenithTUI myConfig "tui" -> runZenithTUI myConfig
"rescan" -> clearSync myConfig "rescan" -> clearSync myConfig
_ -> printUsage _ -> printUsage
@ -234,6 +229,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 "tui\tTUI for zebrad" putStrLn "tui\tTUI for zebrad"
putStrLn "rescan\tRescan the existing wallet(s)" putStrLn "rescan\tRescan the existing wallet(s)"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -2,7 +2,7 @@ packages:
./*.cabal ./*.cabal
zcash-haskell/zcash-haskell.cabal zcash-haskell/zcash-haskell.cabal
with-compiler: ghc-9.6.5 with-compiler: ghc-9.4.8
source-repository-package source-repository-package
type: git type: git

View file

@ -1,49 +1,38 @@
active-repositories: hackage.haskell.org:merge active-repositories: hackage.haskell.org:merge
constraints: any.Cabal ==3.10.3.0, constraints: any.Cabal ==3.8.1.0,
any.Cabal-syntax ==3.10.3.0, any.Cabal-syntax ==3.8.1.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.9, any.OneTuple ==0.4.1.1,
JuicyPixels -mmap,
any.OneTuple ==0.4.2,
any.OpenGLRaw ==3.3.4.1,
OpenGLRaw -osandroid +usegles2 +useglxgetprocaddress +usenativewindowslibraries,
any.QuickCheck ==2.14.3, any.QuickCheck ==2.14.3,
QuickCheck -old-random +templatehaskell, QuickCheck -old-random +templatehaskell,
any.RSA ==2.4.1,
any.SHA ==1.6.4.4,
SHA -exe,
any.StateVar ==1.2.2, any.StateVar ==1.2.2,
any.X11 ==1.10.3, any.X11 ==1.10.3,
X11 -pedantic, X11 -pedantic,
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.1, any.ansi-terminal ==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.6.0, any.array ==0.5.4.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.1, any.assoc ==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.2.0, any.attoparsec-aeson ==2.2.0.1,
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-orphans ==0.9.1,
any.base-compat ==0.14.0,
any.base-compat-batteries ==0.14.0,
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,37 +42,30 @@ constraints: any.Cabal ==3.10.3.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.5, any.binary-orphans ==1.0.4.1,
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.4, any.brick ==2.3.1,
brick -demos, brick -demos,
any.byteorder ==1.0.4, any.byteorder ==1.0.4,
any.bytes ==0.17.3, any.bytes ==0.17.3,
any.bytestring ==0.11.5.3, any.bytestring ==0.11.5.3,
any.bytestring-builder ==0.10.8.2.0,
bytestring-builder +bytestring_has_builder,
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.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,
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.21, any.concurrent-output ==1.10.20,
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,
@ -93,14 +75,13 @@ constraints: any.Cabal ==3.10.3.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.5.0, any.cookie ==0.4.6,
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.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.4.1, any.crypton-connection ==0.3.2,
any.crypton-x509 ==1.7.7, any.crypton-x509 ==1.7.6,
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,
@ -112,57 +93,50 @@ constraints: any.Cabal ==3.10.3.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.4, any.data-fix ==0.3.2,
any.deepseq ==1.4.8.1, any.deepseq ==1.4.8.0,
any.directory ==1.3.8.4, any.directory ==1.3.7.1,
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,
dlist -werror, dlist -werror,
any.double-conversion ==2.0.5.0,
double-conversion -developer +embedded_double_conversion,
any.easy-file ==0.2.5, any.easy-file ==0.2.5,
any.entropy ==0.4.1.10, any.entropy ==0.4.1.10,
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.7, any.exceptions ==0.10.5,
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.foldable1-classes-compat ==0.1,
any.fixed ==0.3, foldable1-classes-compat +tagged,
any.foreign-rust ==0.1.0, any.foreign-rust ==0.1.0,
any.foreign-store ==0.2.1,
any.formatting ==7.2.0,
formatting -no-double-conversion,
any.free ==5.2,
any.generic-deriving ==1.14.5,
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.6.5, any.ghc ==9.4.8,
any.ghc-bignum ==1.3, any.ghc-bignum ==1.3,
any.ghc-boot ==9.6.5, any.ghc-boot ==9.4.8,
any.ghc-boot-th ==9.6.5, any.ghc-boot-th ==9.4.8,
any.ghc-heap ==9.6.5, any.ghc-heap ==9.4.8,
any.ghc-prim ==0.10.0, any.ghc-prim ==0.9.1,
any.ghci ==9.6.5, any.ghci ==9.4.8,
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.7.0, any.hashable ==1.4.4.0,
hashable -arch-native +integer-gmp -random-initial-seed, hashable +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.2.0, any.hpc ==0.6.1.0,
any.hsc2hs ==0.68.10, any.hsc2hs ==0.68.10,
hsc2hs -in-ghc-tree, hsc2hs -in-ghc-tree,
any.hspec ==2.11.9, any.hspec ==2.11.7,
any.hspec-core ==2.11.9, any.hspec-core ==2.11.7,
any.hspec-discover ==2.11.9, any.hspec-discover ==2.11.7,
any.hspec-expectations ==0.8.4, any.hspec-expectations ==0.8.4,
any.http-api-data ==0.6.1, any.http-api-data ==0.6,
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,
@ -170,31 +144,24 @@ constraints: any.Cabal ==3.10.3.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.4, any.indexed-traversable ==0.1.3,
any.indexed-traversable-instances ==0.1.2, any.indexed-traversable-instances ==0.1.1.2,
any.integer-conversion ==0.1.1, any.integer-conversion ==0.1.0.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.iproute ==1.7.12, any.iproute ==1.7.12,
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.3.2,
lens -benchmark-uniplate -dump-splices +inlining -j +test-hunit +test-properties +test-templates +trustworthy,
any.lens-aeson ==1.2.3,
any.lift-type ==0.1.1.1, any.lift-type ==0.1.1.1,
any.lifted-base ==0.2.3.12, any.lifted-base ==0.2.3.12,
any.linear ==1.22,
linear -herbie +template-haskell,
any.megaparsec ==9.6.1, any.megaparsec ==9.6.1,
megaparsec -dev, megaparsec -dev,
any.memory ==0.18.0, any.memory ==0.18.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.15, any.microlens-th ==0.4.3.14,
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,
@ -202,19 +169,14 @@ constraints: any.Cabal ==3.10.3.0,
any.monad-loops ==0.4.3, any.monad-loops ==0.4.3,
monad-loops +base4, monad-loops +base4,
any.mono-traversable ==1.0.17.0, any.mono-traversable ==1.0.17.0,
any.monomer ==1.6.0.1, any.mtl ==2.2.2,
monomer -examples,
any.mtl ==2.3.1,
any.murmur3 ==1.0.5, any.murmur3 ==1.0.5,
any.nanovg ==0.8.1.0, any.network ==3.1.4.0,
nanovg -examples -gl2 -gles3 -stb_truetype,
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.6, any.os-string ==2.0.2,
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,
parser-combinators -dev, parser-combinators -dev,
@ -226,18 +188,12 @@ constraints: any.Cabal ==3.10.3.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.19.0, any.process ==1.6.18.0,
any.profunctors ==5.6.2,
any.psqueues ==0.2.8.0,
any.pureMD5 ==2.1.4, any.pureMD5 ==2.1.4,
pureMD5 -test, pureMD5 -test,
any.qrcode-core ==0.9.9,
any.qrcode-juicypixels ==0.8.5,
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.8,
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,
any.regex-posix ==0.96.0.1, any.regex-posix ==0.96.0.1,
@ -247,17 +203,13 @@ constraints: any.Cabal ==3.10.3.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.8.0, any.scientific ==0.3.7.0,
scientific -integer-simple, scientific -bytestring-builder -integer-simple,
any.sdl2 ==2.5.5.0,
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.1, any.semialign ==1.3,
semialign +semigroupoids, semialign +semigroupoids,
any.semigroupoids ==6.0.1, any.semigroupoids ==6.0.0.1,
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers, semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
any.semigroups ==0.20,
semigroups +binary +bytestring -bytestring-builder +containers +deepseq +hashable +tagged +template-haskell +text +transformers +unordered-containers,
any.serialise ==0.2.6.1, any.serialise ==0.2.6.1,
serialise +newtime15, serialise +newtime15,
any.silently ==1.2.5.3, any.silently ==1.2.5.3,
@ -271,53 +223,52 @@ constraints: any.Cabal ==3.10.3.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.1, any.strict ==0.5,
any.string-conversions ==0.4.0.1, any.string-conversions ==0.4.0.1,
any.system-cxx-std-lib ==1.0, any.structured-cli ==2.7.0.1,
structured-cli -debug,
any.tagged ==0.8.8, any.tagged ==0.8.8,
tagged +deepseq +transformers, tagged +deepseq +transformers,
any.template-haskell ==2.20.0.0, any.template-haskell ==2.19.0.0,
any.terminal-size ==0.3.4, any.terminal-size ==0.3.4,
any.terminfo ==0.4.1.6, any.terminfo ==0.4.1.5,
any.text ==2.0.2, any.text ==2.0.2,
any.text-iso8601 ==0.1.1, any.text-iso8601 ==0.1,
any.text-short ==0.1.6, any.text-short ==0.1.5,
text-short -asserts, text-short -asserts,
any.text-show ==3.10.5,
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.7.0.0, any.th-abstraction ==0.6.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.1, any.these ==1.2,
any.time ==1.12.2, any.time ==1.12.2,
any.time-compat ==1.9.7, any.time-compat ==1.9.6.1,
any.time-locale-compat ==0.1.1.5, time-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.6.1.0, any.transformers ==0.5.6.2,
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.8.4.0, any.unix ==2.7.3,
any.unix-compat ==0.7.2, any.unix-compat ==0.7.1,
any.unix-time ==0.4.15, unix-compat -old-time,
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.6, any.uuid-types ==1.0.5.1,
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.2, any.vector-algorithms ==0.9.0.1,
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,
@ -327,10 +278,8 @@ constraints: any.Cabal ==3.10.3.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.5, any.witherable ==0.4.2,
any.word-wrap ==0.5, any.word-wrap ==0.5,
any.wreq ==0.5.4.3, any.zlib ==0.7.0.0,
wreq -aws -developer +doctest -httpbin,
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-07-10T18:40:26Z index-state: hackage.haskell.org 2024-04-07T10:14:52Z

13
configure vendored
View file

@ -1,17 +1,6 @@
#!/bin/bash #!/bin/bash
echo "Configuring Zenith...."
if grep -q "local/share/zcash-haskell" "$HOME/.bashrc"; then
echo "... Paths already exist"
else
# Set Paths
echo "... Adding new zenith paths to local configuration"
echo "export PKG_CONFIG_PATH=$HOME/.local/share/zcash-haskell:\$PKG_CONFIG_PATH" | tee -a ~/.bashrc echo "export PKG_CONFIG_PATH=$HOME/.local/share/zcash-haskell:\$PKG_CONFIG_PATH" | tee -a ~/.bashrc
echo "export LD_LIBRARY_PATH=$HOME/.local/share/zcash-haskell:\$LD_LIBRARY_PATH" | tee -a ~/.bashrc echo "export LD_LIBRARY_PATH=$HOME/.local/share/zcash-haskell:\$LD_LIBRARY_PATH" | tee -a ~/.bashrc
fi
echo "... Reloading paths"
source ~/.bashrc source ~/.bashrc
echo "... building zcash-haskell"
cd zcash-haskell && cabal build cd zcash-haskell && cabal build
echo
echo "Done"
echo

View file

@ -1,5 +0,0 @@
#!/bin/bash
echo "Deploying Zenith executable..."
ln -s ${PWD}/dist-newstyle/build/x86_64-linux/ghc-9.6.5/zenith-0.6.0.0/build/zenith/zenith ~/.local/bin/zenith
echo "Done."

View file

@ -3,6 +3,7 @@
{-# 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
@ -10,10 +11,8 @@ 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
@ -23,11 +22,13 @@ 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
import Brick.Types (Widget) import Brick.Types (Widget)
import Brick.Util (bg, fg, on, style) import Brick.Util (bg, clamp, fg, on, style)
import qualified Brick.Widgets.Border as B import qualified Brick.Widgets.Border as B
import Brick.Widgets.Border.Style (unicode, unicodeBold) import Brick.Widgets.Border.Style (unicode, unicodeBold)
import qualified Brick.Widgets.Center as C import qualified Brick.Widgets.Center as C
@ -42,8 +43,8 @@ import Brick.Widgets.Core
, joinBorders , joinBorders
, padAll , padAll
, padBottom , padBottom
, padLeft
, padTop , padTop
, padLeft
, setAvailableSize , setAvailableSize
, str , str
, strWrap , strWrap
@ -53,8 +54,8 @@ import Brick.Widgets.Core
, txtWrapWith , txtWrapWith
, updateAttrMap , updateAttrMap
, vBox , vBox
, vLimit
, viewport , viewport
, vLimit
, withAttr , withAttr
, withBorderStyle , withBorderStyle
) )
@ -88,29 +89,22 @@ import ZcashHaskell.Keys (generateWalletSeedPhrase, getWalletSeed)
import ZcashHaskell.Orchard (getSaplingFromUA, isValidUnifiedAddress) import ZcashHaskell.Orchard (getSaplingFromUA, isValidUnifiedAddress)
import ZcashHaskell.Sapling (decodeSaplingAddress, isValidShieldedAddress) import ZcashHaskell.Sapling (decodeSaplingAddress, isValidShieldedAddress)
import ZcashHaskell.Transparent import ZcashHaskell.Transparent
( decodeTransparentAddress ( decodeExchangeAddress
, decodeTransparentAddress
, encodeTransparentReceiver , encodeTransparentReceiver
) )
import ZcashHaskell.Types import ZcashHaskell.Types
import ZcashHaskell.Utils (getBlockTime, makeZebraCall) import ZcashHaskell.Utils (getBlockTime, makeZebraCall)
import Zenith.Core import Zenith.Core
import Zenith.DB import Zenith.DB
import Zenith.Scanner (processTx, updateConfs) import Zenith.Scanner (processTx)
import Zenith.Types import Zenith.Types
( Config(..) ( Config(..)
, PhraseDB(..) , PhraseDB(..)
, UnifiedAddressDB(..) , UnifiedAddressDB(..)
, ZcashNetDB(..) , ZcashNetDB(..)
) )
import Zenith.Utils import Zenith.Utils (displayTaz, displayZec, jsonNumber, showAddress)
( displayTaz
, displayZec
, isRecipientValid
, jsonNumber
, parseAddress
, showAddress
, validBarValue
)
data Name data Name
= WList = WList
@ -205,7 +199,6 @@ data State = State
, _abForm :: !(Form AdrBookEntry () Name) , _abForm :: !(Form AdrBookEntry () Name)
, _abCurAdrs :: !T.Text -- used for address book CRUD operations , _abCurAdrs :: !T.Text -- used for address book CRUD operations
, _sentTx :: !(Maybe HexString) , _sentTx :: !(Maybe HexString)
, _unconfBalance :: !Integer
} }
makeLenses ''State makeLenses ''State
@ -226,8 +219,7 @@ 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: " ++
@ -242,16 +234,9 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
if st ^. network == MainNet if st ^. network == MainNet
then displayZec (st ^. balance) then displayZec (st ^. balance)
else displayTaz (st ^. balance))) <=> else displayTaz (st ^. balance))) <=>
C.hCenter
(str
("Unconf: " ++
if st ^. network == MainNet
then displayZec (st ^. unconfBalance)
else displayTaz (st ^. unconfBalance))) <=>
listAddressBox " Addresses " (st ^. addresses) <+> listAddressBox " Addresses " (st ^. addresses) <+>
B.vBorder <+> B.vBorder <+>
(C.hCenter (C.hCenter (str ("Last block seen: " ++ show (st ^. syncBlock) ++ "\n")) <=>
(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
@ -328,8 +313,7 @@ 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 = keyList = map (C.hCenter . str) ["?", "Esc", "w", "a", "v", "s", "b", "q"]
map (C.hCenter . str) ["?", "Esc", "w", "a", "v", "s", "b", "q"]
actionList = actionList =
map map
(hLimit 40 . str) (hLimit 40 . str)
@ -396,24 +380,21 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
viewport ABViewport BT.Vertical $ viewport ABViewport BT.Vertical $
vLimit 20 $ vLimit 20 $
hLimit 50 $ hLimit 50 $
vBox vBox [vLimit 16 $
[ 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 $ vBox $ [C.hCenter $
[ 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" <+> capCommand3 "E" "x" "it") capCommand "S" "end Zcash" <+>
] capCommand3 "E" "x" "it")]])
])
-- Address Book new entry form -- Address Book new entry form
AdrBookForm -> AdrBookForm ->
D.renderDialog D.renderDialog
@ -434,11 +415,9 @@ 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 (hBox [capCommand "C" "onfirm delete", capCommand3 "" "<Esc>" " Cancel"]))
[ 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
@ -450,14 +429,16 @@ 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.6.0.0-beta")) <=> (withAttr titleAttr (str "Zcash Wallet v0.5.3.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 :: 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 = capCommand2 l h e = hBox [str l, withAttr titleAttr (str h), str e, str " | "]
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
@ -584,8 +565,7 @@ 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 = let abentry = T.pack $
T.pack $
" Descr: " ++ " Descr: " ++
T.unpack (addressBookAbdescrip (entityVal a)) ++ T.unpack (addressBookAbdescrip (entityVal a)) ++
"\n Address: " ++ "\n Address: " ++
@ -617,7 +597,7 @@ mkSendForm bal =
] ]
where where
isAmountValid :: Integer -> Float -> Bool isAmountValid :: Integer -> Float -> Bool
isAmountValid b i = (fromIntegral b / 100000000.0) >= i isAmountValid b i = (fromIntegral b * 100000000.0) >= i && i > 0
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
@ -631,6 +611,19 @@ mkNewABForm =
label s w = label s w =
padBottom (Pad 1) $ vLimit 1 (hLimit 10 $ str s <+> fill ' ') <+> w padBottom (Pad 1) $ vLimit 1 (hLimit 10 $ str s <+> fill ' ') <+> w
isRecipientValid :: T.Text -> Bool
isRecipientValid a =
case isValidUnifiedAddress (E.encodeUtf8 a) of
Just _a1 -> True
Nothing ->
isValidShieldedAddress (E.encodeUtf8 a) ||
(case decodeTransparentAddress (E.encodeUtf8 a) of
Just _a3 -> True
Nothing ->
case decodeExchangeAddress a of
Just _a4 -> True
Nothing -> False)
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 =
@ -722,30 +715,24 @@ abSelAttr = A.attrName "abselected"
abMBarAttr :: A.AttrName abMBarAttr :: A.AttrName
abMBarAttr = A.attrName "menubar" abMBarAttr = A.attrName "menubar"
validBarValue :: Float -> Float
validBarValue = clamp 0 1
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
bStatus <- liftIO $ checkBlockChain zHost zPort bStatus <- liftIO $ checkBlockChain zHost zPort
pool <- runNoLoggingT $ initPool dbP pool <- runNoLoggingT $ initPool dbP
dbBlock <- runNoLoggingT $ getMaxBlock pool dbBlock <- runNoLoggingT $ getMaxBlock pool
confUp <- try $ updateConfs zHost zPort pool :: IO (Either IOError ())
case confUp of
Left _e0 ->
liftIO $
BC.writeBChan eChan $ TickMsg "Failed to update unconfirmed transactions"
Right _ -> do
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 do then liftIO $ BC.writeBChan eChan $ TickMsg "Invalid starting block for scan"
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)
then do then do
let step = let step =
(1.0 :: Float) / (1.0 :: Float) / fromIntegral (zgb_blocks bStatus - (sb + 1))
fromIntegral (zgb_blocks bStatus - (sb + 1))
mapM_ (processBlock pool step) bList mapM_ (processBlock pool step) bList
else liftIO $ BC.writeBChan eChan $ TickVal 1.0 else liftIO $ BC.writeBChan eChan $ TickVal 1.0
where where
@ -1085,8 +1072,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 -> 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
BT.modify $ BT.modify $
@ -1097,9 +1083,8 @@ 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') [] V.EvKey (V.KChar 'c') [] -> do
-- 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 $
@ -1111,8 +1096,7 @@ 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 $ BT.modify $ set msg "Error while copying the address!!"
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
@ -1120,31 +1104,19 @@ appEvent (BT.VtyEvent e) = do
Just (_, a) -> do Just (_, a) -> do
BT.modify $ BT.modify $
set txForm $ set txForm $
mkSendForm mkSendForm (s ^. balance) (SendInput (addressBookAbaddress (entityVal a)) 0.0 "")
(s ^. balance)
(SendInput
(addressBookAbaddress (entityVal a))
0.0
"")
BT.modify $ set dialogBox SendTx BT.modify $ set dialogBox SendTx
_ -> do _ -> do
BT.modify $ BT.modify $ set msg "No receiver address available!!"
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 $ BT.modify $ set abCurAdrs (addressBookAbaddress (entityVal a))
set
abCurAdrs
(addressBookAbaddress (entityVal a))
BT.modify $ BT.modify $
set abForm $ set abForm $
mkNewABForm mkNewABForm (AdrBookEntry (addressBookAbdescrip (entityVal a)) (addressBookAbaddress (entityVal a)))
(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
@ -1152,27 +1124,21 @@ 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 $ BT.modify $ set abCurAdrs (addressBookAbaddress (entityVal a))
set
abCurAdrs
(addressBookAbaddress (entityVal a))
BT.modify $ BT.modify $
set abForm $ set abForm $
mkNewABForm mkNewABForm (AdrBookEntry (addressBookAbdescrip (entityVal a)) (addressBookAbaddress (entityVal a)))
(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 $ BT.modify $ set abForm $ mkNewABForm (AdrBookEntry "" "")
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
@ -1186,27 +1152,13 @@ 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 <- res <- liftIO $ saveAdrsInAdrBook pool $ AddressBook (ZcashNetDB (s ^. network)) (fs ^. descrip) (fs ^.address)
liftIO $
saveAdrsInAdrBook pool $
AddressBook
(ZcashNetDB (s ^. network))
(fs ^. descrip)
(fs ^. address)
case res of case res of
Nothing -> do Nothing -> do
BT.modify $ BT.modify $ set msg ("AddressBook Entry already exists: " ++ T.unpack (fs ^.address))
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 $ BT.modify $ set msg ("New AddressBook entry created!!\n" ++ T.unpack (fs ^.address))
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
@ -1216,8 +1168,7 @@ 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 -> ev -> BT.zoom abForm $ do
BT.zoom abForm $ do
handleFormEvent (BT.VtyEvent ev) handleFormEvent (BT.VtyEvent ev)
fs <- BT.gets formState fs <- BT.gets formState
BT.modify $ BT.modify $
@ -1234,18 +1185,8 @@ 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 <- res <- liftIO $ updateAdrsInAdrBook pool (fs ^. descrip) (fs ^.address) (s ^. abCurAdrs)
liftIO $ BT.modify $ set msg ("AddressBook entry modified!!\n" ++ T.unpack (fs ^.address))
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
@ -1255,8 +1196,7 @@ 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 -> ev -> BT.zoom abForm $ do
BT.zoom abForm $ do
handleFormEvent (BT.VtyEvent ev) handleFormEvent (BT.VtyEvent ev)
fs <- BT.gets formState fs <- BT.gets formState
BT.modify $ BT.modify $
@ -1381,15 +1321,13 @@ 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
else return 0 else return 0
uBal <-
if not (null accList)
then getUnconfirmedBalance pool $ entityKey $ head accList
else return 0
eventChan <- BC.newBChan 10 eventChan <- BC.newBChan 10
_ <- _ <-
forkIO $ forkIO $
@ -1430,7 +1368,6 @@ runZenithTUI config = do
(mkNewABForm (AdrBookEntry "" "")) (mkNewABForm (AdrBookEntry "" ""))
"" ""
Nothing Nothing
uBal
Left e -> do Left e -> do
print $ print $
"No Zebra node available on port " <> "No Zebra node available on port " <>
@ -1459,10 +1396,6 @@ refreshWallet s = do
if not (null aL) if not (null aL)
then getBalance pool $ entityKey $ head aL then getBalance pool $ entityKey $ head aL
else return 0 else return 0
uBal <-
if not (null aL)
then getUnconfirmedBalance pool $ entityKey $ head aL
else return 0
txL <- txL <-
if not (null addrL) if not (null addrL)
then getUserTx pool $ entityKey $ head addrL then getUserTx pool $ entityKey $ head addrL
@ -1473,8 +1406,6 @@ refreshWallet s = do
let txL' = L.listReplace (Vec.fromList txL) (Just 0) (s ^. transactions) let txL' = L.listReplace (Vec.fromList txL) (Just 0) (s ^. transactions)
return $ return $
s & wallets .~ wL & accounts .~ aL' & syncBlock .~ bl & balance .~ bal & s & wallets .~ wL & accounts .~ aL' & syncBlock .~ bl & balance .~ bal &
unconfBalance .~
uBal &
addresses .~ addresses .~
addrL' & addrL' &
transactions .~ transactions .~
@ -1520,7 +1451,8 @@ 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 -> return $ s & msg .~ "Account already exists: " ++ T.unpack n Nothing ->
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 =
@ -1543,7 +1475,6 @@ refreshAccount s = do
Just (_k, w) -> return w Just (_k, w) -> return w
aL <- runNoLoggingT $ getAddresses pool $ entityKey selAccount aL <- runNoLoggingT $ getAddresses pool $ entityKey selAccount
bal <- getBalance pool $ entityKey selAccount bal <- getBalance pool $ entityKey selAccount
uBal <- getUnconfirmedBalance pool $ entityKey selAccount
let aL' = L.listReplace (Vec.fromList aL) (Just 0) (s ^. addresses) let aL' = L.listReplace (Vec.fromList aL) (Just 0) (s ^. addresses)
selAddress <- selAddress <-
do case L.listSelectedElement aL' of do case L.listSelectedElement aL' of
@ -1554,17 +1485,13 @@ refreshAccount s = do
case selAddress of case selAddress of
Nothing -> Nothing ->
return $ return $
s & balance .~ bal & unconfBalance .~ uBal & addresses .~ aL' & msg .~ s & balance .~ bal & addresses .~ aL' & msg .~ "Switched to account: " ++
"Switched to account: " ++
T.unpack (zcashAccountName $ entityVal selAccount) T.unpack (zcashAccountName $ entityVal selAccount)
Just (_i, a) -> do Just (_i, a) -> do
tList <- getUserTx pool $ entityKey a tList <- getUserTx pool $ entityKey a
let tL' = L.listReplace (Vec.fromList tList) (Just 0) (s ^. transactions) let tL' = L.listReplace (Vec.fromList tList) (Just 0) (s ^. transactions)
return $ return $
s & balance .~ bal & unconfBalance .~ uBal & addresses .~ aL' & s & balance .~ bal & addresses .~ aL' & transactions .~ tL' & msg .~
transactions .~
tL' &
msg .~
"Switched to account: " ++ "Switched to account: " ++
T.unpack (zcashAccountName $ entityVal selAccount) T.unpack (zcashAccountName $ entityVal selAccount)
@ -1592,8 +1519,7 @@ 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.listSelectedElement $ L.listMoveToBeginning $ s ^. abAddresses
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)
@ -1621,7 +1547,8 @@ 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 -> return $ s & msg .~ "Address already exists: " ++ T.unpack n Nothing ->
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 =
@ -1647,9 +1574,7 @@ sendTransaction ::
-> IO () -> IO ()
sendTransaction pool chan zHost zPort znet accId bl amt ua memo = do sendTransaction pool chan zHost zPort znet accId bl amt ua memo = do
BC.writeBChan chan $ TickMsg "Preparing transaction..." BC.writeBChan chan $ TickMsg "Preparing transaction..."
case parseAddress ua znet of outUA <- parseAddress ua
Nothing -> BC.writeBChan chan $ TickMsg "Incorrect address"
Just outUA -> do
res <- res <-
runFileLoggingT "zenith.log" $ runFileLoggingT "zenith.log" $
prepareTx pool zHost zPort znet accId bl amt outUA memo prepareTx pool zHost zPort znet accId bl amt outUA memo
@ -1666,3 +1591,19 @@ sendTransaction pool chan zHost zPort znet accId bl amt ua memo = do
case resp of case resp of
Left e1 -> BC.writeBChan chan $ TickMsg $ "Zebra error: " ++ show e1 Left e1 -> BC.writeBChan chan $ TickMsg $ "Zebra error: " ++ show e1
Right txId -> BC.writeBChan chan $ TickTx txId Right txId -> BC.writeBChan chan $ TickTx txId
where
parseAddress :: T.Text -> IO UnifiedAddress
parseAddress a =
case isValidUnifiedAddress (E.encodeUtf8 a) of
Just a1 -> return a1
Nothing ->
case decodeSaplingAddress (E.encodeUtf8 a) of
Just a2 ->
return $
UnifiedAddress znet Nothing (Just $ sa_receiver a2) Nothing
Nothing ->
case decodeTransparentAddress (E.encodeUtf8 a) of
Just a3 ->
return $
UnifiedAddress znet Nothing Nothing (Just $ ta_receiver a3)
Nothing -> throwIO $ userError "Incorrect address"

View file

@ -32,6 +32,7 @@ import qualified Data.Text as T
import qualified Data.Text.Encoding as TE import qualified Data.Text.Encoding as TE
import Data.Word import Data.Word
import Database.Esqueleto.Experimental import Database.Esqueleto.Experimental
import qualified Database.Persist as P
import qualified Database.Persist.Sqlite as PS import qualified Database.Persist.Sqlite as PS
import Database.Persist.TH import Database.Persist.TH
import Haskoin.Transaction.Common import Haskoin.Transaction.Common
@ -42,6 +43,7 @@ import Haskoin.Transaction.Common
) )
import qualified Lens.Micro as ML ((&), (.~), (^.)) import qualified Lens.Micro as ML ((&), (.~), (^.))
import ZcashHaskell.Orchard (isValidUnifiedAddress) import ZcashHaskell.Orchard (isValidUnifiedAddress)
import ZcashHaskell.Sapling (decodeSaplingOutputEsk)
import ZcashHaskell.Types import ZcashHaskell.Types
( DecodedNote(..) ( DecodedNote(..)
, OrchardAction(..) , OrchardAction(..)
@ -75,7 +77,6 @@ import Zenith.Types
, TransparentSpendingKeyDB , TransparentSpendingKeyDB
, UnifiedAddressDB(..) , UnifiedAddressDB(..)
, ZcashNetDB(..) , ZcashNetDB(..)
, ZcashPool(..)
) )
share share
@ -245,15 +246,6 @@ share
position Int position Int
UniqueSSPos tx position UniqueSSPos tx position
deriving Show Eq deriving Show Eq
QrCode
address WalletAddressId OnDeleteCascade OnUpdateCascade
version ZcashPool
bytes BS.ByteString
height Int
width Int
name T.Text
UniqueQr address version
deriving Show Eq
AddressBook AddressBook
network ZcashNetDB network ZcashNetDB
abdescrip T.Text abdescrip T.Text
@ -430,16 +422,6 @@ getWalletAddresses pool w = do
addrs <- mapM (getAddresses pool . entityKey) accs addrs <- mapM (getAddresses pool . entityKey) accs
return $ concat addrs return $ concat addrs
getExternalAddresses :: ConnectionPool -> IO [Entity WalletAddress]
getExternalAddresses pool = do
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
select $ do
addrs <- from $ table @WalletAddress
where_ $ addrs ^. WalletAddressScope ==. val (ScopeDB External)
return addrs
-- | Returns the largest address index for the given account -- | Returns the largest address index for the given account
getMaxAddress :: getMaxAddress ::
ConnectionPool -- ^ The database path ConnectionPool -- ^ The database path
@ -572,41 +554,6 @@ getZcashTransactions pool b =
orderBy [asc $ txs ^. ZcashTransactionBlock] orderBy [asc $ txs ^. ZcashTransactionBlock]
return txs return txs
-- ** QR codes
-- | Functions to manage the QR codes stored in the database
saveQrCode ::
ConnectionPool -- ^ the connection pool
-> QrCode
-> NoLoggingT IO (Maybe (Entity QrCode))
saveQrCode pool qr =
PS.retryOnBusy $ flip PS.runSqlPool pool $ insertUniqueEntity qr
getQrCodes ::
ConnectionPool -- ^ the connection pool
-> WalletAddressId
-> IO [Entity QrCode]
getQrCodes pool wId =
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
select $ do
qrs <- from $ table @QrCode
where_ $ qrs ^. QrCodeAddress ==. val wId
return qrs
getQrCode :: ConnectionPool -> ZcashPool -> WalletAddressId -> IO (Maybe QrCode)
getQrCode pool zp wId = do
r <-
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
selectOne $ do
qrs <- from $ table @QrCode
where_ $ qrs ^. QrCodeAddress ==. val wId
where_ $ qrs ^. QrCodeVersion ==. val zp
return qrs
return $ entityVal <$> r
-- * Wallet -- * Wallet
-- | Get the block of the last transaction known to the wallet -- | Get the block of the last transaction known to the wallet
getMaxWalletBlock :: getMaxWalletBlock ::
@ -1396,35 +1343,6 @@ getBalance pool za = do
let oBal = sum oAmts let oBal = sum oAmts
return . fromIntegral $ tBal + sBal + oBal return . fromIntegral $ tBal + sBal + oBal
getTransparentBalance :: ConnectionPool -> ZcashAccountId -> IO Integer
getTransparentBalance pool za = do
trNotes <- getWalletUnspentTrNotes pool za
let tAmts = map (walletTrNoteValue . entityVal) trNotes
return . fromIntegral $ sum tAmts
getShieldedBalance :: ConnectionPool -> ZcashAccountId -> IO Integer
getShieldedBalance pool za = do
sapNotes <- getWalletUnspentSapNotes pool za
let sAmts = map (walletSapNoteValue . entityVal) sapNotes
let sBal = sum sAmts
orchNotes <- getWalletUnspentOrchNotes pool za
let oAmts = map (walletOrchNoteValue . entityVal) orchNotes
let oBal = sum oAmts
return . fromIntegral $ sBal + oBal
getUnconfirmedBalance :: ConnectionPool -> ZcashAccountId -> IO Integer
getUnconfirmedBalance pool za = do
trNotes <- getWalletUnspentUnconfirmedTrNotes pool za
let tAmts = map (walletTrNoteValue . entityVal) trNotes
let tBal = sum tAmts
sapNotes <- getWalletUnspentUnconfirmedSapNotes pool za
let sAmts = map (walletSapNoteValue . entityVal) sapNotes
let sBal = sum sAmts
orchNotes <- getWalletUnspentUnconfirmedOrchNotes pool za
let oAmts = map (walletOrchNoteValue . entityVal) orchNotes
let oBal = sum oAmts
return . fromIntegral $ tBal + sBal + oBal
clearWalletTransactions :: ConnectionPool -> IO () clearWalletTransactions :: ConnectionPool -> IO ()
clearWalletTransactions pool = do clearWalletTransactions pool = do
runNoLoggingT $ runNoLoggingT $
@ -1462,42 +1380,10 @@ getWalletUnspentTrNotes pool za = do
PS.retryOnBusy $ PS.retryOnBusy $
flip PS.runSqlPool pool $ do flip PS.runSqlPool pool $ do
select $ do select $ do
(txs :& tNotes) <- n <- from $ table @WalletTrNote
from $ table @WalletTransaction `innerJoin` table @WalletTrNote `on` where_ (n ^. WalletTrNoteAccId ==. val za)
(\(txs :& tNotes) -> where_ (n ^. WalletTrNoteSpent ==. val False)
txs ^. WalletTransactionId ==. tNotes ^. WalletTrNoteTx) pure n
where_ (tNotes ^. WalletTrNoteAccId ==. val za)
where_ (tNotes ^. WalletTrNoteSpent ==. val False)
where_
((tNotes ^. WalletTrNoteChange ==. val True &&. txs ^.
WalletTransactionConf >=.
val 3) ||.
(tNotes ^. WalletTrNoteChange ==. val False &&. txs ^.
WalletTransactionConf >=.
val 10))
pure tNotes
getWalletUnspentUnconfirmedTrNotes ::
ConnectionPool -> ZcashAccountId -> IO [Entity WalletTrNote]
getWalletUnspentUnconfirmedTrNotes pool za = do
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
select $ do
(txs :& tNotes) <-
from $ table @WalletTransaction `innerJoin` table @WalletTrNote `on`
(\(txs :& tNotes) ->
txs ^. WalletTransactionId ==. tNotes ^. WalletTrNoteTx)
where_ (tNotes ^. WalletTrNoteAccId ==. val za)
where_ (tNotes ^. WalletTrNoteSpent ==. val False)
where_
((tNotes ^. WalletTrNoteChange ==. val True &&. txs ^.
WalletTransactionConf <.
val 3) ||.
(tNotes ^. WalletTrNoteChange ==. val False &&. txs ^.
WalletTransactionConf <.
val 10))
pure tNotes
getWalletUnspentSapNotes :: getWalletUnspentSapNotes ::
ConnectionPool -> ZcashAccountId -> IO [Entity WalletSapNote] ConnectionPool -> ZcashAccountId -> IO [Entity WalletSapNote]
@ -1506,42 +1392,10 @@ getWalletUnspentSapNotes pool za = do
PS.retryOnBusy $ PS.retryOnBusy $
flip PS.runSqlPool pool $ do flip PS.runSqlPool pool $ do
select $ do select $ do
(txs :& sNotes) <- n1 <- from $ table @WalletSapNote
from $ table @WalletTransaction `innerJoin` table @WalletSapNote `on` where_ (n1 ^. WalletSapNoteAccId ==. val za)
(\(txs :& sNotes) -> where_ (n1 ^. WalletSapNoteSpent ==. val False)
txs ^. WalletTransactionId ==. sNotes ^. WalletSapNoteTx) pure n1
where_ (sNotes ^. WalletSapNoteAccId ==. val za)
where_ (sNotes ^. WalletSapNoteSpent ==. val False)
where_
((sNotes ^. WalletSapNoteChange ==. val True &&. txs ^.
WalletTransactionConf >=.
val 3) ||.
(sNotes ^. WalletSapNoteChange ==. val False &&. txs ^.
WalletTransactionConf >=.
val 10))
pure sNotes
getWalletUnspentUnconfirmedSapNotes ::
ConnectionPool -> ZcashAccountId -> IO [Entity WalletSapNote]
getWalletUnspentUnconfirmedSapNotes pool za = do
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
select $ do
(txs :& sNotes) <-
from $ table @WalletTransaction `innerJoin` table @WalletSapNote `on`
(\(txs :& sNotes) ->
txs ^. WalletTransactionId ==. sNotes ^. WalletSapNoteTx)
where_ (sNotes ^. WalletSapNoteAccId ==. val za)
where_ (sNotes ^. WalletSapNoteSpent ==. val False)
where_
((sNotes ^. WalletSapNoteChange ==. val True &&. txs ^.
WalletTransactionConf <.
val 3) ||.
(sNotes ^. WalletSapNoteChange ==. val False &&. txs ^.
WalletTransactionConf <.
val 10))
pure sNotes
getWalletUnspentOrchNotes :: getWalletUnspentOrchNotes ::
ConnectionPool -> ZcashAccountId -> IO [Entity WalletOrchNote] ConnectionPool -> ZcashAccountId -> IO [Entity WalletOrchNote]
@ -1550,42 +1404,10 @@ getWalletUnspentOrchNotes pool za = do
PS.retryOnBusy $ PS.retryOnBusy $
flip PS.runSqlPool pool $ do flip PS.runSqlPool pool $ do
select $ do select $ do
(txs :& oNotes) <- n2 <- from $ table @WalletOrchNote
from $ table @WalletTransaction `innerJoin` table @WalletOrchNote `on` where_ (n2 ^. WalletOrchNoteAccId ==. val za)
(\(txs :& oNotes) -> where_ (n2 ^. WalletOrchNoteSpent ==. val False)
txs ^. WalletTransactionId ==. oNotes ^. WalletOrchNoteTx) pure n2
where_ (oNotes ^. WalletOrchNoteAccId ==. val za)
where_ (oNotes ^. WalletOrchNoteSpent ==. val False)
where_
((oNotes ^. WalletOrchNoteChange ==. val True &&. txs ^.
WalletTransactionConf >=.
val 3) ||.
(oNotes ^. WalletOrchNoteChange ==. val False &&. txs ^.
WalletTransactionConf >=.
val 10))
pure oNotes
getWalletUnspentUnconfirmedOrchNotes ::
ConnectionPool -> ZcashAccountId -> IO [Entity WalletOrchNote]
getWalletUnspentUnconfirmedOrchNotes pool za = do
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
select $ do
(txs :& oNotes) <-
from $ table @WalletTransaction `innerJoin` table @WalletOrchNote `on`
(\(txs :& oNotes) ->
txs ^. WalletTransactionId ==. oNotes ^. WalletOrchNoteTx)
where_ (oNotes ^. WalletOrchNoteAccId ==. val za)
where_ (oNotes ^. WalletOrchNoteSpent ==. val False)
where_
((oNotes ^. WalletOrchNoteChange ==. val True &&. txs ^.
WalletTransactionConf <.
val 3) ||.
(oNotes ^. WalletOrchNoteChange ==. val False &&. txs ^.
WalletTransactionConf <.
val 10))
pure oNotes
selectUnspentNotes :: selectUnspentNotes ::
ConnectionPool ConnectionPool
@ -1646,27 +1468,6 @@ getWalletTxId pool wId = do
where_ (wtx ^. WalletTransactionId ==. val wId) where_ (wtx ^. WalletTransactionId ==. val wId)
pure $ wtx ^. WalletTransactionTxId pure $ wtx ^. WalletTransactionTxId
getUnconfirmedBlocks :: ConnectionPool -> IO [Int]
getUnconfirmedBlocks pool = do
r <-
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
select $ do
wtx <- from $ table @WalletTransaction
where_ (wtx ^. WalletTransactionConf <=. val 10)
pure $ wtx ^. WalletTransactionBlock
return $ map (\(Value i) -> i) r
saveConfs :: ConnectionPool -> Int -> Int -> IO ()
saveConfs pool b c = do
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
update $ \t -> do
set t [WalletTransactionConf =. val c]
where_ $ t ^. WalletTransactionBlock ==. val b
-- | Helper function to extract a Unified Address from the database -- | Helper function to extract a Unified Address from the database
readUnifiedAddressDB :: WalletAddress -> Maybe UnifiedAddress readUnifiedAddressDB :: WalletAddress -> Maybe UnifiedAddress
readUnifiedAddressDB = readUnifiedAddressDB =
@ -1712,6 +1513,7 @@ updateAdrsInAdrBook pool d a ia = do
-- adrbook <- from $ table @AddressBook -- adrbook <- from $ table @AddressBook
-- where_ ((adrbook ^. AddressBookAbaddress) ==. val a) -- where_ ((adrbook ^. AddressBookAbaddress) ==. val a)
-- return adrbook -- return adrbook
-- | delete an existing address from AddressBook -- | delete an existing address from AddressBook
deleteAdrsFromAB :: ConnectionPool -> T.Text -> IO () deleteAdrsFromAB :: ConnectionPool -> T.Text -> IO ()
deleteAdrsFromAB pool ia = do deleteAdrsFromAB pool ia = do

File diff suppressed because it is too large Load diff

View file

@ -1,340 +0,0 @@
{-# LANGUAGE OverloadedStrings #-}
module Zenith.GUI.Theme
( zenithTheme
) where
import Data.Default
import Lens.Micro ((&), (+~), (.~), (?~), (^.), at, set)
import Monomer
import Monomer.Core.Themes.BaseTheme
import Monomer.Core.Themes.SampleThemes
import Monomer.Graphics (rgbHex, transparent)
import Monomer.Graphics.ColorTable
import qualified Monomer.Lens as L
baseTextStyle :: TextStyle
baseTextStyle = def & L.fontSize ?~ FontSize 10 & L.fontColor ?~ black
hiliteTextStyle :: TextStyle
hiliteTextStyle = def & L.fontSize ?~ FontSize 10 & L.fontColor ?~ white
zenithTheme :: Theme
zenithTheme =
baseTheme zgoThemeColors & L.basic . L.labelStyle . L.text ?~ baseTextStyle &
L.hover .
L.tooltipStyle . L.text ?~
baseTextStyle &
L.hover .
L.labelStyle . L.text ?~
baseTextStyle &
L.basic .
L.dialogTitleStyle . L.text ?~
(baseTextStyle & L.fontSize ?~ FontSize 12 & L.font ?~ "Bold") &
L.hover .
L.dialogTitleStyle . L.text ?~
(baseTextStyle & L.fontSize ?~ FontSize 12 & L.font ?~ "Bold") &
L.basic .
L.btnStyle . L.text ?~
baseTextStyle &
L.hover .
L.btnStyle . L.text ?~
baseTextStyle &
L.focus .
L.btnStyle . L.text ?~
baseTextStyle &
L.focusHover .
L.btnStyle . L.text ?~
baseTextStyle &
L.active .
L.btnStyle . L.text ?~
baseTextStyle &
L.basic .
L.btnMainStyle . L.text ?~
hiliteTextStyle &
L.hover .
L.btnMainStyle . L.text ?~
hiliteTextStyle &
L.focus .
L.btnMainStyle . L.text ?~
hiliteTextStyle &
L.focusHover .
L.btnMainStyle . L.text ?~
hiliteTextStyle &
L.active .
L.btnMainStyle . L.text ?~
hiliteTextStyle &
L.disabled .
L.btnMainStyle . L.text ?~
hiliteTextStyle &
L.disabled .
L.btnMainStyle . L.bgColor ?~
gray07c &
L.basic .
L.textFieldStyle . L.text ?~
baseTextStyle &
L.hover .
L.textFieldStyle . L.text ?~
baseTextStyle &
L.focus .
L.textFieldStyle . L.text ?~
baseTextStyle &
L.active .
L.textFieldStyle . L.text ?~
baseTextStyle &
L.focusHover .
L.textFieldStyle . L.text ?~
baseTextStyle &
L.basic .
L.numericFieldStyle . L.text ?~
baseTextStyle &
L.hover .
L.numericFieldStyle . L.text ?~
baseTextStyle &
L.focus .
L.numericFieldStyle . L.text ?~
baseTextStyle &
L.active .
L.numericFieldStyle . L.text ?~
baseTextStyle &
L.focusHover .
L.numericFieldStyle . L.text ?~
baseTextStyle &
L.basic .
L.textAreaStyle . L.text ?~
baseTextStyle &
L.hover .
L.textAreaStyle . L.text ?~
baseTextStyle &
L.focus .
L.textAreaStyle . L.text ?~
baseTextStyle &
L.active .
L.textAreaStyle . L.text ?~
baseTextStyle &
L.focusHover .
L.textAreaStyle . L.text ?~
baseTextStyle
zenithThemeColors :: BaseThemeColors
zenithThemeColors =
BaseThemeColors
{ clearColor = gray01
, sectionColor = gray01
, btnFocusBorder = blue09
, btnBgBasic = gray07b
, btnBgHover = gray08
, btnBgFocus = gray07c
, btnBgActive = gray06
, btnBgDisabled = gray05
, btnText = gray02
, btnTextDisabled = gray01
, btnMainFocusBorder = blue08
, btnMainBgBasic = btnColor
, btnMainBgHover = btnHiLite
, btnMainBgFocus = btnColor
, btnMainBgActive = btnHiLite
, btnMainBgDisabled = blue04
, btnMainText = white
, btnMainTextDisabled = gray08
, dialogBg = gray01
, dialogBorder = gray01
, dialogText = white
, dialogTitleText = white
, emptyOverlay = gray05 & L.a .~ 0.8
, shadow = gray00 & L.a .~ 0.33
, externalLinkBasic = blue07
, externalLinkHover = blue08
, externalLinkFocus = blue07
, externalLinkActive = blue06
, externalLinkDisabled = gray06
, iconBg = gray08
, iconFg = gray01
, inputIconFg = black
, inputBorder = gray02
, inputFocusBorder = blue08
, inputBgBasic = gray04
, inputBgHover = gray06
, inputBgFocus = gray05
, inputBgActive = gray03
, inputBgDisabled = gray07
, inputFgBasic = gray06
, inputFgHover = blue08
, inputFgFocus = blue08
, inputFgActive = blue07
, inputFgDisabled = gray07
, inputSndBasic = gray05
, inputSndHover = gray06
, inputSndFocus = gray05
, inputSndActive = gray05
, inputSndDisabled = gray03
, inputHlBasic = gray07
, inputHlHover = blue08
, inputHlFocus = blue08
, inputHlActive = blue08
, inputHlDisabled = gray08
, inputSelBasic = gray06
, inputSelFocus = blue06
, inputText = white
, inputTextDisabled = gray02
, labelText = white
, scrollBarBasic = gray01 & L.a .~ 0.2
, scrollThumbBasic = gray07 & L.a .~ 0.6
, scrollBarHover = gray01 & L.a .~ 0.4
, scrollThumbHover = gray07 & L.a .~ 0.8
, slMainBg = gray00
, slNormalBgBasic = transparent
, slNormalBgHover = gray05
, slNormalText = white
, slNormalFocusBorder = blue08
, slSelectedBgBasic = gray04
, slSelectedBgHover = gray05
, slSelectedText = white
, slSelectedFocusBorder = blue08
, tooltipBorder = gray05
, tooltipBg = rgbHex "#1D212B"
, tooltipText = white
}
zgoThemeColors =
BaseThemeColors
{ clearColor = gray10 -- gray12,
, sectionColor = gray09 -- gray11,
, btnFocusBorder = blue08
, btnBgBasic = gray07
, btnBgHover = gray07c
, btnBgFocus = gray07b
, btnBgActive = gray06
, btnBgDisabled = gray05
, btnText = gray02
, btnTextDisabled = gray02
, btnMainFocusBorder = blue09
, btnMainBgBasic = btnColor
, btnMainBgHover = btnHiLite
, btnMainBgFocus = btnColor
, btnMainBgActive = btnHiLite
, btnMainBgDisabled = blue04
, btnMainText = white
, btnMainTextDisabled = white
, dialogBg = white
, dialogBorder = white
, dialogText = black
, dialogTitleText = black
, emptyOverlay = gray07 & L.a .~ 0.8
, shadow = gray00 & L.a .~ 0.2
, externalLinkBasic = blue07
, externalLinkHover = blue08
, externalLinkFocus = blue07
, externalLinkActive = blue06
, externalLinkDisabled = gray06
, iconBg = gray07
, iconFg = gray01
, inputIconFg = black
, inputBorder = gray06
, inputFocusBorder = blue07
, inputBgBasic = gray10
, inputBgHover = white
, inputBgFocus = white
, inputBgActive = gray09
, inputBgDisabled = gray05
, inputFgBasic = gray05
, inputFgHover = blue07
, inputFgFocus = blue07
, inputFgActive = blue06
, inputFgDisabled = gray04
, inputSndBasic = gray04
, inputSndHover = gray05
, inputSndFocus = gray05
, inputSndActive = gray04
, inputSndDisabled = gray03
, inputHlBasic = gray06
, inputHlHover = blue07
, inputHlFocus = blue07
, inputHlActive = blue06
, inputHlDisabled = gray05
, inputSelBasic = gray07
, inputSelFocus = blue08
, inputText = black
, inputTextDisabled = gray02
, labelText = black
, scrollBarBasic = gray03 & L.a .~ 0.2
, scrollThumbBasic = gray01 & L.a .~ 0.2
, scrollBarHover = gray07 & L.a .~ 0.8
, scrollThumbHover = gray05 & L.a .~ 0.8
, slMainBg = white
, slNormalBgBasic = transparent
, slNormalBgHover = gray09
, slNormalText = black
, slNormalFocusBorder = blue07
, slSelectedBgBasic = gray08
, slSelectedBgHover = gray09
, slSelectedText = black
, slSelectedFocusBorder = blue07
, tooltipBorder = gray08
, tooltipBg = gray07
, tooltipText = black
}
--black = rgbHex "#000000"
{-white = rgbHex "#FFFFFF"-}
btnColor = rgbHex "#ff5722" --rgbHex "#1818B2"
btnHiLite = rgbHex "#207DE8"
blue01 = rgbHex "#002159"
blue02 = rgbHex "#01337D"
blue03 = rgbHex "#03449E"
blue04 = rgbHex "#0552B5"
blue05 = rgbHex "#0967D2"
blue05b = rgbHex "#0F6BD7"
blue05c = rgbHex "#1673DE"
blue06 = rgbHex "#2186EB"
blue06b = rgbHex "#2489EE"
blue06c = rgbHex "#2B8FF6"
blue07 = rgbHex "#47A3F3"
blue07b = rgbHex "#50A6F6"
blue07c = rgbHex "#57ACFC"
blue08 = rgbHex "#7CC4FA"
blue09 = rgbHex "#BAE3FF"
blue10 = rgbHex "#E6F6FF"
gray00 = rgbHex "#111111"
gray01 = rgbHex "#2E2E2E"
gray02 = rgbHex "#393939"
gray03 = rgbHex "#515151"
gray04 = rgbHex "#626262"
gray05 = rgbHex "#7E7E7E"
gray06 = rgbHex "#9E9E9E"
gray07 = rgbHex "#B1B1B1"
gray07b = rgbHex "#B4B4B4"
gray07c = rgbHex "#BBBBBB"
gray08 = rgbHex "#CFCFCF"
gray09 = rgbHex "#E1E1E1"
gray10 = rgbHex "#F7F7F7"

View file

@ -33,13 +33,7 @@ import ZcashHaskell.Types
) )
import ZcashHaskell.Utils (getBlockTime, makeZebraCall, readZebraTransaction) import ZcashHaskell.Utils (getBlockTime, makeZebraCall, readZebraTransaction)
import Zenith.Core (checkBlockChain) import Zenith.Core (checkBlockChain)
import Zenith.DB import Zenith.DB (getMaxBlock, initDb, saveTransaction)
( getMaxBlock
, getUnconfirmedBlocks
, initDb
, saveConfs
, saveTransaction
)
import Zenith.Utils (jsonNumber) import Zenith.Utils (jsonNumber)
-- | Function to scan the Zcash blockchain through the Zebra node and populate the Zenith database -- | Function to scan the Zcash blockchain through the Zebra node and populate the Zenith database
@ -161,26 +155,3 @@ processTx host port bt pool t = do
(fromRawSBundle $ zt_sBundle rzt) (fromRawSBundle $ zt_sBundle rzt)
(fromRawOBundle $ zt_oBundle rzt) (fromRawOBundle $ zt_oBundle rzt)
return () return ()
-- | Function to update unconfirmed transactions
updateConfs ::
T.Text -- ^ Host name for `zebrad`
-> Int -- ^ Port for `zebrad`
-> ConnectionPool
-> IO ()
updateConfs host port pool = do
targetBlocks <- getUnconfirmedBlocks pool
mapM_ updateTx targetBlocks
where
updateTx :: Int -> IO ()
updateTx b = do
r <-
makeZebraCall
host
port
"getblock"
[Data.Aeson.String $ T.pack $ show b, jsonNumber 1]
case r of
Left e -> throwIO $ userError e
Right blk -> do
saveConfs pool b $ fromInteger $ bl_confirmations blk

View file

@ -143,9 +143,7 @@ data ZcashPool
| Sprout | Sprout
| Sapling | Sapling
| Orchard | Orchard
deriving (Show, Read, Eq, Generic, ToJSON) deriving (Show, Eq, Generic, ToJSON)
derivePersistField "ZcashPool"
instance FromJSON ZcashPool where instance FromJSON ZcashPool where
parseJSON = parseJSON =

View file

@ -5,24 +5,13 @@ module Zenith.Utils where
import Data.Aeson import Data.Aeson
import Data.Functor (void) import Data.Functor (void)
import Data.Maybe import Data.Maybe
import Data.Ord (clamp)
import Data.Scientific (Scientific(..), scientific) import Data.Scientific (Scientific(..), scientific)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as E import qualified Data.Text.Encoding as E
import System.Process (createProcess_, shell) import System.Process (createProcess_, shell)
import Text.Regex.Posix import Text.Regex.Posix
import ZcashHaskell.Orchard (encodeUnifiedAddress, isValidUnifiedAddress) import ZcashHaskell.Orchard (encodeUnifiedAddress, isValidUnifiedAddress)
import ZcashHaskell.Sapling (decodeSaplingAddress, isValidShieldedAddress) import ZcashHaskell.Sapling (isValidShieldedAddress)
import ZcashHaskell.Transparent
( decodeExchangeAddress
, decodeTransparentAddress
)
import ZcashHaskell.Types
( SaplingAddress(..)
, TransparentAddress(..)
, UnifiedAddress(..)
, ZcashNet(..)
)
import Zenith.Types import Zenith.Types
( AddressGroup(..) ( AddressGroup(..)
, UnifiedAddressDB(..) , UnifiedAddressDB(..)
@ -50,12 +39,6 @@ displayTaz s
| 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 n a =
if n == MainNet
then T.pack $ displayZec a
else T.pack $ displayTaz a
-- | Helper function to display abbreviated Unified Address -- | Helper function to display abbreviated Unified Address
showAddress :: UnifiedAddressDB -> T.Text showAddress :: UnifiedAddressDB -> T.Text
showAddress u = T.take 20 t <> "..." showAddress u = T.take 20 t <> "..."
@ -89,34 +72,3 @@ copyAddress a =
void $ void $
createProcess_ "toClipboard" $ createProcess_ "toClipboard" $
shell $ "echo " ++ T.unpack (addy a) ++ " | xclip -r -selection clipboard" shell $ "echo " ++ T.unpack (addy a) ++ " | xclip -r -selection clipboard"
-- | Bound a value to the 0..1 range, used for progress reporting on UIs
validBarValue :: Float -> Float
validBarValue = clamp (0, 1)
isRecipientValid :: T.Text -> Bool
isRecipientValid a =
case isValidUnifiedAddress (E.encodeUtf8 a) of
Just _a1 -> True
Nothing ->
isValidShieldedAddress (E.encodeUtf8 a) ||
(case decodeTransparentAddress (E.encodeUtf8 a) of
Just _a3 -> True
Nothing ->
case decodeExchangeAddress a of
Just _a4 -> True
Nothing -> False)
parseAddress :: T.Text -> ZcashNet -> Maybe UnifiedAddress
parseAddress a znet =
case isValidUnifiedAddress (E.encodeUtf8 a) of
Just a1 -> Just a1
Nothing ->
case decodeSaplingAddress (E.encodeUtf8 a) of
Just a2 ->
Just $ UnifiedAddress znet Nothing (Just $ sa_receiver a2) Nothing
Nothing ->
case decodeTransparentAddress (E.encodeUtf8 a) of
Just a3 ->
Just $ UnifiedAddress znet Nothing Nothing (Just $ ta_receiver a3)
Nothing -> Nothing

@ -1 +1 @@
Subproject commit e8074419cfb54559a4c09731ad2448d5930869a2 Subproject commit 90c8a7c3028bd6836dea5655221277a25d457653

View file

@ -1,6 +1,6 @@
cabal-version: 3.0 cabal-version: 3.0
name: zenith name: zenith
version: 0.6.0.0-beta version: 0.5.3.0-beta
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Rene Vergara author: Rene Vergara
@ -27,8 +27,6 @@ library
ghc-options: -Wall -Wunused-imports ghc-options: -Wall -Wunused-imports
exposed-modules: exposed-modules:
Zenith.CLI Zenith.CLI
Zenith.GUI
Zenith.GUI.Theme
Zenith.Core Zenith.Core
Zenith.DB Zenith.DB
Zenith.Types Zenith.Types
@ -46,16 +44,13 @@ library
, base64-bytestring , base64-bytestring
, brick , brick
, bytestring , bytestring
, data-default
, directory
, filepath
, esqueleto , esqueleto
, resource-pool , resource-pool
, binary , binary
, exceptions , exceptions
, monad-logger , monad-logger
, vty-crossplatform , vty-crossplatform
, secp256k1-haskell >= 1 , secp256k1-haskell
, pureMD5 , pureMD5
, ghc , ghc
, haskoin-core , haskoin-core
@ -63,13 +58,9 @@ library
, http-client , http-client
, http-conduit , http-conduit
, http-types , http-types
, JuicyPixels
, qrcode-core
, qrcode-juicypixels
, microlens , microlens
, microlens-mtl , microlens-mtl
, microlens-th , microlens-th
, monomer
, mtl , mtl
, persistent , persistent
, Hclip , Hclip
@ -81,7 +72,6 @@ library
, regex-posix , regex-posix
, scientific , scientific
, text , text
, text-show
, time , time
, vector , vector
, vty , vty
@ -102,7 +92,7 @@ executable zenith
, configurator , configurator
, data-default , data-default
, sort , sort
--, structured-cli , structured-cli
, text , text
, time , time
, zenith , zenith