RPC Server #103

Merged
pitmutt merged 16 commits from rav001 into milestone3 2024-11-21 15:30:22 +00:00
19 changed files with 689 additions and 352 deletions

View file

@ -5,6 +5,12 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.7.1.0-beta]
### Changed
- Removed workaround to obtain block time
## [0.7.0.0-beta]
### Added

View file

@ -67,7 +67,7 @@ main = do
zebraPort
(zgb_net chainInfo)
threadDelay 90000000
putStrLn "Zenith RPC Server 0.7.0.0-beta"
putStrLn "Zenith RPC Server 0.8.0.0-beta"
putStrLn "------------------------------"
putStrLn $
"Connected to " ++

View file

@ -9,19 +9,18 @@ constraints: any.Cabal ==3.10.3.0,
any.OneTuple ==0.4.2,
any.OpenGLRaw ==3.3.4.1,
OpenGLRaw -osandroid +usegles2 +useglxgetprocaddress +usenativewindowslibraries,
any.QuickCheck ==2.14.3,
any.QuickCheck ==2.15.0.1,
QuickCheck -old-random +templatehaskell,
any.RSA ==2.4.1,
any.SHA ==1.6.4.4,
SHA -exe,
any.StateVar ==1.2.2,
any.X11 ==1.10.3,
X11 -pedantic,
any.X11 ==1.9.2,
any.adjunctions ==4.4.2,
any.aeson ==2.2.3.0,
aeson +ordered-keymap,
any.alex ==3.5.1.0,
any.ansi-terminal ==1.1.1,
any.ansi-terminal ==1.1.2,
ansi-terminal -example,
any.ansi-terminal-types ==1.1,
any.appar ==0.1.8,
@ -39,11 +38,11 @@ constraints: any.Cabal ==3.10.3.0,
attoparsec -developer,
any.attoparsec-aeson ==2.2.2.0,
any.authenticate-oauth ==1.7,
any.auto-update ==0.2.1,
any.auto-update ==0.2.4,
any.base ==4.18.2.1,
any.base-compat ==0.13.1,
any.base-compat-batteries ==0.13.1,
any.base-orphans ==0.9.2,
any.base-compat ==0.14.1,
any.base-compat-batteries ==0.14.1,
any.base-orphans ==0.9.3,
any.base16 ==1.0,
any.base16-bytestring ==1.0.2.0,
any.base58-bytestring ==0.1.0,
@ -62,18 +61,16 @@ constraints: any.Cabal ==3.10.3.0,
any.boring ==0.2.2,
boring +tagged,
any.borsh ==0.3.0,
any.brick ==2.4,
any.brick ==2.6,
brick -demos,
any.bsb-http-chunked ==0.0.0.4,
any.byteorder ==1.0.4,
any.bytes ==0.17.3,
any.bytes ==0.17.4,
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,
c2hs +base3 -regression,
any.cabal-doctest ==1.0.10,
any.cabal-doctest ==1.0.11,
any.call-stack ==0.4.0,
any.case-insensitive ==1.2.1.0,
any.cborg ==0.2.10.0,
@ -84,10 +81,10 @@ constraints: any.Cabal ==3.10.3.0,
any.clock ==0.8.4,
clock -llvm,
any.colour ==2.3.6,
any.comonad ==5.0.8,
any.comonad ==5.0.9,
comonad +containers +distributive +indexed-traversable,
any.concurrent-output ==1.10.21,
any.conduit ==1.3.5,
any.conduit ==1.3.6,
any.conduit-extra ==1.3.6,
any.config-ini ==0.2.7.0,
config-ini -enable-doctests,
@ -101,21 +98,20 @@ constraints: any.Cabal ==3.10.3.0,
any.crypto-api ==0.13.3,
crypto-api -all_cpolys,
any.crypto-pubkey-types ==0.4.3,
any.crypton ==1.0.0,
any.cryptohash-md5 ==0.11.101.0,
any.cryptohash-sha1 ==0.11.101.0,
any.crypton ==1.0.1,
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.4.3,
any.crypton-x509 ==1.7.7,
any.crypton-x509-store ==1.6.9,
any.crypton-x509-system ==1.6.7,
any.crypton-x509-validation ==1.6.12,
any.crypton-x509-validation ==1.6.13,
any.cryptonite ==0.30,
cryptonite -check_alignment +integer-gmp -old_toolchain_inliner +support_aesni +support_deepseq -support_pclmuldq +support_rdrand -support_sse +use_target_attributes,
any.data-clist ==0.2,
any.data-default ==0.7.1.1,
any.data-default-class ==0.1.2.0,
any.data-default-instances-containers ==0.0.1,
any.data-default-instances-dlist ==0.0.1,
any.data-default-instances-old-locale ==0.0.1,
any.data-default ==0.8.0.0,
any.data-default-class ==0.2.0.0,
any.data-fix ==0.3.4,
any.dec ==0.0.6,
any.deepseq ==1.4.8.1,
@ -129,11 +125,11 @@ constraints: any.Cabal ==3.10.3.0,
any.easy-file ==0.2.5,
any.entropy ==0.4.1.10,
entropy -donotgetentropy,
any.envy ==2.1.3.0,
any.esqueleto ==3.5.11.2,
any.envy ==2.1.4.0,
any.esqueleto ==3.5.13.1,
any.exceptions ==0.10.7,
any.extra ==1.7.16,
any.fast-logger ==3.2.3,
any.extra ==1.8,
any.fast-logger ==3.2.5,
any.file-embed ==0.0.16.0,
any.filepath ==1.4.300.1,
any.fixed ==0.3,
@ -142,8 +138,6 @@ constraints: any.Cabal ==3.10.3.0,
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.generics-sop ==0.5.1.4,
any.ghc ==9.6.5,
@ -153,33 +147,34 @@ constraints: any.Cabal ==3.10.3.0,
any.ghc-heap ==9.6.5,
any.ghc-prim ==0.10.0,
any.ghci ==9.6.5,
any.half ==0.3.1,
any.happy ==1.20.1.1,
any.half ==0.3.2,
any.happy ==2.1.3,
any.happy-lib ==2.1.3,
any.hashable ==1.4.7.0,
hashable -arch-native +integer-gmp -random-initial-seed,
any.haskell-lexer ==1.1.1,
any.haskell-lexer ==1.1.2,
any.haskoin-core ==1.1.0,
any.hexstring ==0.12.1.0,
any.hourglass ==0.2.12,
any.hpc ==0.6.2.0,
any.hsc2hs ==0.68.10,
hsc2hs -in-ghc-tree,
any.hspec ==2.11.9,
any.hspec-core ==2.11.9,
any.hspec-discover ==2.11.9,
any.hspec ==2.11.10,
any.hspec-core ==2.11.10,
any.hspec-discover ==2.11.10,
any.hspec-expectations ==0.8.4,
any.http-api-data ==0.6.1,
http-api-data -use-text-show,
any.http-client ==0.7.17,
http-client +network-uri,
any.http-client-tls ==0.3.6.3,
any.http-conduit ==2.3.8.3,
any.http-client-tls ==0.3.6.4,
any.http-conduit ==2.3.9.1,
http-conduit +aeson,
any.http-date ==0.0.11,
any.http-media ==0.8.1.1,
any.http-semantics ==0.1.2,
any.http-semantics ==0.3.0,
any.http-types ==0.12.4,
any.http2 ==5.2.6,
any.http2 ==5.3.9,
http2 -devel -h2spec,
any.indexed-traversable ==0.1.4,
any.indexed-traversable-instances ==0.1.2,
@ -187,19 +182,19 @@ constraints: any.Cabal ==3.10.3.0,
any.integer-gmp ==1.1,
any.integer-logarithms ==1.0.3.1,
integer-logarithms -check-bounds +integer-gmp,
any.invariant ==0.6.3,
any.iproute ==1.7.12,
any.invariant ==0.6.4,
any.iproute ==1.7.15,
any.kan-extensions ==5.2.6,
any.language-c ==0.9.3,
language-c -allwarnings +iecfpextension +usebytestrings,
any.language-c ==0.10.0,
language-c +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.2.0,
any.lifted-base ==0.2.3.12,
any.linear ==1.22,
linear -herbie +template-haskell,
any.megaparsec ==9.6.1,
any.megaparsec ==9.7.0,
megaparsec -dev,
any.memory ==0.18.0,
memory +support_bytestring +support_deepseq,
@ -213,30 +208,31 @@ constraints: any.Cabal ==3.10.3.0,
monad-logger +template_haskell,
any.monad-loops ==0.4.3,
monad-loops +base4,
any.mono-traversable ==1.0.17.0,
any.mono-traversable ==1.0.21.0,
any.monomer ==1.6.0.1,
monomer -examples,
any.mtl ==2.3.1,
any.murmur3 ==1.0.5,
any.nanovg ==0.8.1.0,
nanovg -examples -gl2 -gles3 -stb_truetype,
any.network ==3.2.1.0,
any.network ==3.2.7.0,
network -devel,
any.network-byte-order ==0.1.7,
any.network-control ==0.1.1,
any.network-control ==0.1.3,
any.network-info ==0.2.1,
any.network-uri ==2.6.4.2,
any.old-locale ==1.0.0.7,
any.old-time ==1.1.0.4,
any.optparse-applicative ==0.18.1.0,
optparse-applicative +process,
any.os-string ==2.0.6,
any.os-string ==2.0.7,
any.parallel ==3.2.2.0,
any.parsec ==3.1.16.1,
any.parser-combinators ==1.3.0,
parser-combinators -dev,
any.path-pieces ==0.2.1,
any.pem ==0.2.4,
any.persistent ==2.14.6.1,
any.persistent ==2.14.6.3,
any.persistent-sqlite ==2.13.3.0,
persistent-sqlite -build-sanity-exe +full-text-search +have-usleep +json1 -systemlib +uri-filenames -use-pkgconfig -use-stat3 +use-stat4,
any.persistent-template ==2.12.0.0,
@ -250,13 +246,13 @@ constraints: any.Cabal ==3.10.3.0,
any.psqueues ==0.2.8.0,
any.pureMD5 ==2.1.4,
pureMD5 -test,
any.qrcode-core ==0.9.9,
any.qrcode-juicypixels ==0.8.5,
any.qrcode-core ==0.9.10,
any.qrcode-juicypixels ==0.8.6,
any.quickcheck-io ==0.2.0,
any.quickcheck-transformer ==0.3.1.2,
any.random ==1.2.1.2,
any.recv ==0.1.0,
any.reflection ==2.1.8,
any.reflection ==2.1.9,
reflection -slow +template-haskell,
any.regex-base ==0.94.0.2,
any.regex-compat ==0.95.2.1,
@ -271,7 +267,7 @@ constraints: any.Cabal ==3.10.3.0,
scientific -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.4.2,
any.semialign ==1.3.1,
semialign +semigroupoids,
any.semigroupoids ==6.0.1,
@ -280,9 +276,9 @@ constraints: any.Cabal ==3.10.3.0,
semigroups +binary +bytestring -bytestring-builder +containers +deepseq +hashable +tagged +template-haskell +text +transformers +unordered-containers,
any.serialise ==0.2.6.1,
serialise +newtime15,
any.servant ==0.20.1,
any.servant-server ==0.20,
any.silently ==1.2.5.3,
any.servant ==0.20.2,
any.servant-server ==0.20.2,
any.silently ==1.2.5.4,
any.simple-sendfile ==0.2.32,
simple-sendfile +allow-bsd -fallback,
any.singleton-bool ==0.1.8,
@ -301,8 +297,10 @@ constraints: any.Cabal ==3.10.3.0,
any.strict ==0.5.1,
any.string-conversions ==0.4.0.1,
any.system-cxx-std-lib ==1.0,
any.tagged ==0.8.8,
any.tagged ==0.8.9,
tagged +deepseq +transformers,
any.tasty ==1.5.2,
tasty +unix,
any.template-haskell ==2.20.0.0,
any.terminal-size ==0.3.4,
any.terminfo ==0.4.1.6,
@ -310,42 +308,43 @@ constraints: any.Cabal ==3.10.3.0,
any.text-iso8601 ==0.1.1,
any.text-short ==0.1.6,
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-show ==3.11,
text-show +integer-gmp,
any.text-zipper ==0.13,
any.tf-random ==0.5,
any.th-abstraction ==0.7.0.0,
any.th-compat ==0.1.5,
any.th-lift ==0.8.4,
any.th-abstraction ==0.7.1.0,
any.th-compat ==0.1.6,
any.th-lift ==0.8.6,
any.th-lift-instances ==0.1.20,
any.these ==1.2.1,
any.time ==1.12.2,
any.time-compat ==1.9.7,
any.time-locale-compat ==0.1.1.5,
time-locale-compat -old-locale,
any.time-manager ==0.1.0,
any.tls ==2.1.0,
any.time-manager ==0.2.1,
any.tls ==2.1.5,
tls -devel,
any.transformers ==0.6.1.0,
any.transformers-base ==0.4.6,
transformers-base +orphaninstances,
any.transformers-compat ==0.7.2,
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
any.typed-process ==0.2.11.1,
any.typed-process ==0.2.12.0,
any.unix ==2.8.4.0,
any.unix-compat ==0.7.2,
any.unix-time ==0.4.15,
any.unix-compat ==0.7.3,
any.unix-time ==0.4.16,
any.unliftio ==0.2.25.0,
any.unliftio-core ==0.2.1.0,
any.unordered-containers ==0.2.20,
unordered-containers -debug,
any.utf8-string ==1.0.2,
any.uuid ==1.3.16,
any.uuid-types ==1.0.6,
any.vault ==0.3.1.5,
vault +useghc,
any.vector ==0.13.1.0,
any.vector ==0.13.2.0,
vector +boundschecks -internalchecks -unsafechecks -wall,
any.vector-algorithms ==0.9.0.2,
any.vector-algorithms ==0.9.0.3,
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
any.vector-stream ==0.1.0.1,
any.void ==0.7.3,
@ -357,10 +356,10 @@ constraints: any.Cabal ==3.10.3.0,
any.wai ==3.2.4,
any.wai-app-static ==3.1.9,
wai-app-static +crypton -print,
any.wai-extra ==3.1.15,
any.wai-extra ==3.1.17,
wai-extra -build-example,
any.wai-logger ==2.4.0,
any.warp ==3.4.1,
any.wai-logger ==2.5.0,
any.warp ==3.4.7,
warp +allow-sendfilefd -network-bytestring -warp-debug +x509,
any.wide-word ==0.1.6.0,
any.witherable ==0.5,
@ -370,4 +369,4 @@ constraints: any.Cabal ==3.10.3.0,
wreq -aws -developer +doctest -httpbin,
any.zlib ==0.7.1.0,
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-12-14T09:52:48Z

Binary file not shown.

Binary file not shown.

View file

@ -79,6 +79,7 @@ import Data.Scientific (Scientific, scientific)
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
import qualified Data.UUID as U
import qualified Data.Vector as Vec
import Database.Persist
import Database.Persist.Sqlite
@ -116,6 +117,7 @@ import Zenith.Types
, ValidAddressAPI(..)
, ZcashNetDB(..)
, ZenithStatus(..)
, ZenithUuid(..)
)
import Zenith.Utils
( displayTaz
@ -528,7 +530,7 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
(str
" _____ _ _ _ \n|__ /___ _ __ (_) |_| |__\n / // _ \\ '_ \\| | __| '_ \\\n / /| __/ | | | | |_| | | |\n/____\\___|_| |_|_|\\__|_| |_|") <=>
C.hCenter
(withAttr titleAttr (str "Zcash Wallet v0.7.0.0-beta")) <=>
(withAttr titleAttr (str "Zcash Wallet v0.7.1.0-beta")) <=>
C.hCenter (withAttr blinkAttr $ str "Press any key..."))
else emptyWidget
capCommand3 :: String -> String -> String -> Widget Name
@ -778,8 +780,8 @@ listDrawTx znet sel tx =
else displayTaz amt
fmtAmt =
if amt > 0
then "" <> dispAmount <> " "
else " " <> dispAmount <> ""
then " " <> dispAmount <> " "
else " " <> dispAmount <> " "
selStr s =
if sel
then withAttr customAttr (txt $ "> " <> s)
@ -894,29 +896,16 @@ scanZebra dbP zHost zPort b eChan znet = do
_ <- liftIO $ completeSync pool Failed
liftIO $ BC.writeBChan eChan $ TickMsg e1
Right blk -> do
r2 <-
liftIO $
makeZebraCall
zHost
zPort
"getblock"
[Data.Aeson.String $ T.pack $ show bl, jsonNumber 0]
case r2 of
Left e2 -> do
_ <- liftIO $ completeSync pool Failed
liftIO $ BC.writeBChan eChan $ TickMsg e2
Right hb -> do
let blockTime = getBlockTime hb
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
blockTime
(ZcashNetDB znet)
mapM_ (processTx zHost zPort bi pool) $ bl_txs blk
liftIO $ BC.writeBChan eChan $ TickVal step
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
(fromIntegral $ bl_time blk)
(ZcashNetDB znet)
mapM_ (processTx zHost zPort bi pool) $ bl_txs blk
liftIO $ BC.writeBChan eChan $ TickVal step
appEvent :: BT.BrickEvent Name Tick -> BT.EventM Name State ()
appEvent (BT.AppEvent t) = do
@ -1296,45 +1285,23 @@ appEvent (BT.VtyEvent e) = do
Just (_j, w1) -> return w1
Just (_k, w) -> return w
fs1 <- BT.zoom deshieldForm $ BT.gets formState
let tAddrMaybe =
Transparent <$>
((decodeTransparentAddress .
E.encodeUtf8 .
encodeTransparentReceiver (s ^. network)) =<<
(t_rec =<<
(isValidUnifiedAddress .
E.encodeUtf8 .
getUA . walletAddressUAddress)
(entityVal selAddr)))
bl <-
liftIO $
getChainTip (s ^. zebraHost) (s ^. zebraPort)
case tAddrMaybe of
Nothing -> do
BT.modify $
set
msg
"Failed to obtain transparent address"
BT.modify $ set displayBox MsgDisplay
BT.modify $ set dialogBox Blank
Just tAddr -> do
_ <-
liftIO $
forkIO $
deshieldTransaction
pool
(s ^. eventDispatch)
(s ^. zebraHost)
(s ^. zebraPort)
(s ^. network)
(entityKey selAcc)
bl
(ProposedNote
(ValidAddressAPI tAddr)
(fs1 ^. shAmt)
Nothing)
BT.modify $ set displayBox SendDisplay
BT.modify $ set dialogBox Blank
_ <-
liftIO $
forkIO $
deshieldTransaction
pool
(s ^. eventDispatch)
(s ^. zebraHost)
(s ^. zebraPort)
(s ^. network)
(entityKey selAcc)
bl
(fs1 ^. shAmt)
BT.modify $ set displayBox SendDisplay
BT.modify $ set dialogBox Blank
else do
BT.modify $ set msg "Invalid inputs"
BT.modify $ set displayBox MsgDisplay
@ -2063,19 +2030,20 @@ shieldTransaction ::
shieldTransaction pool chan zHost zPort znet accId bl = do
BC.writeBChan chan $ TickMsg "Preparing shielding transaction..."
res <- runNoLoggingT $ shieldTransparentNotes pool zHost zPort znet accId bl
forM_ res $ \case
Left e -> BC.writeBChan chan $ TickMsg $ show e
Right rawTx -> do
BC.writeBChan chan $ TickMsg "Transaction ready, sending to Zebra..."
resp <-
makeZebraCall
zHost
zPort
"sendrawtransaction"
[Data.Aeson.String $ toText rawTx]
case resp of
Left e1 -> BC.writeBChan chan $ TickMsg $ "Zebra error: " ++ show e1
Right txId -> BC.writeBChan chan $ TickTx txId
ops <-
mapM
(\case
Left e -> return $ T.pack $ show e
Right x -> do
thisOp <- getOperation pool x
case thisOp of
Nothing -> return ""
Just o ->
return $
(U.toText . getUuid . operationUuid $ entityVal o) <>
": " <> (T.pack . show . operationStatus $ entityVal o))
res
BC.writeBChan chan $ TickMsg $ T.unpack $ T.intercalate "\n" ops
deshieldTransaction ::
ConnectionPool
@ -2085,7 +2053,7 @@ deshieldTransaction ::
-> ZcashNet
-> ZcashAccountId
-> Int
-> ProposedNote
-> Scientific
-> IO ()
deshieldTransaction pool chan zHost zPort znet accId bl pnote = do
BC.writeBChan chan $ TickMsg "Deshielding funds..."

View file

@ -3,6 +3,7 @@
-- | Core wallet functionality for Zenith
module Zenith.Core where
import Control.Concurrent (forkIO)
import Control.Exception (throwIO, try)
import Control.Monad (forM, unless, when)
import Control.Monad.IO.Class (liftIO)
@ -25,6 +26,8 @@ import Data.Scientific (Scientific, scientific, toBoundedInteger)
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import Data.Time
import qualified Data.UUID as U
import Data.UUID.V4 (nextRandom)
import qualified Database.Esqueleto.Experimental as ESQ
import Database.Persist
import Database.Persist.Sqlite
@ -41,6 +44,7 @@ import ZcashHaskell.Orchard
, getOrchardTreeParts
, getOrchardWitness
, isValidUnifiedAddress
, parseAddress
, updateOrchardCommitmentTree
, updateOrchardWitness
)
@ -80,7 +84,10 @@ import Zenith.Types
, ValidAddressAPI(..)
, ZcashNetDB(..)
, ZebraTreeInfo(..)
, ZenithStatus(..)
, ZenithUuid(..)
)
import Zenith.Utils (getTransparentFromUA)
-- * Zebra Node interaction
-- | Checks the status of the `zebrad` node
@ -746,14 +753,37 @@ deshieldNotes ::
-> ZcashNet
-> ZcashAccountId
-> Int
-> ProposedNote
-> Scientific
-> NoLoggingT IO (Either TxError HexString)
deshieldNotes pool zebraHost zebraPort znet za bh pnote = do
bal <- liftIO $ getShieldedBalance pool za
let zats = pn_amt pnote * scientific 1 8
if fromInteger bal > (scientific 2 4 + zats)
then prepareTxV2 pool zebraHost zebraPort znet za bh [pnote] Low
else return $ Left InsufficientFunds
addrs <- getAddresses pool za
let defAddr =
parseAddress $
E.encodeUtf8 $ getUA $ walletAddressUAddress $ entityVal $ head addrs
case defAddr of
Nothing -> return $ Left ZHError
Just (Unified x) -> do
case getTransparentFromUA x of
Nothing -> return $ Left ZHError
Just ta -> do
let zats = pnote * scientific 1 8
if fromInteger bal > (scientific 2 4 + zats)
then prepareTxV2
pool
zebraHost
zebraPort
znet
za
bh
[ ProposedNote
(ValidAddressAPI $ Transparent ta)
pnote
Nothing
]
Low
else return $ Left InsufficientFunds
_anyOther -> return $ Left ZHError
shieldTransparentNotes ::
ConnectionPool
@ -762,8 +792,8 @@ shieldTransparentNotes ::
-> ZcashNet
-> ZcashAccountId
-> Int
-> NoLoggingT IO [Either TxError HexString]
shieldTransparentNotes pool zebraHost zebraPort znet za bh = do
-> NoLoggingT IO [Either TxError U.UUID]
shieldTransparentNotes pool zHost zPort znet za bh = do
accRead <- liftIO $ getAccountById pool za
logDebugN $ T.pack $ "Target block: " ++ show bh
case accRead of
@ -772,58 +802,94 @@ shieldTransparentNotes pool zebraHost zebraPort znet za bh = do
return [Left ZHError]
Just acc -> do
trNotes' <- liftIO $ getWalletUnspentTrNotes pool za
dRecvs <- liftIO $ getReceivers pool trNotes'
let fNotes =
map
(\x ->
filter (\y -> walletTrNoteAddress (entityVal y) == x) trNotes')
dRecvs
sTree <- liftIO $ getSaplingTree pool
oTree <- liftIO $ getOrchardTree pool
forM fNotes $ \trNotes -> do
let noteTotal = getTotalAmount (trNotes, [], [])
tSpends <-
liftIO $
prepTSpends
(getTranSK $ zcashAccountTPrivateKey $ entityVal acc)
trNotes
chgAddr <- getInternalAddresses pool $ entityKey acc
let internalUA =
getUA $ walletAddressUAddress $ entityVal $ head chgAddr
let oRcvr =
fromJust $
o_rec =<< isValidUnifiedAddress (E.encodeUtf8 internalUA)
let dummy =
OutgoingNote
4
(getBytes $ getOrchSK $ zcashAccountOrchSpendKey $ entityVal acc)
(getBytes oRcvr)
(fromIntegral $ noteTotal - 500)
""
True
let feeAmt = calculateTxFee (trNotes, [], []) [dummy]
let snote =
OutgoingNote
4
(getBytes $ getOrchSK $ zcashAccountOrchSpendKey $ entityVal acc)
(getBytes oRcvr)
(fromIntegral $ noteTotal - fromIntegral feeAmt)
""
True
tx <-
liftIO $
createTransaction
(maybe (hexString "00") (getHash . value . fst) sTree)
(maybe (hexString "00") (getHash . value . fst) oTree)
tSpends
[]
[]
[snote]
znet
(bh + 3)
True
logDebugN $ T.pack $ show tx
return tx
if null trNotes'
then return [Left InsufficientFunds]
else do
dRecvs <- liftIO $ getReceivers pool trNotes'
let fNotes =
map
(\x ->
filter
(\y -> walletTrNoteAddress (entityVal y) == x)
trNotes')
dRecvs
sTree <- liftIO $ getSaplingTree pool
oTree <- liftIO $ getOrchardTree pool
forM fNotes $ \trNotes -> do
opid <- liftIO nextRandom
startTime <- liftIO getCurrentTime
opkey <-
liftIO $
saveOperation pool $
Operation (ZenithUuid opid) startTime Nothing Processing Nothing
case opkey of
Nothing -> return $ Left ZHError
Just opkey' -> do
let noteTotal = getTotalAmount (trNotes, [], [])
tSpends <-
liftIO $
prepTSpends
(getTranSK $ zcashAccountTPrivateKey $ entityVal acc)
trNotes
chgAddr <- getInternalAddresses pool $ entityKey acc
let internalUA =
getUA $ walletAddressUAddress $ entityVal $ head chgAddr
let oRcvr =
fromJust $
o_rec =<< isValidUnifiedAddress (E.encodeUtf8 internalUA)
let dummy =
OutgoingNote
4
(getBytes $
getOrchSK $ zcashAccountOrchSpendKey $ entityVal acc)
(getBytes oRcvr)
(fromIntegral $ noteTotal - 500)
""
True
let feeAmt = calculateTxFee (trNotes, [], []) [dummy]
let snote =
OutgoingNote
4
(getBytes $
getOrchSK $ zcashAccountOrchSpendKey $ entityVal acc)
(getBytes oRcvr)
(fromIntegral $ noteTotal - fromIntegral feeAmt)
""
True
_ <-
liftIO $
forkIO $ do
tx <-
liftIO $
createTransaction
(maybe (hexString "00") (getHash . value . fst) sTree)
(maybe (hexString "00") (getHash . value . fst) oTree)
tSpends
[]
[]
[snote]
znet
(bh + 3)
True
case tx of
Left e ->
finalizeOperation pool opkey' Failed $ T.pack $ show e
Right rawTx -> do
zebraRes <-
makeZebraCall
zHost
zPort
"sendrawtransaction"
[Data.Aeson.String $ toText rawTx]
case zebraRes of
Left e1 ->
finalizeOperation pool opkey' Failed $
T.pack $ show e1
Right txId ->
finalizeOperation pool opkey' Successful $
"Tx ID: " <> toText txId
logDebugN $ T.pack $ show opid
return $ Right opid
where
getTotalAmount ::
( [Entity WalletTrNote]

View file

@ -630,6 +630,7 @@ getAddresses pool a =
addrs <- from $ table @WalletAddress
where_ (addrs ^. WalletAddressAccId ==. val a)
where_ (addrs ^. WalletAddressScope ==. val (ScopeDB External))
orderBy [asc $ addrs ^. WalletAddressId]
pure addrs
getAddressById ::

View file

@ -28,6 +28,7 @@ import Data.Scientific (Scientific, fromFloatDigits)
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
import qualified Data.UUID as U
import Database.Esqueleto.Experimental (ConnectionPool, fromSqlKey)
import Database.Persist
import Lens.Micro ((&), (+~), (.~), (?~), (^.), set)
@ -1729,29 +1730,16 @@ scanZebra dbPath zHost zPort net sendMsg = do
_ <- completeSync pool Failed
sendMsg (ShowError $ showt e1)
Right blk -> do
r2 <-
liftIO $
makeZebraCall
zHost
zPort
"getblock"
[Data.Aeson.String $ showt bl, jsonNumber 0]
case r2 of
Left e2 -> do
_ <- completeSync pool Failed
sendMsg (ShowError $ showt e2)
Right hb -> do
let blockTime = getBlockTime hb
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
blockTime
(ZcashNetDB net)
mapM_ (processTx zHost zPort bi pool) $ bl_txs blk
sendMsg (SyncVal step)
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
(fromIntegral $ bl_time blk)
(ZcashNetDB net)
mapM_ (processTx zHost zPort bi pool) $ bl_txs blk
sendMsg (SyncVal step)
shieldTransaction ::
Config -> ZcashNet -> ZcashAccountId -> (AppEvent -> IO ()) -> IO ()
@ -1763,19 +1751,20 @@ shieldTransaction config znet accId sendMsg = do
pool <- runNoLoggingT $ initPool dbPath
bl <- getChainTip zHost zPort
res <- runNoLoggingT $ shieldTransparentNotes pool zHost zPort znet accId bl
forM_ res $ \case
Left e -> sendMsg $ ShowError $ T.pack (show e)
Right rawTx -> do
sendMsg $ ShowMsg "Transaction ready, sending to Zebra..."
resp <-
makeZebraCall
zHost
zPort
"sendrawtransaction"
[Data.Aeson.String $ toText rawTx]
case resp of
Left e1 -> sendMsg $ ShowError $ "Zebra error: " <> T.pack (show e1)
Right txId -> sendMsg $ ShowTxId txId
ops <-
mapM
(\case
Left e -> return $ T.pack $ show e
Right x -> do
thisOp <- getOperation pool x
case thisOp of
Nothing -> return ""
Just o ->
return $
(U.toText . getUuid . operationUuid $ entityVal o) <>
": " <> (T.pack . show . operationStatus $ entityVal o))
res
sendMsg $ ShowMsg $ T.intercalate "\n" ops
deshieldTransaction ::
Config
@ -1795,40 +1784,20 @@ deshieldTransaction config znet accId addR pnote sendMsg = do
let zPort = c_zebraPort config
pool <- runNoLoggingT $ initPool dbPath
bl <- getChainTip zHost zPort
let tAddrMaybe =
Transparent <$>
((decodeTransparentAddress .
E.encodeUtf8 . encodeTransparentReceiver znet) =<<
(t_rec =<<
(isValidUnifiedAddress .
E.encodeUtf8 . getUA . walletAddressUAddress)
(entityVal addr)))
case tAddrMaybe of
Nothing -> sendMsg $ ShowError "No transparent address available"
Just tAddr -> do
res <-
runNoLoggingT $
deshieldNotes
pool
res <- runNoLoggingT $ deshieldNotes pool zHost zPort znet accId bl pnote
case res of
Left e -> sendMsg $ ShowError $ T.pack (show e)
Right rawTx -> do
sendMsg $ ShowModal "Transaction ready, sending to Zebra..."
resp <-
makeZebraCall
zHost
zPort
znet
accId
bl
(ProposedNote (ValidAddressAPI tAddr) pnote Nothing)
case res of
Left e -> sendMsg $ ShowError $ T.pack (show e)
Right rawTx -> do
sendMsg $ ShowModal "Transaction ready, sending to Zebra..."
resp <-
makeZebraCall
zHost
zPort
"sendrawtransaction"
[Data.Aeson.String $ toText rawTx]
case resp of
Left e1 -> sendMsg $ ShowError $ "Zebra error: " <> showt e1
Right txId -> sendMsg $ ShowTxId txId
"sendrawtransaction"
[Data.Aeson.String $ toText rawTx]
case resp of
Left e1 -> sendMsg $ ShowError $ "Zebra error: " <> showt e1
Right txId -> sendMsg $ ShowTxId txId
sendTransaction ::
Config
@ -2023,7 +1992,7 @@ runZenithGUI config = do
Left _e -> print "Zebra not available"
where
params hd =
[ appWindowTitle "Zenith - Zcash Full Node Wallet"
[ appWindowTitle "Zenith - Zcash Full Node Wallet - 0.7.1.0-beta"
, appWindowState $ MainWindowNormal (1000, 700)
, appTheme zenithTheme
, appFontDef

View file

@ -20,7 +20,7 @@ import Control.Monad.Logger (runFileLoggingT, runNoLoggingT, runStderrLoggingT)
import Data.Aeson
import qualified Data.HexString as H
import Data.Int
import Data.Scientific (floatingOrInteger)
import Data.Scientific (Scientific(..), floatingOrInteger)
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import Data.Time.Clock (getCurrentTime)
@ -50,7 +50,9 @@ import Zenith.Core
( checkBlockChain
, createCustomWalletAddress
, createZcashAccount
, deshieldNotes
, prepareTxV2
, shieldTransparentNotes
, syncWallet
, updateCommitmentTrees
)
@ -121,6 +123,8 @@ data ZenithMethod
| GetNewAddress
| GetOperationStatus
| SendMany
| ShieldNotes
| DeshieldFunds
| UnknownMethod
deriving (Eq, Prelude.Show)
@ -136,6 +140,8 @@ instance ToJSON ZenithMethod where
toJSON GetNewAddress = Data.Aeson.String "getnewaddress"
toJSON GetOperationStatus = Data.Aeson.String "getoperationstatus"
toJSON SendMany = Data.Aeson.String "sendmany"
toJSON ShieldNotes = Data.Aeson.String "shieldnotes"
toJSON DeshieldFunds = Data.Aeson.String "deshieldfunds"
toJSON UnknownMethod = Data.Aeson.Null
instance FromJSON ZenithMethod where
@ -152,6 +158,8 @@ instance FromJSON ZenithMethod where
"getnewaddress" -> pure GetNewAddress
"getoperationstatus" -> pure GetOperationStatus
"sendmany" -> pure SendMany
"shieldnotes" -> pure ShieldNotes
"deshieldfunds" -> pure DeshieldFunds
_ -> pure UnknownMethod
data ZenithParams
@ -167,6 +175,8 @@ data ZenithParams
| OpParams !ZenithUuid
| SendParams !Int ![ProposedNote] !PrivacyPolicy
| TestParams !T.Text
| ShieldNotesParams !Int
| DeshieldParams !Int !Scientific
deriving (Eq, Prelude.Show)
instance ToJSON ZenithParams where
@ -191,6 +201,9 @@ instance ToJSON ZenithParams where
Data.Aeson.Array $ V.fromList [Data.Aeson.String $ U.toText $ getUuid i]
toJSON (SendParams i ns p) =
Data.Aeson.Array $ V.fromList [jsonNumber i, toJSON ns, toJSON p]
toJSON (ShieldNotesParams i) = Data.Aeson.Array $ V.fromList [jsonNumber i]
toJSON (DeshieldParams i s) =
Data.Aeson.Array $ V.fromList [jsonNumber i, Data.Aeson.Number s]
data ZenithResponse
= InfoResponse !T.Text !ZenithInfo
@ -203,6 +216,7 @@ data ZenithResponse
| NewAddrResponse !T.Text !ZcashAddressAPI
| OpResponse !T.Text !Operation
| SendResponse !T.Text !U.UUID
| MultiOpResponse !T.Text ![T.Text]
| ErrorResponse !T.Text !Double !T.Text
deriving (Eq, Prelude.Show)
@ -224,6 +238,7 @@ instance ToJSON ZenithResponse where
toJSON (NewAddrResponse i a) = packRpcResponse i a
toJSON (OpResponse i u) = packRpcResponse i u
toJSON (SendResponse i o) = packRpcResponse i o
toJSON (MultiOpResponse i o) = packRpcResponse i o
instance FromJSON ZenithResponse where
parseJSON =
@ -298,6 +313,9 @@ instance FromJSON ZenithResponse where
k5 <- parseJSON r1
pure $ NoteListResponse i k5
Nothing -> fail "Unknown object"
String s -> do
k7 <- parseJSON r1
pure $ MultiOpResponse i k7
_anyOther -> fail "Malformed JSON"
Number k -> do
case floatingOrInteger k of
@ -489,6 +507,27 @@ instance FromJSON RpcCall where
_anyOther -> pure $ RpcCall v i SendMany BadParams
else pure $ RpcCall v i SendMany BadParams
_anyOther -> pure $ RpcCall v i SendMany BadParams
ShieldNotes -> do
p <- obj .: "params"
case p of
Array a ->
if V.length a == 1
then do
x <- parseJSON $ a V.! 0
pure $ RpcCall v i ShieldNotes (ShieldNotesParams x)
else pure $ RpcCall v i ShieldNotes BadParams
_anyOther -> pure $ RpcCall v i ShieldNotes BadParams
DeshieldFunds -> do
p <- obj .: "params"
case p of
Array a ->
if V.length a == 2
then do
x <- parseJSON $ a V.! 0
y <- parseJSON $ a V.! 1
pure $ RpcCall v i DeshieldFunds (DeshieldParams x y)
else pure $ RpcCall v i DeshieldFunds BadParams
_anyOther -> pure $ RpcCall v i DeshieldFunds BadParams
type ZenithRPC
= "status" :> Get '[ JSON] Value :<|> BasicAuth "zenith-realm" Bool :> ReqBody
@ -511,7 +550,7 @@ zenithServer state = getinfo :<|> handleRPC
getinfo =
return $
object
[ "version" .= ("0.7.0.0-beta" :: String)
[ "version" .= ("0.8.0.0-beta" :: String)
, "network" .= ("testnet" :: String)
]
handleRPC :: Bool -> RpcCall -> Handler ZenithResponse
@ -587,7 +626,7 @@ zenithServer state = getinfo :<|> handleRPC
return $
InfoResponse
(callId req)
(ZenithInfo "0.7.0.0-beta" (w_network state) (w_build state))
(ZenithInfo "0.8.0.0-beta" (w_network state) (w_build state))
_anyOtherParams ->
return $ ErrorResponse (callId req) (-32602) "Invalid params"
ListReceived ->
@ -871,6 +910,137 @@ zenithServer state = getinfo :<|> handleRPC
"Account does not exist."
_anyOtherParams ->
return $ ErrorResponse (callId req) (-32602) "Invalid params"
ShieldNotes -> do
case parameters req of
ShieldNotesParams i -> do
let dbPath = w_dbPath state
let net = w_network state
let zHost = w_host state
let zPort = w_port state
pool <- liftIO $ runNoLoggingT $ initPool dbPath
syncChk <- liftIO $ isSyncing pool
if syncChk
then return $
ErrorResponse
(callId req)
(-32012)
"The Zenith server is syncing, please try again later."
else do
acc <-
liftIO $ getAccountById pool $ toSqlKey $ fromIntegral i
case acc of
Just acc' -> do
bl <-
liftIO $
getLastSyncBlock
pool
(zcashAccountWalletId $ entityVal acc')
opids <-
liftIO $
runNoLoggingT $
shieldTransparentNotes
pool
zHost
zPort
net
(entityKey acc')
bl
let ops =
map
(\case
Left e -> T.pack $ show e
Right op -> U.toText op)
opids
return $ MultiOpResponse (callId req) ops
Nothing ->
return $
ErrorResponse
(callId req)
(-32006)
"Account does not exist."
_anyOtherParams ->
return $ ErrorResponse (callId req) (-32602) "Invalid params"
DeshieldFunds -> do
case parameters req of
DeshieldParams i k -> do
let dbPath = w_dbPath state
let net = w_network state
let zHost = w_host state
let zPort = w_port state
pool <- liftIO $ runNoLoggingT $ initPool dbPath
syncChk <- liftIO $ isSyncing pool
if syncChk
then return $
ErrorResponse
(callId req)
(-32012)
"The Zenith server is syncing, please try again later."
else do
opid <- liftIO nextRandom
startTime <- liftIO getCurrentTime
opkey <-
liftIO $
saveOperation pool $
Operation
(ZenithUuid opid)
startTime
Nothing
Processing
Nothing
case opkey of
Nothing ->
return $
ErrorResponse (callId req) (-32010) "Internal Error"
Just opkey' -> do
acc <-
liftIO $ getAccountById pool $ toSqlKey $ fromIntegral i
case acc of
Just acc' -> do
bl <-
liftIO $
getLastSyncBlock
pool
(zcashAccountWalletId $ entityVal acc')
_ <-
liftIO $
forkIO $ do
res <-
runNoLoggingT $
deshieldNotes
pool
zHost
zPort
net
(entityKey acc')
bl
k
case res of
Left e ->
finalizeOperation pool opkey' Failed $
T.pack $ show e
Right rawTx -> do
zebraRes <-
makeZebraCall
zHost
zPort
"sendrawtransaction"
[Data.Aeson.String $ H.toText rawTx]
case zebraRes of
Left e1 ->
finalizeOperation pool opkey' Failed $
T.pack $ show e1
Right txId ->
finalizeOperation pool opkey' Successful $
"Tx ID: " <> H.toText txId
return $ SendResponse (callId req) opid
Nothing ->
return $
ErrorResponse
(callId req)
(-32006)
"Account does not exist."
_anyOtherParams ->
return $ ErrorResponse (callId req) (-32602) "Invalid params"
authenticate :: Config -> BasicAuthCheck Bool
authenticate config = BasicAuthCheck check
@ -932,22 +1102,12 @@ scanZebra dbPath zHost zPort net = do
case r of
Left _ -> completeSync pool Failed
Right blk -> do
r2 <-
makeZebraCall
zHost
zPort
"getblock"
[Data.Aeson.String $ T.pack (show bl), jsonNumber 0]
case r2 of
Left _ -> completeSync pool Failed
Right hb -> do
let blockTime = getBlockTime hb
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
blockTime
(ZcashNetDB net)
mapM_ (processTx zHost zPort bi pool) $ bl_txs blk
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
(fromIntegral $ bl_time blk)
(ZcashNetDB net)
mapM_ (processTx zHost zPort bi pool) $ bl_txs blk

View file

@ -133,29 +133,16 @@ processBlock host port pool pg net b = do
_ <- completeSync pool Failed
liftIO $ throwIO $ userError e
Right blk -> do
r2 <-
liftIO $
makeZebraCall
host
port
"getblock"
[Data.Aeson.String $ T.pack $ show b, jsonNumber 0]
case r2 of
Left e2 -> do
_ <- completeSync pool Failed
liftIO $ throwIO $ userError e2
Right hb -> do
let blockTime = getBlockTime hb
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
blockTime
net
mapM_ (processTx host port bi pool) $ bl_txs blk
liftIO $ tick pg
bi <-
saveBlock pool $
ZcashBlock
(fromIntegral $ bl_height blk)
(HexStringDB $ bl_hash blk)
(fromIntegral $ bl_confirmations blk)
(fromIntegral $ bl_time blk)
net
mapM_ (processTx host port bi pool) $ bl_txs blk
liftIO $ tick pg
-- | Function to process a raw transaction
processTx ::

View file

@ -235,7 +235,7 @@ isValidString c = do
padWithZero :: Int -> String -> String
padWithZero n s
| (length s) >= n = s
| length s >= n = s
| otherwise = padWithZero n ("0" ++ s)
isEmpty :: [a] -> Bool
@ -248,3 +248,6 @@ getChainTip zHost zPort = do
case r of
Left e1 -> pure 0
Right i -> pure i
getTransparentFromUA :: UnifiedAddress -> Maybe TransparentAddress
getTransparentFromUA ua = TransparentAddress (ua_net ua) <$> t_rec ua

View file

@ -86,7 +86,7 @@ main = do
Left e -> assertFailure e
Right r ->
r `shouldBe`
InfoResponse "zh" (ZenithInfo "0.7.0.0-beta" TestNet "v1.9.0")
InfoResponse "zh" (ZenithInfo "0.8.0.0-beta" TestNet "v2.1.0")
describe "Wallets" $ do
describe "listwallet" $ do
it "bad credentials" $ do
@ -676,6 +676,54 @@ main = do
case res of
Left e -> assertFailure e
Right (SendResponse i o) -> o `shouldNotBe` U.nil
describe "Shield notes" $ do
it "bad credentials" $ do
res <-
makeZenithCall
"127.0.0.1"
nodePort
"baduser"
"idontknow"
ShieldNotes
BlankParams
res `shouldBe` Left "Invalid credentials"
describe "correct credentials" $ do
it "no parameters" $ do
res <-
makeZenithCall
"127.0.0.1"
nodePort
nodeUser
nodePwd
ShieldNotes
BlankParams
case res of
Left e -> assertFailure e
Right (ErrorResponse i c m) -> c `shouldBe` (-32602)
it "invalid account" $ do
res <-
makeZenithCall
"127.0.0.1"
nodePort
nodeUser
nodePwd
ShieldNotes
(ShieldNotesParams 27)
case res of
Left e -> assertFailure e
Right (ErrorResponse i c m) -> c `shouldBe` (-32006)
it "valid account" $ do
res <-
makeZenithCall
"127.0.0.1"
nodePort
nodeUser
nodePwd
ShieldNotes
(ShieldNotesParams 1)
case res of
Left e -> assertFailure e
Right (MultiOpResponse i c) -> c `shouldNotBe` []
startAPI :: Config -> IO ()
startAPI config = do

View file

@ -643,8 +643,7 @@ main = do
case ix of
Nothing -> assertFailure "couldn't find index at block"
Just i -> do
updatedTree <-
runFileLoggingT "test.log" $ truncateTree oTree i
updatedTree <- runNoLoggingT $ truncateTree oTree i
let finalAnchor =
getOrchardTreeAnchor $
OrchardCommitmentTree $ ztiOrchard zebraTreesIn
@ -737,7 +736,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -763,7 +762,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -787,7 +786,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -815,7 +814,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -847,7 +846,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -873,7 +872,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -897,7 +896,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -926,7 +925,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -957,7 +956,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -983,7 +982,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -1007,7 +1006,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -1034,7 +1033,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -1061,7 +1060,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"
@ -1086,7 +1085,7 @@ main = do
Just ua -> do
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
tx <-
runFileLoggingT "zenith.log" $
runNoLoggingT $
prepareTxV2
pool
"localhost"

@ -1 +1 @@
Subproject commit d45bd7dcf3c3cf4e893900a1774d24b14bf56591
Subproject commit 7d3ae36d2b48b8ed91a70e40a77fb7efe57765a0

View file

@ -1,7 +1,7 @@
{
"openrpc": "1.0.0-rc1",
"info": {
"version": "0.7.0.0-beta",
"version": "0.8.0.0-beta",
"title": "Zenith RPC",
"description": "The RPC methods to interact with the Zenith Zcash wallet",
"license": {
@ -605,10 +605,9 @@
],
"paramStructure": "by-position",
"result": {
"name": "Operation ID(s)",
"name": "Operation ID",
"schema": {
"type": "array",
"items": { "$ref": "#/components/contentDescriptors/OperationId"}
"$ref": "#/components/contentDescriptors/OperationId"
}
},
"examples": [
@ -620,7 +619,7 @@
{
"name": "Account index",
"summary": "The index for the account to use",
"value": "1"
"value": 1
},
{
"name": "Privacy Policy",
@ -641,9 +640,8 @@
],
"result": {
"name": "SendMany result",
"value": [
"3cc31c07-07cf-4a6e-9190-156c4b8c4088"
]
"value": "3cc31c07-07cf-4a6e-9190-156c4b8c4088"
}
}
],
@ -669,6 +667,130 @@
"errors": [
{ "$ref": "#/components/errors/OpNotFound" }
]
},
{
"name": "shieldnotes",
"summary": "Shield all transparent notes into the Orchard pool for the given account",
"description": "Creates one or more transactions, grouping all the unspent transparent notes for the given account by their transparent address to avoid associating different transparent addresses. These notes are sent to the given account's internal change address as shielded Orchard notes.",
"tags": [],
"params": [
{ "$ref": "#/components/contentDescriptors/AccountId"}
],
"paramStructure": "by-position",
"result": {
"name": "Operation ID(s)",
"schema": {
"type": "array",
"items": { "$ref": "#/components/contentDescriptors/OperationId"}
}
},
"examples": [
{
"name": "Shield transparent notes",
"summary": "Shield transparent notes",
"description": "Shield the transparent notes in a given account",
"params": [
{
"name": "Account index",
"summary": "The index for the account to use",
"value": "3"
}
],
"result": {
"name": "ShieldNotes result",
"value": [
"ab350df0-9f57-44c0-9e0d-f7b8af1f4231",
"8c6f2656-22ef-4f9d-b465-80ddd13fc485"
]
}
},
{
"name": "No transparent funds",
"summary": "Shield transparent notes with no transparent funds",
"description": "Attempt to shield the transparent notes in a given account, when account has none",
"params": [
{
"name": "Account index",
"summary": "The index for the account to use",
"value": "3"
}
],
"result": {
"name": "ShieldNotes result",
"value": [
"InsufficientFunds"
]
}
}
],
"errors": [
{ "$ref": "#/components/errors/ZebraNotAvailable" },
{ "$ref": "#/components/errors/ZenithBusy" },
{ "$ref": "#/components/errors/InvalidAccount" }
]
},
{
"name": "deshieldfunds",
"summary": "De-shield the given amount of ZEC from the given account",
"description": "Creates a new internal transaction with the requested amount of ZEC to the transparent pool. The fee is not included in the given amount.",
"tags": [],
"params": [
{ "$ref": "#/components/contentDescriptors/AccountId"},
{ "$ref": "#/components/contentDescriptors/Amount"}
],
"paramStructure": "by-position",
"result": {
"name": "Operation ID",
"schema": {
"$ref": "#/components/contentDescriptors/OperationId"
}
},
"examples": [
{
"name": "De-Shield funds",
"summary": "De-shield funds",
"description": "Move the given amount of ZEC for the given acount from the shielded pool to the transparent pool",
"params": [
{
"name": "Account index",
"summary": "The index for the account to use",
"value": "3"
},
{
"name": "Amount",
"summary": "The amount of ZEC to use",
"value": 1.23
}
],
"result": {
"name": "Deshield funds result",
"value": "ab350df0-9f57-44c0-9e0d-f7b8af1f4231"
}
},
{
"name": "No transparent funds",
"summary": "Shield transparent notes with no transparent funds",
"description": "Attempt to shield the transparent notes in a given account, when account has none",
"params": [
{
"name": "Account index",
"summary": "The index for the account to use",
"value": "3"
}
],
"result": {
"name": "ShieldNotes result",
"value": [
"InsufficientFunds"
]
}
}
],
"errors": [
{ "$ref": "#/components/errors/ZebraNotAvailable" },
{ "$ref": "#/components/errors/ZenithBusy" },
{ "$ref": "#/components/errors/InvalidAccount" }
]
}
],
"components": {
@ -700,6 +822,15 @@
"type": "string"
}
},
"Amount": {
"name": "A numeric amount",
"summary": "A numeric amount",
"description": "A number that represents an amount to be used by a function as an input",
"required": true,
"schema": {
"type": "number"
}
},
"Name": {
"name": "Name",
"summary": "A user-friendly name",

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 KiB